Add typed trait requirements and enforce actual capability results
This commit is contained in:
@@ -375,6 +375,12 @@ impl<'a> NativeContext<'a> {
|
||||
if let Some(signature) = &signature {
|
||||
signature.check_arguments(store, &name, arguments)?;
|
||||
}
|
||||
let trait_returns = if let Some(Value::Object(receiver)) = arguments.first() {
|
||||
store.check_method_contract_call(function, *receiver, false)?;
|
||||
store.method_trait_returns(function, *receiver)?
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let mut context = Self {
|
||||
store,
|
||||
roots: Vec::new(),
|
||||
@@ -386,6 +392,11 @@ impl<'a> NativeContext<'a> {
|
||||
context.protect(&Value::Object(reference))?;
|
||||
}
|
||||
}
|
||||
for (_, expected) in &trait_returns {
|
||||
for reference in expected.references() {
|
||||
context.protect(&Value::Object(reference))?;
|
||||
}
|
||||
}
|
||||
for argument in arguments {
|
||||
context.protect(argument)?;
|
||||
}
|
||||
@@ -393,6 +404,11 @@ impl<'a> NativeContext<'a> {
|
||||
if let (Some(signature), NativeResult::Return(value)) = (&signature, &result) {
|
||||
signature.check_return(context.store(), &name, value)?;
|
||||
}
|
||||
if let NativeResult::Return(value) = &result {
|
||||
for (name, expected) in &trait_returns {
|
||||
expected.check(context.store(), name, "return".into(), value)?;
|
||||
}
|
||||
}
|
||||
let transferred_from = context.roots.len();
|
||||
match &result {
|
||||
NativeResult::Return(value) => context.protect(value)?,
|
||||
|
||||
Reference in New Issue
Block a user