Documentation
¶
Overview ¶
Package vm implement a stack based virtual machine.
Index ¶
- Constants
- Variables
- func DumpFrame(w io.Writer, mem []Value, code Code, fp, sp, narg, nret int, di *DebugInfo)
- func DumpFrameStderr(mem []Value, code Code, fp, sp, narg, nret int, di *DebugInfo)
- func RegisterArgProxy(fn any, arg int, factory ProxyFactory)
- func RegisterArgProxyMethod(recvInstance any, methodName string, arg int, factory ProxyFactory)
- func Vstring(lv []Value) string
- type Closure
- type Code
- type DebugInfo
- type EmbeddedField
- type Iface
- type IfaceMethod
- type Instruction
- type LocalVar
- type Machine
- func (m *Machine) CallFunc(fval Value, funcType reflect.Type, args []reflect.Value) ([]reflect.Value, error)
- func (m *Machine) DumpCallStack(w io.Writer, di *DebugInfo)
- func (m *Machine) DumpCallStackStderr(di *DebugInfo)
- func (m *Machine) MakeMethodCallable(ifc Iface, method Method) Value
- func (m *Machine) MethodByName(t *Type, name string) (Method, bool)
- func (m *Machine) Out() io.Writer
- func (m *Machine) PopExit()
- func (m *Machine) Push(v ...Value) (l int)
- func (m *Machine) PushCode(code ...Instruction) (p int)
- func (m *Machine) Run() (err error)
- func (m *Machine) SetDebugIO(in io.Reader, out io.Writer)
- func (m *Machine) SetDebugInfo(fn func() *DebugInfo)
- func (m *Machine) SetIO(in io.Reader, out, err io.Writer)
- func (m *Machine) SetIP(ip int)
- func (m *Machine) Top() (v Value)
- func (m *Machine) TrimStack()
- type Method
- type MvmFunc
- type Op
- type Opaque
- type Pos
- type ProxyFactory
- type SelectCaseInfo
- type SelectMeta
- type Type
- func ArrayOf(length int, t *Type) *Type
- func ChanOf(dir reflect.ChanDir, elem *Type) *Type
- func FuncOf(arg, ret []*Type, variadic bool) *Type
- func MapOf(k, e *Type) *Type
- func NewStructType() *Type
- func PointerTo(t *Type) *Type
- func SliceOf(t *Type) *Type
- func StructOf(fields []*Type, embedded []EmbeddedField, tags []string) *Type
- func TypeOf(v any) *Type
- func (t *Type) Elem() *Type
- func (t *Type) EnsureIfaceMethods()
- func (t *Type) FieldIndex(name string) []int
- func (t *Type) FieldLookup(name string) ([]int, *Type)
- func (t *Type) FieldType(name string) *Type
- func (t *Type) Implements(iface *Type) bool
- func (t *Type) IsInterface() bool
- func (t *Type) IsPtr() bool
- func (t *Type) Key() *Type
- func (t *Type) MissingMethod(rt reflect.Type) string
- func (t *Type) NativeImplements(rt reflect.Type) bool
- func (t *Type) Out(i int) *Type
- func (t *Type) ReturnType(i int) *Type
- func (t *Type) SameAs(u *Type) bool
- func (t *Type) SetFields(src *Type)
- func (t *Type) String() string
- type TypeElem
- type Value
- func (v Value) Addr() reflect.Value
- func (v Value) Bool() bool
- func (v Value) CanAddr() bool
- func (v Value) CanInt() bool
- func (v Value) CopyArray() Value
- func (v Value) Elem() reflect.Value
- func (v Value) Equal(u Value) bool
- func (v Value) Field(i int) reflect.Value
- func (v Value) FieldByIndex(index []int) reflect.Value
- func (v Value) Float() float64
- func (v Value) IfaceVal() Iface
- func (v Value) Index(i int) reflect.Value
- func (v Value) Int() int64
- func (v Value) Interface() any
- func (v Value) IsIface() bool
- func (v Value) IsValid() bool
- func (v Value) Kind() reflect.Kind
- func (v Value) Len() int
- func (v Value) MapIndex(key reflect.Value) reflect.Value
- func (v Value) Reflect() reflect.Value
- func (v Value) Seq() iter.Seq[reflect.Value]
- func (v Value) Seq2() iter.Seq2[reflect.Value, reflect.Value]
- func (v Value) Set(x reflect.Value)
- func (v Value) SetMapIndex(key, elem reflect.Value)
- func (v Value) Slice(i, j int) reflect.Value
- func (v Value) Slice3(i, j, k int) reflect.Value
- func (v Value) Type() reflect.Type
- func (v Value) Uint() uint64
- func (v Value) UnwrapType() (reflect.Type, bool)
Constants ¶
const ( Global = 0 Local = 1 )
Memory attributes.
const CallSpreadFlag int32 = 1 << 15
CallSpreadFlag is set in the B operand of Call to indicate a spread call (f(s...)), so the VM uses reflect.CallSlice instead of reflect.Call for native variadic functions.
Variables ¶
var AnyRtype = reflect.TypeOf((*any)(nil)).Elem()
AnyRtype is the reflect.Type for the empty interface (any).
var Bridges = map[string]reflect.Type{}
Bridges maps interface method names to their bridge pointer types. Each bridge type is a struct with a Fn field and a pointer-receiver method that delegates to Fn. Populated at init time by stdlib (or any compiled package binding). The VM uses these to build wrapper types that make interpreted values satisfy Go interfaces at the native call boundary.
var CompositeBridges = map[[2]string]reflect.Type{}
CompositeBridges maps sorted pairs of method names to composite bridge pointer types that implement both methods. Used to preserve additional interface capabilities when wrapping for a single-method target interface (e.g. wrapping a Reader+WriterTo value for an io.Reader parameter keeps the WriterTo capability so io.Copy's internal type assertion succeeds).
var DisplayBridges = map[string]bool{}
DisplayBridges is the subset of Bridges that should be used when the target type is interface{}/any. These are "display" methods (String, Error, GoString, etc.) that change how the value appears in fmt output. Behavioral methods (Write, Read, Close) are NOT in this set because wrapping a value as e.g. BridgeWrite for an interface{} parameter changes its identity without benefit.
var InterfaceBridges = map[reflect.Type]reflect.Type{}
InterfaceBridges maps Go interface types to bridge pointer types that implement all methods of the interface. Each bridge struct has fields named Fn<MethodName> for each method. Used for multi-method interfaces like heap.Interface or sort.Interface.
var NumKindOffset [reflect.Float64 + 1]int
NumKindOffset maps a reflect.Kind to a 0-based offset into per-type opcode blocks. Returns -1 for non-numeric kinds.
var OpaqueRtype = reflect.TypeFor[Opaque]()
OpaqueRtype is the reflect.Type for Opaque.
var ValBridgeTypes = map[reflect.Type]bool{}
ValBridgeTypes is the set of bridge pointer types that carry a Val field holding the original concrete value. Populated at init time by stdlib.
Functions ¶
func DumpFrame ¶
DumpFrame decodes and pretty-prints the call frame at the given fp. di is optional (may be nil); when set, slots are annotated with variable names.
func DumpFrameStderr ¶
DumpFrameStderr is a convenience wrapper that prints to stderr.
func RegisterArgProxy ¶
func RegisterArgProxy(fn any, arg int, factory ProxyFactory)
RegisterArgProxy installs a ProxyFactory for argument arg of the native function fn. arg is zero-based. reflect.ValueOf(fn).Pointer() is used as the key. For methods, use RegisterArgProxyMethod instead.
func RegisterArgProxyMethod ¶
func RegisterArgProxyMethod(recvInstance any, methodName string, arg int, factory ProxyFactory)
RegisterArgProxyMethod installs a ProxyFactory for argument arg of the named method on recvInstance's type. arg is the zero-based index into the explicit (non-receiver) argument list. recvInstance may be a typed-nil pointer (e.g. (*Encoder)(nil)); only its type is used.
Types ¶
type Closure ¶
type Closure struct {
Code int // code address (same as the plain-int function value)
Heap []*Value // heap-allocated cells, one per captured variable
}
Closure bundles a function code address with its captured variables.
type DebugInfo ¶
type DebugInfo struct {
Sources scan.Sources // source position registry (multi-file / REPL)
Labels map[int]string // code address -> label/function name
Globals map[int]string // data index -> symbol name
Locals map[string][]LocalVar // function name -> local variable list
}
DebugInfo holds symbolic information for annotating debug output. Built by the compiler from the symbol table and source registry.
func NewDebugInfo ¶
func NewDebugInfo() *DebugInfo
NewDebugInfo returns an empty DebugInfo ready to be populated.
type EmbeddedField ¶
type EmbeddedField struct {
FieldIdx int // index of this field in the parent struct
Type *Type // mvm type of the embedded field (shares identity with symbol table)
}
EmbeddedField records a mvm embedded field within a struct type.
type Iface ¶
type Iface struct {
Typ *Type // concrete mvm type (carries Name for method lookup)
Val Value // the concrete value
}
Iface represents a boxed interface value at runtime. It preserves the concrete mvm type identity for dynamic method dispatch.
type IfaceMethod ¶
type IfaceMethod struct {
Name string
ID int // global method ID; -1 = not yet assigned
Rtype reflect.Type // method signature (with receiver as 1st param); nil if unknown
}
IfaceMethod describes a method required by an interface type.
type Instruction ¶
Instruction represents a virtual machine bytecode instruction (16 bytes). Fields A, B hold up to 2 immediate operands (0 when unused).
func (Instruction) String ¶
func (i Instruction) String() (s string)
type LocalVar ¶
type LocalVar struct {
Offset int // offset from fp (1-based, as in Get Local N)
Name string // variable name (short, without scope prefix)
}
LocalVar describes a local variable within a function frame.
type Machine ¶
type Machine struct {
MethodNames []string // names by global method ID
// contains filtered or unexported fields
}
Machine is a stack-based virtual machine that executes bytecode instructions.
func (*Machine) CallFunc ¶
func (m *Machine) CallFunc(fval Value, funcType reflect.Type, args []reflect.Value) ([]reflect.Value, error)
CallFunc executes a mvm function value with the given arguments and returns the results. It saves and restores all execution state so it can be called from native Go callbacks (reflect.MakeFunc wrappers) even while Run is in progress (single-threaded re-entrancy).
func (*Machine) DumpCallStack ¶
DumpCallStack walks the frame pointer chain and prints every frame.
func (*Machine) DumpCallStackStderr ¶
DumpCallStackStderr is a convenience wrapper that prints to stderr.
func (*Machine) MakeMethodCallable ¶
MakeMethodCallable returns a mvm func Value suitable for Machine.CallFunc. The receiver cell is constructed with method.Path applied.
func (*Machine) MethodByName ¶
MethodByName returns the first resolved method named `name` reachable from t. For pointer types, methods declared on the element type are also searched (mvm registers methods on the base type T, not *T). Struct-field *Type shallow copies preserve a Base back-pointer to the source type so methods registered after the copy was taken (typical when a struct is defined before its methods) remain reachable. Returns (Method, true) on hit.
func (*Machine) PopExit ¶
func (m *Machine) PopExit()
PopExit removes the last machine code instruction if is Exit.
func (*Machine) Push ¶
Push pushes data values into the machine's global storage. Globals are always loaded via Push before Run is called.
func (*Machine) PushCode ¶
func (m *Machine) PushCode(code ...Instruction) (p int)
PushCode adds instructions to the machine code (with zero source positions).
func (*Machine) SetDebugIO ¶
SetDebugIO sets the I/O streams for the interactive debug mode.
func (*Machine) SetDebugInfo ¶
SetDebugInfo registers a function that builds DebugInfo on demand.
type Method ¶
type Method struct {
Index int // data index of code address (-1 if unset or EmbedIface)
Path []int // field index path to embedded receiver (nil = direct, []int{} = deref only)
EmbedIface bool // Path leads to an embedded interface field; dispatch through it
PtrRecv bool // true if the method has a pointer receiver (e.g. *T)
}
Method records a method's code location and receiver path for interface dispatch.
func (Method) IsResolved ¶
IsResolved reports whether this method slot has been populated with either a compiled code address or an embedded-interface dispatch entry.
type MvmFunc ¶
type MvmFunc struct {
Val Value // mvm func (int code addr or Closure)
GF reflect.Value // reflect.MakeFunc wrapper for native Go callbacks
}
MvmFunc bundles a mvm func value with its native Go reflect.MakeFunc wrapper. Stored when a mvm func is assigned to a struct field of func type: GF is callable from native Go (HTTP handlers, callbacks, etc.); Val is the original mvm func dispatched directly by the VM.
type Op ¶
type Op int32
Op is a VM opcode (bytecode instruction).
const ( // Instruction effect on stack: values consumed -- values produced. Nop Op = iota // -- Addr // a -- &a ; AddrLocal // -- &local ; push pointer to mem[fp-1+$1]; promotes slot to addressable storage on first use so writes via the pointer propagate back Append // slice [v0..vn-1] -- slice' ; append $0 values to slice AppendSlice // slice [v0..vn-1] -- slice' ; pack $0 values into []T, reflect.AppendSlice; elem type at mem[$1]; $0=0 means spread mode: append(a, b...) Call // f [a1 .. ai] -- [r1 .. rj] ; r1, ... = prog[f](a1, ...); B bit 15 = spread flag CallImm // [a1 .. ai] -- [r1 .. rj] ; $1=dataIdx of func, $2=narg<<16|nret Cap // -- x ; x = cap(mem[sp-$0]) Convert // v -- v' ; v' = convert(v, type at mem[$1]); optional $2 = stack depth offset CopySlice // dst src -- n ; n = copy(dst, src) DeferPush // func [a0..an-1] -- func [a0..an-1] [packed prevHead retIP] ; register deferred call on stack; $0=narg, $1=1 if native DeferRet // -- ; sentinel: restore outer frame after a deferred call returns DeleteMap // map key -- ; delete(map, key) Deref // x -- *x ; DerefSet // ptr val -- ; *ptr = val Equal // n1 n2 -- cond ; cond = n1 == n2 EqualSet // n1 n2 -- n1 cond ; cond = n1 == n2 Exit // -- ; Field // s -- f ; f = s.FieldIndex($1, ...) FieldFset // s i v -- s; s.FieldIndex(i) = v FieldRefSet // fref v -- ; fref = v (via setFuncField) FieldSet // s d -- s ; s.FieldIndex($1, ...) = d Fnew // -- x; x = new mem[$1] FnewE // -- x; x = new mem[$1].Elem() Get // addr -- value ; value = mem[addr] Grow // -- ; sp += $1 HeapAlloc // -- &cell ; cell = new(Value), push its pointer HeapGet // -- v ; v = *State.Heap[$1] HeapPtr // -- &cell ; push State.Heap[$1] itself (transitive capture) HeapSet // v -- ; *State.Heap[$1] = v CellGet // -- v ; cell = mem[fp-1+$1].(*Value); push *cell CellSet // v -- ; cell = mem[fp-1+$1].(*Value); *cell = v IfaceCall // iface -- closure ; dynamic dispatch method $1 on iface IfaceWrap // v -- iface ; wrap v in Iface{type at $1, v} Index // a i -- a[i] ; IndexAddr // a i -- &a[i] ; pointer to element IndexSet // a i v -- a; a[i] = v Jump // -- ; ip += $1 JumpFalse // cond -- ; if cond { ip += $1 } JumpSetFalse // JumpSetTrue // JumpTrue // cond -- ; if cond { ip += $1 } Len // -- x; x = mem[sp-$1] MapIndex // a i -- a[i] MapIndexOk // a i -- v ok ; v, ok = a[i] MapSet // a i v -- a; a[i] = v MkClosure // code [&c0..&cn-1] -- clo ; clo = Closure{code, heap} MkMap // -- map ; create map[K]V, key type at mem[$0], val type at mem[$1] MkSlice // [v0..vn-1] -- slice ; collect $0 values into []T, elem type at mem[$1] New // -- x; mem[fp+$1] = new mem[$2] Next // -- ; iterator next, set K Next0 // -- ; iterator next, no variable Next2 // -- ; iterator next, set K V Not // c -- r ; r = !c Panic // v -- ; pop value, start stack unwinding PanicUnwind // -- ; sentinel: handle panic stack unwinding Pop // v -- PtrNew // -- ptr ; ptr = new(T), type at mem[$0] Pull // a -- a s n; pull iterator next and stop function Pull2 // a -- a s n; pull iterator next and stop function Push // -- v Recover // -- v ; push recovered value (or nil if not panicking in a deferred call) Return // [r1 .. ri] -- ; exit frame, nret and frameBase from frames SetGlobal // v -- ; mem[$1] = v (globals) SetLocal // v -- ; mem[fp-1+$1] = v SetS // dest val -- ; dest.Set(val) Slice // a l h -- a; a = a [l:h] Slice3 // a l h m -- a; a = a[l:h:m] Stop // -- iterator stop; sp -= 3 + $1 Swap // -- Trap // -- ; pause VM execution and enter debug mode TypeAssert // iface -- v [ok] ; assert iface holds type at mem[$1]; $2=0 panics, $2=1 ok form TypeBranch // iface -- ; pop iface; if iface doesn't hold type at mem[$2] (or $2==-1 for nil), ip += $1 WrapFunc // mvmFuncVal -- MvmFunc ; wrap mvm func in reflect.MakeFunc for native callbacks; $0=typeIdx, $1=depth from sp (0=top) // Goroutine and channel opcodes. GoCall // f [a1..ai] -- ; spawn goroutine; $0=narg GoCallImm // [a1..ai] -- ; spawn goroutine to known func; $0=dataIdx, $1=narg MkChan // -- ch ; create channel; $0=elemTypeIdx, $1=bufsize (-1=from stack) ChanSend // ch v -- ; send to channel ChanRecv // ch -- v [ok] ; receive from channel; $0=1 for ok-form ChanClose // ch -- ; close channel SelectExec // ch0 [v0] .. chN [vN] -- chosenIdx ; $0=metaIdx, $1=ncase; calls reflect.Select Print // [v0..vn-1] -- ; print $0 values to m.out Println // [v0..vn-1] -- ; println $0 values to m.out, space-separated, trailing newline Min // [v0..vn-1] -- min ; find min of $0 values; $1 = reflect.Kind for dispatch Max // [v0..vn-1] -- max ; find max of $0 values; $1 = reflect.Kind for dispatch AddStr // s1 s2 -- s ; s = s1 + s2 (string concatenation) GreaterStr // s1 s2 -- cond ; cond = s1 > s2 LowerStr // s1 s2 -- cond ; cond = s1 < s2 AddInt // n1 n2 -- sum AddInt8 AddInt16 AddInt32 AddInt64 AddUint AddUint8 AddUint16 AddUint32 AddUint64 AddFloat32 AddFloat64 SubInt // n1 n2 -- diff SubInt8 SubInt16 SubInt32 SubInt64 SubUint SubUint8 SubUint16 SubUint32 SubUint64 SubFloat32 SubFloat64 MulInt // n1 n2 -- prod MulInt8 MulInt16 MulInt32 MulInt64 MulUint MulUint8 MulUint16 MulUint32 MulUint64 MulFloat32 MulFloat64 NegInt // n -- -n NegInt8 NegInt16 NegInt32 NegInt64 NegUint NegUint8 NegUint16 NegUint32 NegUint64 NegFloat32 NegFloat64 GreaterInt // n1 n2 -- cond GreaterInt8 GreaterInt16 GreaterInt32 GreaterInt64 GreaterUint GreaterUint8 GreaterUint16 GreaterUint32 GreaterUint64 GreaterFloat32 GreaterFloat64 LowerInt // n1 n2 -- cond LowerInt8 LowerInt16 LowerInt32 LowerInt64 LowerUint LowerUint8 LowerUint16 LowerUint32 LowerUint64 LowerFloat32 LowerFloat64 DivInt // n1 n2 -- quot DivInt8 DivInt16 DivInt32 DivInt64 DivUint DivUint8 DivUint16 DivUint32 DivUint64 DivFloat32 DivFloat64 RemInt // n1 n2 -- rem (integer only) RemInt8 RemInt16 RemInt32 RemInt64 RemUint RemUint8 RemUint16 RemUint32 RemUint64 RemFloat32 // unused, but keeps NumTypes alignment RemFloat64 // unused, but keeps NumTypes alignment // Bitwise opcodes (generic, operate on raw uint64 bits). BitAnd // n1 n2 -- n1 & n2 BitOr // n1 n2 -- n1 | n2 BitXor // n1 n2 -- n1 ^ n2 BitAndNot // n1 n2 -- n1 &^ n2 BitShl // n1 n2 -- n1 << n2 BitShr // n1 n2 -- n1 >> n2 (arithmetic for signed) BitComp // n -- ^n // Bit manipulation opcodes (32-bit and 64-bit variants). Clz32 // n -- count ; count leading zeros (32-bit) Clz64 // n -- count ; count leading zeros (64-bit) Ctz32 // n -- count ; count trailing zeros (32-bit) Ctz64 // n -- count ; count trailing zeros (64-bit) Popcnt32 // n -- count ; population count (32-bit) Popcnt64 // n -- count ; population count (64-bit) Rotl32 // n k -- result ; rotate left (32-bit) Rotl64 // n k -- result ; rotate left (64-bit) Rotr32 // n k -- result ; rotate right (32-bit) Rotr64 // n k -- result ; rotate right (64-bit) // Float math opcodes (unary: 1 operand; binary: 2 operands). AbsFloat32 // n -- |n| AbsFloat64 // n -- |n| SqrtFloat32 // n -- sqrt(n) SqrtFloat64 // n -- sqrt(n) CeilFloat32 // n -- ceil(n) CeilFloat64 // n -- ceil(n) FloorFloat32 // n -- floor(n) FloorFloat64 // n -- floor(n) TruncFloat32 // n -- trunc(n) TruncFloat64 // n -- trunc(n) NearestFloat32 // n -- nearest(n) NearestFloat64 // n -- nearest(n) MinFloat32 // a b -- min(a,b) MinFloat64 // a b -- min(a,b) MaxFloat32 // a b -- max(a,b) MaxFloat64 // a b -- max(a,b) CopysignFloat32 // a b -- copysign(a,b) CopysignFloat64 // a b -- copysign(a,b) // Immediate operand variants: fold Push+BinOp into one instruction. // Arg[0] holds the right-hand constant (int, sign-extended to int64). AddIntImm // n -- n+$1 SubIntImm // n -- n-$1 MulIntImm // n -- n*$1 GreaterIntImm // n -- n>$1 (signed) GreaterUintImm // n -- n>$1 (unsigned) LowerIntImm // n -- n<$1 (signed) LowerUintImm // n -- n<$1 (unsigned) GetGlobal // -- value ; value = mem[$1] (global variable, syncs num from ref if needed) GetLocal // -- value ; value = mem[$1+fp-1] (local variable, no scope check) NextLocal // -- ; iterator next, set K (local scope); like Next but scope is always Local Next2Local // -- ; iterator next, set K V (local scope); like Next2 but scope is always Local // Fused GetLocal + operation superinstructions. // $1 = local offset (as in GetLocal), $2 = immediate operand. GetLocal2 // -- v1 v2 ; push two locals: mem[$1+fp-1] then mem[$2+fp-1] GetLocalAddIntImm // -- n+$2 ; push local $1 then add immediate $2 GetLocalSubIntImm // -- n-$2 ; push local $1 then subtract immediate $2 GetLocalMulIntImm // -- n*$2 ; push local $1 then multiply by immediate $2 GetLocalLowerIntImm // -- cond ; push local $1 then compare < immediate $2 (signed) GetLocalLowerUintImm // -- cond ; push local $1 then compare < immediate $2 (unsigned) GetLocalGreaterIntImm // -- cond ; push local $1 then compare > immediate $2 (signed) GetLocalGreaterUintImm // -- cond ; push local $1 then compare > immediate $2 (unsigned) GetLocalReturn // -- ; push local $1 then return (nret/frameBase from frame) // Fused compare + conditional-jump superinstructions. // Only LowerInt variants are needed, compiler rewrites Greater comparisons // using the identity: (a > imm) same as !(a < imm+1). LowerIntImmJumpFalse // n -- ; if n >= $2 { ip += $1 } ; sp-- LowerIntImmJumpTrue // n -- ; if n < $2 { ip += $1 } ; sp-- GetLocalLowerIntImmJumpFalse // -- ; if local >= imm { ip += $1 } ; $2 = localOff<<16 | imm&0xFFFF GetLocalLowerIntImmJumpTrue // -- ; if local < imm { ip += $1 } ; $2 = localOff<<16 | imm&0xFFFF )
Byte-code instruction set.
type Opaque ¶
type Opaque struct{}
Opaque stands in for an external type which could not be resolved at parse time.
type ProxyFactory ¶
ProxyFactory builds a pointer-to-struct that wraps a mvm Iface and re-enters mvm. Used at native-call boundaries to hand a stdlib shadow package (e.g. jsonx) a proxy whose methods (MarshalJSON, UnmarshalJSON, etc.) dispatch back into the interpreter with full Iface metadata.
type SelectCaseInfo ¶
type SelectCaseInfo struct {
Dir reflect.SelectDir // SelectSend, SelectRecv, or SelectDefault
Slot int // local/global index for received value (-1 if unused)
OkSlot int // local/global index for ok bool (-1 if unused)
Local bool // true if slots are local (frame-relative), false for global
}
SelectCaseInfo describes one case of a select statement.
type SelectMeta ¶
type SelectMeta struct {
Cases []SelectCaseInfo
TotalPop int // precomputed number of stack slots consumed by channel/value entries
}
SelectMeta holds metadata for a select statement, stored in the data section.
type Type ¶
type Type struct {
PkgPath string
Name string
Rtype reflect.Type
Placeholder bool // true for forward-declared struct placeholders until SetFields is called
IfaceMethods []IfaceMethod // non-nil for interface types: required method signatures
TypeElems []TypeElem // non-nil for constraint interfaces: union members (e.g. cmp.Ordered)
Methods []Method // concrete types: methods[methodID] = code location + receiver path
Embedded []EmbeddedField // mvm types of anonymous (embedded) fields, for promoted method lookup
Params []*Type // mvm-level parameter types for func types (nil for non-func or if unknown)
Returns []*Type // mvm-level return types for func types (nil for non-func or if unknown)
Fields []*Type // mvm-level field types for struct types, parallel to reflect visible fields
ElemType *Type // mvm-level element type for map/slice/array/pointer/chan types
KeyType *Type // mvm-level key type for map types; nil for non-maps or native-built maps
// Base points at the source *Type that struct-field shallow copies
// were derived from. Methods registered on the source after the copy
// was taken (normal for mvm, which parses struct types before
// method declarations) remain reachable through Base.
Base *Type
}
Type is the representation of a runtime type.
func NewStructType ¶
func NewStructType() *Type
NewStructType creates a forward-declared struct type. Register it in the symbol table, then call SetFields to finalize.
func StructOf ¶
func StructOf(fields []*Type, embedded []EmbeddedField, tags []string) *Type
StructOf returns the struct type with the given field types, embedded field info, and tags.
func (*Type) Elem ¶
Elem returns a type's element type, preserving mvm-level info (e.g. IfaceMethods).
func (*Type) EnsureIfaceMethods ¶
func (t *Type) EnsureIfaceMethods()
EnsureIfaceMethods populates IfaceMethods from the reflect method set if not already set. This covers native interface types (e.g. io.Reader) whose method sets were not explicitly enumerated at parse time.
func (*Type) FieldIndex ¶
FieldIndex returns the index of struct field name.
func (*Type) FieldLookup ¶
FieldLookup returns the index path and type of struct field name in a single pass.
func (*Type) FieldType ¶
FieldType returns the type of struct field name, using mvm-level info when available.
func (*Type) Implements ¶
Implements reports whether the concrete type t satisfies interface iface. iface.IfaceMethods must have IDs populated (by the compiler) before calling this.
func (*Type) IsInterface ¶
IsInterface reports whether t represents an interface type.
func (*Type) MissingMethod ¶
MissingMethod returns the name of the first method required by interface type t that native reflect type rt does not have. Returns "" if all methods are present or t has no IfaceMethods.
func (*Type) NativeImplements ¶
NativeImplements reports whether native reflect type rt has all the methods required by interface type t.
func (*Type) ReturnType ¶
ReturnType returns the mvm-level i'th return type if known, else falls back to Out(i).
type TypeElem ¶
TypeElem describes one member of a constraint interface's type-element union, e.g. for "type Ordered interface { ~int | ~string }" the type elements are TypeElem{Approx: true, Type: intType}, TypeElem{Approx: true, Type: stringType}. Approx encodes the "~" prefix (any type whose underlying type is Type).
type Value ¶
type Value struct {
// contains filtered or unexported fields
}
Value is the VM runtime value. Numeric types (bool, int*, uint*, float*) store their value inline in num. ref carries reflect.Zero(t) for type metadata on numeric types. Composite types (string, slice, map, struct, ptr, func, interface) use ref.
func FromReflect ¶
FromReflect wraps a reflect.Value into a Value.
func TypeValue ¶
TypeValue returns a zero value for use as a type descriptor in the data table. Preserves the exact reflect.Type for all kinds so opcodes like MkChan can recover it via ref.Type().
func (Value) CopyArray ¶
CopyArray returns a Value holding a copy of the array in v, so that range iterates over a snapshot (Go spec: range over array uses a copy).
func (Value) Elem ¶
Elem returns the value that the interface v contains or the pointer v points to.
func (Value) FieldByIndex ¶
FieldByIndex returns the nested field corresponding to index.
func (Value) Reflect ¶
Reflect reconstructs a reflect.Value from an inline numeric Value. For composite types, returns ref directly. This may allocate for numeric types; use only at reflect boundaries.
func (Value) SetMapIndex ¶
SetMapIndex sets the element associated with key in the map v.