From 48629ab55b0d8d21c73d60abc8a9cf9fbd724c77 Mon Sep 17 00:00:00 2001 From: Codex Bot Date: Sun, 15 Nov 2026 17:47:28 +0800 Subject: [PATCH] docs(core): explain VM facade ownership and store delegation --- crates/core/src/vm.rs | 69 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/crates/core/src/vm.rs b/crates/core/src/vm.rs index 6f67be4..56bf63a 100644 --- a/crates/core/src/vm.rs +++ b/crates/core/src/vm.rs @@ -1,3 +1,7 @@ +//! 嵌入宿主及 eval 共用的 VM 门面;本文件多数方法直接委托 ObjectStore,不重复实现堆规则。 +//! 指令执行/调用/暂停在 eval,状态类型在 frame;这里仅持有状态并暴露受控对象 API。 +//! new_*/allocate/成功 upgrade 返回拥有根;get_attr/cell_get/dict_get 等读取仍为借用句柄。 + use objects::ObjectStore; use crate::{ @@ -9,36 +13,47 @@ use crate::{ /// reference accounting and builtin operations live in the objects crate. #[derive(Debug)] pub struct Vm { + // 唯一对象图与受控堆门面,对象规则不在 VM 重复实现。 pub(crate) objects: ObjectStore, + // 最近执行失败的回溯快照,eval 启动新调用时清空。 pub(crate) last_traceback: Vec, + // 源码参数/返回检查开关,与 Store 字段检查一起配置,默认关闭。 pub(crate) source_type_checks: bool, + // VM 最多保存一个只读续执行及其活跃只读作用域;可变协程另在托管载荷中。 pub(crate) suspended_call: Option, } impl Vm { + /// 宿主开启源码参数/返回及 Store 字段检查;只读调用期间不能改变配置。 pub fn set_source_type_checks(&mut self, enabled: bool) -> Result<(), VmError> { + // 配置会影响后续语义,不能由只读调用改变,即使写入相同值也拒绝。 if self.objects.is_read_only() { return Err(VmError::UnsupportedOperation( "configure source type checks during read-only call", )); } + // 先让 Store 接受字段配置,成功后才更新 VM 的源码检查开关。 self.objects.set_field_type_checks(enabled)?; self.source_type_checks = enabled; Ok(()) } /// Known whole-call effect; unproved source/delegated calls return None. + /// 宿主调度/契约查询当前整次调用效果;无法证明或动态委托返回 None,不代表确定写入。 pub fn call_effect(&self, function: ObjectRef) -> Result, VmError> { self.objects.call_effect(function) } + /// 宿主参数检查委托 Store,统一源码/原生数量区间并扣除已绑定接收者。 pub fn call_arity(&self, function: ObjectRef) -> Result, VmError> { self.objects.call_arity(function) } + /// 宿主初始化 Function 名义类型配置,Store 保存弱引用用于后续函数分配。 pub fn set_function_type(&mut self, definition: ObjectRef) -> Result<(), VmError> { self.objects.set_function_type(definition) } + /// 宿主注册最小方法数量能力,返回一份外部拥有根,要求数量不含 self。 pub fn new_trait( &mut self, name: impl Into, @@ -46,6 +61,7 @@ impl Vm { ) -> Result { self.objects.new_trait(name, requirements) } + /// 宿主注册含 self 的完整参数/返回/效果能力,成功返回一份拥有根。 pub fn new_typed_trait( &mut self, name: impl Into, @@ -53,6 +69,7 @@ impl Vm { ) -> Result { self.objects.new_typed_trait(name, requirements) } + /// 宿主给类型显式声明能力,Store 先校验后代方法和已有实例再提交。 pub fn implement_trait( &mut self, definition: ObjectRef, @@ -60,6 +77,7 @@ impl Vm { ) -> Result<(), VmError> { self.objects.implement_trait(definition, capability) } + /// 宿主查询类型显式/继承声明,命中还会重验当前契约,不做结构猜测。 pub fn implements_trait( &self, definition: ObjectRef, @@ -67,10 +85,12 @@ impl Vm { ) -> Result { self.objects.implements_trait(definition, capability) } + /// 宿主/UI bridge 查询值级能力,同时核对有效类型及实例存储遮蔽。 pub fn supports(&self, object: ObjectRef, capability: ObjectRef) -> Result { self.objects.supports(object, capability) } + /// 宿主注册或替换方法,Store 校验能力/覆盖并维护方法强边,保留类型身份。 pub fn define_method( &mut self, type_object: ObjectRef, @@ -82,15 +102,18 @@ impl Vm { /// Owned result; release_value when finished. Unlike get_attr, methods bind /// their receiver and retain it until the bound method itself is released. + /// eval LoadAttr/宿主取得拥有结果;方法包装持有原接收者,结果用 release_value 归还。 pub fn bind_attr(&mut self, object: ObjectRef, name: &str) -> Result { self.objects.bind_attr(object, name) } + /// 宿主显式自举 Object 与 Type,返回两份根;Vm::new 不隐式调用它。 pub fn bootstrap_types(&mut self) -> Result { self.objects.bootstrap_types() } /// Host registration uses the same validated class builder as source code. + /// 宿主使用与源码相同的类构造校验,继承字段在前,失败不交付半成品。 pub fn new_class( &mut self, name: impl Into, @@ -101,6 +124,7 @@ impl Vm { self.objects.new_class(name, base, fields, methods) } + /// 宿主构造名义派生类型及实例分配策略,返回一份拥有根。 pub fn new_type( &mut self, name: impl Into, @@ -110,6 +134,7 @@ impl Vm { self.objects.new_type(name, base, constructor) } + /// 宿主/构造路径附着不可替换的名义类型,能力和只读屏障由 Store/Heap 检查。 pub fn attach_type( &mut self, object: ObjectRef, @@ -118,27 +143,33 @@ impl Vm { self.objects.attach_type(object, type_object) } + /// 宿主/执行器查询有效名义类型,遵循 type_target 转发;返回句柄借用,无类型为 None。 pub fn type_of(&self, object: ObjectRef) -> Result, VmError> { self.objects.type_of(object) } + /// 宿主类型检查沿固定基类链按身份判定,包含自反关系。 pub fn is_subtype(&self, candidate: ObjectRef, expected: ObjectRef) -> Result { self.objects.is_subtype(candidate, expected) } + /// 宿主值类型检查以有效类型判定,无名义类型对象为 false。 pub fn is_instance(&self, object: ObjectRef, expected: ObjectRef) -> Result { self.objects.is_instance(object, expected) } /// Read-only access for embedding protocols sharing the same object graph. + /// 宿主共享同一对象图的只读协议入口,不提供绕过写屏障的可变存储。 pub fn object_store(&self) -> &ObjectStore { &self.objects } + /// 宿主缓存弱身份,不新增计数、不消耗当前拥有根;句柄仍须先有效。 pub fn downgrade(&self, reference: ObjectRef) -> Result { self.objects.downgrade(reference) } + /// 宿主尝试把弱身份转为一份新拥有根;过期返回 None,异堆仍报错。 pub fn upgrade( &mut self, reference: crate::WeakObjectRef, @@ -146,14 +177,17 @@ impl Vm { self.objects.upgrade(reference) } + /// 宿主渲染/模型缓存取走累计变更与溢出标志,通知本身不保留源对象。 pub fn take_changes(&mut self) -> crate::ChangeBatch { self.objects.take_changes() } + /// 缓存观察当前对象版本;读取会经过 Store 的依赖收集入口。 pub fn change_version(&self, reference: ObjectRef) -> Result { self.objects.change_version(reference) } + /// 宿主受控提交载荷及 trace 边快照,稳定对象身份,先校验/保留新边再释放旧边。 pub fn replace_payload( &mut self, reference: ObjectRef, @@ -162,7 +196,9 @@ impl Vm { self.objects.replace_payload(reference, payload) } + /// 嵌入方创建空 Store 和空执行状态;不注册类型、函数或语言全局空间。 pub fn new() -> Result { + // 空状态与 Store::new 保持一致,执行时按需建立全局空间与帧。 Ok(Self { objects: ObjectStore::new()?, last_traceback: Vec::new(), @@ -171,56 +207,69 @@ impl Vm { }) } + /// 宿主/测试查询当前存活堆对象数,不包括直接 Value 标量。 pub fn object_count(&self) -> usize { self.objects.object_count() } /// Returns one external strong reference. Copies of the returned handle /// are borrowed; use retain/release to manage additional owned references. + /// 宿主/内部构造载荷的统一门面,Store 负责内置校验、强边计数与函数类型附着。 pub fn allocate(&mut self, payload: impl ObjectPayload) -> Result { self.objects.allocate(payload) } + /// 宿主/原生构造器创建可附动态字段的 Record,返回一份根,类型可另附着。 pub fn new_object(&mut self) -> Result { self.objects.new_object() } + /// eval/宿主借用完整对象,验证句柄并收集整对象读取,不新增根。 pub fn object(&self, reference: ObjectRef) -> Result<&EndorObject, VmError> { self.objects.object(reference) } + /// 宿主/执行槽取得额外外部根,复制 ObjectRef 本身不会自动执行此操作。 pub fn retain(&mut self, reference: ObjectRef) -> Result<(), VmError> { self.objects.retain(reference) } + /// 宿主/执行槽归还一份拥有根,零强计数时级联释放;不能归还仅借用的内部边。 pub fn release(&mut self, reference: ObjectRef) -> Result<(), VmError> { self.objects.release(reference) } + /// 测试/诊断读总强计数,包含外部根和堆内边,不是仅宿主引用数。 pub fn ref_count(&self, reference: ObjectRef) -> Result { self.objects.ref_count(reference) } + /// 宿主/执行器先验证两端再比较完整身份,不调用数值或载荷相等协议。 pub fn is_same(&self, left: ObjectRef, right: ObjectRef) -> Result { self.objects.is_same(left, right) } + /// 宿主/错误显示委托载荷诊断表示,不运行源码 repr 方法。 pub fn repr(&self, reference: ObjectRef) -> Result { self.objects.repr(reference) } + /// 宿主显示文本协议,默认载荷可回退 repr,不自动转为语言调用。 pub fn str(&self, reference: ObjectRef) -> Result { self.objects.str(reference) } + /// eval 条件分支/宿主走载荷真值协议,协议失败保持错误。 pub fn is_true(&self, reference: ObjectRef) -> Result { self.objects.is_true(reference) } + /// 字典键/宿主走载荷哈希,数值等未实现种类可明确拒绝。 pub fn hash(&self, reference: ObjectRef) -> Result { self.objects.hash(reference) } + /// eval 对象比较委托 Store 的正向、反向及身份回退;直接数值另走 eval 数学比较。 pub fn compare( &self, left: ObjectRef, @@ -232,12 +281,14 @@ impl Vm { /// Reads a borrowed value. An Object result needs retain() if the host /// wants it to survive removal of the attribute that currently owns it. + /// 宿主借用属性值,方法以函数句柄返回,不分配接收者绑定对象。 pub fn get_attr(&self, reference: ObjectRef, name: &str) -> Result { self.objects.get_attr(reference, name) } /// Object-valued attributes own internal strong references independently /// of the caller's external references. Failure leaves the field unchanged. + /// 宿主/执行器写属性,值对象由字段独立强边持有,不消耗调用者外部根。 pub fn set_attr( &mut self, reference: ObjectRef, @@ -247,20 +298,24 @@ impl Vm { self.objects.set_attr(reference, name, value) } + /// 宿主/执行器删除属性,经类型字段保护和转发定位后释放原值内部边。 pub fn del_attr(&mut self, reference: ObjectRef, name: &str) -> Result<(), VmError> { self.objects.del_attr(reference, name) } + /// eval 验证借用 Value 中对象句柄的堆归属和存活,不 retain 或新增读取依赖。 pub(crate) fn validate_value(&self, value: &Value) -> Result<(), VmError> { self.objects.validate_value(value) } /// Explicit full collection. Execution slots use owned roots, so values /// on live execution stacks participate in the same root accounting. + /// 宿主显式回收外部根不可达的环;活跃帧根与停放协程边参与同一对象图计数。 pub fn collect_cycles(&mut self) -> usize { self.objects.collect_cycles() } + /// eval/宿主借用具体 Rust 载荷,expected 只是错误标签,不等于名义类型注解。 pub fn payload( &self, reference: ObjectRef, @@ -269,14 +324,17 @@ impl Vm { self.objects.payload::(reference, expected) } + /// 宿主创建不可变堆字符串,返回拥有根;与直接 Value::Text 区分。 pub fn new_string(&mut self, text: impl Into) -> Result { self.objects.new_string(text) } + /// 编译器加载/宿主把已校验 EndorCode 分配成托管代码对象,常量强边由 Store 维护。 pub fn new_code(&mut self, code: EndorCode) -> Result { self.objects.new_code(code) } + /// eval 执行入口/闭包构造与宿主创建源码函数,Store 校验代码/默认值/捕获槽并捕获内置空间。 pub fn new_function( &mut self, name: impl Into, @@ -289,23 +347,28 @@ impl Vm { .new_function(name, code, globals, defaults, closure) } + /// 宿主创建堆数值对象,返回拥有根;直接 Value::Number 不占该堆槽。 pub fn new_number(&mut self, number: EndorNumber) -> Result { self.objects.new_number(number) } + /// eval 字典构造/宿主创建空插入顺序字典,返回拥有根。 pub fn new_dict(&mut self) -> Result { self.objects.new_dict() } /// Returns borrowed keys and values in insertion order. + /// eval 构类及宿主借用插入顺序条目,观察整个字典,不新增对象根。 pub fn dict_items(&self, dictionary: ObjectRef) -> Result<&[(Value, Value)], VmError> { self.objects.dict_items(dictionary) } + /// eval/宿主通用键读取,缺键 None 与已存 Nil 分开,结果对象句柄仍借用。 pub fn dict_get(&self, dictionary: ObjectRef, key: &Value) -> Result, VmError> { self.objects.dict_get(dictionary, key) } + /// eval 构图/全局赋值与宿主写字典,Store 保留首键及插入顺序并事务维护强边。 pub fn dict_set( &mut self, dictionary: ObjectRef, @@ -315,27 +378,33 @@ impl Vm { self.objects.dict_set(dictionary, key, value) } + /// eval 删除全局名/宿主删除键,缺键 false,不存在时不产生替换通知。 pub fn dict_delete(&mut self, dictionary: ObjectRef, key: &Value) -> Result { self.objects.dict_delete(dictionary, key) } + /// 宿主清空字典,保留对象身份,旧键值边由 Heap 释放;空字典也受写屏障。 pub fn dict_clear(&mut self, dictionary: ObjectRef) -> Result<(), VmError> { self.objects.dict_clear(dictionary) } + /// eval 把局部提升为闭包共享槽时创建,None 为未初始化,Some(Nil) 是已初始化。 pub fn new_cell(&mut self, value: Option) -> Result { self.objects.new_cell(value) } /// Reads a borrowed value; an empty cell is not Value::Nil. + /// eval 自由变量读取/宿主借用槽值,空槽返回 EmptyCell,不把 Nil 当未初始化。 pub fn cell_get(&self, cell: ObjectRef) -> Result { self.objects.cell_get(cell) } + /// eval 捕获变量赋值/宿主更新共享槽,保留 Cell 身份,引用边由 Heap 替换。 pub fn cell_set(&mut self, cell: ObjectRef, value: Value) -> Result<(), VmError> { self.objects.cell_set(cell, value) } + /// eval 删除捕获变量/宿主恢复空槽,释放旧值边,不把它替换为 Some(Nil)。 pub fn cell_clear(&mut self, cell: ObjectRef) -> Result<(), VmError> { self.objects.cell_clear(cell) }