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 pub(crate) permission_set: Option<shape_abi_v1::PermissionSet>,
39 pub allow_internal_builtins: bool,
42}
43
44impl Default for BytecodeExecutor {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50impl BytecodeExecutor {
51 pub fn extensions(&self) -> &[shape_runtime::module_exports::ModuleExports] {
53 &self.extensions
54 }
55
56 pub fn new() -> Self {
58 let mut executor = Self {
59 extensions: Vec::new(),
60 virtual_modules: HashMap::new(),
61 compiled_module_paths: HashSet::new(),
62 interrupt: Arc::new(AtomicU8::new(0)),
63 bytecode_cache: None,
64 dependency_paths: HashMap::new(),
65 native_resolution_context: None,
66 root_package_key: None,
67 module_loader: None,
68 permission_set: None,
69 allow_internal_builtins: false,
70 };
71 executor.register_stdlib_modules();
72
73 let mut loader = shape_runtime::module_loader::ModuleLoader::new();
76 executor.register_extension_artifacts_in_loader(&mut loader);
77 executor.module_loader = Some(loader);
78
79 executor
80 }
81
82 fn register_stdlib_modules(&mut self) {
85 self.extensions
87 .extend(shape_runtime::stdlib::all_stdlib_modules());
88 self.extensions
90 .push(crate::executor::state_builtins::create_state_module());
91 self.extensions
92 .push(crate::executor::create_transport_module_exports());
93 self.extensions
94 .push(crate::executor::create_remote_module_exports());
95 }
96
97 pub fn register_extension(&mut self, module: shape_runtime::module_exports::ModuleExports) {
101 let module_name = module.name.clone();
105 for artifact in &module.module_artifacts {
106 let Some(source) = artifact.source.as_ref() else {
107 continue;
108 };
109 let module_path = artifact.module_path.clone();
110 self.virtual_modules
111 .entry(module_path)
112 .or_insert_with(|| source.clone());
113 }
114
115 for (_filename, source) in &module.shape_sources {
118 self.virtual_modules
119 .entry(module_name.clone())
120 .or_insert_with(|| source.clone());
121 }
122 self.extensions.push(module);
123 }
124
125 pub fn module_schemas(&self) -> Vec<shape_runtime::extensions::ParsedModuleSchema> {
127 self.extensions
128 .iter()
129 .map(|module| {
130 let mut functions = Vec::with_capacity(module.schemas.len());
131 for (name, schema) in &module.schemas {
132 if !module.is_export_public_surface(name, false) {
133 continue;
134 }
135 functions.push(shape_runtime::extensions::ParsedModuleFunction {
136 name: name.clone(),
137 description: schema.description.clone(),
138 params: schema.params.iter().map(|p| p.type_name.clone()).collect(),
139 return_type: schema.return_type.clone(),
140 });
141 }
142 let artifacts = module
143 .module_artifacts
144 .iter()
145 .map(|artifact| shape_runtime::extensions::ParsedModuleArtifact {
146 module_path: artifact.module_path.clone(),
147 source: artifact.source.clone(),
148 compiled: artifact.compiled.clone(),
149 })
150 .collect();
151 shape_runtime::extensions::ParsedModuleSchema {
152 module_name: module.name.clone(),
153 functions,
154 artifacts,
155 }
156 })
157 .collect()
158 }
159
160 pub fn enable_bytecode_cache(&mut self) -> bool {
164 match crate::bytecode_cache::BytecodeCache::new() {
165 Some(cache) => {
166 self.bytecode_cache = Some(cache);
167 true
168 }
169 None => false,
170 }
171 }
172
173 pub fn set_interrupt(&mut self, flag: Arc<AtomicU8>) {
175 self.interrupt = flag;
176 }
177
178 pub fn set_dependency_paths(&mut self, paths: HashMap<String, std::path::PathBuf>) {
183 self.dependency_paths = paths.clone();
184 if let Some(loader) = self.module_loader.as_mut() {
185 loader.set_dependency_paths(paths);
186 }
187 }
188
189 pub fn set_native_resolution_context(
191 &mut self,
192 resolutions: shape_runtime::native_resolution::NativeResolutionSet,
193 root_package_key: Option<String>,
194 ) {
195 self.native_resolution_context = Some(resolutions);
196 self.root_package_key = root_package_key;
197 }
198
199 pub fn clear_native_resolution_context(&mut self) {
201 self.native_resolution_context = None;
202 self.root_package_key = None;
203 }
204
205 pub fn set_permission_set(&mut self, permissions: Option<shape_abi_v1::PermissionSet>) {
210 self.permission_set = permissions;
211 }
212}
213
214#[cfg(test)]
215mod tests {
216 use super::*;
217
218 #[test]
219 fn test_new_executor_has_module_loader() {
220 let executor = BytecodeExecutor::new();
221 assert!(
222 executor.module_loader.is_some(),
223 "new() should initialize module_loader"
224 );
225 }
226}