Validate unified source and native positional call contracts
This commit is contained in:
@@ -117,6 +117,11 @@ pub trait ObjectPayload: Any + fmt::Debug + Send + Sync {
|
||||
/// Host-call entry: arguments and raw results are borrowed handles. The VM
|
||||
/// validates/retains the result before exposing it as an owned call result.
|
||||
/// Language functions are dispatched by Vm's frame evaluator instead.
|
||||
/// Positional metadata for native call protocols; source code is queried by the store.
|
||||
fn call_arity(&self) -> Option<crate::CallArity> {
|
||||
self.native_callable().and_then(|callable| callable.arity())
|
||||
}
|
||||
|
||||
fn call(&self, _arguments: &[Value]) -> Result<Value, VmError> {
|
||||
Err(VmError::UnsupportedOperation("call"))
|
||||
}
|
||||
@@ -176,6 +181,7 @@ pub type NativeCall = EndorNativeCall;
|
||||
pub struct EndorNativeFunctionObject {
|
||||
name: String,
|
||||
function: NativeCall,
|
||||
arity: Option<crate::CallArity>,
|
||||
}
|
||||
|
||||
impl EndorNativeFunctionObject {
|
||||
@@ -183,12 +189,17 @@ impl EndorNativeFunctionObject {
|
||||
Self {
|
||||
name: name.into(),
|
||||
function,
|
||||
arity: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
pub fn with_arity(mut self, arity: crate::CallArity) -> Self {
|
||||
self.arity = Some(arity);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Compatibility name for existing embedders.
|
||||
@@ -213,7 +224,13 @@ impl ObjectPayload for EndorNativeFunctionObject {
|
||||
Ok(format!("<native-function {}>", self.name))
|
||||
}
|
||||
|
||||
fn call_arity(&self) -> Option<crate::CallArity> {
|
||||
self.arity
|
||||
}
|
||||
fn call(&self, arguments: &[Value]) -> Result<Value, VmError> {
|
||||
if let Some(arity) = self.arity {
|
||||
arity.check(self.name.clone(), arguments.len())?;
|
||||
}
|
||||
(self.function)(arguments)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user