zen_vm/
isolate.rs

1use std::cell::{RefCell, UnsafeCell};
2use std::collections::HashMap;
3use std::hash::BuildHasherDefault;
4use std::mem::ManuallyDrop;
5use std::ops::DerefMut;
6use std::rc::Rc;
7
8use ahash::AHasher;
9use bumpalo::Bump;
10use serde_json::Value;
11use thiserror::Error;
12
13use zen_parser::lexer::error::LexerError;
14use zen_parser::lexer::Lexer;
15use zen_parser::parser::error::ParserError;
16use zen_parser::parser::{StandardParser, UnaryParser};
17
18use crate::compiler::{Compiler, CompilerError};
19use crate::opcodes::{ExecResult, Opcode, Variable};
20use crate::vm::{Scope, VMError, VM};
21
22type ADefHasher = BuildHasherDefault<AHasher>;
23
24#[derive(Debug, Error)]
25pub enum IsolateError {
26    #[error("Lexer error")]
27    LexerError { source: LexerError },
28
29    #[error("Parser error")]
30    ParserError { source: ParserError },
31
32    #[error("Compiler error")]
33    CompilerError { source: CompilerError },
34
35    #[error("VM error")]
36    VMError { source: VMError },
37
38    #[error("Value cast error")]
39    ValueCastError,
40
41    #[error("Failed to compute reference")]
42    ReferenceError,
43}
44
45#[derive(Debug)]
46pub struct Isolate<'a> {
47    lexer: Lexer<'a>,
48    bump: RefCell<Bump>,
49    reference_bump: Bump,
50    bytecode: Rc<UnsafeCell<Vec<&'a Opcode<'a>>>>,
51    stack: UnsafeCell<Vec<&'a Variable<'a>>>,
52    scopes: UnsafeCell<Vec<Scope<'a>>>,
53    environment: UnsafeCell<ManuallyDrop<Variable<'a>>>,
54    references: RefCell<HashMap<&'a str, &'a Variable<'a>, ADefHasher>>,
55}
56
57impl<'a> Default for Isolate<'a> {
58    fn default() -> Self {
59        Self {
60            lexer: Lexer::new(),
61            bump: Default::default(),
62            reference_bump: Default::default(),
63            bytecode: Default::default(),
64            stack: Default::default(),
65            scopes: Default::default(),
66            environment: UnsafeCell::new(ManuallyDrop::new(Variable::Null)),
67            references: Default::default(),
68        }
69    }
70}
71
72impl<'a> Isolate<'a> {
73    pub fn inject_env(&self, value: &Value) {
74        let new_env = Variable::from_serde(value, self.get_reference_bump());
75        let env = unsafe { &mut (*self.environment.get()) };
76        *env = ManuallyDrop::new(new_env);
77    }
78
79    pub fn run(&self, source: &'a str) -> Result<ExecResult, IsolateError> {
80        if self.contains_ref(source) {
81            self.run_standard(source)
82        } else {
83            self.run_unary(source)
84        }
85    }
86
87    fn get_bump(&self) -> &'a Bump {
88        unsafe { std::mem::transmute::<&Bump, &'a Bump>(&self.bump.borrow()) }
89    }
90
91    fn get_reference_bump(&self) -> &'a Bump {
92        unsafe { std::mem::transmute(&self.reference_bump) }
93    }
94
95    pub fn set_reference(&self, reference: &'a str) -> Result<(), IsolateError> {
96        let mut references = self.references.borrow_mut();
97        let bump = self.get_reference_bump();
98
99        if !references.contains_key(reference) {
100            let result = self.run_standard(reference)?;
101            let value = result
102                .to_variable(bump)
103                .map_err(|_| IsolateError::ValueCastError)?;
104
105            references.insert(reference, value);
106        }
107
108        let value = references
109            .get(reference)
110            .ok_or(IsolateError::ReferenceError)?;
111
112        let env_w = unsafe { &mut (*self.environment.get()) };
113        let env = env_w.deref_mut();
114        match env {
115            Variable::Object(..) => {
116                //
117            }
118            _ => {
119                *env = Variable::empty_object_in(bump);
120            }
121        }
122
123        if let Variable::Object(obj) = env {
124            obj.insert("$", value);
125        }
126
127        Ok(())
128    }
129
130    pub fn run_standard(&self, source: &'a str) -> Result<ExecResult, IsolateError> {
131        self.clear();
132
133        let tokens = self
134            .lexer
135            .tokenize(source)
136            .map_err(|source| IsolateError::LexerError { source })?;
137
138        let tkn = tokens.borrow();
139        let bump = self.get_bump();
140
141        let parser = StandardParser::try_new(tkn.as_ref(), bump)
142            .map_err(|source| IsolateError::ParserError { source })?;
143
144        let ast = parser
145            .parse()
146            .map_err(|source| IsolateError::ParserError { source })?;
147
148        let compiler = Compiler::new(ast, self.bytecode.clone(), bump);
149        compiler
150            .compile()
151            .map_err(|source| IsolateError::CompilerError { source })?;
152
153        let mut vm = unsafe {
154            VM::new(
155                &*self.bytecode.get(),
156                &mut *self.stack.get(),
157                &mut *self.scopes.get(),
158                bump,
159            )
160        };
161
162        let res = vm
163            .run(unsafe { &*self.environment.get() })
164            .map_err(|source| IsolateError::VMError { source })?;
165
166        ExecResult::try_from(res).map_err(|_| IsolateError::ValueCastError)
167    }
168
169    pub fn run_unary(&self, source: &'a str) -> Result<ExecResult, IsolateError> {
170        self.clear();
171
172        let tokens = self
173            .lexer
174            .tokenize(source)
175            .map_err(|source| IsolateError::LexerError { source })?;
176
177        let tkn = tokens.borrow();
178        let bump = self.get_bump();
179
180        let parser = UnaryParser::try_new(tkn.as_ref(), bump)
181            .map_err(|source| IsolateError::ParserError { source })?;
182
183        let ast = parser
184            .parse()
185            .map_err(|source| IsolateError::ParserError { source })?;
186
187        let compiler = Compiler::new(ast, self.bytecode.clone(), bump);
188        compiler
189            .compile()
190            .map_err(|source| IsolateError::CompilerError { source })?;
191
192        let mut vm = unsafe {
193            VM::new(
194                &*self.bytecode.get(),
195                &mut *self.stack.get(),
196                &mut *self.scopes.get(),
197                bump,
198            )
199        };
200
201        let res = vm
202            .run(unsafe { &*self.environment.get() })
203            .map_err(|source| IsolateError::VMError { source })?;
204
205        ExecResult::try_from(res).map_err(|_| IsolateError::ValueCastError)
206    }
207
208    fn clear(&self) {
209        self.bump.borrow_mut().reset();
210        unsafe {
211            (*self.bytecode.get()).clear();
212            (*self.stack.get()).clear();
213            (*self.scopes.get()).clear();
214        }
215    }
216
217    fn contains_ref(&self, source: &str) -> bool {
218        source.chars().any(|c| c == '$')
219    }
220}