156 lines
7.2 KiB
Rust
156 lines
7.2 KiB
Rust
//! objects 定义、compiler/core 与宿主共用的错误协议,避免底层存储反向依赖 VM 执行器。
|
|
//! Display 只生成诊断文本,不恢复对象、不回滚操作,也不等同于托管的异常对象载荷。
|
|
|
|
use std::fmt;
|
|
|
|
/// 覆盖对象、字节码与执行错误;保留 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"),
|
|
Self::ForeignHandle => f.write_str("handle belongs to another VM"),
|
|
Self::InvalidHandle => f.write_str("handle does not identify a live object"),
|
|
Self::IdentityExhausted => f.write_str("process-local VM identities exhausted"),
|
|
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}")
|
|
}
|
|
Self::InvalidArgument(message) => f.write_str(message),
|
|
Self::ObjectKindMismatch(expected) => write!(f, "expected {expected} object"),
|
|
Self::TraitViolation {
|
|
capability,
|
|
method,
|
|
reason,
|
|
} => write!(f, "trait {capability} method {method}: {reason}"),
|
|
// 名称来自注解解析,不把它伪装成已经解析的语言类型。
|
|
Self::UnknownAnnotation(name) => {
|
|
write!(f, "unknown or invalid type annotation: {name}")
|
|
}
|
|
Self::OverrideViolation {
|
|
definition,
|
|
method,
|
|
reason,
|
|
} => write!(f, "override {definition}.{method}: {reason}"),
|
|
Self::TypeMismatch {
|
|
function,
|
|
position,
|
|
expected,
|
|
actual,
|
|
} => write!(
|
|
f,
|
|
"{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}")
|
|
}
|
|
Self::UnboundLocal(name) => write!(f, "local variable is unbound: {name}"),
|
|
Self::NameNotFound(name) => write!(f, "name not found: {name}"),
|
|
Self::ArgumentCount {
|
|
name,
|
|
required,
|
|
maximum,
|
|
provided,
|
|
} => write!(
|
|
f,
|
|
"{name} expects {required}..={maximum} positional arguments, received {provided}"
|
|
),
|
|
Self::ExecutionLimit(limit) => write!(f, "execution limit reached: {limit}"),
|
|
}
|
|
}
|
|
}
|
|
|
|
// 使宿主可通过标准 Error 接口传播/封装;当前未另提供嵌套 source 错误链。
|
|
impl std::error::Error for VmError {}
|