lust/vm/
mod.rs

1mod cycle;
2pub mod stdlib;
3mod task;
4pub(super) use self::task::{TaskId, TaskInstance, TaskManager, TaskState};
5pub(super) use crate::ast::{FieldOwnership, StructDef};
6pub(super) use crate::bytecode::{
7    FieldStorage, Function, Instruction, NativeCallResult, Register, StructLayout, TaskHandle,
8    Value,
9};
10pub(super) use crate::error::StackFrame;
11pub(super) use crate::jit::{
12    JitCompiler, JitState, TraceOptimizer, TraceRecorder, MAX_TRACE_LENGTH,
13};
14pub(super) use crate::{LustError, Result};
15pub(super) use std::cell::RefCell;
16pub(super) use std::collections::HashMap;
17pub(super) use std::rc::Rc;
18mod api;
19mod execution;
20mod tasks;
21mod tracing;
22pub use self::api::{NativeExport, NativeExportParam};
23thread_local! {
24    static CURRENT_VM_STACK: RefCell<Vec<*mut VM>> = RefCell::new(Vec::new());
25}
26
27pub(crate) fn push_vm_ptr(vm: *mut VM) {
28    CURRENT_VM_STACK.with(|stack| {
29        stack.borrow_mut().push(vm);
30    });
31}
32
33pub(crate) fn pop_vm_ptr() {
34    CURRENT_VM_STACK.with(|stack| {
35        let mut stack = stack.borrow_mut();
36        stack.pop();
37    });
38}
39
40pub(super) const TO_STRING_TRAIT: &str = "ToString";
41pub(super) const TO_STRING_METHOD: &str = "to_string";
42pub struct VM {
43    pub(super) functions: Vec<Function>,
44    pub(super) natives: HashMap<String, Value>,
45    pub(super) globals: HashMap<String, Value>,
46    pub(super) call_stack: Vec<CallFrame>,
47    pub(super) max_stack_depth: usize,
48    pub(super) pending_return_value: Option<Value>,
49    pub(super) pending_return_dest: Option<Register>,
50    pub(super) jit: JitState,
51    pub(super) trace_recorder: Option<TraceRecorder>,
52    pub(super) side_trace_context: Option<(crate::jit::TraceId, usize)>,
53    pub(super) skip_next_trace_record: bool,
54    pub(super) trait_impls: HashMap<(String, String), bool>,
55    pub(super) struct_tostring_cache: HashMap<usize, Rc<String>>,
56    pub(super) struct_metadata: HashMap<String, RuntimeStructInfo>,
57    pub(super) call_until_depth: Option<usize>,
58    pub(super) task_manager: TaskManager,
59    pub(super) current_task: Option<TaskId>,
60    pub(super) pending_task_signal: Option<TaskSignal>,
61    pub(super) last_task_signal: Option<TaskSignal>,
62    pub(super) cycle_collector: cycle::CycleCollector,
63    pub(super) exported_natives: Vec<NativeExport>,
64    pub(super) export_prefix_stack: Vec<String>,
65}
66
67#[derive(Debug, Clone)]
68pub(super) struct CallFrame {
69    pub(super) function_idx: usize,
70    pub(super) ip: usize,
71    pub(super) registers: [Value; 256],
72    #[allow(dead_code)]
73    pub(super) base_register: usize,
74    pub(super) return_dest: Option<Register>,
75    pub(super) upvalues: Vec<Value>,
76}
77
78#[derive(Debug, Clone)]
79pub(super) struct RuntimeStructInfo {
80    pub layout: Rc<StructLayout>,
81}
82
83#[derive(Debug, Clone)]
84pub(super) enum TaskSignal {
85    Yield { dest: Register, value: Value },
86    Stop { value: Value },
87}
88
89impl Default for VM {
90    fn default() -> Self {
91        Self::new()
92    }
93}