diff options
Diffstat (limited to 'core/runtime.rs')
-rw-r--r-- | core/runtime.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/core/runtime.rs b/core/runtime.rs index 1981df5f3..51b231eb0 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -20,6 +20,8 @@ use crate::modules::NoopModuleLoader; use crate::modules::PrepareLoadFuture; use crate::modules::RecursiveModuleLoad; use crate::ops::*; +use crate::Extension; +use crate::OpMiddlewareFn; use crate::OpPayload; use crate::OpResponse; use crate::OpState; @@ -84,6 +86,7 @@ pub struct JsRuntime { snapshot_creator: Option<v8::SnapshotCreator>, has_snapshotted: bool, allocations: IsolateAllocations, + extensions: Vec<Extension>, } struct DynImportModEvaluate { @@ -189,6 +192,10 @@ pub struct RuntimeOptions { /// executed tries to load modules. pub module_loader: Option<Rc<dyn ModuleLoader>>, + /// JsRuntime extensions, not to be confused with ES modules + /// these are sets of ops and other JS code to be initialized. + pub extensions: Vec<Extension>, + /// V8 snapshot that should be loaded on startup. /// /// Currently can't be used with `will_snapshot`. @@ -303,6 +310,7 @@ impl JsRuntime { snapshot_creator: maybe_snapshot_creator, has_snapshotted: false, allocations: IsolateAllocations::default(), + extensions: options.extensions, }; if !has_startup_snapshot { @@ -357,6 +365,57 @@ impl JsRuntime { .unwrap(); } + /// Initializes JS of provided Extensions + // NOTE: this will probably change when streamlining snapshot flow + pub fn init_extension_js(&mut self) -> Result<(), AnyError> { + // Take extensions to avoid double-borrow + let mut extensions: Vec<Extension> = std::mem::take(&mut self.extensions); + for m in extensions.iter_mut() { + let js_files = m.init_js(); + for (filename, source) in js_files { + // TODO(@AaronO): use JsRuntime::execute_static() here to move src off heap + self.execute(filename, source)?; + } + } + // Restore extensions + self.extensions = extensions; + + Ok(()) + } + + /// Initializes ops of provided Extensions + // NOTE: this will probably change when streamlining snapshot flow + pub fn init_extension_ops(&mut self) -> Result<(), AnyError> { + let op_state = self.op_state(); + // Take extensions to avoid double-borrow + let mut extensions: Vec<Extension> = std::mem::take(&mut self.extensions); + + // Middleware + let middleware: Vec<Box<OpMiddlewareFn>> = extensions + .iter_mut() + .filter_map(|e| e.init_middleware()) + .collect(); + // macroware wraps an opfn in all the middleware + let macroware = + move |name, opfn| middleware.iter().fold(opfn, |opfn, m| m(name, opfn)); + + // Register ops + for e in extensions.iter_mut() { + e.init_state(&mut op_state.borrow_mut())?; + // Register each op after middlewaring it + let mut ops = e.init_ops().unwrap_or_default(); + for (name, opfn) in ops { + self.register_op(name, macroware(name, opfn)); + } + } + // Sync ops cache + self.sync_ops_cache(); + // Restore extensions + self.extensions = extensions; + + Ok(()) + } + /// Grabs a reference to core.js' handleAsyncMsgFromRust fn init_recv_cb(&mut self) { let scope = &mut self.handle_scope(); |