diff --git a/crates/objects/src/types.rs b/crates/objects/src/types.rs index 2232e09..67ccba9 100644 --- a/crates/objects/src/types.rs +++ b/crates/objects/src/types.rs @@ -1,3 +1,5 @@ +//! 类型、能力与实例共享同一托管堆;Store 定义身份/继承规则,VM 负责构造调用的执行调度。 +//! contracts 校验方法替换与能力契约,effects 查询当前快照的调用效果。 //! Nominal type identities in the same managed heap as their instances. #[path = "contracts.rs"] mod contracts; @@ -13,21 +15,28 @@ use crate::{ // A host type_target may read its receiver's raw attributes. Validate the // outer lookup after resolution without recursively re-entering its guard. struct AttributeCheckGuard<'a> { + /// 借用当前 Store 的属性检查递归表。 store: &'a ObjectStore, + /// 进入检查时的线程,用于隔离递归标记。 thread: std::thread::ThreadId, + /// 当前被检查对象,守卫不为其建立根。 object: ObjectRef, } impl Drop for AttributeCheckGuard<'_> { + /// 属性/类型重入检查的 RAII 清理,移除本线程当前对象,不清除其他活跃检查。 fn drop(&mut self) { + // 锁内定位递归检查表,守卫保证当前项此前已插入。 let mut checks = self .store .active_attribute_checks .lock() .expect("attribute checker poisoned"); + // 仅删除本线程该对象的检查项,嵌套其他对象仍保持活跃。 let active = checks .get_mut(&self.thread) .expect("active attribute check"); active.remove(&self.object); + // 线程内无剩余对象检查时移除空集合。 if active.is_empty() { checks.remove(&self.thread); } @@ -43,11 +52,13 @@ pub enum TypeConstructor { /// Opt-in allocator inheritance. The requested nominal type is prepended /// to the constructor arguments; the allocator must create that real type. NativeTyped(ObjectRef), + /// 禁止直接构造,源码派生沿用该策略后仍为抽象类型。 Abstract, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ClassField { + /// 字段存储名称,源码类创建时检查重复及保留名。 pub name: String, /// Source annotation resolved at checked construction/field writes. pub type_name: String, @@ -58,60 +69,81 @@ pub struct ClassField { /// edges; no registry outside the heap keeps unused definitions alive. #[derive(Debug, Clone)] pub struct EndorTypeObject { + /// 诊断名称,名义身份仍由对象句柄决定。 name: String, + /// 固定基类强边,根 Object 为 None。 base: Option, + /// 实例创建策略,类型可调用路径按此分派。 constructor: TypeConstructor, + /// 方法名到函数的拥有边,更新走 define_method。 methods: BTreeMap, + /// 继承字段在前的完整构造布局。 fields: Vec, // Declaring execution environment; a managed edge, never an external root. + /// 自有字段注解的声明函数环境强边,不是外部根。 field_scope: Option, + /// 本层显式能力定义的强边,继承能力另沿基类查询。 traits: Vec, } impl EndorTypeObject { + /// 宿主/诊断借用类型声明名称,不代表仅按名称判断类型相等。 pub fn name(&self) -> &str { &self.name } + /// 继承查找借用固定基类句柄,不产生外部根。 pub fn base(&self) -> Option { self.base } + /// 构造器和宿主借用完整字段序列,包含从父类复制的字段。 pub fn fields(&self) -> &[ClassField] { &self.fields } } impl ObjectPayload for EndorTypeObject { + /// 类型定义不实现旧式原地赋值,允许只读局部重绑定引用。 fn reference_assignment_only(&self) -> bool { true } + /// Store 下转型为具体类型载荷的入口。 fn as_any(&self) -> &dyn std::any::Any { self } + /// 错误与默认诊断使用载荷类别,名义类型关系另外判断。 fn kind_name(&self) -> &'static str { "type" } + /// Heap 分配/受控更新类型时登记基类、构造器、字段环境、能力及方法强边。 fn trace(&self, visit: &mut dyn FnMut(ObjectRef)) { + // 基类本身是一条拥有边,不依赖堆外注册表维持存活。 if let Some(base) = self.base { visit(base); } + // 两类原生构造都持有函数强边;Record/Abstract 不包含函数。 if let TypeConstructor::Native(function) | TypeConstructor::NativeTyped(function) = self.constructor { visit(function); } + // 字段声明环境必须由类型拥有,否则稍后注解解析可能失去环境。 if let Some(scope) = self.field_scope { visit(scope); } + // 逐项登记已声明能力,重复引用也按拥有次数计算。 for capability in &self.traits { visit(*capability); } + // 方法表每个槽拥有函数强边,不因同一函数多名注册而去重。 for method in self.methods.values() { visit(*method); } } + /// Store 显示类型名称,不展开方法表或执行构造器。 fn repr(&self, _: ObjectRef) -> Result { Ok(format!("", self.name)) } + /// VM 把类型作为可调用对象时取得构造分派器;Type 可调用但不是函数分类。 fn native_callable(&self) -> Option> { Some(Arc::new(Construct)) } @@ -120,19 +152,24 @@ impl ObjectPayload for EndorTypeObject { #[derive(Debug)] struct Construct; impl NativeCallable for Construct { + /// NativeContext 构造入口:按类型的构造策略返回实例或委托 VM 调用分配器。 fn invoke( &self, cx: &mut NativeContext<'_>, arguments: &[Value], ) -> Result { + // 当前被调用对象就是类型,借用身份已由上下文保护。 let type_object = cx.callee(); + // 只读借用构造策略;下方修改前先复制需要跨修改使用的元数据。 let definition = cx.store().payload::(type_object, "Type")?; + // 原生委托交回 VM 帧循环,不能递归调用执行器;抽象类型明确拒绝。 match definition.constructor { TypeConstructor::Native(function) => Ok(NativeResult::Invoke { function, arguments: arguments.to_vec(), }), TypeConstructor::NativeTyped(function) => { + // NativeTyped 把实际请求类型放在首位,让继承分配器创建正确的派生载荷。 let mut values = Vec::with_capacity(arguments.len() + 1); values.push(Value::Object(type_object)); values.extend_from_slice(arguments); @@ -145,6 +182,7 @@ impl NativeCallable for Construct { Err(VmError::UnsupportedOperation("abstract type construction")) } TypeConstructor::Record => { + // Record 字段按位置一一对应,缺少或多余都在分配实例前拒绝。 if arguments.len() != definition.fields.len() { return Err(VmError::ArgumentCount { name: definition.name.clone(), @@ -153,11 +191,14 @@ impl NativeCallable for Construct { provided: arguments.len(), }); } + // 释放类型载荷借用后仍需要字段名,因此复制布局,不复制托管对象。 let fields = definition.fields.clone(); cx.store() .check_class_field_arguments(type_object, arguments)?; + // 分配临时根后再附着类型/写字段,失败时上下文统一清理半成品。 let instance = cx.new_object()?; cx.attach_type(instance, type_object)?; + // 按继承字段在前的布局依次写入,克隆 Value 不自动 retain,由属性拥有边承担持有。 for (field, value) in fields.iter().zip(arguments) { cx.set_attr(instance, &field.name, value.clone())?; } @@ -170,14 +211,18 @@ impl NativeCallable for Construct { /// Each field owns one external root; the caller must release both. #[derive(Debug, Clone, Copy)] pub struct RootTypes { + /// Object 根类型的一份外部拥有根,调用方须 release。 pub object: ObjectRef, + /// Type 元类型的一份外部拥有根,调用方须 release。 pub type_type: ObjectRef, } impl ObjectStore { /// Explicit bootstrap preserves the empty-store contract. Inheritance: /// Type -> Object; instance relations: Object : Type and Type : Type. + /// 宿主/VM 显式创建 Object/Type;不改变 Store::new 保持空堆的约定。 pub fn bootstrap_types(&mut self) -> Result { + // 先创建无元类型的 Object 定义,随后建立自举关系。 let object = self.allocate(EndorTypeObject { name: "Object".into(), base: None, @@ -187,8 +232,11 @@ impl ObjectStore { field_scope: None, traits: Vec::new(), })?; + // 记录第二次分配是否成功,便于后续任何错误清理已建对象。 let mut allocated_type = None; + // 闭包归拢 Type 分配与关系附着错误,外层统一释放自举临时根。 let result = (|| { + // Type 以 Object 为基类,随后自己以 Type 为类型,形成合法类型图环。 let type_type = self.allocate(EndorTypeObject { name: "Type".into(), base: Some(object), @@ -203,7 +251,9 @@ impl ObjectStore { self.attach_type(type_type, type_type)?; Ok(RootTypes { object, type_type }) })(); + // 自举失败归还已有根并收集可能形成的环,避免半初始化定义泄漏。 if result.is_err() { + // 只有成功分配 Type 后才需要归还其根。 if let Some(type_type) = allocated_type { self.release(type_type)?; } @@ -214,23 +264,29 @@ impl ObjectStore { } /// Base links are fixed at allocation, preventing inheritance cycles. + /// 宿主创建派生类型,复制父字段布局并沿用元类型;返回一份外部拥有根。 pub fn new_type( &mut self, name: impl Into, base: ObjectRef, constructor: TypeConstructor, ) -> Result { + // 父字段复制成新类型布局;后续不能私自改变继承前缀。 let fields = self .payload::(base, "Type")? .fields .clone(); + // 新类型继承基类的有效元类型,缺失元类型时拒绝构造。 let metatype = self .type_of(base)? .ok_or(VmError::InvalidArgument("base type has no metatype"))?; + // 持有名称用于新载荷与诊断,后续校验借用该字符串。 let name = name.into(); + // 类型名称不允许空串,但身份判断仍使用句柄而非文本。 if name.is_empty() { return Err(VmError::InvalidArgument("type name must not be empty")); } + // 分配时基类/构造器/方法环境等由 trace 登记边,返回一份外部根。 let definition = self.allocate(EndorTypeObject { name, base: Some(base), @@ -240,6 +296,7 @@ impl ObjectStore { field_scope: None, traits: Vec::new(), })?; + // 元类型附着失败则归还新定义根,不交付无元类型半成品。 if let Err(error) = self.attach_type(definition, metatype) { self.release(definition)?; return Err(error); @@ -247,12 +304,14 @@ impl ObjectStore { Ok(definition) } + /// 宿主/构造器先检查类型和能力存储约束,再交 Heap 建立不可替换的类型强边。 pub fn attach_type( &mut self, object: ObjectRef, type_object: ObjectRef, ) -> Result<(), VmError> { self.payload::(type_object, "Type")?; + // 逐项登记已声明能力,重复引用也按拥有次数计算。 for capability in self.inherited_traits(type_object)? { self.check_capability_storage(object, capability)?; } @@ -260,16 +319,23 @@ impl ObjectStore { } /// Borrowed type reference; legacy/untyped host objects return None. + /// VM/契约查询有效类型,沿 type_target 转发,最终返回头部的借用类型或 None。 pub fn type_of(&self, object: ObjectRef) -> Result, VmError> { + // 从门面对象出发追踪实际类型目标,不直接忽略 type_target 协议。 let mut current = object; + // 保存已访问身份,防宿主转发环导致无限循环。 let mut visited = std::collections::BTreeSet::new(); + // 逐跳验证存活句柄和载荷,直到无类型转发目标。 loop { + // 同一身份再出现说明转发环,返回明确协议错误。 if !visited.insert(current) { return Err(VmError::InvalidArgument( "cyclic shared-reference type target", )); } + // 分配临时根后再附着类型/写字段,失败时上下文统一清理半成品。 let instance = self.object(current)?; + // 有转发目标则继续,无目标时读取当前对象头部名义类型。 match instance.payload().type_target(self)? { Some(target) => current = target, None => return Ok(instance.header().type_object()), @@ -277,11 +343,16 @@ impl ObjectStore { } } + /// 注解/替换检查沿单继承链比较名义身份,包含类型自身。 pub fn is_subtype(&self, candidate: ObjectRef, expected: ObjectRef) -> Result { self.payload::(expected, "Type")?; + // 从候选类型本身开始,因此自反子类型关系成立。 let mut current = Some(candidate); + // 基类在创建时固定且指向已有类型,正常类型图不会出现继承环。 while let Some(type_object) = current { + // 借用类型载荷验证身份和种类,再读字段、基类或方法表。 let definition = self.payload::(type_object, "Type")?; + // 比较完整名义身份,不接受仅同名的另一个类型。 if type_object == expected { return Ok(true); } @@ -290,8 +361,10 @@ impl ObjectStore { Ok(false) } + /// VM/宿主判断实例有效类型是否为 expected 的子类型,无类型旧对象返回 false。 pub fn is_instance(&self, object: ObjectRef, expected: ObjectRef) -> Result { self.payload::(expected, "Type")?; + // 有效类型可来自转发对象;无类型不是 InvalidHandle,而是正常 false。 match self.type_of(object)? { Some(type_object) => self.is_subtype(type_object, expected), None => Ok(false), @@ -299,6 +372,7 @@ impl ObjectStore { } /// Updating the managed method table preserves nominal identity and base. + /// 宿主/VM 受控更新方法表,身份/基类不变,先验证覆盖及能力约束再替换载荷。 pub fn define_method( &mut self, type_object: ObjectRef, @@ -306,20 +380,26 @@ impl ObjectStore { function: ObjectRef, ) -> Result<(), VmError> { self.object(function)?; + // 持有名称用于新载荷与诊断,后续校验借用该字符串。 let name = name.into(); + // 类型名称不允许空串,但身份判断仍使用句柄而非文本。 if name.is_empty() || name == "type" { return Err(VmError::InvalidArgument("reserved or empty method name")); } + // 借用类型载荷验证身份和种类,再读字段、基类或方法表。 let definition = self.payload::(type_object, "Type")?; + // 实例字段与类型方法不能同名,避免构造/查找产生歧义。 if definition.fields.iter().any(|field| field.name == name) { return Err(VmError::InvalidArgument( "method conflicts with class field", )); } + // 先准备独立方法表副本,契约失败时真实载荷保持原状。 let mut methods = definition.methods.clone(); self.validate_override_update(type_object, &name, function)?; self.validate_method_update(type_object, &name, function)?; methods.insert(name, function); + // 保留名称、基类、构造、字段和能力,只替换方法表;Heap 再更新强边和版本。 let updated = EndorTypeObject { name: definition.name.clone(), base: definition.base, @@ -335,6 +415,7 @@ impl ObjectStore { /// Atomically build a source class, including inherited constructor fields. /// Only explicitly inheritable native allocators are reused. Abstract /// subclasses remain abstract; no Record can forge a native payload. + /// eval/宿主创建源码类的无字段声明环境入口,转交统一构造路径。 pub fn new_class( &mut self, name: impl Into, @@ -347,6 +428,7 @@ impl ObjectStore { /// Source class builder with a traced function environment for field names. /// None supports primitive annotations and the declaring class itself. + /// eval 创建源码类,组合继承字段、当前方法与声明环境,完成契约检查后才交付根。 pub fn new_class_with_scope( &mut self, name: impl Into, @@ -355,19 +437,27 @@ impl ObjectStore { methods: BTreeMap, scope: Option, ) -> Result { + // 字段声明环境必须由类型拥有,否则稍后注解解析可能失去环境。 if let Some(scope) = scope { self.payload::(scope, "function")?; } + // 没有自有字段时无需持有当前声明环境,继承字段仍通过其声明层解析。 let field_scope = if own_fields.is_empty() { None } else { scope }; + // 借用类型载荷验证身份和种类,再读字段、基类或方法表。 let definition = self.payload::(base, "Type")?; + // Native 未显式允许源码继承分配,不能用普通 Record 伪造原生载荷。 if matches!(definition.constructor, TypeConstructor::Native(_)) { return Err(VmError::UnsupportedOperation( "native allocator does not opt into source subclass construction", )); } + // 源码派生沿用允许继承的策略,Abstract 仍为 Abstract,NativeTyped 得到请求类型。 let constructor = definition.constructor; + // 继承字段保持前缀,再按源码顺序附加新字段。 let mut fields = definition.fields.clone(); + // 逐个检查重复、保留名及继承方法冲突,不允许覆盖已有字段布局。 for field in own_fields { + // 名称与注解都不能空,字段不能重复或遮蔽父方法。 if field.name.is_empty() || field.type_name.is_empty() || field.name == "type" @@ -380,21 +470,27 @@ impl ObjectStore { } fields.push(field); } + // 方法提交前验证函数句柄,拒绝与完整继承字段序列重名。 for (name, method) in &methods { self.object(*method)?; + // 类型名称不允许空串,但身份判断仍使用句柄而非文本。 if name.is_empty() || name == "type" || fields.iter().any(|field| field.name == *name) { return Err(VmError::InvalidArgument( "method conflicts with class field", )); } } + // 新类型继承基类的有效元类型,缺失元类型时拒绝构造。 let metatype = self .type_of(base)? .ok_or(VmError::InvalidArgument("base type has no metatype"))?; + // 持有名称用于新载荷与诊断,后续校验借用该字符串。 let name = name.into(); + // 类型名称不允许空串,但身份判断仍使用句柄而非文本。 if name.is_empty() { return Err(VmError::InvalidArgument("type name must not be empty")); } + // 一次构造完整类载荷,后面的验证失败只需释放这份新根。 let class = self.allocate(EndorTypeObject { name, base: Some(base), @@ -404,6 +500,7 @@ impl ObjectStore { field_scope, traits: Vec::new(), })?; + // 继承能力、普通覆盖和元类型附着按顺序完成,任一失败都不交付该类。 if let Err(error) = self .validate_inherited_traits(class) .and_then(|()| self.validate_class_overrides(class))