# 原生对象调用、弱引用与变更记录 本页定义宿主扩展使用的通用接口,不引入渲染或窗口语义。托管名义类型见[类型机制](types.md)。 ## 有上下文的调用 旧 ObjectPayload::call 保留借用参数和借用结果协议。新载荷可通过 native_callable 返回 Arc;VM 先取得独立分派器,再可变访问 ObjectStore,避免同时借用 堆中载荷与可变对象存储。ContextNativeFunction 提供名称、分派器和不可变捕获边列表。 捕获中的 ObjectRef 必须全部在 captures 中登记,未登记句柄不能保活对象。 NativeCallable::invoke 接收 NativeContext 和借用参数。context 提供对象、字典、Cell 分配、托管属性和容器写入、载荷事务替换及弱引用升级。store() 仅暴露只读访问; callee() 返回当前可调用对象的借用句柄;attach_type 通过受校验的类型边事务附加实例类型。 没有不受控的 &mut Vm、手动释放根或重入执行器入口。 context 内分配或升级得到的对象由本次作用域临时持有。NativeResult::Return(value) 返回借用结果;作用域为结果额外持有一份根,再释放其余临时根。出错或 unwind 也会 清理本作用域根,但此前完成的业务写入不会回滚;这不承诺整个执行帧的 panic 恢复。 NativeResult::Invoke { function, arguments } 将调用委托给另一个原生或语言函数。 function 和每个对象参数在移交前取得根;VM 完成调用准备后释放这些临时输入。 委托通过原有帧循环推进,不递归调用 Vm::call;语言函数使用原有帧限额。每次原生 分派计入同一指令预算,避免无界原生委托链。预算仍不能抢占一次长时间原生操作。 委托函数的结果就是该次调用结果,当前不提供任意原生调用后续 continuation。 ## 托管共享引用赋值 assignment_cell(source, store) 是与原生 assign_from 并存的可选协议。实现先只读验证 目标及组合环,返回自身持有的内建 Cell;对象存储再事务性地将 source 写入 Cell。 修改的引用属于可追踪堆边,旧对象身份与方法不变。默认返回 None,沿用既有赋值规则。 Cell 的持有边也必须通过 trace 或托管字段登记;字典 API 和属性写入不隐式执行此协议。 ## 弱引用 downgrade 验证对象后产生 WeakObjectRef,不增加强引用。upgrade 在同一个对象存储中 重新验证堆、槽位与代次;存活时返回一份新的拥有式根,过期返回 None,其他存储返回 ForeignHandle。释放后复用槽位不会使旧弱引用指向新对象。弱引用不保活 VM 本身。 宿主使用升级结果后须 release;NativeContext::upgrade 的升级根归当前调用作用域。 ## 对象变更 每个对象头有从 0 开始的 change_version。成功的属性写入或删除产生 Attribute(name), 字典、Cell、通用载荷替换及共享引用赋值产生 Contents;失败写入不产生变更。 同值写入仍视为成功写入,消费方可自行比较派生结果。版本耗尽拒绝修改。 take_changes 按对象与变更键合并同一批写入,返回最终版本。记录不持有对象,消费时 对象可能已经回收,应重新验证身份。通知只保证修改信息,不包含旧值或回滚日志。 最多保留 4096 个不同变更键,超额后清空细项并设置 rescan_required,直到下一次提取; 消费方必须完整重查依赖,不能把溢出当成没有变化。版本仍继续递增。 引擎只记录通用对象变化,依赖订阅、视觉失效和事件提交由宿主负责。托管原生状态须 通过 replace_payload、属性或容器事务更新;载荷内部自行变动不会自动通知。 远端回归用例见 [native_context.rs](../../crates/core/tests/native_context.rs);本地不执行测试。