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 }
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}