interp

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: MulanPSL-2.0 Imports: 15 Imported by: 0

Documentation

Overview

host 命名空间宿主注入支(§3.3.2)——非 waiton 宿主(C / Rust / Go 等)注册函数进 引擎 host 命名空间的手工映射 API(等价 waiton 宿主的 inject)。

设计要点(用户拍板):原型阶段用实现原型的语言(Go)先实现,但接口形态保持 **语言无关**——签名描述符 HOST_SIG_* 编码跨边界类型(i32/u32/bool/str/bytes/ host_ref),任何语言的宿主都遵循同一套类型编码与封送规则,C ABI 版只是同一 接口的另一种绑定(Go 版传 Value,C 版按 sig 做内存封送)。

Package interp 是 waiton-script 子集的树遍历解释器(原型执行器)。

设计约束(见 spec/waiton-script.md §2.2 与 plugin-engine-draft.md):

  • 子集无类型系统,解释器不做类型检查,按值直接求值;
  • host 命名空间的打印能力直接复用 engine 的 print 实现(host 是 engine 在宿主侧的呈现);
  • world 实例字段来自 CLI 注入或 swapon 参数,无注入时取零值;
  • Actor 交互经 engine 命名空间;脚本内部不手写 spawn,执行器不实现并发调度。

Index

Constants

This section is empty.

Variables

View Source
var ErrPreempted = fmt.Errorf("actor preempted at safepoint (step quota exhausted or preempt flag set)")

ErrPreempted 安全点抢占错误(§8.7B):Actor 在循环回边检查到 preemptFlag 置位 或步数配额耗尽时返回,由 worker goroutine 以 err variant 送达(抢占 = 终止当前任务)。

View Source
var HostSigNames = map[HostSig]string{
	HostSigVoid:    "void",
	HostSigI32:     "i32",
	HostSigU32:     "u32",
	HostSigF64:     "f64",
	HostSigBool:    "bool",
	HostSigStr:     "str",
	HostSigBytes:   "bytes",
	HostSigHostRef: "host_ref",
	HostSigRecord:  "record",
	HostSigAny:     "any",
}

HostSigNames 签名描述符可读名(诊断/日志)。

View Source
var RevertModeNames = map[RevertMode]string{
	RevertCoarse: "coarse",
	RevertFine:   "fine",
}

RevertModeNames 可读名(诊断/日志)。

Functions

func CollectSymbols

func CollectSymbols(f *ast.File, pkg *Package)

CollectSymbols 是 collectSymbols 的导出壳(engine 层 vm 字节码路径目录包复用)。

func HashInterface

func HashInterface(sig []HostSig, version string) string

HashInterface 生成接口哈希(§9.4 drift 检测):由签名描述符序列 + 版本段 生成确定性哈希。宿主升级签名(增删参数/改返回类型)→ 哈希变化 → 加载期 drift 检测触发。语言无关:任何宿主按同一规则计算即可比对。

func HostBindingKey

func HostBindingKey(name, version string) string

HostBindingKey 注册表绑定表 key:无版本 = name;带版本 = name@version(并行多版本)。 engine 层注册(RegisterHostFnVersion)与 interp 侧注入共用,保证 key 一致。

func InferWorldName

func InferWorldName(file *ast.File, fileBase string) error

InferWorldName 是 inferWorldName 的导出壳(engine 层 vm 字节码路径复用)。

func NormalizeRegPath

func NormalizeRegPath(path string) string

NormalizeRegPath 规范化注册表键路径:去首尾斜杠、防空段。 返回空串表示非法路径(根不可寻址为值)。

func RegistryKeyOf

func RegistryKeyOf(name, version string) string

RegistryKeyOf 返回 host 注册记录在注册表登记簿中的路径(§9.4)。 host/<pkg>/<vN>/<fn>;无版本时 host/<pkg>/<fn>。 例:name="fs.read_file", version="v1" → "host/fs/v1/read_file"

func Run

func Run(src string, worldArgs map[string]string) (string, error)

Run 解析并执行一个 .wos 源文件。worldArgs 为 CLI 注入的 world 字段(name->string 值,按需转换)。

func RunDir

func RunDir(dir string, worldArgs map[string]string) (string, error)

RunDir 加载并执行一个目录(包根)下的 waiton-script 包。 目录内全部 .wos 合并为一个包;入口为带 `func main(self <worldtype>)` 的 world(swapon 包)。 use <pkg> 解析:优先同目录(同包)文件,其次目录树内子路径。 不带宿主注入(spawnFunc/hostBindings 为 nil);需要宿主能力的目录包走 RunDirWithSpawnHost。

func RunDirWithSpawnHost

func RunDirWithSpawnHost(dir string, worldArgs map[string]string, spawnFunc func(ref *ActorRef), hostBindings map[string]HostBinding, reg *registry.Registry, regScope string, opts ...LoadOption) (string, error)

RunDirWithSpawnHost 同 RunDir,另注入宿主注册的 host 函数(§3.3.2)与 spawnFunc。 目录包消费宿主能力(如 host.ui.*)的前置——Engine.LoadDir 透传用(LoadDir 此前不注入 host 函数,目录包无法调用任何宿主能力,是既有缺口)。 reg/regScope 为分层注册表注入(§9.6,nil = 不启用)。

func RunFile

func RunFile(path string, worldArgs map[string]string) (string, error)

RunFile 加载并执行一个 .wos 文件,支持 `use <pkg>` 引入同目录下的其他 .wos 文件(包模型)。 baseDir 为 use 解析的基准目录(默认取文件所在目录)。

func RunFileWithSpawn

func RunFileWithSpawn(path string, worldArgs map[string]string, spawnFunc func(ref *ActorRef)) (string, error)

RunFileWithSpawn 同 RunFile,但允许注入 spawnFunc 回调(引擎层用)。

func RunFileWithSpawnHost

func RunFileWithSpawnHost(path string, worldArgs map[string]string, spawnFunc func(ref *ActorRef), hostBindings map[string]HostBinding, opts ...LoadOption) (string, error)

RunFileWithSpawnHost 同 RunFileWithSpawn,另注入宿主注册的 host 函数(§3.3.2)。 opts 为加载期选项(§数据重要性分层:WithTrustCap 信任上限等)。

func RunFileWithSpawnHostReg

func RunFileWithSpawnHostReg(path string, worldArgs map[string]string, spawnFunc func(ref *ActorRef), hostBindings map[string]HostBinding, reg *registry.Registry, regScope string, opts ...LoadOption) (string, error)

RunFileWithSpawnHostReg 同 RunFileWithSpawnHost,另挂载分层注册表(§9.6)。 reg 为全局系统层;regScope 为本脚本 realm 视图标识。

func RunWithSpawn

func RunWithSpawn(src string, worldArgs map[string]string, spawnFunc func(ref *ActorRef)) (string, error)

RunWithSpawn 同 Run,但允许注入 spawnFunc 回调(引擎层用)。

func RunWithSpawnHost

func RunWithSpawnHost(src string, worldArgs map[string]string, spawnFunc func(ref *ActorRef), hostBindings map[string]HostBinding, opts ...LoadOption) (string, error)

RunWithSpawnHost 同 RunWithSpawn,另注入宿主注册的 host 函数(§3.3.2)。 hostBindings 为 Engine.RegisterHostFn 收集的绑定表;nil 时仅默认 print_line。 opts 为加载期选项(§数据重要性分层:WithTrustCap 信任上限等)。

func RunWithSpawnHostReg

func RunWithSpawnHostReg(src string, worldArgs map[string]string, spawnFunc func(ref *ActorRef), hostBindings map[string]HostBinding, reg *registry.Registry, regScope string, opts ...LoadOption) (string, error)

RunWithSpawnHostReg 同 RunWithSpawnHost,另挂载分层注册表(§9.6)。 reg 为全局系统层(跨脚本共享);regScope 为本脚本 realm 视图标识(引擎层分配唯一 id)。

func WithBlocking

func WithBlocking() func(*HostBinding)

WithBlocking 宿主注册阻塞型函数标注(2026-08-22 看门狗语义)。 标注后脚本调用期间(宿主实现执行中)当前 actor 记 MarkBlocked——看门狗 按连续忙碌计时跳过等待中的宿主调用(如 present.poll(100ms) 轮询回路)。 不标注的宿主调用(print_line 等)照常计入忙碌(纯计算死循环仍会被杀)。

func WithDataLevel

func WithDataLevel(level ast.DataLevel, reason string) func(*HostBinding)

WithDataLevel 宿主注册 host 函数时的数据级别声明选项(§数据重要性分层)。 不传 = 默认 DataNormal(存量宿主代码零改动)。

level:该函数触碰的数据重要性级别
reason:可选,声明理由(拒绝调用错误信息携带,鸿蒙 reason 思想)

Types

type ActorRef

type ActorRef struct {
	ID     int64
	FnName string
	// BasePriority 调度优先级(§8.7:@actor world 初始化指定,或 spawn 参数),默认 128。
	BasePriority uint8

	// DoneSet 关闭即完成(非阻塞查询,actor_done 用)
	DoneSet chan struct{}
	// Cancel 关闭即请求撤销(宿主/引擎撤销 Actor)
	Cancel chan struct{}

	// SpawnFunc 由引擎层注入:创建 Actor 时调用,注册到调度器。
	// interp 不直接导入 engine 包,通过此回调解耦。
	SpawnFunc func(ref *ActorRef)
	// contains filtered or unexported fields
}

ActorRef 是引擎层并发 Actor 的运行时句柄(脚本侧经 engine.spawn 获得,不可解引用内部字段)。 对应主语言 §8 `@actor func` 轻量形态:函数即消息处理器,goroutine 承载执行, mailbox 经 channel 实现,await 等待函数返回。仅引擎内调度器管辖,不逃逸到宿主(§2.2 并发条款)。

调度器集成(§8.7):BasePriority 为调度优先级(0=最高,255=最低,128=默认); Step/Kill/IsDone/IsCancelled 为调度器提供统一的 Actor 操作接口。

func NewActorRef

func NewActorRef(id int64, fnName string, priority uint8) *ActorRef

NewActorRef 创建一个 ActorRef,各通道初始化。

func (*ActorRef) BusySinceNano

func (a *ActorRef) BusySinceNano() int64

BusySinceNano 返回当前「连续忙碌段」起点(unix nano)。

func (*ActorRef) CheckSafepointForTest

func (a *ActorRef) CheckSafepointForTest() error

CheckSafepointForTest 导出测试辅助:直接执行安全点检查(含让出路径)。 测试模拟解释器循环回边行为用。

func (*ActorRef) CreatedAt

func (a *ActorRef) CreatedAt() time.Time

CreatedAt 返回 Actor 创建时间(调度器看门狗计时起点)。

func (*ActorRef) IsBlocked

func (a *ActorRef) IsBlocked() bool

IsBlocked 返回 Actor 当前是否处于阻塞(让出)状态。

func (*ActorRef) IsCancelRequested

func (a *ActorRef) IsCancelRequested() bool

IsCancelRequested 非阻塞检查是否收到协作撤销请求(§8.7B)。

func (*ActorRef) IsCancelled

func (a *ActorRef) IsCancelled() bool

IsCancelled 非阻塞检查 Actor 是否已被取消。

func (*ActorRef) IsDone

func (a *ActorRef) IsDone() bool

IsDone 非阻塞检查 Actor 是否已完成。

func (*ActorRef) IsPreempted

func (a *ActorRef) IsPreempted() bool

IsPreempted 非阻塞检查 Actor 是否被置位抢占标志(§8.7B)。

func (*ActorRef) IsWaiting

func (a *ActorRef) IsWaiting() bool

IsWaiting 检查 Actor 是否正处于让出挂起状态(§8.7B:等待调度器恢复)。

func (*ActorRef) Kill

func (a *ActorRef) Kill()

Kill 终止 Actor(关闭 Cancel 通道)。

func (*ActorRef) MarkBlocked

func (a *ActorRef) MarkBlocked()

MarkBlocked 标记 Actor 进入阻塞(让出)状态(2026-08-22 看门狗修复): receive/send 等待、yield 让出前调用。阻塞期间调度器跳过看门狗检查。

func (*ActorRef) MarkDone

func (a *ActorRef) MarkDone()

MarkDone 标记 Actor 完成(关闭 DoneSet)。

func (*ActorRef) MarkUnblocked

func (a *ActorRef) MarkUnblocked()

MarkUnblocked 标记 Actor 恢复执行(2026-08-22 看门狗修复): 阻塞结束(收到消息/发送完成/让出恢复)时调用,刷新「连续忙碌段」起点。

func (*ActorRef) Preempt

func (a *ActorRef) Preempt()

Preempt 置位安全点抢占标志(§8.7B):Actor 在下个循环回边检查到并让出。

func (*ActorRef) Replay

func (a *ActorRef) Replay(msgs []Value) bool

Replay 把消息按原顺序重放(放回)到 mailbox(§9.2 HMR mailbox 迁移)。 用于把 SnapshotMailbox 捕获的旧 actor 消息注入新 actor,保证 HMR 不丢消息。 非阻塞:mailbox 缓冲 64,快照消息数 ≤ 64 时必然入队;若超限(理论上不可能, 快照已 drain 空)阻塞发送。返回是否全部入队成功。

func (*ActorRef) RequestCancel

func (a *ActorRef) RequestCancel()

RequestCancel 协作撤销(§8.7B 语义分离):engine.actor_cancel 调用,关闭 cancelCh。 worker 在 receive 感知(返回 none 优雅退出),不触发安全点 ErrPreempted——返回值不丢。

func (*ActorRef) Resume

func (a *ActorRef) Resume()

Resume 恢复一个处于让出挂起状态的 Actor(§8.7B):向 yieldCh 发信号。 非阻塞:channel 带缓冲 1,即使 Actor 尚未阻塞到 yieldCh 也不会丢信号。

func (*ActorRef) SendResult

func (a *ActorRef) SendResult(v Value)

SendResult 将结果发送到 resultCh(非阻塞,带缓冲 1)。

func (*ActorRef) SetStepBudget

func (a *ActorRef) SetStepBudget(budget int64)

SetStepBudget 设置步数配额(§8.7B):每循环迭代扣 1,耗尽 → 抢占终止;0 = 不限。

func (*ActorRef) SnapshotMailbox

func (a *ActorRef) SnapshotMailbox() []Value

SnapshotMailbox 捕获(drain)mailbox 中当前未处理的消息(§9.2 HMR mailbox 迁移)。 非阻塞:把 mailbox 现有消息全部取出返回,mailbox 变空。 与正在 receive 的 worker 竞态:已取出的消息归快照,worker 取走的归 worker; 两者不会重复取到同一条(chan 语义)。HMR 迁移时序上,此调用应先于 RequestCancel(让旧 worker 退出前先把剩余消息救下来)。

func (*ActorRef) Step

func (a *ActorRef) Step()

Step 执行一步调度(§8.7 调度器事件循环调用)。 原型期 @actor func 是 goroutine 自驱动,不需要外部 step。 此方法留给 @actor world 消息驱动形态使用。

type EffectRecord

type EffectRecord struct {
	ScriptID string // 脚本 id(引擎层分配 script#N)
	HostFn   string // host 函数名(如 "fs.open" / "timer.set")
	Seq      int    // 调用序号(从 1 递增,卸载按逆序回滚)
	HasRef   bool   // 返回是否为 host_ref
	HostRef  uint64 // HasRef 时的句柄值(0 表示无句柄)
}

EffectRecord 一条 effect 痕迹(§9.5):脚本调用 host 函数产生的副作用元数据。 只存轻量元数据(不存宿主资源本身),开销可控。HasRef 表示该调用返回了 host_ref 句柄(宿主侧资源),HostRef 为句柄值(供宿主定位资源账本条目)。

type Env

type Env struct {

	// 并发(A:Actor):引擎层调度器回调
	// SpawnFunc 由引擎层注入:创建 Actor 时调用,注册到调度器(§8.7)。
	// interp 不直接导入 engine 包,通过此回调解耦。
	SpawnFunc func(ref *ActorRef)

	UnloadHandler func(scriptID string)
	UnwindHandler func(sig UnwindSignal)
	// contains filtered or unexported fields
}

Env 是解释器的求值环境(变量作用域链)。

func BuildEnv

func BuildEnv(file *ast.File, worldArgs map[string]string, dir string, mainPkg *Package, shared *Env, spawnFunc func(ref *ActorRef), hostBindings map[string]HostBinding, reg *registry.Registry, regScope string, cfg *LoadConfig) (*Env, *ast.FuncDecl, error)

BuildEnv 是 buildEnv 的导出壳(engine 层 vm 字节码路径复用同一构建逻辑)。 构建脚本运行时环境:符号表 / host 命名空间 / world 实例 / 输出缓冲 / 并发状态, 不执行任何函数(main 由调用方决定执行方式——AST 或字节码)。

func NewEnvForTest

func NewEnvForTest() *Env

NewEnvForTest 创建一个空解释环境(vm 单测用:输出缓冲 + 符号表)。

func (*Env) CallFunc

func (e *Env) CallFunc(fn *ast.FuncDecl, args []Value, selfTy string) (Value, error)

callFunc 调用一个函数声明。selfTy 用于方法调用时 receiver 类型匹配。 callFunc 调用一个函数声明。selfTy 用于方法调用时 receiver 类型匹配。 CallFunc 是导出的薄包装(vm 字节码解释器回落用)。

func (*Env) CallHostBuiltin

func (e *Env) CallHostBuiltin(name string, args []ast.Expr) (Value, error)

CallHostBuiltin 导出 host 注入支(hostBuiltins)调用。

func (*Env) CallHostFunc

func (e *Env) CallHostFunc(fn *ast.FuncDecl, args []ast.Expr) (Value, error)

CallHostFunc 导出 callHostFunc(vm 的 CALL_HOST 指令回落用)。

func (*Env) CheckSafepoint

func (e *Env) CheckSafepoint() error

CheckSafepoint 导出安全点检查(vm 的 OpSafePoint 用)。

func (*Env) EffectLog

func (e *Env) EffectLog() []EffectRecord

EffectLog 返回当前 effect 痕迹日志(诊断用;fine 模式才有内容)。

func (*Env) EnableRegistry

func (e *Env) EnableRegistry(r *registry.Registry, scope string)

EnableRegistry 把全局注册表 + 本脚本 realm 视图挂到 env。 scope 为本脚本标识(脚本 id),用于区分不同派生视图。

func (*Env) EvalBuiltin

func (e *Env) EvalBuiltin(name string, args []ast.Expr) (Value, error)

EvalBuiltin 导出 evalBuiltin(vm 的 CALL_ENG 指令回落用)。

func (*Env) EvalCall

func (e *Env) EvalCall(c *ast.CallExpr) (Value, error)

EvalCall 导出 evalCall(vm 的 CALL 指令回落用)。

func (*Env) EvalExpr

func (e *Env) EvalExpr(x ast.Expr) (Value, error)

EvalExpr 导出 evalExpr(vm 回落含调用的表达式用)。

func (*Env) Funcs

func (e *Env) Funcs() map[string]*ast.FuncDecl

func (*Env) Generics

func (e *Env) Generics() map[string]*ast.FuncDecl

Generics 返回泛型表。

func (*Env) Host

func (e *Env) Host() map[string]map[string]*ast.FuncDecl

Host 返回 host 脚本库表。

func (*Env) HostBuiltins

func (e *Env) HostBuiltins() map[string]HostBinding

HostBuiltins 返回 host 注入支表。

func (*Env) Lookup

func (e *Env) Lookup(name string) (Value, bool)

Lookup 导出变量查找(vm 的 LOAD_LOCAL 用)。

func (*Env) Output

func (e *Env) Output() string

Output 返回输出缓冲内容(NewEnvForTest 用)。

func (*Env) ReapActors

func (e *Env) ReapActors(timeout time.Duration)

ReapActors 三段式确定性回收本脚本 spawn 的活跃 actor(Close/Unload 调用, 引擎终结不留 goroutine 泄漏):

  1. RequestCancel 全部未完成 actor(协作撤销:worker 下次 receive 返回 none 优雅退出)
  2. 限时轮询等全部 DoneSet 关闭(优雅退出窗口,默认 actorReapGrace)
  3. 超时仍未退出的 Kill 强杀(关 Cancel 通道 → worker 在循环回边 checkSafepoint 报 ErrPreempted / 阻塞 receive 的 Cancel 分支返回 err 退出)

轮询实现(10ms 粒度)不产生等待 goroutine,超时路径无泄漏。幂等:无活跃 actor 立即返回。强杀后只再等一个短窗口(尽力而为——卡死在宿主调用里的 worker 非引擎能解决)。

func (*Env) RegisterHostFn

func (e *Env) RegisterHostFn(name string, version string, sig []HostSig, fn HostFn) error

RegisterHostFn 把宿主函数注册进 host 命名空间(§3.3.2 / §9.4 版本化)。 等价 engine_register_host_fn(engine, "host.print_line", &fn, HOST_SIG_2(STR, STR, VOID)):

  • name:脚本侧完整限定名(§2.2 use 路径规则,如 "fs.read_file",可带 pkg 前缀)
  • version:接口版本段(如 "v1"/"v2",空 = 无版本,脚本 `host.<fn>` 直接命中)
  • sig:参数类型序列,最后一位是返回类型(HOST_SIG_*)
  • fn:宿主实现(Go 绑定)

同名 + 同版本重复注册 → 覆盖;不同版本并行注册(§9.4 版本标签)。 返回错误:签名空 / 缺返回类型。

func (*Env) RegisterHostFnCompat

func (e *Env) RegisterHostFnCompat(name string, sig []HostSig, fn HostFn) error

RegisterHostFnCompat 旧 3 参注册(无版本,§3.3.2 原签名)。 保留向后兼容:现有宿主代码 RegisterHostFn(name, sig, fn) 无需改动。

func (*Env) RegisterHostFnGo

func (e *Env) RegisterHostFnGo(name string, fn HostFn, argsSig []HostSig, ret HostSig) error

RegisterHostFnGo 便捷注册:Go 泛型签名推断(参数类型序列 + 返回)。 仅原型期便利,不改变语言无关的 HostSig 编码。

func (*Env) Registry

func (e *Env) Registry() *registry.Registry

Registry 返回当前 env 挂载的全局注册表(nil 表示未启用)。

func (*Env) ResetOutput

func (e *Env) ResetOutput()

ResetOutput 清空输出缓冲。基准/测试复用同一 Env 连续执行时调用, 避免输出随执行轮数线性累积(否则 GC 压力放大导致基准 ns/op 漂移)。

func (*Env) RevertMode

func (e *Env) RevertMode() RevertMode

RevertMode 返回当前卸载回滚粒度。

func (*Env) ScriptID

func (e *Env) ScriptID() string

ScriptID 返回脚本 id。

func (*Env) Set

func (e *Env) Set(name string, v Value)

Set 导出变量设置(vm 的 STORE_LOCAL 用)。

func (*Env) SetFuncs

func (e *Env) SetFuncs(f map[string]*ast.FuncDecl)

SetFuncs 设置函数表(vm 单测用)。

func (*Env) SetRevertMode

func (e *Env) SetRevertMode(m RevertMode)

SetRevertMode 设置卸载回滚粒度(§9.5 可选开关)。默认 RevertCoarse。 RevertFine 启用 effect 痕迹日志;RevertCoarse 不记日志。 设置作用于 effect 归属根 env(函数调用子 env 继承同一配置)。

func (*Env) SetScriptID

func (e *Env) SetScriptID(id string)

SetScriptID 设置脚本 id(引擎层分配,script#N)。卸载信号携带此 id, 宿主据此区分是哪个脚本留下的 effect。

func (*Env) SetUnloadHandler

func (e *Env) SetUnloadHandler(h func(scriptID string))

SetUnloadHandler 注册粗粒度卸载回调(§6.2 on_script_unload 的 Go 形态)。 卸载时调用一次,入参为脚本 id;宿主凭自身资源账本整体回滚该脚本全部副作用。

func (*Env) SetUnwindHandler

func (e *Env) SetUnwindHandler(h func(sig UnwindSignal))

SetUnwindHandler 注册细粒度逆序回调(§9.5 on_script_effect_unwind 的 Go 形态)。 卸载时按 effect 逆序调用多次,每次入参一条 UnwindSignal;宿主对每个信号 执行对应逆操作。仅 RevertFine 模式下生效。

func (*Env) SetWorld

func (e *Env) SetWorld(v Value)

SetWorld 设置 world 实例(vm 入口用)。

func (*Env) Unload

func (e *Env) Unload() int

Unload 撤销本脚本:按 revertMode 触发卸载信号(§6.2 粗 / §9.5 细), 然后清空 effect 日志。幂等(多次调用只触发一次)。

  • RevertCoarse:调 UnloadHandler(scriptID) 一次(若已注册)。
  • RevertFine:按 effect 逆序(seq 大 → 小)调 UnwindHandler 多次 (若已注册),再调 UnloadHandler(scriptID) 一次(宿主仍可做整体收尾)。

返回本次触发的信号计数(诊断)。

func (*Env) WaitActors

func (e *Env) WaitActors()

WaitActors 等待 main 生成的所有 actor 完成(vm 字节码路径的并发收尾)。 语义与 runFileAST 一致:main 汇合模型——main 是 Supervisor,spawn 的 actor 是其 worker,main 返回前等待 worker 收尾(引擎不逃逸到宿主)。

func (*Env) World

func (e *Env) World() Value

World 返回当前 world 实例。

func (*Env) WorldField

func (e *Env) WorldField(name string) (Value, bool)

WorldField 读当前 world 字段(vm 的 LOAD_SELF 用)。

type HostBinding

type HostBinding struct {
	Sig []HostSig // 参数签名 + 返回类型(最后一位)
	Fn  HostFn
	// Variadic 变参(如 print_line 任意多参任意类型):true 时跳过固定签名校验,
	// 实参求值后直接传给 Fn(原型期内部注入支形态)。
	Variadic bool
	// Version 接口版本段(§9.4):宿主可并行注册多版本(v1/v2),
	// 脚本 use 时绑定特定版本;drift 时旧脚本链旧版、新版脚本链新版。
	Version string
	// InterfaceHash 接口哈希(§9.4 drift 检测):由签名 + 版本生成。
	// 注册时记入注册表 host/ 子树登记簿;加载期脚本 use 的哈希与登记簿
	// 不符 → 加载期报错(宿主升级签名变了),而非静默用错版本。
	InterfaceHash string
	// DataLevel 数据重要性级别(§数据重要性分层):宿主声明该函数触碰的数据级别。
	// 默认 DataNormal(向后兼容:不声明 = 普通)。脚本调用时引擎按
	// min(脚本声明, 信任上限) ≥ DataLevel 仲裁,不满足拒绝调用(带 Reason)。
	DataLevel ast.DataLevel
	// Reason 数据级别声明理由(§数据重要性分层,鸿蒙 reason 思想):
	// 宿主注册敏感/机密函数时附带的用途说明,拒绝调用时展示给调试者
	// ("为什么这个函数是敏感的")。零成本,审计体验改善。
	Reason string
	// Blocking 阻塞型标注(2026-08-22 看门狗语义):宿主函数实现内部会阻塞
	// (如 present.poll 轮询、sleep)——脚本调用期间当前 actor 记 MarkBlocked,
	// 调度器看门狗按「连续忙碌时长」计时时跳过——泵事件回路(无 receive 的
	// 轮询主循环,UI 主循环典型形态)不被误判为忙碌死循环强杀。
	Blocking bool
}

HostBinding 一条宿主注册(签名 + 实现)。hostBuiltins 升级为绑定表。 §9.4 依赖版本化:Version 为接口语义版本段(如 "v1"/"v2",空 = 无版本); InterfaceHash 为接口哈希(签名 + 版本生成),drift 检测依据。

type HostFn

type HostFn func(args []Value) (Value, error)

HostFn 宿主注册的函数(Go 绑定,§3.3.2)。 原型期值级封送:引擎按签名校验参数类型后,把脚本 Value 直接传给宿主函数, 宿主返回 Value(含 host_ref)。未来 C ABI 版(wonc 导出表 / C 宿主)按同一 HostSig 做内存级封送(str↔const char*+len、切片↔ptr+len、句柄↔void*)。

type HostSig

type HostSig int

HostSig 签名描述符(§3.3.2:语言无关的类型编码,HOST_SIG_* 宏等价物)。 编码子集允许跨边界的类型。参数序列 + 返回类型(最后一位)组成完整签名。

const (
	HostSigVoid    HostSig = iota // void(仅返回类型可用)
	HostSigI32                    // i32:脚本 int(int64 截断)
	HostSigU32                    // u32:脚本 int(非负校验)
	HostSigF64                    // f64:脚本 float(Go float64 直通;int 实参按数值提升语义放行,2026-08-22 加)
	HostSigBool                   // bool
	HostSigStr                    // string(脚本 string ↔ const char* + len)
	HostSigBytes                  // 字节切片(脚本 slice of int ↔ ptr + len)
	HostSigHostRef                // host_ref 不透明句柄(脚本只能回传,不能解引用)
	HostSigRecord                 // record 值整体跨边界(脚本 Value{Kind:"record", Fields} 直接传宿主,嵌套结构保留)
	HostSigAny                    // 任意脚本值(record/variant/enum 等复杂对象)整体跨边界
)

type LoadConfig

type LoadConfig struct {
	// TrustCap 脚本信任上限:脚本声明级别经 min(声明, 上限) 收紧。
	// 未设置(WithTrustCap 未调用)= 不设上限(DataSecret),向后兼容。
	TrustCap ast.DataLevel
	// contains filtered or unexported fields
}

LoadConfig 加载期配置(数据重要性分层信任上限等)。经 LoadOption 设置。

type LoadOption

type LoadOption func(*LoadConfig)

LoadOption 加载期选项(§数据重要性分层):变参模式,存量调用零改动。

func WithTrustCap

func WithTrustCap(level ast.DataLevel) LoadOption

WithTrustCap 设置脚本信任上限(§数据重要性分层,鸿蒙 APL 应用等级启发)。 脚本经 `use host { level = "..." }` 声明的级别不得超过该上限, 引擎仲裁用 min(脚本声明, 信任上限) ≥ 函数数据级别。 默认无上限(DataSecret),向后兼容;宿主按脚本来源/信任度注入。

type MetaInfo

type MetaInfo struct {
	// 各作用域的 #doc 文本:key 如 "world.demo" / "func.main" / "type.Point" / "impl.stream.Point" / "field.x"
	Docs map[string]string
	// world 的 #plugin 信息:world 名 -> {name, kind}
	Plugins map[string]PluginInfo
	// #deprecated 声明:key 同 Docs,value 为 reason(无则空串)
	Deprecated map[string]string
}

MetaInfo 是 wos meta 命令输出的结构化元数据(声明期收集,不执行脚本)。

func CollectMeta

func CollectMeta(src string) (*MetaInfo, error)

CollectMeta 解析源码并收集全部声明期元数据(#doc / #plugin / #deprecated),不执行脚本。 纯静态扫描 AST,无副作用,是 wos meta 命令的引擎端入口。

type Package

type Package struct {
	Path     string                              // use 路径(如 "a.b")或文件路径
	Funcs    map[string]*ast.FuncDecl            // 顶层函数(非泛型)
	Generics map[string]*ast.FuncDecl            // 泛型函数
	Methods  map[string]map[string]*ast.FuncDecl // impl 方法表:Type -> fn -> 声明
	Variants map[string]bool                     // variant 类型名集合
	Records  map[string]bool                     // record 类型名集合(包模型深化)
	Deps     map[string]bool                     // 已并入的依赖 use 路径(use 传递去重)
}

Package 一个已加载的包(单个 .wos 文件或目录下的多个 .wos 合并)。 对应 spec/waiton-script.md §2.6 包模型:单文件即包、目录(含多个 .wos)也组成包。

func NewPackage

func NewPackage(path string) *Package

NewPackage 是 newPackage 的导出壳(engine 层 vm 字节码路径 LoadDirVM 复用)。

type PluginInfo

type PluginInfo struct {
	Name string // #plugin{ name: "..." }
	Kind string // #plugin{ kind: "..." }
}

PluginInfo 是 #plugin 注解的解析结果。

type RevertMode

type RevertMode int

RevertMode 卸载回滚粒度(§9.5 可选开关)。 RevertCoarse 默认粗粒度:不记 effect 日志,卸载时发一次粗信号(§6.2); RevertFine 细粒度:记 effect 日志,卸载时按 effect 逆序发细信号(§9.5)。

const (
	RevertCoarse RevertMode = iota
	RevertFine
)

type Script

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

Script 一个已加载的驻留脚本(§3.6 反向调用的句柄)。 封装脚本运行时 env(符号表/world/输出缓冲/并发状态),宿主经 Call 反向调用。 reloadCtx 保存 reload 所需的加载上下文(§9.2 HMR 热替换时重建 env 用)。

func LoadScript

func LoadScript(src string, worldArgs map[string]string, hostBindings map[string]HostBinding, opts ...LoadOption) (*Script, error)

LoadScript 加载脚本为驻留形态(§3.6):构建 env、收集导出表,不执行 main。 与 Run 的一次性形态不同——返回的 Script 可多次调用导出函数,宿主可按名 查导出表(§3.6「按名字查导出表」)。worldArgs 为 world 字段注入。 hostBindings 为宿主注册的 host 函数(§3.3.2);nil 时仅默认 print_line。 opts 为加载期选项(§数据重要性分层:WithTrustCap 信任上限等)。

func LoadScriptFile

func LoadScriptFile(path string, worldArgs map[string]string, hostBindings map[string]HostBinding, opts ...LoadOption) (*Script, error)

LoadScriptFile 加载 .wos 文件为驻留形态(§3.6)。支持 use <pkg> 跨文件引入。

func LoadScriptReg

func LoadScriptReg(src string, worldArgs map[string]string, hostBindings map[string]HostBinding, reg *registry.Registry, regScope string, opts ...LoadOption) (*Script, error)

LoadScriptReg 加载脚本为驻留形态并挂载分层注册表(§9.6)。 regScope 为本脚本 realm 视图标识(引擎层分配唯一 id)。

func (*Script) Call

func (s *Script) Call(name string, args []Value) (Value, error)

Call 按名调用脚本函数(§3.6 反向调用)。 name 可以是导出函数(#export)或任意顶层函数;args 为调用实参。 有 self 的顶层函数(方法/impl)不支持直接反向调用(需 receiver 绑定)。 返回函数返回值。脚本用 host.console.print_line 等的输出写入 env 缓冲, 宿主可经 Output() 取回。

func (*Script) Close

func (s *Script) Close() error

Close 回收脚本:三段式确定性回收 spawn 的 actor(cancel → 限时等 → 超时强杀), 标记句柄失效。引擎终结不留 goroutine 泄漏(actorWG 是死代码,等待真实语义见 ReapActors)。

func (*Script) EffectLog

func (s *Script) EffectLog() []EffectRecord

EffectLog 返回当前 effect 痕迹日志(诊断;fine 模式才有内容)。

func (*Script) ExportNames

func (s *Script) ExportNames() []string

ExportNames 返回脚本导出函数名列表(§3.6「按名字查导出表」)。

func (*Script) Output

func (s *Script) Output() string

Output 返回脚本运行至今的输出缓冲内容(宿主调用的 host.console 输出)。

func (*Script) Reload

func (s *Script) Reload(newSrc string) ([]string, error)

Reload 热替换脚本源码(§9.2 运行期 HMR)。在不销毁引擎/不中断宿主句柄的 前提下,把本脚本替换为其新版本。返回 (新导出表, error)。

  • 原子性:newSrc 先解析 + 构建校验,失败返回错误,本脚本保持旧版本有效 (旧版本继续可调,错误上报宿主——§9.2「失败则放弃替换、保留旧 Actor」)。
  • 状态迁移:新 env 经 shared=旧 env 复用旧输出缓冲(输出历史保留)与并发 状态(actorNextID/outMu/actorWG/SpawnFunc)。world 实例按 reloadCtx 的 worldArgs 重新构造(§9.2 状态边界:值类型状态重放,host_ref 由宿主持有)。
  • 不发卸载信号(§9.2「revertible 卸载信号在 HMR 路径上不发」):HMR 是 替换不是卸载,宿主无需清理;只有最终 Unload 才发信号。
  • mailbox 级重放(§9.2「有状态脚本靠 mailbox 队列 + 值状态重放恢复」): 旧脚本 spawn 的活跃 actor 的 mailbox 未处理消息被快照(SnapshotMailbox), 旧 actor 经 RequestCancel 优雅退出,新 main 重新执行 spawn 同名新 actor, 快照消息按 fnName 匹配 Replay 进新 actor——HMR 不丢消息。已完成/未匹配 fnName 的旧 actor 消息不迁移(旧 actor 自己处理或丢弃)。

reloadCtx 未保存(脚本非 buildScript 构造,如测试手搭)时返回错误。

func (*Script) ScriptID

func (s *Script) ScriptID() string

ScriptID 返回脚本 id(script#N,§6.2 卸载信号携带)。

func (*Script) SetRevertMode

func (s *Script) SetRevertMode(m RevertMode)

SetRevertMode 设置卸载回滚粒度(§9.5 可选开关)。默认 RevertCoarse。

func (*Script) SetScriptID

func (s *Script) SetScriptID(id string)

SetScriptID 设置脚本 id(引擎层分配,script#N)。卸载信号携带此 id。

func (*Script) SetUnloadHandler

func (s *Script) SetUnloadHandler(h func(scriptID string))

SetUnloadHandler 注册粗粒度卸载回调(§6.2 on_script_unload)。

func (*Script) SetUnwindHandler

func (s *Script) SetUnwindHandler(h func(sig UnwindSignal))

SetUnwindHandler 注册细粒度逆序回调(§9.5 on_script_effect_unwind)。

func (*Script) SetVMRunner

func (s *Script) SetVMRunner(fn VMRunner)

SetVMRunner 注入字节码执行回调(2026-08-22 C2)。nil 恢复 AST 路径。

func (*Script) Unload

func (s *Script) Unload() error

Unload 撤销脚本:按 revertMode 触发卸载信号(§6.2 粗 / §9.5 细), 然后三段式确定性回收 spawn 的 actor(cancel → 限时等 → 超时强杀),标记句柄失效。 宿主撤销脚本 Actor 时调用(§6.2:引擎撤销某脚本 Actor 时向宿主发卸载信号)。 §9.5 卸载语义至此闭环:「信号 + 等退 + 强杀兜底」。

type UnwindSignal

type UnwindSignal struct {
	ScriptID string // 脚本 id
	Seq      int    // 原调用序号(逆序排列:大 → 小)
	HostFn   string // host 函数名
	HostRef  uint64 // 原调用返回的 host_ref(0 = 该 effect 无句柄)
}

UnwindSignal 细粒度逆序信号载荷(§9.5 on_script_effect_unwind 的 Go 形态)。 宿主在回调中凭 HostFn + HostRef 定位资源账本条目的逆操作(关定时器/关文件/注销回调)。

type VMRunner

type VMRunner func(env *Env, name string, args []Value) (Value, error)

VMRunner 字节码执行回调(2026-08-22 C2):engine 层注入(interp 不反向 import vm,SpawnFunc 式解耦)。env 为当前脚本环境;name 为入口函数名; args 为实参。返回函数返回值。

type Value

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

════════════════════════════════════════════════════════════════════════════ Value:NaN-box 值表示

优化动机(对应本仓库 bench/nanbench_test.go 与 bench/nancomp_test.go 的实测):

  • 标量(int/float/bool/none/unit)编码进 IEEE754 双精度 NaN 空间的 payload 区, 单字(bits uint64)承载,无字符串 Kind 比较,构造/解构是位运算;
  • 复合类型(string/record/variant/enum/slice/func/actor/host_ref)经 ptr 指向堆对象, bits 只存 tag——值从 88 字节大结构体缩到 16 字节(bits+ptr),map/slice 拷贝便宜、 缓存友好(基准:热路径 ~2x、复合访问 1.5-3.5x、内存 8-50x);
  • Go GC 不认 NaN 空间里的指针,故复合指针单独走 ptr 字段(被 GC 追踪), 这是 Go 下 NaN-boxing 的现实形态(基准已验证 16 字节值 + GC 安全)。

编码布局(bits uint64):

  • 真 float:原样 math.Float64bits(f),不进 NaN 空间(exp≠0x7FF 直接可判);
  • boxed 值:sign=0, exp=0x7FF(NaN 空间), bit51=1(quiet 标记), bit47-50 放 tag(4 位,16 个),bit0-46 放数据(47 位,原型期 int 够用)。
  • 控制流标记(return/break/continue)与正常值流隔离,也是独立 tag。

func ActorValue

func ActorValue(ref *ActorRef) Value

ActorValue 构造 actor 句柄值。

func Bool

func Bool(b bool) Value

Bool 构造 bool 值。

func BreakMark

func BreakMark() *Value

BreakMark 构造 break 控制流标记,返回 *Value(evalStmt 用)。

func BreakValue

func BreakValue() Value

BreakValue 构造 break 控制流标记。

func ContinueMark

func ContinueMark() *Value

ContinueMark 构造 continue 控制流标记,返回 *Value(evalStmt 用)。

func ContinueValue

func ContinueValue() Value

ContinueValue 构造 continue 控制流标记。

func Enum

func Enum(typeName, tag string) Value

Enum 构造 enum 值(typeName + tag)。

func Float

func Float(f float64) Value

Float 构造 float 值(真浮点,不进 NaN 空间)。 2026-08-22 NaN 规范化:真 NaN 的 payload 可能恰好落在 boxed tag 编码上—— 例:Int(3) 编码 = qnan|tagInt<<47|3 = 0x7FF8800000000003,而 `Int(3).Float()` 解出的 NaN(payload 3)经运算传播后位模式与之相同 → Kind() 误判 int。统一规范成 裸 qnan(payload 清零,ptag=0=tagFloat,Kind() 恒为 float)。构造器是 float 值 的唯一入口,覆盖运算/宿主返回/字面量全部路径。

func FuncRef

func FuncRef(fn *funcRef) Value

FuncRef 构造函数引用值。

func HostRef

func HostRef(ref uint64) Value

HostRef 构造 host_ref 值。

func Int

func Int(n int64) Value

Int 构造 int 值。 int64 完整值截断到低 47 位(含符号位 bit46)存入 NaN 空间数据区; 解码时 Int() 用算术右移恢复符号(见下)。

func NewHostRef

func NewHostRef(id uint64) Value

NewHostRef 构造 host_ref 不透明句柄(宿主函数返回资源用,§3.3.2)。 脚本侧只能回传该值给宿主函数,不能解引用(子集不含 raw pointer)。

func None

func None() Value

None 构造 none 值。

func Record

func Record(typeName string, fields map[string]Value) Value

Record 构造 record 值(含 typeName 与字段表)。

func ReturnMark

func ReturnMark() *Value

ReturnMark 构造无值 return 的控制流标记,返回 *Value(evalStmt 用)。

func ReturnValue

func ReturnValue(ret *Value) Value

ReturnValue 构造 return 控制流标记(Ret 指向实际返回值;nil = 无返回值 return)。

func ReturnValuePtr

func ReturnValuePtr(ret *Value) *Value

ReturnValuePtr 构造带返回值的 return 控制流标记,返回 *Value(evalStmt 用)。

func Slice

func Slice(items []Value) Value

Slice 构造 slice 值。

func String

func String(s string) Value

String 构造 string 值。

func Unit

func Unit() Value

Unit 构造 unit 值。

func Variant

func Variant(typeName, tag string, payload []Value) Value

Variant 构造 variant 值(typeName + tag + 载荷)。

func Zero

func Zero(typeName string) Value

Zero 返回指定类型名的零值。

func (Value) Actor

func (v Value) Actor() *ActorRef

Actor 返回 actor 句柄(仅 Kind()=="actor" 时有效)。

func (Value) Bool

func (v Value) Bool() bool

Bool 返回 bool 值(仅 Kind()=="bool" 时有效)。

func (Value) Fields

func (v Value) Fields() map[string]Value

Fields 返回 record 的字段表(仅 Kind()=="record" 时有效)。

func (Value) Float

func (v Value) Float() float64

Float 返回 float 值(仅 Kind()=="float" 时有效)。

func (Value) Func

func (v Value) Func() *funcRef

Func 返回函数引用(仅 Kind()=="func" 时有效)。

func (Value) Int

func (v Value) Int() int64

Int 返回 int 值(仅 Kind()=="int" 时有效)。 符号扩展:低 47 位存 int64 截断,算术右移 17 位恢复符号(负数值正确)。

func (Value) IsBreak

func (v Value) IsBreak() bool

IsBreak 判断是否为 break 标记。

func (Value) IsContinue

func (v Value) IsContinue() bool

IsContinue 判断是否为 continue 标记。

func (Value) IsControlFlow

func (v Value) IsControlFlow() bool

IsControlFlow 判断是否为控制流标记(return/break/continue)。

func (Value) IsNone

func (v Value) IsNone() bool

IsNone 判断是否 none 值(仅 tagNone)。2026-08-22 修正:零值 Value(bits==0)是 +0.0(合法 float),不是 none——原 `v.bits == 0` 分支把 Float(0.0).IsNone() 误判 true。

func (Value) IsReturn

func (v Value) IsReturn() bool

IsReturn 判断是否为 return 标记。

func (Value) Kind

func (v Value) Kind() string

Kind 返回值的类型名(语义与旧字符串 Kind 完全兼容)。

func (Value) Payload

func (v Value) Payload() []Value

Payload 返回 variant 的载荷(仅 Kind()=="variant" 时有效)。

func (Value) Ref

func (v Value) Ref() uint64

Ref 返回 host_ref 的句柄值(仅 Kind()=="host_ref" 时有效)。

func (Value) Ret

func (v Value) Ret() *Value

Ret 返回 return 控制流包装的实际返回值(仅 Kind()=="return" 时有效;nil = 无返回值)。

func (Value) Slice

func (v Value) Slice() []Value

Slice 返回 slice 的元素(仅 Kind()=="slice" 时有效)。

func (Value) Str

func (v Value) Str() string

Str 返回 string 值(仅 Kind()=="string" 时有效)。

func (Value) Tag

func (v Value) Tag() string

Tag 返回 variant/enum 的 tag(其他类型返回 "")。

func (Value) ToString

func (v Value) ToString() string

ToString 用于打印。

func (Value) TypeName

func (v Value) TypeName() string

TypeName 返回 record/variant/enum 的 typeName(其他类型返回 "")。

Source Files

  • effect.go
  • host_bridge.go
  • interp.go
  • reg_bridge.go
  • script.go
  • value.go

Jump to

Keyboard shortcuts

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