docs: 补全 Aster 中文调用链、控制流与生命周期注释 #3

Merged
Zayden-Jung merged 62 commits from codex/detailed-chinese-comments into main 2026-11-15 12:13:30 +00:00
Showing only changes of commit 56df4e5b35 - Show all commits
+46
View File
@@ -858,15 +858,19 @@ impl Vm {
Ok(frame)
}
/// prepare_call 分派非源码载荷:上下文回调交 NativeContext,旧式回调自行验证并保留返回根。
fn invoke_native(
&mut self,
function: ObjectRef,
arguments: &[Value],
) -> Result<NativeResult, VmError> {
// 先验证当前函数句柄,不让失效/异堆身份进入原生协议。
self.object(function)?;
// 参数起初是借用,仅验证有效性;此循环本身不取得拥有根。
for argument in arguments {
self.validate_value(argument)?;
}
// 对象首参可能是方法接收者,普通覆盖和显式能力检查不可只靠原生数量约束。
if let Some(Value::Object(receiver)) = arguments.first() {
self.objects.check_method_contract_call(
function,
@@ -874,6 +878,7 @@ impl Vm {
self.source_type_checks,
)?;
}
// 已发布的数量区间必须满足,缺少元数据不在此处猜测数量。
if let Some(arity) = self.objects.call_arity(function)?
&& !arity.accepts(arguments.len())
{
@@ -884,22 +889,30 @@ impl Vm {
provided: arguments.len(),
});
}
// 克隆到的分派器 Arc 不借用载荷,可在 NativeContext 中安全可变访问 Store。
if let Some(callable) = self.object(function)?.payload().native_callable() {
return NativeContext::execute(&mut self.objects, function, arguments, callable);
}
// 无上下文旧式协议读取完整签名;有签名才检查参数/效果及结果。
let signature = self.objects.native_signature(function)?;
// 复制诊断类别名,不在执行回调后依赖之前的载荷借用。
let name = self.object(function)?.payload().kind_name().to_owned();
// 完整签名存在才执行相应参数或返回检查,缺失时维持旧协议行为。
if let Some(signature) = &signature {
signature.check_arguments(&self.objects, &name, arguments)?;
}
// 旧式回调返回借用值,不能立即作为拥有结果交给宿主。
let result = self.object(function)?.payload().call(arguments)?;
// 完整签名存在才执行相应参数或返回检查,缺失时维持旧协议行为。
if let Some(signature) = &signature {
signature.check_return(&self.objects, &name, &result)?;
}
// 验证并取得结果根,即使回调原样返回某个参数,也必须给结果独立所有权。
self.retain_value(&result)?;
Ok(NativeResult::Return(result))
}
/// 同步调用、只读续执行、协程及 Call 指令共用准备循环,原生委托不递归进入求值器。
fn prepare_call(
&mut self,
mut function: ObjectRef,
@@ -907,42 +920,59 @@ impl Vm {
executed: &mut usize,
limits: ExecutionLimits,
) -> Result<PreparedCall, VmError> {
// 最初函数/实参借用;第一次 Invoke 后才接管 NativeContext 移交的函数/参数根。
let mut owned = false;
// 累计原生/能力返回约束,后续委托每一层完成都仍须满足这些要求。
let mut returns = Vec::new();
// 闭包把委托循环的提前错误汇总,外层统一清理尚未移交的约束与输入根。
let result = (|| loop {
// 源码载荷交给 prepare_frame,不走原生调用协议或 Rust 递归执行。
if self
.object(function)?
.payload()
.as_any()
.is::<EndorFunctionObject>()
{
// 源码帧取得自己的函数/参数根,后面归还委托输入根不会使帧失效。
let mut frame = self.prepare_frame(function, &arguments)?;
// 暂取帧本地能力返回约束,将外层原生委托约束放在前面。
let mut local = std::mem::take(&mut frame.native_returns);
// 把累计约束所有权移入源码帧,外层 returns 变空,避免统一清理重复归还。
frame.native_returns = std::mem::take(&mut returns);
// 本地约束追加在外层之后,最终返回时按反序检查。
frame.native_returns.append(&mut local);
return Ok(PreparedCall::Frame(frame));
}
// 每次原生/委托分派前检查累计硬预算,避免无限原生委托链绕过指令限制。
if *executed >= limits.max_instructions {
return Err(VmError::ExecutionLimit("instructions"));
}
*executed += 1;
// 非 Any 返回约束需要跨委托保留,不能只校验中间包装器直接返回值。
if let Some(signature) = self.objects.native_signature(function)?
&& !signature.returns.is_any()
{
// 诊断名与解析后的返回类型一并保存,不在最终返回时重查可能被重绑定的全局。
let check = NativeReturn {
name: self.object(function)?.payload().kind_name().into(),
expected: signature.returns,
};
self.push_native_return(&mut returns, check)?;
}
// 对象首参可能是方法接收者,普通覆盖和显式能力检查不可只靠原生数量约束。
if let Some(Value::Object(receiver)) = arguments.first() {
// 有效接收者的全部能力返回约束同样跨委托保留。
for (name, expected) in self.objects.method_trait_returns(function, *receiver)? {
self.push_native_return(&mut returns, NativeReturn { name, expected })?;
}
}
// 结果已经拥有:Return 的结果根或 Invoke 的函数/各参数根由本循环接管。
match self.invoke_native(function, &arguments)? {
// 最终直接结果要通过委托链所有返回检查后才可交付。
NativeResult::Return(value) => {
// 从最内层到外层校验,每项约束都必须满足。
for check in returns.iter().rev() {
// 检查失败先归还本次结果根,再让外层清理链上剩余资源。
if let Err(error) = check.check(&self.objects, &value) {
self.drop_root(value);
return Err(error);
@@ -954,22 +984,29 @@ impl Vm {
function: next,
arguments: values,
} => {
// 只有已接管 Invoke 输入时才归还当前函数/实参,初始借用输入不能释放。
if owned {
self.release(function)?;
// 先清空旧拥有参数列表并逐项归还,随后安装新委托输出。
for value in arguments.drain(..) {
self.release_value(value)?;
}
}
// 新委托函数/参数根已经由 NativeContext 保留,赋值只转交清理责任。
function = next;
arguments = values;
// 从此循环退出时须统一归还当前委托输入;返回结果或源码帧各自已保活。
owned = true;
}
}
})();
// 直接完成/错误清理仍在本地的约束,已移入源码帧的那部分不再在此表中。
self.clear_native_returns(returns);
// 只有已接管 Invoke 输入时才归还当前函数/实参,初始借用输入不能释放。
if owned {
self.release(function)
.expect("delegated call owns its function");
// 循环结束时归还最后一批拥有参数,重复对象参数逐项计数。
for value in arguments {
self.drop_root(value);
}
@@ -977,14 +1014,19 @@ impl Vm {
result
}
/// 委托链保留返回约束定义根,全部 retain 成功后才追加检查项,中途失败回滚已保留部分。
fn push_native_return(
&mut self,
returns: &mut Vec<NativeReturn>,
check: NativeReturn,
) -> Result<(), VmError> {
// 先记成功 retain 的定义身份,未全部成功前不提交检查项。
let mut retained = Vec::new();
// 枚举联合返回类型内全部定义引用,重复引用不能去重。
for reference in check.expected.references() {
// 后续定义根失败时,归还此前成功取得的根,不留下半安装约束。
if let Err(error) = self.retain(reference) {
// 回滚只处理本次取得的根,不触碰原签名载荷拥有边。
for reference in retained {
self.release(reference)?;
}
@@ -992,11 +1034,15 @@ impl Vm {
}
retained.push(reference);
}
// 全部定义根已取得,追加检查项后由返回链/帧负责清理。
returns.push(check);
Ok(())
}
/// 委托结束/帧销毁统一归还返回约束定义根,每个引用按拥有次数独立 release。
fn clear_native_returns(&mut self, returns: Vec<NativeReturn>) {
// 销毁每份检查项持有的定义根,Rust CallType 的 drop 不会自动 release。
for check in returns {
// 枚举联合返回类型内全部定义引用,重复引用不能去重。
for reference in check.expected.references() {
self.release(reference)
.expect("native return check owns its type");