shape_vm/
configuration.rs1use std::collections::{HashMap, HashSet};
7use std::sync::Arc;
8use std::sync::atomic::AtomicU8;
9
10pub struct BytecodeExecutor {
15 pub(crate) extensions: Vec<shape_runtime::module_exports::ModuleExports>,
17 pub(crate) virtual_modules: HashMap<String, String>,
19 pub(crate) compiled_module_paths: HashSet<String>,
21 pub(crate) interrupt: Arc<AtomicU8>,
23 pub(crate) bytecode_cache: Option<crate::bytecode_cache::BytecodeCache>,
25 pub(crate) dependency_paths: HashMap<String, std::path::PathBuf>,
27 pub(crate) native_resolution_context:
29 Option<shape_runtime::native_resolution::NativeResolutionSet>,
30 pub(crate) root_package_key: Option<String>,
32 pub(crate) module_loader: Option<shape_runtime::module_loader::ModuleLoader>,
35}
36
37impl Default for BytecodeExecutor {
38 fn default() -> Self {
39 Self::new()
40 }
41}
42
43impl BytecodeExecutor {
44 pub fn new() -> Self {
46 let mut executor = Self {
47 extensions: Vec::new(),
48 virtual_modules: HashMap::new(),
49 compiled_module_paths: HashSet::new(),
50 interrupt: Arc::new(AtomicU8::new(0)),
51 bytecode_cache: None,
52 dependency_paths: HashMap::new(),
53 native_resolution_context: None,
54 root_package_key: None,
55 module_loader: None,
56 };
57 executor.register_stdlib_modules();
58
59 let mut loader = shape_runtime::module_loader::ModuleLoader::new();
62 executor.register_extension_artifacts_in_loader(&mut loader);
63 executor.module_loader = Some(loader);
64
65 executor
66 }
67
68 fn register_stdlib_modules(&mut self) {
71 self.extensions
72 .push(shape_runtime::stdlib::regex::create_regex_module());
73 self.extensions
74 .push(shape_runtime::stdlib::http::create_http_module());
75 self.extensions
76 .push(shape_runtime::stdlib::crypto::create_crypto_module());
77 self.extensions
78 .push(shape_runtime::stdlib::env::create_env_module());
79 self.extensions
80 .push(shape_runtime::stdlib::json::create_json_module());
81 self.extensions
82 .push(shape_runtime::stdlib::toml_module::create_toml_module());
83 self.extensions
84 .push(shape_runtime::stdlib::yaml::create_yaml_module());
85 self.extensions
86 .push(shape_runtime::stdlib::xml::create_xml_module());
87 self.extensions
88 .push(shape_runtime::stdlib::compress::create_compress_module());
89 self.extensions
90 .push(shape_runtime::stdlib::archive::create_archive_module());
91 self.extensions
92 .push(shape_runtime::stdlib::unicode::create_unicode_module());
93 self.extensions
94 .push(shape_runtime::stdlib::csv_module::create_csv_module());
95 self.extensions
96 .push(shape_runtime::stdlib::msgpack_module::create_msgpack_module());
97 self.extensions
98 .push(shape_runtime::stdlib::set_module::create_set_module());
99 }
100
101 pub fn register_extension(&mut self, module: shape_runtime::module_exports::ModuleExports) {
105 let module_name = module.name.clone();
109 for artifact in &module.module_artifacts {
110 let Some(source) = artifact.source.as_ref() else {
111 continue;
112 };
113 let module_path = artifact.module_path.clone();
114 self.virtual_modules
115 .entry(module_path)
116 .or_insert_with(|| source.clone());
117 }
118
119 let mut registered_primary_path = false;
121 for (filename, source) in &module.shape_sources {
122 let legacy_path = format!("std::loaders::{}", module_name);
124 self.virtual_modules
125 .entry(legacy_path)
126 .or_insert_with(|| source.clone());
127
128 if !registered_primary_path {
130 self.virtual_modules
131 .entry(module_name.clone())
132 .or_insert_with(|| source.clone());
133 registered_primary_path = true;
134 } else if let Some(stem) = std::path::Path::new(filename)
135 .file_stem()
136 .and_then(|s| s.to_str())
137 {
138 let extra_path = format!("{}::{}", module_name, stem);
139 self.virtual_modules
140 .entry(extra_path)
141 .or_insert_with(|| source.clone());
142 }
143 }
144 self.extensions.push(module);
145 }
146
147 pub fn module_schemas(&self) -> Vec<shape_runtime::extensions::ParsedModuleSchema> {
149 self.extensions
150 .iter()
151 .map(|module| {
152 let mut functions = Vec::with_capacity(module.schemas.len());
153 for (name, schema) in &module.schemas {
154 if !module.is_export_public_surface(name, false) {
155 continue;
156 }
157 functions.push(shape_runtime::extensions::ParsedModuleFunction {
158 name: name.clone(),
159 description: schema.description.clone(),
160 params: schema.params.iter().map(|p| p.type_name.clone()).collect(),
161 return_type: schema.return_type.clone(),
162 });
163 }
164 let artifacts = module
165 .module_artifacts
166 .iter()
167 .map(|artifact| shape_runtime::extensions::ParsedModuleArtifact {
168 module_path: artifact.module_path.clone(),
169 source: artifact.source.clone(),
170 compiled: artifact.compiled.clone(),
171 })
172 .collect();
173 shape_runtime::extensions::ParsedModuleSchema {
174 module_name: module.name.clone(),
175 functions,
176 artifacts,
177 }
178 })
179 .collect()
180 }
181
182 pub fn enable_bytecode_cache(&mut self) -> bool {
186 match crate::bytecode_cache::BytecodeCache::new() {
187 Some(cache) => {
188 self.bytecode_cache = Some(cache);
189 true
190 }
191 None => false,
192 }
193 }
194
195 pub fn set_interrupt(&mut self, flag: Arc<AtomicU8>) {
197 self.interrupt = flag;
198 }
199
200 pub fn set_dependency_paths(&mut self, paths: HashMap<String, std::path::PathBuf>) {
205 self.dependency_paths = paths.clone();
206 if let Some(loader) = self.module_loader.as_mut() {
207 loader.set_dependency_paths(paths);
208 }
209 }
210
211 pub fn set_native_resolution_context(
213 &mut self,
214 resolutions: shape_runtime::native_resolution::NativeResolutionSet,
215 root_package_key: Option<String>,
216 ) {
217 self.native_resolution_context = Some(resolutions);
218 self.root_package_key = root_package_key;
219 }
220
221 pub fn clear_native_resolution_context(&mut self) {
223 self.native_resolution_context = None;
224 self.root_package_key = None;
225 }
226}
227
228#[cfg(test)]
229mod tests {
230 use super::*;
231
232 #[test]
233 fn test_new_executor_has_module_loader() {
234 let executor = BytecodeExecutor::new();
235 assert!(
236 executor.module_loader.is_some(),
237 "new() should initialize module_loader"
238 );
239 }
240}