diff options
Diffstat (limited to 'core/isolate.rs')
-rw-r--r-- | core/isolate.rs | 108 |
1 files changed, 64 insertions, 44 deletions
diff --git a/core/isolate.rs b/core/isolate.rs index 43fa4854a..74b8a7270 100644 --- a/core/isolate.rs +++ b/core/isolate.rs @@ -43,7 +43,7 @@ impl Future for PendingOp { } /// Stores a script used to initalize a Isolate -pub struct StartupScript { +pub struct Script { pub source: String, pub filename: String, } @@ -52,7 +52,7 @@ pub struct StartupScript { /// either a binary snapshot or a javascript source file /// in the form of the StartupScript struct. pub enum StartupData { - Script(StartupScript), + Script(Script), Snapshot(deno_buf), } @@ -63,9 +63,6 @@ pub trait Behavior { /// Isolate is created. fn startup_data(&mut self) -> Option<StartupData>; - /// Called during mod_instantiate() to resolve imports. - fn resolve(&mut self, specifier: &str, referrer: deno_mod) -> deno_mod; - /// Called whenever libdeno.send() is called in JavaScript. zero_copy_buf /// corresponds to the second argument of libdeno.send(). fn dispatch( @@ -329,27 +326,46 @@ impl<B: Behavior> Isolate<B> { } out } +} + +/// Called during mod_instantiate() to resolve imports. +type ResolveFn = dyn FnMut(&str, deno_mod) -> deno_mod; + +/// Used internally by Isolate::mod_instantiate to wrap ResolveFn and +/// encapsulate pointer casts. +struct ResolveContext<'a> { + resolve_fn: &'a mut ResolveFn, +} + +impl<'a> ResolveContext<'a> { + #[inline] + fn as_raw_ptr(&mut self) -> *mut c_void { + self as *mut _ as *mut c_void + } + + #[inline] + unsafe fn from_raw_ptr(ptr: *mut c_void) -> &'a mut Self { + &mut *(ptr as *mut _) + } +} - pub fn mod_instantiate(&self, id: deno_mod) -> Result<(), JSError> { +impl<B: Behavior> Isolate<B> { + pub fn mod_instantiate( + &mut self, + id: deno_mod, + resolve_fn: &mut ResolveFn, + ) -> Result<(), JSError> { + let libdeno_isolate = self.libdeno_isolate; + let mut ctx = ResolveContext { resolve_fn }; unsafe { libdeno::deno_mod_instantiate( - self.libdeno_isolate, - self.as_raw_ptr(), + libdeno_isolate, + ctx.as_raw_ptr(), id, Self::resolve_cb, ) }; - if let Some(js_error) = self.last_exception() { - return Err(js_error); - } - Ok(()) - } - pub fn mod_evaluate(&mut self, id: deno_mod) -> Result<(), JSError> { - self.shared_init(); - unsafe { - libdeno::deno_mod_evaluate(self.libdeno_isolate, self.as_raw_ptr(), id) - }; if let Some(js_error) = self.last_exception() { return Err(js_error); } @@ -362,10 +378,23 @@ impl<B: Behavior> Isolate<B> { specifier_ptr: *const libc::c_char, referrer: deno_mod, ) -> deno_mod { - let isolate = unsafe { Isolate::<B>::from_raw_ptr(user_data) }; + let ResolveContext { resolve_fn } = + unsafe { ResolveContext::from_raw_ptr(user_data) }; let specifier_c: &CStr = unsafe { CStr::from_ptr(specifier_ptr) }; let specifier: &str = specifier_c.to_str().unwrap(); - isolate.behavior.resolve(specifier, referrer) + + resolve_fn(specifier, referrer) + } + + pub fn mod_evaluate(&mut self, id: deno_mod) -> Result<(), JSError> { + self.shared_init(); + unsafe { + libdeno::deno_mod_evaluate(self.libdeno_isolate, self.as_raw_ptr(), id) + }; + if let Some(js_error) = self.last_exception() { + return Err(js_error); + } + Ok(()) } } @@ -498,7 +527,7 @@ pub fn js_check(r: Result<(), JSError>) { #[cfg(test)] mod tests { use super::*; - use std::collections::HashMap; + use std::sync::atomic::{AtomicUsize, Ordering}; pub enum TestBehaviorMode { AsyncImmediate, @@ -510,8 +539,6 @@ mod tests { pub struct TestBehavior { pub dispatch_count: usize, - pub resolve_count: usize, - pub mod_map: HashMap<String, deno_mod>, mode: TestBehaviorMode, } @@ -519,9 +546,7 @@ mod tests { pub fn setup(mode: TestBehaviorMode) -> Isolate<Self> { let mut isolate = Isolate::new(TestBehavior { dispatch_count: 0, - resolve_count: 0, mode, - mod_map: HashMap::new(), }); js_check(isolate.execute( "setup.js", @@ -536,10 +561,6 @@ mod tests { assert_eq!(isolate.behavior.dispatch_count, 0); isolate } - - pub fn register(&mut self, name: &str, id: deno_mod) { - self.mod_map.insert(name.to_string(), id); - } } impl Behavior for TestBehavior { @@ -547,14 +568,6 @@ mod tests { None } - fn resolve(&mut self, specifier: &str, _referrer: deno_mod) -> deno_mod { - self.resolve_count += 1; - match self.mod_map.get(specifier) { - Some(id) => *id, - None => 0, - } - } - fn dispatch( &mut self, control: &[u8], @@ -632,7 +645,6 @@ mod tests { "#, ).unwrap(); assert_eq!(isolate.behavior.dispatch_count, 0); - assert_eq!(isolate.behavior.resolve_count, 0); let imports = isolate.mod_get_imports(mod_a); assert_eq!(imports, vec!["b.js".to_string()]); @@ -643,18 +655,26 @@ mod tests { let imports = isolate.mod_get_imports(mod_b); assert_eq!(imports.len(), 0); - js_check(isolate.mod_instantiate(mod_b)); + let resolve_count = Arc::new(AtomicUsize::new(0)); + let resolve_count_ = resolve_count.clone(); + + let mut resolve = move |specifier: &str, _referrer: deno_mod| -> deno_mod { + resolve_count_.fetch_add(1, Ordering::SeqCst); + assert_eq!(specifier, "b.js"); + mod_b + }; + + js_check(isolate.mod_instantiate(mod_b, &mut resolve)); assert_eq!(isolate.behavior.dispatch_count, 0); - assert_eq!(isolate.behavior.resolve_count, 0); + assert_eq!(resolve_count.load(Ordering::SeqCst), 0); - isolate.behavior.register("b.js", mod_b); - js_check(isolate.mod_instantiate(mod_a)); + js_check(isolate.mod_instantiate(mod_a, &mut resolve)); assert_eq!(isolate.behavior.dispatch_count, 0); - assert_eq!(isolate.behavior.resolve_count, 1); + assert_eq!(resolve_count.load(Ordering::SeqCst), 1); js_check(isolate.mod_evaluate(mod_a)); assert_eq!(isolate.behavior.dispatch_count, 1); - assert_eq!(isolate.behavior.resolve_count, 1); + assert_eq!(resolve_count.load(Ordering::SeqCst), 1); } #[test] |