Validate declared class fields at construction and attribute writes
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
| 文档 | 内容 |
|
||||
| --- | --- |
|
||||
| [types.md](types.md) | 托管 Object/Type、名义继承、构造与类型边生命周期 |
|
||||
| [types.md](types.md) | 托管 Object/Type、名义继承、声明字段/函数注解检查、构造与类型边生命周期 |
|
||||
| [objects.md](objects.md) | 对象、句柄与默认操作 |
|
||||
| [native-calls.md](native-calls.md) | 原生上下文、非递归委托、弱引用、托管赋值与变更批次 |
|
||||
| [builtins.md](builtins.md) | Number、String、Dict、Cell、Function、异常数据 |
|
||||
|
||||
@@ -64,3 +64,5 @@ take_changes 按对象与变更键合并同一批写入,返回最终版本。
|
||||
通过 replace_payload、属性或容器事务更新;载荷内部自行变动不会自动通知。
|
||||
|
||||
远端回归用例见 [native_context.rs](../../crates/core/tests/native_context.rs);本地不执行测试。
|
||||
|
||||
声明字段检查启用时,NativeContext::set_attr 使用同一字段写入屏障。NativeTyped 分配器应在副作用前调用 ObjectStore::check_class_field_arguments 检查自己的字段参数切片,具体参数组合仍由宿主定义;配置、声明环境与生命周期的唯一契约见[名义类型](types.md#声明字段注解检查)。
|
||||
|
||||
+18
-3
@@ -56,7 +56,7 @@ class DetailedCounter: Counter {
|
||||
|
||||
方法表本身是类型对象拥有的托管边。宿主 define_method 可显式替换条目,不改变类型身份、基类或已有绑定方法选中的函数。bind_attr 返回一份拥有式根;get_attr 返回借用值和未绑定方法,宿主不能把两者的调用/释放协议混用。positional_parameter_count 会扣除绑定的接收者,供宿主判断事件回调的剩余源码参数。
|
||||
|
||||
这是一份实现子集说明:构造器只按字段赋值,没有默认值、命名字段构造或隐式 init;字段注解保留名称但尚未约束字段写入;源码参数/返回注解支持下述宿主可选的运行时检查。源码类可继承 Record 或 NativeTyped 分配器;未选择支持继承的旧 Native 分配器仍明确报错。继承会保留分配器和父类字段,不能伪造带原生名义身份的普通 Record。字段构造参数如何与原生参数组合由宿主分配器负责;Tessera 使用原生参数在前、继承及本类字段在后的协议。trait 的正式源码语法、完整类型兼容性和效果系统仍待实现;宿主显式能力子集见下文。正式语言文档的候选语法不因这一实现被自动确认为规范。
|
||||
这是一份实现子集说明:构造器只按字段赋值,没有默认值、命名字段构造或隐式 init;字段注解在启用运行时检查后约束构造及字段写入,见下文;源码参数/返回注解支持下述宿主可选的运行时检查。源码类可继承 Record 或 NativeTyped 分配器;未选择支持继承的旧 Native 分配器仍明确报错。继承会保留分配器和父类字段,不能伪造带原生名义身份的普通 Record。字段构造参数如何与原生参数组合由宿主分配器负责;Tessera 使用原生参数在前、继承及本类字段在后的协议。trait 的正式源码语法、完整类型兼容性和效果系统仍待实现;宿主显式能力子集见下文。正式语言文档的候选语法不因这一实现被自动确认为规范。
|
||||
|
||||
|
||||
## 可转移的字段存储
|
||||
@@ -81,7 +81,7 @@ implement_trait(Type, Trait)明确建立能力关系并校验必需方法。只
|
||||
|
||||
## 源码函数注解检查
|
||||
|
||||
`Vm::set_source_type_checks(true)` 启用源码函数调用的运行时检查,默认关闭;Tessera 显式启用,其他宿主须自行选择。Compiler 把形参注解、返回注解及可选的声明类名保存为 `SourceSignature`,模板装载后仍保留。宿主也可通过 `EndorCode::with_source_signature` 添加经过形参数量/非空名称校验的元数据;没有该元数据的宿主生成代码继续沿原调用协议执行。
|
||||
`Vm::set_source_type_checks(true)` 启用源码函数调用及声明字段写入的运行时检查,默认关闭;Tessera 显式启用,其他宿主须自行选择。Compiler 把形参注解、返回注解及可选的声明类名保存为 `SourceSignature`,模板装载后仍保留。宿主也可通过 `EndorCode::with_source_signature` 添加经过形参数量/非空名称校验的元数据;没有该元数据的宿主生成代码继续沿原调用协议执行。
|
||||
|
||||
每次调用在进入函数体前检查所有实参与用到的默认参数,并解析本次返回约束;`ReturnValue` 在交出结果前检查返回值。错误分别是 `UnknownAnnotation` 或带函数、参数/return、预期及实际名称的 `TypeMismatch`。参数失败不进入函数体;返回失败不回滚此前完成的业务写入。执行帧持有返回约束中实际 Type/Trait 的一份根,直到成功或失败清理;全局名字在调用中改变也不会释放这一约束。约束查询不写函数或类型对象,适用于只读布局/绘制调用。
|
||||
|
||||
@@ -96,6 +96,21 @@ implement_trait(Type, Trait)明确建立能力关系并校验必需方法。只
|
||||
| Type/Trait | 真实 Type/Trait 定义载荷 |
|
||||
| 其他名称 | 从函数自己的 globals、其次创建时捕获的 builtins 找到实际 Type 或 Trait;前者检查名义实例/继承,后者检查显式能力 |
|
||||
|
||||
普通名称每次调用重新解析,不是静态推断或定义时冻结的类型绑定。同名新定义不等于旧定义;自由函数可观察后续全局类型名重绑定。方法注解中指向自身声明类的名称,优先从实际接收者祖先中查找仍持有该函数的方法定义,因此 REPL 重定义全局类名后,原实例保存的绑定方法仍可调用。其他类型名仍遵循上述全局解析规则。此机制不提供重写方差、字段赋值检查、泛型、效果类型或原生函数的统一签名元数据。
|
||||
普通名称每次调用重新解析,不是静态推断或定义时冻结的类型绑定。同名新定义不等于旧定义;自由函数可观察后续全局类型名重绑定。方法注解中指向自身声明类的名称,优先从实际接收者祖先中查找仍持有该函数的方法定义,因此 REPL 重定义全局类名后,原实例保存的绑定方法仍可调用。其他类型名仍遵循上述全局解析规则。此机制不提供重写方差、泛型、效果类型或原生函数的统一签名元数据。字段赋值检查见下文。
|
||||
|
||||
源码与原生函数的统一名义分类由 `ObjectStore::set_function_type`/`Vm::set_function_type` 显式配置。配置验证 Type、拒绝只读修改,只保留弱引用且不可改成另一个定义;设置后新分配的显式 `ObjectPayload::is_function` 载荷自动附加该类型,已有对象不追溯改写。语言函数、两类原生函数及绑定方法提供此标记;仅有 call 能力不算函数。配置类型过期则函数分配报错并清理新对象,不引入隐藏 GC 根。宿主应在创建函数前配置,并通过正常对象边保活定义。
|
||||
|
||||
|
||||
## 声明字段注解检查
|
||||
|
||||
`Vm::set_source_type_checks(true)` 同时启用 ObjectStore 的声明字段检查;独立存储宿主也可调用 `ObjectStore::set_field_type_checks(true)`,默认关闭。配置在只读作用域内被拒绝。启用不会追溯扫描已有对象,只检查此后发生的字段写入。
|
||||
|
||||
Record 构造在分配前校验全部位置字段。NativeTyped 分配器通过 `check_class_field_arguments(definition, values)` 在自身副作用前检查字段参数;方法始终检查数量,注解匹配遵循开关。字段参数与原生参数如何组合仍由分配器定义;Tessera 在原生参数之后放字段参数并在创建原生对象前检查。所有经 ObjectStore/Vm/NativeContext 的 `set_attr` 写入,包括 StoreAttr,按实际对象类型查找字段声明,在最终 attribute_target 存储变更前检查。失败保持该字段值、引用边和版本不变;不回滚先前完成的其他操作。启用后 `del_attr` 拒绝删除声明字段;未声明的动态属性沿用现有行为。
|
||||
|
||||
源码 BuildClass 把声明执行函数作为 Type 的托管强边保存,用其 globals 与创建时 builtins 解析字段注解;声明环境与实例/类型环由普通循环回收处理,没有隐藏外部根。`ObjectStore::new_class_with_scope(..., Some(function))` 提供相同的宿主入口。无环境的 `new_class` 支持上述基本注解及本类名;其他名称报 UnknownAnnotation,宿主可显式提供环境。没有本类字段的派生定义无需保存新的字段环境。
|
||||
|
||||
继承字段总是使用声明它的祖先定义和环境。注解为本类名时匹配该实际定义,REPL 重定义同名类不会改变旧实例的自引用字段约束;其他名称在每次构造/写入时从声明环境动态解析真实 Type/Trait,前向名称可在构造前建立,未知名称写入报错。不会仅以字符串相同判断名义兼容。基本注解与函数检查共用匹配规则。字段环境尚不解析函数局部类型名称或捕获的类型变量。
|
||||
|
||||
原生共享引用对象以当前 type_target 决定声明,以 attribute_target 决定存储;共享替换后的别名因而按新内容的字段契约写入。宿主直接写裸存储对象、改载荷、附加类型或改变字段所引用对象的共享转发,不属于 `set_attr` 的完整初始化/持续不变量保证;这些低层入口仍由宿主维护。没有静态推断、字段默认值、非空递归图初始化语法、重写方差或效果系统。
|
||||
|
||||
回归源码位于 compiler/tests/classes.rs,覆盖普通/原生构造、继承、错误写入的值/版本保持、未知名称、动态类型重绑定、自引用定义、开关、删除和 GC 清理,仅编译未本地执行。Tessera 在真实原生程序中验证共享字段更新、错误赋值与构造前副作用保护。
|
||||
|
||||
Reference in New Issue
Block a user