Documentation
¶
Overview ¶
Package vm 是 waiton-script 子集的字节码虚拟机(§4.6 三级执行统一枢纽)。
对应 plugin-engine-draft.md §4.1/§4.6/§4.7:
- 源码(字节缓冲区)经引擎前端编译为子集字节码(compiler)
- 解释器以字节码为唯一输入(源码从不被直接解释)
- AOT/JIT 都产出字节码并落盘索引缓存(gob 序列化,平台无关、跨架构复用)
- 机器码(若有)仅运行期加速、永不落盘
选型:栈式 VM(§4.6「轻量」)。指令 = 1 字节 opcode + 可选操作数。 值复用 interp.Value(避免两套运行时值系统)。
Index ¶
Constants ¶
This section is empty.
Variables ¶
var MaxSteps = 0
MaxSteps 执行步数上限(调试防死循环,0 = 不限)。临时。
var OpNames = map[Opcode]string{ OpPushInt: "PUSH_INT", OpPushFloat: "PUSH_FLOAT", OpPushStr: "PUSH_STR", OpPushBool: "PUSH_BOOL", OpPushNone: "PUSH_NONE", OpDup: "DUP", OpLoadLocal: "LOAD_LOCAL", OpStoreLocal: "STORE_LOCAL", OpLoadSelf: "LOAD_SELF", OpStoreSelf: "STORE_SELF", OpPushScope: "PUSH_SCOPE", OpPopScope: "POP_SCOPE", OpJmp: "JMP", OpJmpIfFalse: "JMP_IF_FALSE", OpJmpIfTrue: "JMP_IF_TRUE", OpRet: "RET", OpRetNone: "RET_NONE", OpCall: "CALL", OpCallHost: "CALL_HOST", OpCallEng: "CALL_ENG", OpMakeVariant: "MAKE_VARIANT", OpMakeEnum: "MAKE_ENUM", OpAdd: "ADD", OpSub: "SUB", OpMul: "MUL", OpDiv: "DIV", OpMod: "MOD", OpEq: "EQ", OpNe: "NE", OpLt: "LT", OpGt: "GT", OpLe: "LE", OpGe: "GE", OpAnd: "AND", OpOr: "OR", OpNot: "NOT", OpNeg: "NEG", OpConcat: "CONCAT", OpMakeRecord: "MAKE_RECORD", OpGetField: "GET_FIELD", OpMakeRange: "MAKE_RANGE", OpMakeRecordSpread: "MAKE_RECORD_SPREAD", OpLenSlice: "LEN_SLICE", OpIndexSlice: "INDEX_SLICE", OpIndexRange: "INDEX_RANGE", OpMakeSlice: "MAKE_SLICE", OpMakeSliceSpread: "MAKE_SLICE_SPREAD", OpStoreIndex: "STORE_INDEX", OpSafePoint: "SAFEPOINT", OpMatch: "MATCH", OpNop: "NOP", OpQuestion: "QUESTION", }
OpNames 调试用指令名表。
var Trace = false
Trace 调试开关(导出,临时)。
Functions ¶
func BinOp ¶
BinOp 按 op 分派二元运算(覆盖算术/比较/逻辑/拼接)。 与主 run 的 Op* 分支语义一致;非二元运算返回零值。供 bench 包自包含执行器复用。
func FuncMap ¶
FuncMap 顶层函数表(bench 专用):包装 vm_test 的 funcMap helper。 基准用 Env.SetFuncs 注入,使脚本函数调用可解析。
Types ¶
type Block ¶
type Block struct {
Start int // 起始指令索引(Instrs 下标)
End int // 结束指令索引(不含,即块内 [Start, End))
// Next 顺序后继块索引(无跳转的 fall-through),-1 表示无(块尾是返回/跳转)
Next int
// Jump 本块是否以条件跳转结尾:true 时 JumpTo 为「条件成立」目标块,
// Next 为「条件不成立」的 fall-through 块;false 时 JumpTo 为无条件跳转目标
// (Next 应为 -1)。
Jump bool
JumpTo int // 跳转目标块索引
// EndIdx 块尾跳转指令在 Instrs 的索引(OpJmp/OpJmpIfFalse/OpJmpIfTrue)
JumpInstr int
// Ret 本块是否以 RET/RET_NONE 结尾(函数出口)
Ret bool
}
Block 一个基本块。
type Code ¶
type Code struct {
// 常量池(平台无关、跨架构复用)
Ints []int64
Floats []float64
Strings []string
// 符号表
Funcs []FuncRef // 函数池
Fields []string // self/record 字段名表(LOAD_SELF/GET_FIELD 索引 → 名)
Types []string // record/variant/enum 类型名表
Enums []string // 枚举成员名表
// 指令流
Instrs []Instr
// 函数入口表:函数名 → 指令流偏移
Entry map[string]int
// SlotNames 槽位 → 变量名(LOAD_LOCAL/STORE_LOCAL 的 A 索引解析)
SlotNames []string
// CallExprs 委托调用表达式表(OpCall/OpCallHost/OpCallEng 的 A 索引 → AST CallExpr,
// 运行时委托 interp.EvalCall/EvalBuiltin/CallHostFunc 求值)
CallExprs []ast.Expr
// RecordFields record 构造字段名表(MAKE_RECORD 的 A 索引 → 字段名列表,正序)
RecordFields [][]string
// Matches match 描述符表(OpMatch 的 A 索引 → 描述符)。每个描述符描述一个
// match 语句的 tag 分发:每 case 的 tag("_" 为通配)、payload 绑定变量名、
// case body 入口偏移与 match 结束偏移(相对 OpMatch 指令位置)。
Matches []MatchDesc
// FallbackFuncs 需回落 interp 的函数集合(含未覆盖节点:match/record-lit/变参等)
FallbackFuncs map[string]bool
// contains filtered or unexported fields
}
Code 一段编译产物(统一枢纽:解释器输入 + AOT/JIT 落盘格式)。
func Compile ¶
Compile 把 AST 文件编译为字节码(§4.1 前端:源码 → 字节码)。 返回的 Code 可被解释器执行,也可 gob 序列化落盘(AOT/JIT 索引缓存)。 含未覆盖节点(match/record-lit/变参/泛型调用等)的函数登记到 FallbackFuncs, 不生成字节码——执行时该函数整体回落 interp(语义不丢)。
func Decode ¶
Decode 从字节反序列化 Code(gob)。 注意:CallExprs/RecordFields 依赖 AST,反序列化后为空,需调用方 (编译期)重新关联——纯字节码执行(无 AST)时这些指令会委托失败。 实际使用:Decode 后用于 inspect/缓存命中判定;执行仍需 AST(v1 混合模型)。
func (*Code) Disasm ¶
Disasm 反汇编字节码为可读文本。调试用:查看编译产物、对比 AST/VM 语义、 定位跳转回填错误等。
func (*Code) Encode ¶
Encode 把 Code 序列化为字节(gob,平台无关、跨架构复用,§4.6 落盘格式)。 AOT 提前编译的字节码经此落盘索引缓存;JIT 懒编译产物同样可落盘。
type FuncRef ¶
FuncRef 函数池条目(保留:未来函数池直接调用用)。
type Instr ¶
Instr 一条指令。操作数按指令语义解释:A/B 为 u16,Off 为跳转偏移(i32)。
type MatchDesc ¶
type MatchDesc struct {
// Tags 每 case 的 tag("_" 表示通配,匹配任意 subject)
Tags []string
// BindNames 每 case 的 payload 绑定变量名(如 int_val(i) 的 "i";无载荷 case 为空)。
// 命中时 OpMatch 执行 env.Set(BindNames[j], subject.Payload[j])。
BindNames [][]string
// Entries 每 case body 入口相对 OpMatch 指令的偏移(pc += Entries[i] 落到 case body)
Entries []int32
// End 未命中任何 case 时跳转偏移(pc += End 落到 match 结束标记)
End int32
}
MatchDesc 一条 match 语句的字节码描述(§4.6 三级执行:match variant 解构下沉)。
type Opcode ¶
type Opcode byte
Opcode 字节码指令。1 字节。
const ( // ── 值操作 ── OpPushInt Opcode = iota // A: 整数常量池索引 → 压 int OpPushFloat // A: 浮点常量池索引 → 压 float OpPushStr // A: 字符串常量池索引 → 压 string OpPushBool // A: 0/1 → 压 bool OpPushNone // → 压 none/unit OpDup // 栈顶复制 // ── 局部变量 / 环境 ── OpLoadLocal // A: 槽位 → 压局部变量 OpStoreLocal // A: 槽位 ← 弹栈存储 OpLoadSelf // A: 字段索引 → 压 self.x OpStoreSelf // A: 字段索引 ← 弹栈存储 self.x // ── 作用域 / 控制流 ── OpPushScope OpPopScope OpJmp // Off: 无条件跳转(相对偏移) OpJmpIfFalse // Off: 栈顶为假则跳转 OpJmpIfTrue // Off: 栈顶为真则跳转 OpRet // 函数返回(栈顶为返回值) OpRetNone // void 返回 none // ── 调用 ── OpCall // A: 调用表达式索引(委托 interp.EvalCall) OpCallHost // A: 调用表达式索引(委托 interp.EvalCall host 支) OpCallEng // A: 调用表达式索引(委托 interp.EvalCall engine 支) OpMakeVariant // A: variant 类型索引, B: case 索引 → 构造 variant OpMakeEnum // A: 类型索引, B: 成员索引 → 构造枚举值 // ── 运算 ── OpAdd OpSub OpMul OpDiv OpMod OpEq OpNe OpLt OpGt OpLe OpGe OpAnd OpOr OpNot OpNeg OpConcat // ── 复合类型 ── OpMakeRecord // A: record 构造索引, B: 类型索引 → 弹字段值构造 record OpGetField // A: 字段索引 → 弹 record 压字段 OpMakeRange // 弹 lo, hi → 压 range OpMakeRecordSpread // A: 新字段名表索引, B: 类型索引(0xFFFF = 匿名构造继承 base)→ 弹新字段值 + 弹 base record → 复制字段 + 覆盖 → 新 record(2026-08-22 下沉) // ── 切片 ── OpLenSlice // 栈顶 slice → 压长度(int) OpIndexSlice // 弹 idx, slice → 压 slice[idx](2026-08-22 扩展 string 字节索引) OpIndexRange // 弹 hi, lo, X → 压子切片/子串(2026-08-22 下沉) OpMakeSlice // A: 元素个数 → 弹 n 元素 → 压 slice(2026-08-22 下沉) OpMakeSliceSpread // A: 元素个数 → 弹 n 元素 + 弹 spread slice → 压拼接 slice(2026-08-22 下沉) OpStoreIndex // 弹 value, idx, slice → slice[idx] = value(原地写,2026-08-23 索引赋值) // ── 安全点 ── OpSafePoint // §8.7B 循环回边安全点检查 // ── ? 错误传播 ── OpQuestion // ?(§4.3):弹 v——ok/some 解包 payload 继续;err/none 原值提前返回(跳 Off 到函数末尾 RET);非 variant 透传(2026-08-22 下沉) // ── match 解构 ── OpMatch // A: match 描述符索引 → 按 tag 分发到命中 case body(栈顶弹 subject) // ── 特殊 ── OpNop )
type VM ¶
type VM struct {
// UseFast 是否使用直线执行器(runFast,§4.7 路线 B)。
// 默认 false 走 run(解释器,稳定);true 走基本块直线执行。
// benchmark/实验对比用;开启时测试全覆盖验证等价性。
UseFast bool
// contains filtered or unexported fields
}
VM 是子集字节码解释器(§4.6 统一枢纽的执行侧)。 混合模型:字节码承担表达式求值,函数调用回落 interp。
func NewVM ¶
NewVM 创建 VM。env 为解释环境(含符号表/世界/输出缓冲)。
func (*VM) Exec ¶
Exec 执行入口函数(main)。self 为 world 实例(main 有 self 参数时绑定,可为零值)。 返回函数返回值。 若入口函数登记为 FallbackFuncs(含未覆盖节点),委托 interp 执行(语义不丢)。
Source Files
¶
- bench_api.go
- blocks.go
- compile.go
- disasm.go
- exec_fast.go
- serialize.go
- vm.go