Skip to main content

runmat_vm/bytecode/
program.rs

1use crate::bytecode::instr::Instr;
2#[cfg(feature = "native-accel")]
3use runmat_accelerate::graph::AccelGraph;
4#[cfg(feature = "native-accel")]
5use runmat_accelerate::FusionGroup;
6use runmat_builtins::{Type, Value};
7use runmat_hir::{HirStmt, VarId};
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct UserFunction {
13    pub name: String,
14    pub params: Vec<VarId>,
15    pub outputs: Vec<VarId>,
16    pub body: Vec<HirStmt>,
17    pub local_var_count: usize,
18    pub has_varargin: bool,
19    pub has_varargout: bool,
20    #[serde(default)]
21    pub var_types: Vec<Type>,
22    #[serde(default)]
23    pub source_id: Option<runmat_hir::SourceId>,
24}
25
26#[derive(Debug, Clone)]
27pub struct CallFrame {
28    pub function_name: String,
29    pub return_address: usize,
30    pub locals_start: usize,
31    pub locals_count: usize,
32    pub expected_outputs: usize,
33}
34
35#[derive(Debug)]
36pub struct ExecutionContext {
37    pub call_stack: Vec<CallFrame>,
38    pub locals: Vec<Value>,
39    pub instruction_pointer: usize,
40    pub functions: std::collections::HashMap<String, UserFunction>,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct Bytecode {
45    pub instructions: Vec<Instr>,
46    #[serde(default)]
47    pub instr_spans: Vec<runmat_hir::Span>,
48    #[serde(default)]
49    pub call_arg_spans: Vec<Option<Vec<runmat_hir::Span>>>,
50    #[serde(default)]
51    pub source_id: Option<runmat_hir::SourceId>,
52    pub var_count: usize,
53    pub functions: HashMap<String, UserFunction>,
54    #[serde(default)]
55    pub var_types: Vec<Type>,
56    #[serde(default)]
57    pub var_names: HashMap<usize, String>,
58    #[cfg(feature = "native-accel")]
59    #[serde(default)]
60    pub accel_graph: Option<AccelGraph>,
61    #[cfg(feature = "native-accel")]
62    #[serde(default)]
63    pub fusion_groups: Vec<FusionGroup>,
64}
65
66impl Bytecode {
67    pub fn empty() -> Self {
68        Self {
69            instructions: Vec::new(),
70            instr_spans: Vec::new(),
71            call_arg_spans: Vec::new(),
72            source_id: None,
73            var_count: 0,
74            functions: HashMap::new(),
75            var_types: Vec::new(),
76            var_names: HashMap::new(),
77            #[cfg(feature = "native-accel")]
78            accel_graph: None,
79            #[cfg(feature = "native-accel")]
80            fusion_groups: Vec::new(),
81        }
82    }
83
84    pub fn with_instructions(instructions: Vec<Instr>, var_count: usize) -> Self {
85        let instr_spans = vec![runmat_hir::Span::default(); instructions.len()];
86        let call_arg_spans = vec![None; instructions.len()];
87        Self {
88            instructions,
89            instr_spans,
90            call_arg_spans,
91            var_count,
92            ..Self::empty()
93        }
94    }
95}