runmat_runtime/native/
call.rs1use super::{NativeExit, NativeFrame, NativeHostVTable, NativeValueRef};
2
3#[repr(transparent)]
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5pub struct NativeCallKind(pub u32);
6
7impl NativeCallKind {
8 pub const DIRECT: Self = Self(0);
9 pub const DYNAMIC: Self = Self(1);
10 pub const BUILTIN: Self = Self(2);
11 pub const METHOD: Self = Self(3);
12 pub const CALLBACK: Self = Self(4);
13 pub const RESUME: Self = Self(5);
14
15 pub const fn is_known(self) -> bool {
16 self.0 <= Self::RESUME.0
17 }
18}
19
20#[repr(C)]
23#[derive(Clone, Copy, Debug)]
24pub struct NativeCall {
25 pub abi_version: u32,
26 pub kind: NativeCallKind,
27 pub flags: u32,
28 pub requested_outputs: u32,
29 pub host: *const NativeHostVTable,
30 pub frame: *mut NativeFrame,
31 pub arguments: *const NativeValueRef,
32 pub argument_count: usize,
33 pub results: *mut NativeValueRef,
34 pub result_capacity: usize,
35}
36
37impl Default for NativeCall {
38 fn default() -> Self {
39 Self {
40 abi_version: super::NATIVE_ABI_VERSION.encoded(),
41 kind: NativeCallKind::DIRECT,
42 flags: 0,
43 requested_outputs: 0,
44 host: std::ptr::null(),
45 frame: std::ptr::null_mut(),
46 arguments: std::ptr::null(),
47 argument_count: 0,
48 results: std::ptr::null_mut(),
49 result_capacity: 0,
50 }
51 }
52}
53
54impl NativeCall {
55 pub fn validate_exit(&self, exit: &NativeExit) -> Result<(), super::NativeAbiError> {
60 self.validate()?;
61 exit.validate()?;
62 if exit.kind == super::NativeExitKind::COMPLETED {
63 if exit.produced_outputs > self.requested_outputs
64 || exit.produced_outputs as usize > self.result_capacity
65 {
66 return Err(super::NativeAbiError::new(
67 "native.exit.produced_outputs",
68 "completed outputs exceed the call result window",
69 ));
70 }
71 } else if exit.produced_outputs != 0 {
72 return Err(super::NativeAbiError::new(
73 "native.exit.produced_outputs",
74 "non-completed exits cannot commit outputs",
75 ));
76 }
77 Ok(())
78 }
79}