Prove read-only effects through current source call graphs

This commit is contained in:
2026-10-22 15:55:44 +08:00
parent cd25f819f2
commit ae821aea2e
11 changed files with 614 additions and 58 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
| 文档 | 内容 |
| --- | --- |
| [types.md](types.md) | 托管 Object/Type、名义继承、方法覆写/类型化Trait/已知效果与源码只读证明/动态检查、声明字段/函数注解检查、构造与类型边生命周期 |
| [types.md](types.md) | 托管 Object/Type、名义继承、方法覆写/类型化Trait/已知效果与源码/调用图只读证明/动态检查、声明字段/函数注解检查、构造与类型边生命周期 |
| [objects.md](objects.md) | 对象、句柄与默认操作 |
| [native-calls.md](native-calls.md) | 原生上下文、读取分类、统一参数数量/类型/联合/固定与委托效果、非递归委托返回、弱引用、托管赋值与变更批次 |
| [builtins.md](builtins.md) | Number、String、Dict、Cell、Function、异常数据 |
+1 -1
View File
@@ -100,7 +100,7 @@ NativeCallable::signature 默认 None,明确表示尚未发布类型/效果契
NativeResult::Invoke 仍是尾委托,不递归进入 Rust/VM。VM 为每层已声明的返回契约保留检查项;委托原生立即返回或 Endor 帧返回时,按由内到外顺序验证全部契约。返回定义作为执行根保留,原生载荷替换、释放原委托者或源码全局重绑定不会使检查丢失。准备失败、帧限额、指令限额、错误返回与正常完成都释放这些执行根。委托不会为检查额外创建 VM 帧;仍共享每次原生分派和 Endor 指令预算。NativeContext::execute 单独返回 Invoke 时,调用者须使用具有等效最终返回检查的求值器;通常直接使用 Vm::call。
CallEffect::ReadOnly 声明只读现存对象,可分配临时结果;Delegated 声明原生包装自身只读,但后续委托的整体效果动态确定,VM 保持同一只读/预算作用域并检查实际目标;Mutating 与 External 在 ObjectStore 只读作用域内、进入实现前拒绝。普通执行允许这些效果。ReadOnly 声明不绕过已有写屏障,也不证明可信 Rust 不会进行隐藏 I/O;未知旧原生函数仍沿原调用/宿主检查,不能把 None 理解为纯函数。这不是完整 I/O 沙箱或对阻塞原生代码的抢占。统一已知效果查询和保守源码只读证明见[类型主题](types.md#已知调用效果与保守源码证明)。
CallEffect::ReadOnly 声明只读现存对象,可分配临时结果;Delegated 声明原生包装自身只读,但后续委托的整体效果动态确定,VM 保持同一只读/预算作用域并检查实际目标;Mutating 与 External 在 ObjectStore 只读作用域内、进入实现前拒绝。普通执行允许这些效果。ReadOnly 声明不绕过已有写屏障,也不证明可信 Rust 不会进行隐藏 I/O;未知旧原生函数仍沿原调用/宿主检查,不能把 None 理解为纯函数。这不是完整 I/O 沙箱或对阻塞原生代码的抢占。统一已知效果查询和保守源码/调用图只读证明见[类型主题](types.md#已知调用效果与保守源码证明)。
Tessera 的 measure/arrange/paint/hitTest、Point 几何查询、Window、Block/Container/Page、Mount、Task、Event、Subscription 方法和 ObjectList.at 发布签名。Page.open 的 Window | Unit、Page.window 的 Window | Unit 返回,以及 Block.on 的 Bool | String 可选阶段有准确元数据;Mount 的父/子/同级/Page 弱查询为可空结果。Mount.bounds 现在返回带 Bounds 名义类型的现有几何记录,可直接组合到 Point.inside 或视觉方法。滚动位置/字典等通用记录仍声明 Object,不冒充新语言类型;任务 owner 的具体资源资格仍按原域检查。构造器和其他管理 API 的签名覆盖仍未全部接入。已接入的方法覆写方差与动态名称规则见类型主题。旧能力注册保留数量模式;类型化能力还检查类型/已知效果,并在实际返回和尾委托结果处保留能力返回约束。
+9 -2
View File
@@ -154,8 +154,15 @@ core/tests/typed_traits.rs 覆盖登记失败原子性、参数扩大仍可直
ObjectStore/Vm::call_effect(function) 返回已知的整体 CallEffect 或 None,解包绑定方法后检查真实目标;原生签名照常验证,Delegated 包装整体未知,旧函数和通用Type构造也不猜测。查询不执行函数,不固定动态全局名称,不新增托管强边。参数/返回类型签名查询仍由 native_signature 和源码注解承担。
EndorCode::is_statically_read_only 只在全部已验证指令都在只读白名单内时返回true。读取、控制流、局部删除、创建新Dict/Function允许;Call、所有Store、DeleteGlobal/DeleteDeref、BuildClass及未来未审阅指令均保守未知。StoreFast也不能直接视为纯度:已有局部值可能通过共享引用赋值更新原对象。未知不表示一定有写入;创建新结果后填字段或调用纯函数仍可能安全,但本证明不作别名/新鲜性或调用图推断。不可达指令也参与保守扫描,嵌套函数代码不被当作工厂已执行的函数体。
EndorCode::is_statically_read_only 只在全部已验证指令都在只读白名单内时返回true。读取、控制流、局部删除、创建新Dict/Function允许;Call、所有Store、DeleteGlobal/DeleteDeref、BuildClass及未来未审阅指令均保守未知。StoreFast也不能直接视为纯度:已有局部值可能通过共享引用赋值更新原对象。未知不表示一定有写入;创建新结果后填字段或调用纯函数仍可能安全,但此局部证明不作别名/新鲜性或调用图推断。不可达指令也参与保守扫描,嵌套函数代码不被当作工厂已执行的函数体。
源码方法的此项只读证明用于方法替换/类型化能力的已知效果比较,不扩大全局源码检查开关的范围,也不拒绝目前未知的源码实现。只读执行的堆屏障和实际原生目标检查继续沿原VM帧、预算和尾委托作用域传递;它们不能被静态结果替代。可信ObjectPayload读取/比较仍属于宿主约定,不构成Rust隐藏I/O沙箱;只读不证明终止。完整调用图、可变全局/闭包目标和新对象写入的静态证明仍未实现。
源码方法的此项只读证明用于方法替换/类型化能力的已知效果比较,不扩大全局源码检查开关的范围,也不拒绝目前未知的源码实现。只读执行的堆屏障和实际原生目标检查继续沿原VM帧、预算和尾委托作用域传递;它们不能被静态结果替代。可信ObjectPayload读取/比较仍属于宿主约定,不构成Rust隐藏I/O沙箱;只读不证明终止。查询另有保守调用图证明,规则见下段;别名/新对象写入、未知调用结果和完整效果推断仍未实现。
method_contracts.rs新增已证明源码基类的原生效果扩大拒绝/原子性、绑定查询,以及共享局部赋值、自由Cell写入、动态调用保持未知的回归源码。仅编译,不在本地执行。
call_effect 对含 Call 的源码执行只读调用图证明:控制流逐点传播栈上的已知对象/绑定方法事实,分支或循环汇合的不同事实退化为未知。解析当前 globals,缺失时查该函数实际捕获的 builtins;自由Cell从当前闭包读取。绑定接收者及可确定的第一实参用于解析方法/对象字段,按普通属性查找顺序,不绕过实例遮蔽规则。其他参数、调用结果、新建函数/Dict内容和无法解析的调用目标保持未知;不凭注解猜测具体对象。调用图与控制流均采用显式队列,无Rust递归或长期缓存/保活索引,循环关系只证明无写入,不证明终止。
只有所有可能执行的调用目标都已证明/声明ReadOnly,且源码自身没有未证明操作时,整个源码查询返回ReadOnly。有Mutating/External、Delegated、旧未知原生目标或无法确定的调用就返回None;尤其不将含已知写目标的源码简单总结成Mutating,因为该目标可能重绑定后续全局、Cell或方法,让快照边失效。直接查询原生函数仍返回其签名的已知效果。当前只读证明依赖可信宿主读取/比较和原生ReadOnly契约,不是外部I/O沙箱。
全局/闭包/方法更新之后每次重新解析,不把某次查询作为永久保证;实际只读调用继续执行原VM作用域和目标检查。method_contracts.rs增加当前builtins与全局覆盖/恢复、自由Cell变化、递归图、控制流事实汇合和实际绑定方法/实例字段更新回归;Tessera增加真实Endor转调、self.helper与重绑定后重新查询且不执行业务方法的回归。仅编译,不本地运行。