Documentation
¶
Overview ¶
Package vm 实现了 JavaScript 的栈式字节码虚拟机。
VM 核心包含三个组件:
- 操作数栈 (Stack): 计算过程中的临时值栈
- 调用帧 (Frame): 每个函数调用创建一个帧,保存局部变量和 PC
- 全局环境 (Environment): 存储全局变量 (通过 OP_LOAD_GLOBAL 访问)
执行流程:
- 编译器输出字节码 + 常量池
- VM 创建主帧,开始取指-解码-执行循环
- 每条指令: 读取 1 字节 opcode + 2 字节 operand, 执行对应操作
- PC 前进 3 字节,取下一条指令
- OP_CALL 创建新帧, OP_RETURN 弹出帧并返回值
Index ¶
- Constants
- func Eval(input string) (object.Value, error)
- func EvalFile(path string) (object.Value, error)
- func EvalWithGlobals(input string, globals *runtime.Environment) (object.Value, error)
- type Frame
- type FrameError
- type ModuleExports
- type Stack
- type ThrowError
- type VM
- func EvalFileVM(path string) (*VM, error)
- func EvalFileVMModuleEarlyErrors(path string) (*VM, error)
- func EvalFileVMT262(path string) (*VM, error)
- func EvalModuleFileVM(path string) (*VM, error)
- func EvalModuleFileVMWithGlobals(path string, globals *runtime.Environment) (*VM, error)
- func EvalVM(input string) (*VM, error)
- func New(ins bytecode.Instructions, constants *bytecode.ConstantPool, numLocals int) *VM
- func NewWithGlobals(ins bytecode.Instructions, constants *bytecode.ConstantPool, numLocals int, ...) *VM
- func (vm *VM) AttachFrame(err error) error
- func (vm *VM) Globals() *runtime.Environment
- func (vm *VM) LastPopped() object.Value
- func (vm *VM) Run() error
- func (vm *VM) RunCompiled(c *compiler.Compiler) error
- func (vm *VM) RunCompiledAsync(c *compiler.Compiler) error
- func (vm *VM) RunTimers() error
- func (vm *VM) RunTimersUntil(until time.Time) error
- func (vm *VM) RunTimersWithPump(pump func(maxWait time.Duration) bool) error
- func (vm *VM) SetModuleBase(path string)
- func (vm *VM) SetSourceInfo(file, text string)
- func (vm *VM) SetStmtPositions(tbl map[int]ast.Pos)
- func (vm *VM) SetTranspileMap(lm *tstransform.LineMap, jsText string)
- type YieldSignal
Constants ¶
const MaxFrames = 2048
const StackSize = 2048
StackSize 是操作数栈的初始容量。
Variables ¶
This section is empty.
Functions ¶
func EvalWithGlobals ¶
Types ¶
type Frame ¶
type Frame struct {
Instructions bytecode.Instructions
PC int
Locals []object.Value
Closure *object.Closure
// This 是本帧**生效**的 this 绑定 (已按 sloppy 规则归一)。callClosure 在
// 装配帧时写入: 箭头帧取其词法捕获的 this, 非箭头帧把 undefined/null 归一
// 为 globalThis。主帧 (frame.Closure == nil) 保持 nil, 由 OP_THIS 按
// script/module 决定取值。与 Closure.This (创建时携带的原始绑定) 区分开。
This object.Value
// NewTarget 是本帧的 `new.target` 绑定 (构造目标)。callClosure 装配帧时:
// - 构造调用 (OP_NEW): 写被 new 的构造器;
// - super() 调用 (OP_NEW_TARGET_MARK 传递): 写调用者帧的 NewTarget
// —— 派生类构造器里 super() 父构造器看到的 new.target 是最初被 new 的那个;
// - 其余 (普通调用/箭头): nil, 由 OP_NEW_TARGET 归一为 undefined。
NewTarget object.Value
Constants *bytecode.ConstantPool
ModifiedSlots map[int]bool // 修改过的 slot (用于 popFrame 传播)
CreatedClosures []*object.Closure // 本帧创建的闭包 (用于 STORE 传播)
// ===== 迭代边界的共享前缀模型 (rUm0q6) =====
//
// OP_ITER_BOUNDARY 只应"定版"**每轮新建的词法绑定** (循环变量 + 循环体内
// 的 let/const), 而 var (函数作用域) 与外层 let 是**单实例**, 所有轮次的
// 闭包必须共享同一颗 cell。旧实现直接清空 CreatedClosures + 克隆整个 Locals
// 数组, 把不该定版的共享绑定也一并封死 ⇒ 闭包看到的是各自轮次的快照
// (for(var x of …) 得到 [1,2,3] 而非规范要求的 [3,3,3])。
//
// 现模型: 迭代边界携带 sealFrom (块作用域内首个新槽位), 只把该边界之后的
// 写入视为"新 cell"; 边界之前的 slot (< sealFrom) 视为共享, 照常传播给
// 全部已创建闭包。Epoch 每过一次边界 +1; 闭包记录创建时的 Epoch。
Epoch int // 已执行的迭代边界次数
SealMarks []sealMark // 各边界的 (sealFrom → 过界后的 Epoch), 按 sealFrom 去重取最新
StackBase int // 进入本帧时栈高度 (返回时截断到此处)
// PendingGen 非 nil 表示本帧是生成器/异步生成器的"形参前导帧":
// 帧内指令只覆盖形参绑定前导段 [0, StopPC)。执行到 PC >= StopPC 时
// 冻结为 Generator (见 runFrom/freezeGenPrologue), 函数体随后才在
// 首次 next() 时运行。规范要求形参绑定在调用时同步完成。
PendingGen *object.Generator
StopPC int
}
Frame 表示 VM 调用栈中的一个帧。 每次函数调用创建一个新帧,函数返回时弹出。
帧包含:
- Instructions: 当前正在执行的字节码
- PC: 程序计数器 (字节偏移,每条指令 3 字节)
- Locals: 局部变量数组 (通过 OP_LOAD/OP_STORE 按 slot 索引)
- Closure: 如果是闭包调用,关联的闭包对象
- Constants: 常量池引用 (所有帧共享同一个)
- ModifiedSlots: 本帧中修改过的 slot 集合 (用于 popFrame 时向上一帧传播闭包变量修改)
- CreatedClosures: 在本帧中创建的闭包列表 (用于 OP_STORE 时向子闭包传播外层变量修改)
func NewClosureFrame ¶
func NewClosureFrame(meta *bytecode.FunctionMetadata, constants *bytecode.ConstantPool, captured []object.Value, closure *object.Closure) *Frame
NewClosureFrame 为闭包调用创建新帧。 captured 是从创建闭包的帧中捕获的局部变量。
func NewFrame ¶
func NewFrame(ins bytecode.Instructions, constants *bytecode.ConstantPool, numLocals int) *Frame
NewFrame 创建新的调用帧。
Locals 刻意保持零值 (nil): nil 表示"该绑定尚未初始化",OP_LOAD 读到它时 抛 ReferenceError —— 这就是 let/const 的 TDZ (暂时性死区)。 若像以前那样预填 undefined,声明前访问会静默得到 undefined。
type FrameError ¶ added in v0.8.0
FrameError 是附带源码帧的错误。Error() 把帧渲染在原错误消息之后。
func (*FrameError) Error ¶ added in v0.8.0
func (e *FrameError) Error() string
func (*FrameError) Unwrap ¶ added in v0.8.0
func (e *FrameError) Unwrap() error
type ModuleExports ¶
type Stack ¶
type Stack struct {
// contains filtered or unexported fields
}
Stack 是 VM 的操作数栈。 所有计算中间结果都暂存在这里。
type ThrowError ¶
func (*ThrowError) Error ¶
func (e *ThrowError) Error() string
type VM ¶
type VM struct {
// contains filtered or unexported fields
}
func EvalFileVM ¶
func EvalFileVMModuleEarlyErrors ¶ added in v0.10.0
func EvalFileVMT262 ¶ added in v0.10.0
EvalFileVMT262 与 EvalFileVM 相同,但额外注入 test262 宿主约定所需的 $262 全局对象($262.detachArrayBuffer)。仅供 cmd/gox 的 test262 runner 使用 —— 常规脚本执行不应看到 $262。
func EvalModuleFileVM ¶ added in v0.10.0
func EvalModuleFileVMWithGlobals ¶ added in v0.10.0
func EvalModuleFileVMWithGlobals(path string, globals *runtime.Environment) (*VM, error)
func New ¶
func New(ins bytecode.Instructions, constants *bytecode.ConstantPool, numLocals int) *VM
func NewWithGlobals ¶
func NewWithGlobals(ins bytecode.Instructions, constants *bytecode.ConstantPool, numLocals int, globals *runtime.Environment) *VM
func (*VM) AttachFrame ¶ added in v0.8.0
AttachFrame 给运行时错误附加源码帧 (尽力而为): 无位置信息或找不到 匹配语句时原样返回。模块/eval 等无源码场景不受影响。
func (*VM) Globals ¶
func (vm *VM) Globals() *runtime.Environment
func (*VM) LastPopped ¶
func (*VM) RunCompiledAsync ¶ added in v0.10.0
func (*VM) RunTimersWithPump ¶
func (*VM) SetModuleBase ¶
func (*VM) SetSourceInfo ¶ added in v0.8.0
SetSourceInfo 注入当前脚本的文件名与文本 (EvalFileVM / loadModuleFile 接线)。 text 对 .ts/.tsx 是**用户原文**, JS 文件就是 JS 本身。
func (*VM) SetStmtPositions ¶ added in v0.8.0
SetStmtPositions 注入主脚本的语句位置表并建立升序索引。
func (*VM) SetTranspileMap ¶ added in v0.10.0
func (vm *VM) SetTranspileMap(lm *tstransform.LineMap, jsText string)
SetTranspileMap 注入 TS 转译的行映射与转译后 JS 文本。
调用约定: 先 SetSourceInfo(file, tsText) (给原文), 再调用本方法 (补映射与 JS)。 jsText 即使映射缺失也要给 —— 它是回退展示的素材。
type YieldSignal ¶
type YieldSignal struct {
// contains filtered or unexported fields
}
func (*YieldSignal) Error ¶
func (e *YieldSignal) Error() string