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}