414 lines
18 KiB
Rust
414 lines
18 KiB
Rust
//! 嵌入宿主及 eval 共用的 VM 门面;本文件多数方法直接委托 ObjectStore,不重复实现堆规则。
|
|
//! 指令执行/调用/暂停在 eval,状态类型在 frame;这里仅持有状态并暴露受控对象 API。
|
|
//! new_*/allocate/成功 upgrade 返回拥有根;get_attr/cell_get/dict_get 等读取仍为借用句柄。
|
|
|
|
use objects::ObjectStore;
|
|
|
|
use crate::{
|
|
CompareOp, EndorCode, EndorNumber, EndorObject, ExecutionLocation, ObjectPayload, ObjectRef,
|
|
Value, VmError,
|
|
};
|
|
|
|
/// Owns the object store and execution state. Object representation, allocation,
|
|
/// 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<ExecutionLocation>,
|
|
// 源码参数/返回检查开关,与 Store 字段检查一起配置,默认关闭。
|
|
pub(crate) source_type_checks: bool,
|
|
// VM 最多保存一个只读续执行及其活跃只读作用域;可变协程另在托管载荷中。
|
|
pub(crate) suspended_call: Option<crate::frame::SuspendedCall>,
|
|
}
|
|
|
|
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<Option<objects::CallEffect>, VmError> {
|
|
self.objects.call_effect(function)
|
|
}
|
|
|
|
/// 宿主参数检查委托 Store,统一源码/原生数量区间并扣除已绑定接收者。
|
|
/// None 表示未发布数量元数据,不能仅凭此结果断定该对象可以调用。
|
|
pub fn call_arity(&self, function: ObjectRef) -> Result<Option<objects::CallArity>, 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<String>,
|
|
requirements: Vec<crate::MethodRequirement>,
|
|
) -> Result<ObjectRef, VmError> {
|
|
self.objects.new_trait(name, requirements)
|
|
}
|
|
/// 宿主注册含 self 的完整参数/返回/效果能力,成功返回一份拥有根。
|
|
pub fn new_typed_trait(
|
|
&mut self,
|
|
name: impl Into<String>,
|
|
requirements: Vec<crate::TypedMethodRequirement>,
|
|
) -> Result<ObjectRef, VmError> {
|
|
self.objects.new_typed_trait(name, requirements)
|
|
}
|
|
/// 宿主给类型显式声明能力,Store 先校验后代方法和已有实例再提交。
|
|
pub fn implement_trait(
|
|
&mut self,
|
|
definition: ObjectRef,
|
|
capability: ObjectRef,
|
|
) -> Result<(), VmError> {
|
|
self.objects.implement_trait(definition, capability)
|
|
}
|
|
/// 宿主查询类型显式/继承声明,命中还会重验当前契约,不做结构猜测。
|
|
pub fn implements_trait(
|
|
&self,
|
|
definition: ObjectRef,
|
|
capability: ObjectRef,
|
|
) -> Result<bool, VmError> {
|
|
self.objects.implements_trait(definition, capability)
|
|
}
|
|
/// 宿主/UI bridge 查询值级能力,同时核对有效类型及实例存储遮蔽。
|
|
pub fn supports(&self, object: ObjectRef, capability: ObjectRef) -> Result<bool, VmError> {
|
|
self.objects.supports(object, capability)
|
|
}
|
|
|
|
/// 宿主注册或替换方法,Store 校验能力/覆盖并维护方法强边,保留类型身份。
|
|
pub fn define_method(
|
|
&mut self,
|
|
type_object: ObjectRef,
|
|
name: impl Into<String>,
|
|
function: ObjectRef,
|
|
) -> Result<(), VmError> {
|
|
self.objects.define_method(type_object, name, function)
|
|
}
|
|
|
|
/// 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<Value, VmError> {
|
|
self.objects.bind_attr(object, name)
|
|
}
|
|
|
|
/// 宿主显式自举 Object 与 Type,返回两份根;Vm::new 不隐式调用它。
|
|
pub fn bootstrap_types(&mut self) -> Result<crate::RootTypes, VmError> {
|
|
self.objects.bootstrap_types()
|
|
}
|
|
|
|
/// Host registration uses the same validated class builder as source code.
|
|
/// 宿主使用与源码相同的类构造校验,继承字段在前,失败不交付半成品。
|
|
pub fn new_class(
|
|
&mut self,
|
|
name: impl Into<String>,
|
|
base: ObjectRef,
|
|
fields: Vec<crate::ClassField>,
|
|
methods: std::collections::BTreeMap<String, ObjectRef>,
|
|
) -> Result<ObjectRef, VmError> {
|
|
self.objects.new_class(name, base, fields, methods)
|
|
}
|
|
|
|
/// 宿主构造名义派生类型及实例分配策略,返回一份拥有根。
|
|
pub fn new_type(
|
|
&mut self,
|
|
name: impl Into<String>,
|
|
base: ObjectRef,
|
|
constructor: crate::TypeConstructor,
|
|
) -> Result<ObjectRef, VmError> {
|
|
self.objects.new_type(name, base, constructor)
|
|
}
|
|
|
|
/// 宿主/构造路径附着不可替换的名义类型,能力和只读屏障由 Store/Heap 检查。
|
|
pub fn attach_type(
|
|
&mut self,
|
|
object: ObjectRef,
|
|
type_object: ObjectRef,
|
|
) -> Result<(), VmError> {
|
|
self.objects.attach_type(object, type_object)
|
|
}
|
|
|
|
/// 宿主/执行器查询有效名义类型,遵循 type_target 转发;返回句柄借用,无类型为 None。
|
|
pub fn type_of(&self, object: ObjectRef) -> Result<Option<ObjectRef>, VmError> {
|
|
self.objects.type_of(object)
|
|
}
|
|
|
|
/// 宿主类型检查沿固定基类链按身份判定,包含自反关系。
|
|
pub fn is_subtype(&self, candidate: ObjectRef, expected: ObjectRef) -> Result<bool, VmError> {
|
|
self.objects.is_subtype(candidate, expected)
|
|
}
|
|
|
|
/// 宿主值类型检查以有效类型判定,无名义类型对象为 false。
|
|
pub fn is_instance(&self, object: ObjectRef, expected: ObjectRef) -> Result<bool, VmError> {
|
|
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<crate::WeakObjectRef, VmError> {
|
|
self.objects.downgrade(reference)
|
|
}
|
|
|
|
/// 宿主尝试把弱身份转为一份新拥有根;过期返回 None,异堆仍报错。
|
|
pub fn upgrade(
|
|
&mut self,
|
|
reference: crate::WeakObjectRef,
|
|
) -> Result<Option<ObjectRef>, VmError> {
|
|
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<u64, VmError> {
|
|
self.objects.change_version(reference)
|
|
}
|
|
|
|
/// 宿主受控提交载荷及 trace 边快照,稳定对象身份,先校验/保留新边再释放旧边。
|
|
pub fn replace_payload(
|
|
&mut self,
|
|
reference: ObjectRef,
|
|
payload: impl ObjectPayload,
|
|
) -> Result<(), VmError> {
|
|
self.objects.replace_payload(reference, payload)
|
|
}
|
|
|
|
/// 嵌入方创建空 Store 和空执行状态;不注册类型、函数或语言全局空间。
|
|
pub fn new() -> Result<Self, VmError> {
|
|
// 空状态与 Store::new 保持一致;对象/环境由调用方显式分配,执行入口按需准备帧。
|
|
Ok(Self {
|
|
objects: ObjectStore::new()?,
|
|
last_traceback: Vec::new(),
|
|
source_type_checks: false,
|
|
suspended_call: None,
|
|
})
|
|
}
|
|
|
|
/// 宿主/测试查询当前存活堆对象数,不包括直接 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<ObjectRef, VmError> {
|
|
self.objects.allocate(payload)
|
|
}
|
|
|
|
/// 宿主/原生构造器创建可附动态字段的 Record,返回一份根,类型可另附着。
|
|
pub fn new_object(&mut self) -> Result<ObjectRef, VmError> {
|
|
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<usize, VmError> {
|
|
self.objects.ref_count(reference)
|
|
}
|
|
|
|
/// 宿主/执行器先验证两端再比较完整身份,不调用数值或载荷相等协议。
|
|
pub fn is_same(&self, left: ObjectRef, right: ObjectRef) -> Result<bool, VmError> {
|
|
self.objects.is_same(left, right)
|
|
}
|
|
|
|
/// 宿主/错误显示委托载荷诊断表示,不运行源码 repr 方法。
|
|
pub fn repr(&self, reference: ObjectRef) -> Result<String, VmError> {
|
|
self.objects.repr(reference)
|
|
}
|
|
|
|
/// 宿主显示文本协议,默认载荷可回退 repr,不自动转为语言调用。
|
|
pub fn str(&self, reference: ObjectRef) -> Result<String, VmError> {
|
|
self.objects.str(reference)
|
|
}
|
|
|
|
/// eval 条件分支/宿主走载荷真值协议,协议失败保持错误。
|
|
pub fn is_true(&self, reference: ObjectRef) -> Result<bool, VmError> {
|
|
self.objects.is_true(reference)
|
|
}
|
|
|
|
/// 字典键/宿主走载荷哈希,数值等未实现种类可明确拒绝。
|
|
pub fn hash(&self, reference: ObjectRef) -> Result<u64, VmError> {
|
|
self.objects.hash(reference)
|
|
}
|
|
|
|
/// eval 对象比较委托 Store 的正向、反向及身份回退;直接数值另走 eval 数学比较。
|
|
pub fn compare(
|
|
&self,
|
|
left: ObjectRef,
|
|
right: ObjectRef,
|
|
operation: CompareOp,
|
|
) -> Result<bool, VmError> {
|
|
self.objects.compare(left, right, operation)
|
|
}
|
|
|
|
/// 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<Value, VmError> {
|
|
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,
|
|
name: impl Into<String>,
|
|
value: Value,
|
|
) -> Result<(), VmError> {
|
|
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<T: ObjectPayload>(
|
|
&self,
|
|
reference: ObjectRef,
|
|
expected: &'static str,
|
|
) -> Result<&T, VmError> {
|
|
self.objects.payload::<T>(reference, expected)
|
|
}
|
|
|
|
/// 宿主创建不可变堆字符串,返回拥有根;与直接 Value::Text 区分。
|
|
pub fn new_string(&mut self, text: impl Into<String>) -> Result<ObjectRef, VmError> {
|
|
self.objects.new_string(text)
|
|
}
|
|
|
|
/// 编译器加载/宿主把已校验 EndorCode 分配成托管代码对象,常量强边由 Store 维护。
|
|
pub fn new_code(&mut self, code: EndorCode) -> Result<ObjectRef, VmError> {
|
|
self.objects.new_code(code)
|
|
}
|
|
|
|
/// eval 执行入口/闭包构造与宿主创建源码函数,Store 校验代码/默认值/捕获槽并捕获内置空间。
|
|
pub fn new_function(
|
|
&mut self,
|
|
name: impl Into<String>,
|
|
code: ObjectRef,
|
|
globals: ObjectRef,
|
|
defaults: Vec<Value>,
|
|
closure: Vec<ObjectRef>,
|
|
) -> Result<ObjectRef, VmError> {
|
|
self.objects
|
|
.new_function(name, code, globals, defaults, closure)
|
|
}
|
|
|
|
/// 宿主创建堆数值对象,返回拥有根;直接 Value::Number 不占该堆槽。
|
|
pub fn new_number(&mut self, number: EndorNumber) -> Result<ObjectRef, VmError> {
|
|
self.objects.new_number(number)
|
|
}
|
|
|
|
/// eval 字典构造/宿主创建空插入顺序字典,返回拥有根。
|
|
pub fn new_dict(&mut self) -> Result<ObjectRef, VmError> {
|
|
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<Option<Value>, VmError> {
|
|
self.objects.dict_get(dictionary, key)
|
|
}
|
|
|
|
/// eval 构图/全局赋值与宿主写字典,Store 保留首键及插入顺序并事务维护强边。
|
|
pub fn dict_set(
|
|
&mut self,
|
|
dictionary: ObjectRef,
|
|
key: Value,
|
|
value: Value,
|
|
) -> Result<(), VmError> {
|
|
self.objects.dict_set(dictionary, key, value)
|
|
}
|
|
|
|
/// eval 删除全局名/宿主删除键,缺键 false,不存在时不产生替换通知。
|
|
pub fn dict_delete(&mut self, dictionary: ObjectRef, key: &Value) -> Result<bool, VmError> {
|
|
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<Value>) -> Result<ObjectRef, VmError> {
|
|
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<Value, VmError> {
|
|
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)
|
|
}
|
|
}
|