docs(objects): explain change notifications and shared errors

This commit is contained in:
2026-11-15 17:19:52 +08:00
parent 9861a6d586
commit 717eab6d32
2 changed files with 63 additions and 6 deletions
+48 -2
View File
@@ -1,55 +1,97 @@
//! objects 定义、compiler/core 与宿主共用的错误协议,避免底层存储反向依赖 VM 执行器。
//! Display 只生成诊断文本,不恢复对象、不回滚操作,也不等同于托管的异常对象载荷。
use std::fmt;
/// Shared object/bytecode/execution errors. The established VmError name is
/// retained for embedders; defining it here avoids a dependency on the VM.
/// 覆盖对象、字节码与执行错误;保留 VmError 名称供既有嵌入方匹配。
/// 各操作用 Result 返回;Clone 复制诊断信息,不复制 VM 状态或托管对象。
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum VmError {
/// 宿主等待对象的异步操作失败,携带提供方报告的原因。
AwaitFailed(String),
/// 宿主等待对象报告取消,与失败原因或暂未就绪区分。
AwaitCancelled,
/// Heap::get 发现句柄属于其他堆;不是本堆对象已过期。
ForeignHandle,
/// Heap::get 发现越界、代际不符或空槽;不能再访问该身份。
InvalidHandle,
/// Heap::new 的进程级身份计数耗尽,拒绝复用身份。
IdentityExhausted,
/// Heap 引用增量预检溢出,阻止计数绕回。
RefCountOverflow,
/// Heap::release 没有可归还的外部根;内部强边不能当外部根释放。
NoOwnedReference,
/// 属性存储查找/删除未找到字段,携带字段名。
AttributeNotFound(String),
/// 载荷不支持操作或当前上下文禁止操作,携带静态操作说明。
UnsupportedOperation(&'static str),
/// 构造或协议校验不满足结构约束,携带静态原因。
InvalidArgument(&'static str),
/// Store 下转型或执行器要求某种载荷而实际不符,携带预期诊断名称。
ObjectKindMismatch(&'static str),
/// 能力契约校验失败,定位能力、方法及不兼容原因。
TraitViolation {
/// 能力名称,用于定位失败契约。
capability: String,
/// 被核对的方法名称。
method: String,
/// 无需动态分配的具体失败原因。
reason: &'static str,
},
/// 方法替换不满足父级契约,定位定义、方法和原因。
OverrideViolation {
/// 方法所属类型定义名称。
definition: String,
/// 被核对的方法名称。
method: String,
/// 无需动态分配的具体失败原因。
reason: &'static str,
},
/// 类型解析无法接受注解名称;部分延后校验路径可暂缓此错误。
UnknownAnnotation(String),
/// 源码/原生签名或字段校验不匹配,携带调用位置与预期/实际类型诊断。
TypeMismatch {
/// 被校验函数或相关诊断主体。
function: String,
/// 参数、返回值或字段等发生不匹配的位置。
position: String,
/// 期望类型的可读名称。
expected: String,
/// 实际值类型的可读名称。
actual: String,
},
/// Store::cell_get 读取尚未初始化的闭包槽,不等于槽中存放 Nil。
EmptyCell,
/// 解码或代码校验拒绝指令,offset 是代码单元偏移,reason 是静态说明。
InvalidBytecode {
/// 字节码代码单元偏移,不是源文本行号。
offset: usize,
/// 无需动态分配的具体失败原因。
reason: &'static str,
},
/// 执行器读取/删除未绑定局部或相关捕获变量,携带变量名称。
UnboundLocal(String),
/// 执行器全局/内置查找或删除名称失败,携带名称。
NameNotFound(String),
/// 调用入口数量校验失败,记录函数名、最少/最多及实际位置参数数目。
ArgumentCount {
/// 被调用对象的诊断名称。
name: String,
/// 允许的最少位置参数数。
required: usize,
/// 允许的最多位置参数数。
maximum: usize,
/// 调用方实际提供的位置参数数。
provided: usize,
},
/// 执行帧、指令等预算或内部有界计数达到限制,携带具体限制类别。
ExecutionLimit(&'static str),
}
impl fmt::Display for VmError {
/// 宿主日志、UI 错误文本及标准 Error 展示调用;只借用错误,不消费其中的诊断数据。
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// 按变体生成稳定的可读诊断;结构化匹配应使用变体,不能依赖解析此文本。
match self {
Self::AwaitFailed(message) => write!(f, "await failed: {message}"),
Self::AwaitCancelled => f.write_str("await cancelled"),
@@ -59,6 +101,7 @@ impl fmt::Display for VmError {
Self::RefCountOverflow => f.write_str("object reference count exhausted"),
Self::NoOwnedReference => f.write_str("no external strong reference to release"),
Self::AttributeNotFound(name) => write!(f, "attribute not found: {name}"),
// 保留具体受限操作,便于区分协议缺失和只读上下文等限制。
Self::UnsupportedOperation(operation) => {
write!(f, "object does not support {operation}")
}
@@ -69,6 +112,7 @@ impl fmt::Display for VmError {
method,
reason,
} => write!(f, "trait {capability} method {method}: {reason}"),
// 名称来自注解解析,不把它伪装成已经解析的语言类型。
Self::UnknownAnnotation(name) => {
write!(f, "unknown or invalid type annotation: {name}")
}
@@ -87,6 +131,7 @@ impl fmt::Display for VmError {
"{function} {position} expects {expected}, received {actual}"
),
Self::EmptyCell => f.write_str("cell is empty"),
// 偏移单位与指令解码器一致,避免把代码单元误报为源代码行号。
Self::InvalidBytecode { offset, reason } => {
write!(f, "invalid bytecode at code unit {offset}: {reason}")
}
@@ -106,4 +151,5 @@ impl fmt::Display for VmError {
}
}
// 使宿主可通过标准 Error 接口传播/封装;当前未另提供嵌套 source 错误链。
impl std::error::Error for VmError {}