docs(tests): correct nominal and native contract scenario boundaries
This commit is contained in:
@@ -10,10 +10,15 @@ use std::collections::BTreeMap;
|
||||
/// 测试辅助,生成先写 globals.ran=42 再返回 result 的源码方法,附显式 owner/参数/返回注解。
|
||||
fn source(
|
||||
vm: &mut Vm,
|
||||
// 借用全局字典,源码函数持环境边;副作用 ran 与动态注解名称都从这里观察。
|
||||
globals: ObjectRef,
|
||||
// 写入源码签名的方法所属类名,按接收者继承链解析该声明身份。
|
||||
owner: &str,
|
||||
// 含显式 self 的参数注解文本,也决定位置参数及局部槽数量。
|
||||
parameters: &[&str],
|
||||
// 返回注解文本,实际类型在注册/调用契约检查时解析。
|
||||
returns: &str,
|
||||
// 写 ran 后返回的常量;对象身份由托管代码常量边持有,不因 Value 移动自动 retain。
|
||||
result: Value,
|
||||
) -> ObjectRef {
|
||||
// 手工指令保证源码体可观测,参数/局部槽按注解数量保持一致。
|
||||
@@ -50,6 +55,7 @@ fn source(
|
||||
function
|
||||
}
|
||||
/// 测试辅助,以给定基类构造只声明 check 方法、无自有字段的源码类。
|
||||
/// base/function 均借用,成功返回新类拥有根并建立内部边;失败不消耗调用方持有的根。
|
||||
fn class(
|
||||
vm: &mut Vm,
|
||||
name: &str,
|
||||
@@ -300,7 +306,7 @@ fn global_rebinding_is_rechecked_before_the_source_body_and_recovers() {
|
||||
"Actual",
|
||||
Value::Object(result),
|
||||
);
|
||||
// 先创建当前合法后代,再对父方法提出可能使它失效的更新。
|
||||
// 先创建当前合法后代;下面只重绑定其 Actual 注解名,不修改父方法或子方法载荷。
|
||||
let child = class(&mut vm, "Child", base, child_fn).unwrap();
|
||||
// 显式 self 为 Child 实例,调用时据其继承链解析各方法 own-class 注解。
|
||||
let receiver = vm.new_object().unwrap();
|
||||
@@ -487,7 +493,7 @@ fn unknown_forward_names_defer_until_call_without_entering_the_body() {
|
||||
);
|
||||
// 定义阶段允许未知名称的派生创建,实例调用时会重新核对。
|
||||
let child = class(&mut vm, "Child", base, child_fn).unwrap();
|
||||
// 实例提供实际接收者身份,绑定效果分析可据此查 helper,未绑定函数则未知。
|
||||
// 显式 self 使用 Child 实例,让调用预检按其继承链解析 Base/Child,再检查仍未知的 Later。
|
||||
let receiver = vm.new_object().unwrap();
|
||||
vm.attach_type(receiver, child).unwrap();
|
||||
assert!(matches!(
|
||||
@@ -577,7 +583,7 @@ fn verified_source_read_only_effects_constrain_native_overrides() {
|
||||
// 后代继承已证明只读的方法,候选原生覆盖不能扩大已知效果。
|
||||
let child = vm.new_type("Child", base, TypeConstructor::Record).unwrap();
|
||||
assert_eq!(vm.call_effect(source).unwrap(), Some(CallEffect::ReadOnly));
|
||||
// 实例提供实际接收者身份,绑定效果分析可据此查 helper,未绑定函数则未知。
|
||||
// 以 Child 实例创建绑定方法,核对绑定形式仍可证明只读;此处未绑定源码本身也已由白名单证明。
|
||||
let receiver = vm.new_object().unwrap();
|
||||
vm.attach_type(receiver, child).unwrap();
|
||||
// 绑定对象拥有函数和实际接收者边,分析可用 receiver 区分实例方法/字段。
|
||||
@@ -594,7 +600,7 @@ fn verified_source_read_only_effects_constrain_native_overrides() {
|
||||
CallEffect::ReadOnly,
|
||||
CallEffect::Delegated,
|
||||
] {
|
||||
// 函数持有其代码/全局边,效果查询从当前载荷及环境读取快照。
|
||||
// 候选为原生包装器,仅签名引用类型形成 trace 边;效果查询读取其声明,不存在源码代码/全局字段。
|
||||
let function = vm
|
||||
.allocate(ContextNativeFunction::new(
|
||||
"check",
|
||||
|
||||
@@ -62,7 +62,7 @@ fn scoped_allocations_return_one_root_and_clean_up_errors() {
|
||||
/// 返回目标借用身份,由包装载荷 captures 保活,NativeContext 为 Invoke 输出取得拥有根。
|
||||
struct Delegate(ObjectRef);
|
||||
impl NativeCallable for Delegate {
|
||||
/// VM 在 NativeContext 内调用此测试分派器,临时分配与输入由上下文保活,返回/委托后移交输出根。
|
||||
/// VM 分派时原样委托给 captures 保活的目标;参数 clone 仍借用,NativeContext 随后为 Invoke 输出逐项取根。
|
||||
fn invoke(&self, _cx: &mut NativeContext<'_>, args: &[Value]) -> Result<NativeResult, VmError> {
|
||||
Ok(NativeResult::Invoke {
|
||||
function: self.0,
|
||||
@@ -157,7 +157,7 @@ fn native_delegation_shares_budget_and_cleans_owned_arguments() {
|
||||
assert_eq!(vm.ref_count(target).unwrap(), 2);
|
||||
// VM 调用已完成根移交,返回对象应只有一份调用者根。
|
||||
let value = vm.call(delegate, &[]).unwrap();
|
||||
// 归还成功结果,之后只剩函数载荷,临时对象应已自动清理。
|
||||
// 归还 Allocate 返回的独立结果根;delegate、target、arg 的测试根仍在下面分别释放。
|
||||
vm.release_value(value).unwrap();
|
||||
vm.release(delegate).unwrap();
|
||||
vm.release(target).unwrap();
|
||||
@@ -237,6 +237,7 @@ fn notification_overflow_requires_rescan_instead_of_losing_changes_silently() {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// 只读场景的复制器:读输入字段并构造新结果,可选故意改旧输入以验证写屏障及错误退出。
|
||||
struct ReadResult {
|
||||
/// 输入借用身份,包装载荷 captures 负责保活。
|
||||
source: ObjectRef,
|
||||
@@ -381,6 +382,7 @@ fn annotation_reads_remain_dependencies_without_becoming_program_content_reads()
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// 完整签名场景共用分派器,以计数器区分预检/回调/返回检查,支持委托、新分配或回传实参。
|
||||
struct TypedNative {
|
||||
/// 构造时快照的完整签名,包装载荷负责 trace 类型定义。
|
||||
signature: endor_core::CallSignature,
|
||||
@@ -479,7 +481,7 @@ fn delegated_source_results_obey_every_native_contract_without_extra_frames() {
|
||||
let code = vm.new_code(code).unwrap();
|
||||
// 源码环境有分配根,函数持有它的内部边。
|
||||
let globals = vm.new_dict().unwrap();
|
||||
// 源码函数返回文本或 Nil,作为后续返回契约一致/不一致的终点。
|
||||
// 此源码函数固定返回文本;inner 的 String 返回约束可通过,outer 的 Number 约束必须失败。
|
||||
let source = vm
|
||||
.new_function("source", code, globals, vec![], vec![])
|
||||
.unwrap();
|
||||
@@ -705,10 +707,11 @@ fn legacy_native_signatures_check_optional_variadic_types_and_metadata() {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// 移除自身载荷的回归分派器,迫使签名类型在原持边消失后仍由执行检查根保活。
|
||||
struct EraseThenDelegate {
|
||||
/// 构造时快照的完整签名,包装载荷负责 trace 类型定义。
|
||||
signature: endor_core::CallSignature,
|
||||
/// 被委托源码函数,由包装载荷 captures 保活至回调中输出保护接管。
|
||||
/// 被委托源码函数最初有 captures 边;载荷自替换后该边消失,本测试另保留 source 根保护目标。
|
||||
target: ObjectRef,
|
||||
}
|
||||
impl NativeCallable for EraseThenDelegate {
|
||||
@@ -719,6 +722,7 @@ impl NativeCallable for EraseThenDelegate {
|
||||
/// 测试原生分派入口,回调内借用参数/目标,NativeContext 校验并移交 Return 或 Invoke 输出根。
|
||||
fn invoke(&self, cx: &mut NativeContext<'_>, _: &[Value]) -> Result<NativeResult, VmError> {
|
||||
// 将当前函数换为普通 Record,移除签名及捕获边,迫使返回约束靠执行器自己的根存活。
|
||||
// self.target 的存活此时依赖测试未归还的 source 根,Arc 中的 ObjectRef 不构成托管边。
|
||||
cx.replace_payload(cx.callee(), endor_core::Record)?;
|
||||
Ok(NativeResult::Invoke {
|
||||
function: self.target,
|
||||
@@ -758,7 +762,7 @@ fn delegated_return_type_survives_removal_of_the_original_signature_edges() {
|
||||
let code = vm.new_code(code).unwrap();
|
||||
// 源码环境有分配根,函数持有它的内部边。
|
||||
let globals = vm.new_dict().unwrap();
|
||||
// 源码函数返回文本或 Nil,作为后续返回契约一致/不一致的终点。
|
||||
// 此源码函数固定返回 Nil,故意不满足包装器的 Transient | Number 返回联合。
|
||||
let source = vm
|
||||
.new_function("source", code, globals, vec![], vec![])
|
||||
.unwrap();
|
||||
@@ -916,7 +920,7 @@ fn native_union_and_nullable_contracts_accept_each_branch_and_reject_invalid_met
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// Delegated 包装器能进入只读域,但实际目标仍在同域核对效果,目标换为纯函数后可通过。
|
||||
/// Delegated 包装器能进入只读域,但实际目标仍在同域核对效果,目标改为 ReadOnly 声明后可通过。
|
||||
fn delegated_effects_keep_the_original_read_only_scope_and_check_the_actual_target() {
|
||||
use endor_core::{AnnotationType as T, CallEffect, CallSignature};
|
||||
use std::sync::{
|
||||
|
||||
@@ -242,7 +242,7 @@ fn late_trait_registration_and_ancestor_updates_validate_existing_descendants()
|
||||
vm.object_store().lookup_method(base, "render").unwrap(),
|
||||
Some(good)
|
||||
);
|
||||
// 第三堆查询已有类型/能力应报 ForeignHandle,不是简单 false。
|
||||
// 另建独立 VM 查询原堆类型/能力应报 ForeignHandle,不是简单 false。
|
||||
let foreign = Vm::new().unwrap();
|
||||
assert_eq!(
|
||||
foreign.implements_trait(base, capability),
|
||||
@@ -357,7 +357,7 @@ fn failed_nominal_return_releases_value_and_captured_type_roots() {
|
||||
Value::Object(expected),
|
||||
)
|
||||
.unwrap();
|
||||
// 测试用已验证指令,返回常量 Nil;数量由参数布局决定。
|
||||
// 零参数代码返回 Other 实例常量,故意违背下面声明的 Expected 返回类型。
|
||||
let code = EndorCode::from_instructions(
|
||||
&[
|
||||
Instruction::new(Opcode::LoadConst, 0),
|
||||
@@ -438,7 +438,7 @@ fn native_arity_checks_precede_effects_and_traits_require_published_signatures()
|
||||
// 副作用标志载体被 CountedNative 的显式 captures 边保活。
|
||||
let state = vm.new_object().unwrap();
|
||||
vm.set_attr(state, "called", Value::Bool(false)).unwrap();
|
||||
// 原生载荷也按 is_function 分类附着类型,数量协议仍独立。
|
||||
// 本场景未配置 Function 名义类型;包装器发布的数量区间独立用于预检及能力匹配。
|
||||
let native = vm
|
||||
.allocate(ContextNativeFunction::new(
|
||||
"counted",
|
||||
@@ -477,7 +477,7 @@ fn native_arity_checks_precede_effects_and_traits_require_published_signatures()
|
||||
let Value::Object(instance) = vm.call(class, &[]).unwrap() else {
|
||||
panic!("instance")
|
||||
};
|
||||
// 绑定结果持有函数与 receiver,且本身应自动取得 Function 类型。
|
||||
// 绑定结果持有 native 和 instance;这里只核对扣除 self 后的数量区间,不要求 Function 名义类型。
|
||||
let Value::Object(bound) = vm.bind_attr(instance, "run").unwrap() else {
|
||||
panic!("bound")
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user