summaryrefslogtreecommitdiff
path: root/core/isolate.rs
diff options
context:
space:
mode:
Diffstat (limited to 'core/isolate.rs')
-rw-r--r--core/isolate.rs108
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]