Represent nullable and union native contracts with traced alternatives
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
| 文件 | 职责 |
|
||||
| --- | --- |
|
||||
| [lib.rs](lib.rs) | VM 类型导出、objects 类型兼容重导出(含 ReadAccess/CallSignature/CallEffect)、宿主调用与字节码 rustdoc 示例 |
|
||||
| [lib.rs](lib.rs) | VM 类型导出、objects 类型兼容重导出(含 ReadAccess/CallSignature/CallType/CallEffect)、宿主调用与字节码 rustdoc 示例 |
|
||||
| [vm.rs](vm.rs) | Vm 拥有 ObjectStore 与错误位置记录;对象操作和宿主 new_class 和显式Trait注册/关系查询显式委托给 objects;函数/字段检查统一开关、统一参数区间查询与函数类型配置 |
|
||||
| [frame.rs](frame.rs) | EndorFrame、栈条目、源码与原生委托返回契约执行根、执行位置元数据、ExecutionLimits |
|
||||
| [eval.rs](eval.rs) | execute/call、只读调用与依赖结果、参数绑定、原生实现前数量/类型/效果检查和委托返回检查、可选注解检查、源码类字段环境绑定、帧切换、取指分派、MakeFunction、结果根转移与失败清理 |
|
||||
|
||||
+11
-4
@@ -313,14 +313,21 @@ impl Vm {
|
||||
}
|
||||
*executed += 1;
|
||||
if let Some(signature) = self.objects.native_signature(function)?
|
||||
&& !matches!(signature.returns, crate::AnnotationType::Any)
|
||||
&& !signature.returns.is_any()
|
||||
{
|
||||
let check = NativeReturn {
|
||||
name: self.object(function)?.payload().kind_name().into(),
|
||||
expected: signature.returns,
|
||||
};
|
||||
if let Some(reference) = check.expected.reference() {
|
||||
self.retain(reference)?;
|
||||
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)?;
|
||||
}
|
||||
return Err(error);
|
||||
}
|
||||
retained.push(reference);
|
||||
}
|
||||
returns.push(check);
|
||||
}
|
||||
@@ -363,7 +370,7 @@ impl Vm {
|
||||
|
||||
fn clear_native_returns(&mut self, returns: Vec<NativeReturn>) {
|
||||
for check in returns {
|
||||
if let Some(reference) = check.expected.reference() {
|
||||
for reference in check.expected.references() {
|
||||
self.release(reference)
|
||||
.expect("native return check owns its type");
|
||||
}
|
||||
|
||||
@@ -13,19 +13,12 @@ pub(crate) enum StackEntry {
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct NativeReturn {
|
||||
pub name: String,
|
||||
pub expected: crate::AnnotationType,
|
||||
pub expected: crate::CallType,
|
||||
}
|
||||
impl NativeReturn {
|
||||
pub fn check(&self, store: &objects::ObjectStore, value: &Value) -> Result<(), crate::VmError> {
|
||||
if !store.matches_annotation(value, self.expected)? {
|
||||
return Err(crate::VmError::TypeMismatch {
|
||||
function: self.name.clone(),
|
||||
position: "return".into(),
|
||||
expected: store.annotation_type_name(self.expected)?,
|
||||
actual: store.value_type_name(value)?,
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
self.expected
|
||||
.check(store, &self.name, "return".into(), value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ pub use objects::{
|
||||
TypeConstructor,
|
||||
};
|
||||
pub use objects::{
|
||||
CallArity, CallEffect, CallSignature, ChangeBatch, ChangeKey, CodeLayout, CompareOp,
|
||||
CallArity, CallEffect, CallSignature, CallType, ChangeBatch, ChangeKey, CodeLayout, CompareOp,
|
||||
ContextNativeFunction, DecodedInstruction, EndorBaseExceptionObject, EndorCellObject,
|
||||
EndorCode, EndorCodeObject, EndorDecimal, EndorDictObject, EndorFunctionObject, EndorInteger,
|
||||
EndorNativeCall, EndorNativeFunctionObject, EndorNumber, EndorNumberObject, EndorObject,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
| [builtins.rs](builtins.rs) | 无损 Number、Unicode 字符串、Dict 顺序与键、Cell、函数环境/共享代码、异常数据 |
|
||||
| [execution.rs](execution.rs) | wordcode 与校验、控制流、参数/默认值、嵌套帧、字节码函数创建/默认值/环境捕获、闭包、返回值存活、失败清理、限额 |
|
||||
| [types.rs](types.rs) | 名义身份、继承与实例关系、类型边保活/循环回收、只读类型元数据与外来句柄、显式Trait身份/继承/参数约束及后代更新原子性;统一函数分类、原生数量元数据/副作用前拒绝/能力更新/默认参数与返回类型错误根清理;仅远端执行 |
|
||||
| [native_context.rs](native_context.rs) | 原生作用域根、分配失败清理、原生签名/效果和委托返回根、绑定方法元数据、委托、只读结果分配/写入拒绝/依赖/校验与普通读取区分及失败恢复、弱引用过期及有界变更;仅远端执行 |
|
||||
| [native_context.rs](native_context.rs) | 原生作用域根、分配失败清理、原生签名/联合与可空类型/效果和委托返回根、绑定方法元数据、委托、只读结果分配/写入拒绝/依赖/校验与普通读取区分及失败恢复、弱引用过期及有界变更;仅远端执行 |
|
||||
|
||||
核心对象现由 objects 定义,本目录保留既有 endor_core 导入与 Vm 方法的兼容性检查。独立对象存储检查见 [objects/tests](../../objects/tests/README.md)。堆内部伪造句柄与计数溢出检查在 objects 的 src/heap.rs,公开示例由 src/lib.rs rustdoc 提供。文件职责见 [src](../src/README.md),检查方式和结果边界见 [验证](../../../docs/operations/validation.md)。本地不执行测试;存在测试文件不代表某次提交已通过。返回 [core](../README.md)。
|
||||
|
||||
|
||||
@@ -505,8 +505,8 @@ fn legacy_native_signatures_check_optional_variadic_types_and_metadata() {
|
||||
NativeFunction::new("legacy", echo).with_signature(CallSignature {
|
||||
arity: CallArity::range(0, usize::MAX),
|
||||
parameters: vec![],
|
||||
variadic: Some(T::Number),
|
||||
returns: T::Number,
|
||||
variadic: Some(T::Number.into()),
|
||||
returns: T::Number.into(),
|
||||
effect: CallEffect::ReadOnly,
|
||||
}),
|
||||
)
|
||||
@@ -585,15 +585,13 @@ fn delegated_return_type_survives_removal_of_the_original_signature_edges() {
|
||||
let source = vm
|
||||
.new_function("source", code, globals, vec![], vec![])
|
||||
.unwrap();
|
||||
let mut signature = CallSignature::exact(vec![], T::Any, CallEffect::Mutating);
|
||||
signature.returns = endor_core::CallType::Union(vec![T::Nominal(definition), T::Number]);
|
||||
let wrapper = vm
|
||||
.allocate(ContextNativeFunction::new(
|
||||
"erased",
|
||||
EraseThenDelegate {
|
||||
signature: CallSignature::exact(
|
||||
vec![],
|
||||
T::Nominal(definition),
|
||||
CallEffect::Mutating,
|
||||
),
|
||||
signature,
|
||||
target: source,
|
||||
},
|
||||
vec![source],
|
||||
@@ -601,7 +599,7 @@ fn delegated_return_type_survives_removal_of_the_original_signature_edges() {
|
||||
.unwrap();
|
||||
vm.release(definition).unwrap();
|
||||
assert!(
|
||||
matches!(vm.call(wrapper, &[]), Err(VmError::TypeMismatch { function, expected, .. }) if function == "erased" && expected == "Transient")
|
||||
matches!(vm.call(wrapper, &[]), Err(VmError::TypeMismatch { function, expected, .. }) if function == "erased" && expected == "Transient | Number")
|
||||
);
|
||||
assert!(vm.upgrade(weak).unwrap().is_none());
|
||||
for object in [
|
||||
@@ -617,3 +615,107 @@ fn delegated_return_type_survives_removal_of_the_original_signature_edges() {
|
||||
vm.collect_cycles();
|
||||
assert_eq!(vm.object_count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_union_and_nullable_contracts_accept_each_branch_and_reject_invalid_metadata() {
|
||||
use endor_core::{AnnotationType as T, CallEffect, CallSignature, CallType};
|
||||
use std::sync::{
|
||||
Arc,
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
let mut vm = Vm::new().unwrap();
|
||||
let calls = Arc::new(AtomicUsize::new(0));
|
||||
let mut signature = CallSignature::exact(vec![T::Any], T::Any, CallEffect::ReadOnly);
|
||||
signature.parameters[0] = CallType::Union(vec![T::String, T::Bool]);
|
||||
signature.returns = signature.parameters[0].clone();
|
||||
let function = vm
|
||||
.allocate(ContextNativeFunction::new(
|
||||
"union",
|
||||
TypedNative {
|
||||
signature,
|
||||
calls: calls.clone(),
|
||||
delegate: None,
|
||||
allocate_result: false,
|
||||
},
|
||||
vec![],
|
||||
))
|
||||
.unwrap();
|
||||
for value in [
|
||||
Value::Text("capture".into()),
|
||||
Value::Bool(true),
|
||||
Value::Bool(false),
|
||||
] {
|
||||
assert_eq!(
|
||||
vm.call(function, std::slice::from_ref(&value)).unwrap(),
|
||||
value
|
||||
);
|
||||
}
|
||||
assert!(
|
||||
matches!(vm.call(function, &[Value::Number(3.into())]), Err(VmError::TypeMismatch { expected, .. }) if expected == "String | Bool")
|
||||
);
|
||||
assert_eq!(calls.load(Ordering::SeqCst), 3);
|
||||
let mut signature = CallSignature::exact(vec![T::Any], T::Any, CallEffect::ReadOnly);
|
||||
signature.parameters[0] = CallType::nullable(T::Number);
|
||||
signature.returns = signature.parameters[0].clone();
|
||||
vm.replace_payload(
|
||||
function,
|
||||
ContextNativeFunction::new(
|
||||
"nullable",
|
||||
TypedNative {
|
||||
signature,
|
||||
calls: calls.clone(),
|
||||
delegate: None,
|
||||
allocate_result: false,
|
||||
},
|
||||
vec![],
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
for value in [Value::Nil, Value::Number(2.into())] {
|
||||
assert_eq!(
|
||||
vm.call(function, std::slice::from_ref(&value)).unwrap(),
|
||||
value
|
||||
);
|
||||
}
|
||||
let record = vm.new_object().unwrap();
|
||||
let mut signature = CallSignature::exact(vec![T::Any], T::Any, CallEffect::ReadOnly);
|
||||
// A matching first branch must not hide a later invalid nominal definition.
|
||||
signature.parameters[0] = CallType::Union(vec![T::Any, T::Nominal(record)]);
|
||||
vm.replace_payload(
|
||||
function,
|
||||
ContextNativeFunction::new(
|
||||
"invalid union",
|
||||
TypedNative {
|
||||
signature,
|
||||
calls: calls.clone(),
|
||||
delegate: None,
|
||||
allocate_result: false,
|
||||
},
|
||||
vec![],
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(vm.call(function, &[Value::Nil]).is_err());
|
||||
assert_eq!(calls.load(Ordering::SeqCst), 5);
|
||||
let mut signature = CallSignature::exact(vec![], T::Any, CallEffect::ReadOnly);
|
||||
signature.returns = CallType::Union(vec![]);
|
||||
vm.replace_payload(
|
||||
function,
|
||||
ContextNativeFunction::new(
|
||||
"empty union",
|
||||
TypedNative {
|
||||
signature,
|
||||
calls: calls.clone(),
|
||||
delegate: None,
|
||||
allocate_result: false,
|
||||
},
|
||||
vec![],
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(vm.call(function, &[]).is_err());
|
||||
assert_eq!(calls.load(Ordering::SeqCst), 5);
|
||||
vm.release(record).unwrap();
|
||||
vm.release(function).unwrap();
|
||||
assert_eq!(vm.object_count(), 0);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
| 文件 | 职责 |
|
||||
| --- | --- |
|
||||
| [lib.rs](lib.rs) | 包边界、对象类型/ObjectStore 公开导出(含Trait/MethodRequirement/SourceSignature/AnnotationType/CallArity/CallSignature/CallEffect/ReadAccess)与独立存储 rustdoc 示例 |
|
||||
| [lib.rs](lib.rs) | 包边界、对象类型/ObjectStore 公开导出(含Trait/MethodRequirement/SourceSignature/AnnotationType/CallArity/CallSignature/CallType/CallEffect/ReadAccess)与独立存储 rustdoc 示例 |
|
||||
| [object.rs](object.rs) | Value、CompareOp、ObjectPayload(含显式函数标记)、ObjectHeader、EndorObject、Record、可发布数量元数据的 NativeFunction |
|
||||
| [types.rs](types.rs) | 托管名义类型、显式 Object/Type 引导、继承查询、受管方法表/接收者绑定、类字段、显式Trait定义/声明/方法参数约束、原生构造委托、统一源码/原生/绑定方法参数区间查询与能力验证、声明环境托管边、字段构造/写入检查与标记为校验读取的注解解析/匹配 |
|
||||
| [native.rs](native.rs) | NativeContext、CallArity/CallSignature 类型与效果元数据、调用前检查、签名类型强边、上下文原生函数、作用域语言函数工厂、显式能力声明入口、函数标记、根与非递归委托调用 |
|
||||
|
||||
@@ -36,8 +36,8 @@ pub use error::VmError;
|
||||
pub use heap::{ObjectRef, ReadAccess, WeakObjectRef};
|
||||
pub use instruction::{DecodedInstruction, Instruction, Opcode};
|
||||
pub use native::{
|
||||
CallArity, CallEffect, CallSignature, ContextNativeFunction, NativeCallable, NativeContext,
|
||||
NativeResult,
|
||||
CallArity, CallEffect, CallSignature, CallType, ContextNativeFunction, NativeCallable,
|
||||
NativeContext, NativeResult,
|
||||
};
|
||||
pub use number::{
|
||||
EndorDecimal, EndorInteger, EndorNumber, EndorNumberObject, EndorRational, EndorReal,
|
||||
|
||||
@@ -59,14 +59,91 @@ pub enum CallEffect {
|
||||
External,
|
||||
}
|
||||
|
||||
/// Resolved native value contract. A union is flat, nonempty and preserves
|
||||
/// all definition edges even when an earlier alternative already matches.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CallType {
|
||||
Single(crate::AnnotationType),
|
||||
Union(Vec<crate::AnnotationType>),
|
||||
}
|
||||
impl From<crate::AnnotationType> for CallType {
|
||||
fn from(value: crate::AnnotationType) -> Self {
|
||||
Self::Single(value)
|
||||
}
|
||||
}
|
||||
impl CallType {
|
||||
pub fn nullable(value: crate::AnnotationType) -> Self {
|
||||
Self::Union(vec![value, crate::AnnotationType::Unit])
|
||||
}
|
||||
fn alternatives(&self) -> &[crate::AnnotationType] {
|
||||
match self {
|
||||
Self::Single(value) => std::slice::from_ref(value),
|
||||
Self::Union(values) => values,
|
||||
}
|
||||
}
|
||||
pub fn references(&self) -> impl Iterator<Item = ObjectRef> + '_ {
|
||||
self.alternatives()
|
||||
.iter()
|
||||
.copied()
|
||||
.filter_map(crate::AnnotationType::reference)
|
||||
}
|
||||
pub fn is_any(&self) -> bool {
|
||||
self.alternatives()
|
||||
.iter()
|
||||
.any(|value| matches!(value, crate::AnnotationType::Any))
|
||||
}
|
||||
pub fn validate(&self, store: &ObjectStore) -> Result<(), VmError> {
|
||||
if self.alternatives().is_empty() {
|
||||
return Err(VmError::InvalidArgument("empty native union type"));
|
||||
}
|
||||
for value in self.alternatives() {
|
||||
match *value {
|
||||
crate::AnnotationType::Nominal(reference) => {
|
||||
store.payload::<crate::EndorTypeObject>(reference, "Type")?;
|
||||
}
|
||||
crate::AnnotationType::Capability(reference) => {
|
||||
store.payload::<crate::EndorTraitObject>(reference, "Trait")?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn check(
|
||||
&self,
|
||||
store: &ObjectStore,
|
||||
name: &str,
|
||||
position: String,
|
||||
value: &Value,
|
||||
) -> Result<(), VmError> {
|
||||
self.validate(store)?;
|
||||
for expected in self.alternatives() {
|
||||
if store.matches_annotation(value, *expected)? {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
let names = self
|
||||
.alternatives()
|
||||
.iter()
|
||||
.map(|expected| store.annotation_type_name(*expected))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Err(VmError::TypeMismatch {
|
||||
function: name.into(),
|
||||
position,
|
||||
expected: names.join(" | "),
|
||||
actual: store.value_type_name(value)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Immutable native contract, including an explicit receiver where applicable.
|
||||
/// Missing fixed slots are covered by variadic; optionality comes from arity.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CallSignature {
|
||||
pub arity: CallArity,
|
||||
pub parameters: Vec<crate::AnnotationType>,
|
||||
pub variadic: Option<crate::AnnotationType>,
|
||||
pub returns: crate::AnnotationType,
|
||||
pub parameters: Vec<CallType>,
|
||||
pub variadic: Option<CallType>,
|
||||
pub returns: CallType,
|
||||
pub effect: CallEffect,
|
||||
}
|
||||
impl CallSignature {
|
||||
@@ -77,19 +154,18 @@ impl CallSignature {
|
||||
) -> Self {
|
||||
Self {
|
||||
arity: CallArity::exact(parameters.len()),
|
||||
parameters,
|
||||
parameters: parameters.into_iter().map(CallType::from).collect(),
|
||||
variadic: None,
|
||||
returns,
|
||||
returns: returns.into(),
|
||||
effect,
|
||||
}
|
||||
}
|
||||
pub fn references(&self) -> impl Iterator<Item = ObjectRef> + '_ {
|
||||
self.parameters
|
||||
.iter()
|
||||
.copied()
|
||||
.chain(self.variadic)
|
||||
.chain([self.returns])
|
||||
.filter_map(crate::AnnotationType::reference)
|
||||
.chain(self.variadic.as_ref())
|
||||
.chain([&self.returns])
|
||||
.flat_map(CallType::references)
|
||||
}
|
||||
pub fn validate(&self, store: &ObjectStore) -> Result<(), VmError> {
|
||||
self.arity.validate()?;
|
||||
@@ -101,19 +177,10 @@ impl CallSignature {
|
||||
for expected in self
|
||||
.parameters
|
||||
.iter()
|
||||
.copied()
|
||||
.chain(self.variadic)
|
||||
.chain([self.returns])
|
||||
.chain(self.variadic.as_ref())
|
||||
.chain([&self.returns])
|
||||
{
|
||||
match expected {
|
||||
crate::AnnotationType::Nominal(reference) => {
|
||||
store.payload::<crate::EndorTypeObject>(reference, "Type")?;
|
||||
}
|
||||
crate::AnnotationType::Capability(reference) => {
|
||||
store.payload::<crate::EndorTraitObject>(reference, "Trait")?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
expected.validate(store)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -134,16 +201,9 @@ impl CallSignature {
|
||||
let expected = self
|
||||
.parameters
|
||||
.get(index)
|
||||
.copied()
|
||||
.or(self.variadic)
|
||||
.or(self.variadic.as_ref())
|
||||
.ok_or(VmError::InvalidArgument("incomplete native signature"))?;
|
||||
self.check_value(
|
||||
store,
|
||||
name,
|
||||
format!("parameter {}", index + 1),
|
||||
value,
|
||||
expected,
|
||||
)?;
|
||||
expected.check(store, name, format!("parameter {}", index + 1), value)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -153,25 +213,7 @@ impl CallSignature {
|
||||
name: &str,
|
||||
value: &Value,
|
||||
) -> Result<(), VmError> {
|
||||
self.check_value(store, name, "return".into(), value, self.returns)
|
||||
}
|
||||
fn check_value(
|
||||
&self,
|
||||
store: &ObjectStore,
|
||||
name: &str,
|
||||
position: String,
|
||||
value: &Value,
|
||||
expected: crate::AnnotationType,
|
||||
) -> Result<(), VmError> {
|
||||
if !store.matches_annotation(value, expected)? {
|
||||
return Err(VmError::TypeMismatch {
|
||||
function: name.into(),
|
||||
position,
|
||||
expected: store.annotation_type_name(expected)?,
|
||||
actual: store.value_type_name(value)?,
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
self.returns.check(store, name, "return".into(), value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
| 引擎与宿主边界 | [架构](architecture/README.md) | [crates](../crates/README.md) |
|
||||
| 解释执行、资源修订与引擎升级 | [执行与版本](architecture/execution-and-versions.md) | frontend/compiler/core |
|
||||
| EndorObject、句柄、默认操作 | [对象模型](runtime/objects.md) | objects/src |
|
||||
| 原生上下文、只读调用、子调用读取依赖及校验分类、统一参数数量/类型/效果、委托返回与变更通知 | [原生调用](runtime/native-calls.md) | objects/src/native.rs、changes.rs、core/src/eval.rs |
|
||||
| 原生上下文、只读调用、子调用读取依赖及校验分类、统一参数数量/类型/联合/效果、委托返回与变更通知 | [原生调用](runtime/native-calls.md) | objects/src/native.rs、changes.rs、core/src/eval.rs |
|
||||
| 托管类型、宿主类注册、原生分配继承、字段存储、显式能力、函数分类、声明字段与可选源码注解检查 | [名义类型](runtime/types.md) | objects/src/types.rs |
|
||||
| Number、String、Dict、Cell、Function | [基本对象](runtime/builtins.md) | objects/src |
|
||||
| 源码读取与来源 | [Reader](runtime/reader.md) | frontend/src/reader.rs |
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
| --- | --- |
|
||||
| [types.md](types.md) | 托管 Object/Type、名义继承、声明字段/函数注解检查、构造与类型边生命周期 |
|
||||
| [objects.md](objects.md) | 对象、句柄与默认操作 |
|
||||
| [native-calls.md](native-calls.md) | 原生上下文、读取分类、统一参数数量/类型/效果、非递归委托返回、弱引用、托管赋值与变更批次 |
|
||||
| [native-calls.md](native-calls.md) | 原生上下文、读取分类、统一参数数量/类型/联合/效果、非递归委托返回、弱引用、托管赋值与变更批次 |
|
||||
| [builtins.md](builtins.md) | Number、String、Dict、Cell、Function、异常数据 |
|
||||
| [reader.md](reader.md) | 输入、来源和修订标签 |
|
||||
| [frontend.md](frontend.md) | 词法、语法和诊断 |
|
||||
|
||||
@@ -90,7 +90,9 @@ Tessera 为原生方法、回调和内部视觉 continuation 发布数量元数
|
||||
|
||||
## 原生参数、返回类型与宿主效果
|
||||
|
||||
CallSignature 保存 CallArity、固定位置的 AnnotationType 列表、可选 variadic 类型、returns 与 CallEffect。exact 提供无默认参数的便捷构造;可选参数仍通过 arity.required/maximum 表示,列表覆盖所有固定位置。开放上界必须有 variadic,有限上界未被固定列表覆盖的部分也必须有 variadic;错误区间、不完整列表、非 Type/Trait 的名义/能力引用和独立 arity 与签名不一致在调用前拒绝。名义类型引用是实际定义,不从字符串或调用者全局环境重新解析。
|
||||
CallSignature 保存 CallArity、固定位置的 CallType 列表、可选 variadic 类型、returns 与 CallEffect。exact 提供无默认参数的便捷构造;可选参数仍通过 arity.required/maximum 表示,列表覆盖所有固定位置。开放上界必须有 variadic,有限上界未被固定列表覆盖的部分也必须有 variadic;错误区间、不完整列表、非 Type/Trait 的名义/能力引用和独立 arity 与签名不一致在调用前拒绝。名义类型引用是实际定义,不从字符串或调用者全局环境重新解析。
|
||||
|
||||
CallType::Single 封装一个现有 AnnotationType;Union 保存非空的平坦分支列表,nullable(T) 等价于 T | Unit。每个分支先完整校验,不能因较早的 Object/匹配分支而隐藏后续错误定义。匹配任一分支即接受,不匹配时报告按声明顺序组合的名称。全部分支的类型/能力引用都参加 trace 与委托返回执行根保活,包括未被本次值选中的分支;根取得中途出错会撤销已取得的根。exact 仍接受原来的单类型列表作便捷构造并转换为 Single。此能力属于原生宿主契约,没有增加 Endor 的联合类型语法。
|
||||
|
||||
NativeCallable::signature 默认 None,明确表示尚未发布类型/效果契约;默认 arity 从签名取得。ObjectPayload::call_signature 供自定义直接调用协议发布。ContextNativeFunction 在创建时保存不可变签名并在 trace 中自动登记每个类型/能力引用;其他捕获仍须显式传 captures。NativeFunction::with_signature 同样追踪签名边并设置数量。自定义载荷须在 trace 中登记自己的签名引用,元数据与其他载荷边一样禁止原地改变;更换使用 replace_payload。ObjectStore::native_signature 校验并返回借用描述,不创建隐藏强注册表。
|
||||
|
||||
@@ -100,6 +102,8 @@ NativeResult::Invoke 仍是尾委托,不递归进入 Rust/VM。VM 为每层已
|
||||
|
||||
CallEffect::ReadOnly 声明只读现存对象,可分配临时结果;Mutating 与 External 在 ObjectStore 只读作用域内、进入实现前拒绝。普通执行允许这些效果。ReadOnly 声明不绕过已有写屏障,也不证明可信 Rust 不会进行隐藏 I/O;未知旧原生函数仍沿原调用/宿主检查,不能把 None 理解为纯函数。这不是静态效果推断、完整 I/O 沙箱或对阻塞原生代码的抢占。
|
||||
|
||||
Tessera 的 measure/arrange/paint/hitTest、Point 几何查询、Window 方法及可表达的 Block/Container/Page 方法发布签名。需要 nullable/union 参数的 Page.open/window 与 Block.on 尚保留无类型元数据;构造器、其他管理 API 和完整源码覆写方差仍未全部接入。能力注册目前继续检查参数数量,不声称已经比较签名类型或效果。
|
||||
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 和完整源码覆写方差仍未全部接入。能力注册目前继续检查参数数量,不声称已经比较签名类型或效果。
|
||||
|
||||
回归源码 native_context.rs 覆盖参数副作用前拒绝、错误结果清理、跨原生/源码委托检查、单帧限制、名义签名边与绑定方法循环回收、只读效果拒绝、传统直接函数及重复参数和元数据错误。只编译,不本地执行。
|
||||
|
||||
联合/可空回归另覆盖两个标量分支、nil、数值拒绝、Object 分支不掩盖非法名义类型、空联合拒绝,以及移除签名后联合返回定义仍存活。
|
||||
|
||||
Reference in New Issue
Block a user