94 lines
2.5 KiB
Rust
94 lines
2.5 KiB
Rust
use std::sync::Arc;
|
|
|
|
use crate::{EndorCode, ObjectRef, Value};
|
|
|
|
/// NULL is a call-protocol marker and can never escape as a language value.
|
|
/// Each Value::Object in a live frame owns one execution root.
|
|
#[derive(Debug, Clone)]
|
|
pub(crate) enum StackEntry {
|
|
Null,
|
|
Value(Value),
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub(crate) struct NativeReturn {
|
|
pub name: String,
|
|
pub expected: crate::CallType,
|
|
}
|
|
impl NativeReturn {
|
|
pub fn check(&self, store: &objects::ObjectStore, value: &Value) -> Result<(), crate::VmError> {
|
|
self.expected
|
|
.check(store, &self.name, "return".into(), value)
|
|
}
|
|
}
|
|
|
|
/// Internal activation record, analogous to _PyInterpreterFrame. It has no
|
|
/// EndorObject header; introspection objects can be added independently later.
|
|
#[derive(Debug)]
|
|
pub struct EndorFrame {
|
|
pub(crate) function: ObjectRef,
|
|
pub(crate) return_type: Option<crate::AnnotationType>,
|
|
pub(crate) native_returns: Vec<NativeReturn>,
|
|
/// Index of the caller in the execution's frame vector, never a pointer.
|
|
pub(crate) previous: Option<usize>,
|
|
pub(crate) code: ObjectRef,
|
|
pub(crate) executable: Arc<EndorCode>,
|
|
pub(crate) globals: ObjectRef,
|
|
pub(crate) builtins: Option<ObjectRef>,
|
|
pub(crate) name: String,
|
|
pub(crate) instruction_offset: usize,
|
|
pub(crate) current_offset: usize,
|
|
pub(crate) localsplus: Vec<Option<Value>>,
|
|
pub(crate) stack: Vec<StackEntry>,
|
|
}
|
|
|
|
impl EndorFrame {
|
|
pub fn previous(&self) -> Option<usize> {
|
|
self.previous
|
|
}
|
|
pub fn function(&self) -> ObjectRef {
|
|
self.function
|
|
}
|
|
pub fn code(&self) -> ObjectRef {
|
|
self.code
|
|
}
|
|
pub fn globals(&self) -> ObjectRef {
|
|
self.globals
|
|
}
|
|
pub fn builtins(&self) -> Option<ObjectRef> {
|
|
self.builtins
|
|
}
|
|
pub fn instruction_offset(&self) -> usize {
|
|
self.instruction_offset
|
|
}
|
|
pub fn localsplus(&self) -> &[Option<Value>] {
|
|
&self.localsplus
|
|
}
|
|
pub fn stack_depth(&self) -> usize {
|
|
self.stack.len()
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub struct ExecutionLocation {
|
|
pub function: String,
|
|
pub filename: String,
|
|
pub first_line: usize,
|
|
pub instruction_offset: usize,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub struct ExecutionLimits {
|
|
pub max_frames: usize,
|
|
pub max_instructions: usize,
|
|
}
|
|
|
|
impl Default for ExecutionLimits {
|
|
fn default() -> Self {
|
|
Self {
|
|
max_frames: 1000,
|
|
max_instructions: usize::MAX,
|
|
}
|
|
}
|
|
}
|