summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/examples/disable_ops.rs2
-rw-r--r--core/examples/hello_world.rs2
-rw-r--r--core/examples/http_bench_json_ops.rs2
-rw-r--r--core/examples/panik.rs5
-rw-r--r--core/examples/schedule_task.rs2
-rw-r--r--core/examples/wasm.rs2
-rw-r--r--core/extensions.rs40
-rw-r--r--core/modules.rs4
-rw-r--r--core/ops_builtin.rs2
-rw-r--r--core/runtime.rs61
10 files changed, 89 insertions, 33 deletions
diff --git a/core/examples/disable_ops.rs b/core/examples/disable_ops.rs
index a99568589..b9a5e7fca 100644
--- a/core/examples/disable_ops.rs
+++ b/core/examples/disable_ops.rs
@@ -7,7 +7,7 @@ use deno_core::JsRuntime;
use deno_core::RuntimeOptions;
fn main() {
- let my_ext = Extension::builder()
+ let my_ext = Extension::builder("my_ext")
.middleware(|op| match op.name {
"op_print" => op.disable(),
_ => op,
diff --git a/core/examples/hello_world.rs b/core/examples/hello_world.rs
index a1edbead0..50cbe4e2c 100644
--- a/core/examples/hello_world.rs
+++ b/core/examples/hello_world.rs
@@ -22,7 +22,7 @@ fn op_sum(nums: Vec<f64>) -> Result<f64, deno_core::error::AnyError> {
fn main() {
// Build a deno_core::Extension providing custom ops
- let ext = Extension::builder()
+ let ext = Extension::builder("my_ext")
.ops(vec![
// An op for summing an array of numbers
// The op-layer automatically deserializes inputs
diff --git a/core/examples/http_bench_json_ops.rs b/core/examples/http_bench_json_ops.rs
index 23945c632..9a55a0823 100644
--- a/core/examples/http_bench_json_ops.rs
+++ b/core/examples/http_bench_json_ops.rs
@@ -117,7 +117,7 @@ impl From<tokio::net::TcpStream> for TcpStream {
}
fn create_js_runtime() -> JsRuntime {
- let ext = deno_core::Extension::builder()
+ let ext = deno_core::Extension::builder("my_ext")
.ops(vec![op_listen::decl(), op_accept::decl()])
.build();
diff --git a/core/examples/panik.rs b/core/examples/panik.rs
index 76be108ec..1d2286a88 100644
--- a/core/examples/panik.rs
+++ b/core/examples/panik.rs
@@ -24,8 +24,9 @@ fn main() {
panic!("panik !!!")
}
- let extensions =
- vec![Extension::builder().ops(vec![op_panik::decl()]).build()];
+ let extensions = vec![Extension::builder("my_ext")
+ .ops(vec![op_panik::decl()])
+ .build()];
let mut rt = JsRuntime::new(RuntimeOptions {
extensions,
..Default::default()
diff --git a/core/examples/schedule_task.rs b/core/examples/schedule_task.rs
index ba0f3ef0f..6a61619d8 100644
--- a/core/examples/schedule_task.rs
+++ b/core/examples/schedule_task.rs
@@ -18,7 +18,7 @@ use deno_core::*;
type Task = Box<dyn FnOnce()>;
fn main() {
- let my_ext = Extension::builder()
+ let my_ext = Extension::builder("my_ext")
.ops(vec![op_schedule_task::decl()])
.event_loop_middleware(|state_rc, cx| {
let mut state = state_rc.borrow_mut();
diff --git a/core/examples/wasm.rs b/core/examples/wasm.rs
index c4bb8b9ad..7c2d98bc9 100644
--- a/core/examples/wasm.rs
+++ b/core/examples/wasm.rs
@@ -51,7 +51,7 @@ fn op_set_wasm_mem(
fn main() {
// Build a deno_core::Extension providing custom ops
- let ext = Extension::builder()
+ let ext = Extension::builder("my_ext")
.ops(vec![op_wasm::decl(), op_set_wasm_mem::decl()])
.build();
diff --git a/core/extensions.rs b/core/extensions.rs
index 6fca570df..437621c0e 100644
--- a/core/extensions.rs
+++ b/core/extensions.rs
@@ -42,13 +42,39 @@ pub struct Extension {
event_loop_middleware: Option<Box<OpEventLoopFn>>,
initialized: bool,
enabled: bool,
+ name: &'static str,
+ deps: Option<Vec<&'static str>>,
}
// Note: this used to be a trait, but we "downgraded" it to a single concrete type
// for the initial iteration, it will likely become a trait in the future
impl Extension {
- pub fn builder() -> ExtensionBuilder {
- Default::default()
+ pub fn builder(name: &'static str) -> ExtensionBuilder {
+ ExtensionBuilder {
+ name,
+ ..Default::default()
+ }
+ }
+
+ /// Check if dependencies have been loaded, and errors if either:
+ /// - The extension is depending on itself or an extension with the same name.
+ /// - A dependency hasn't been loaded yet.
+ pub fn check_dependencies(&self, previous_exts: &[&mut Extension]) {
+ if let Some(deps) = &self.deps {
+ 'dep_loop: for dep in deps {
+ if dep == &self.name {
+ panic!("Extension '{}' is either depending on itself or there is another extension with the same name", self.name);
+ }
+
+ for ext in previous_exts {
+ if dep == &ext.name {
+ continue 'dep_loop;
+ }
+ }
+
+ panic!("Extension '{}' is missing dependency '{dep}'", self.name);
+ }
+ }
}
/// returns JS source code to be loaded into the isolate (either at snapshotting,
@@ -121,9 +147,16 @@ pub struct ExtensionBuilder {
state: Option<Box<OpStateFn>>,
middleware: Option<Box<OpMiddlewareFn>>,
event_loop_middleware: Option<Box<OpEventLoopFn>>,
+ name: &'static str,
+ deps: Vec<&'static str>,
}
impl ExtensionBuilder {
+ pub fn dependencies(&mut self, dependencies: Vec<&'static str>) -> &mut Self {
+ self.deps.extend(dependencies);
+ self
+ }
+
pub fn js(&mut self, js_files: Vec<SourcePair>) -> &mut Self {
self.js.extend(js_files);
self
@@ -161,6 +194,7 @@ impl ExtensionBuilder {
pub fn build(&mut self) -> Extension {
let js_files = Some(std::mem::take(&mut self.js));
let ops = Some(std::mem::take(&mut self.ops));
+ let deps = Some(std::mem::take(&mut self.deps));
Extension {
js_files,
ops,
@@ -169,6 +203,8 @@ impl ExtensionBuilder {
event_loop_middleware: self.event_loop_middleware.take(),
initialized: false,
enabled: true,
+ name: self.name,
+ deps,
}
}
}
diff --git a/core/modules.rs b/core/modules.rs
index ff253db61..8abced200 100644
--- a/core/modules.rs
+++ b/core/modules.rs
@@ -1479,7 +1479,9 @@ import "/a.js";
43
}
- let ext = Extension::builder().ops(vec![op_test::decl()]).build();
+ let ext = Extension::builder("test_ext")
+ .ops(vec![op_test::decl()])
+ .build();
let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext],
diff --git a/core/ops_builtin.rs b/core/ops_builtin.rs
index 6889c5dbc..905496025 100644
--- a/core/ops_builtin.rs
+++ b/core/ops_builtin.rs
@@ -17,7 +17,7 @@ use std::io::{stderr, stdout, Write};
use std::rc::Rc;
pub(crate) fn init_builtins() -> Extension {
- Extension::builder()
+ Extension::builder("deno_builtins")
.js(include_js_files!(
prefix "deno:core",
"00_primordials.js",
diff --git a/core/runtime.rs b/core/runtime.rs
index 4a1302b3f..baa7de1a1 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -728,10 +728,9 @@ impl JsRuntime {
/// Initializes JS of provided Extensions in the given realm
fn init_extension_js(&mut self, realm: &JsRealm) -> Result<(), Error> {
// Take extensions to avoid double-borrow
- let mut extensions: Vec<Extension> =
- std::mem::take(&mut self.extensions_with_js);
- for m in extensions.iter_mut() {
- let js_files = m.init_js();
+ let extensions = std::mem::take(&mut self.extensions_with_js);
+ for ext in &extensions {
+ let js_files = ext.init_js();
for (filename, source) in js_files {
// TODO(@AaronO): use JsRuntime::execute_static() here to move src off heap
realm.execute_script(self.v8_isolate(), filename, source)?;
@@ -752,6 +751,12 @@ impl JsRuntime {
exts.extend(extensions);
exts.extend(extensions_with_js);
+ for (ext, previous_exts) in
+ exts.iter().enumerate().map(|(i, ext)| (ext, &exts[..i]))
+ {
+ ext.check_dependencies(previous_exts);
+ }
+
// Middleware
let middleware: Vec<Box<OpMiddlewareFn>> = exts
.iter_mut()
@@ -2554,7 +2559,7 @@ pub mod tests {
fn setup(mode: Mode) -> (JsRuntime, Arc<AtomicUsize>) {
let dispatch_count = Arc::new(AtomicUsize::new(0));
let dispatch_count2 = dispatch_count.clone();
- let ext = Extension::builder()
+ let ext = Extension::builder("test_ext")
.ops(vec![op_test::decl()])
.state(move |state| {
state.put(TestState {
@@ -2976,7 +2981,9 @@ pub mod tests {
}
run_in_task(|cx| {
- let ext = Extension::builder().ops(vec![op_err::decl()]).build();
+ let ext = Extension::builder("test_ext")
+ .ops(vec![op_err::decl()])
+ .build();
let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext],
get_error_class_fn: Some(&get_error_class_name),
@@ -3428,7 +3435,7 @@ main();
}
run_in_task(|cx| {
- let ext = Extension::builder()
+ let ext = Extension::builder("test_ext")
.ops(vec![op_err_sync::decl(), op_err_async::decl()])
.build();
let mut runtime = JsRuntime::new(RuntimeOptions {
@@ -3596,7 +3603,7 @@ assertEquals(1, notify_return_value);
Ok(())
}
- let extension = Extension::builder()
+ let extension = Extension::builder("test_ext")
.ops(vec![op_async_borrow::decl()])
.state(|state| {
state.put(InnerState(42));
@@ -3631,7 +3638,7 @@ assertEquals(1, notify_return_value);
Ok(())
}
- let extension = Extension::builder()
+ let extension = Extension::builder("test_ext")
.ops(vec![op_sync_serialize_object_with_numbers_as_keys::decl()])
.build();
@@ -3673,7 +3680,7 @@ Deno.core.ops.op_sync_serialize_object_with_numbers_as_keys({
Ok(())
}
- let extension = Extension::builder()
+ let extension = Extension::builder("test_ext")
.ops(vec![op_async_serialize_object_with_numbers_as_keys::decl()])
.build();
@@ -3712,7 +3719,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
Ok(())
}
- let extension = Extension::builder()
+ let extension = Extension::builder("test_ext")
.ops(vec![op_async_sleep::decl()])
.build();
@@ -3792,7 +3799,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
Ok(())
}
- let extension = Extension::builder()
+ let extension = Extension::builder("test_ext")
.ops(vec![op_macrotask::decl(), op_next_tick::decl()])
.build();
@@ -3922,7 +3929,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
Ok(())
}
- let extension = Extension::builder()
+ let extension = Extension::builder("test_ext")
.ops(vec![op_promise_reject::decl()])
.build();
@@ -3982,7 +3989,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
Ok(())
}
- let extension = Extension::builder()
+ let extension = Extension::builder("test_ext")
.ops(vec![op_promise_reject::decl()])
.build();
@@ -4051,7 +4058,9 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
Ok([(1, 2), (3, 4)].into_iter().collect()) // Maps can't have non-string keys in serde_v8
}
- let ext = Extension::builder().ops(vec![op_err::decl()]).build();
+ let ext = Extension::builder("test_ext")
+ .ops(vec![op_err::decl()])
+ .build();
let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext],
..Default::default()
@@ -4076,7 +4085,9 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
Ok(x1 + x2 + x3 + x4)
}
- let ext = Extension::builder().ops(vec![op_add_4::decl()]).build();
+ let ext = Extension::builder("test_ext")
+ .ops(vec![op_add_4::decl()])
+ .build();
let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext],
..Default::default()
@@ -4095,7 +4106,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
Ok(42)
}
- let ext = Extension::builder()
+ let ext = Extension::builder("test_ext")
.ops(vec![op_foo::decl().disable()])
.build();
let mut runtime = JsRuntime::new(RuntimeOptions {
@@ -4125,7 +4136,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
Ok(b)
}
- let ext = Extension::builder()
+ let ext = Extension::builder("test_ext")
.ops(vec![op_sum_take::decl(), op_boomerang::decl()])
.build();
@@ -4193,7 +4204,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
Ok(42)
}
- let ext = Extension::builder()
+ let ext = Extension::builder("test_ext")
.ops(vec![op_foo::decl(), op_bar::decl()])
.middleware(|op| if op.is_unstable { op.disable() } else { op })
.build();
@@ -4245,7 +4256,9 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
}
let mut runtime = JsRuntime::new(RuntimeOptions {
- extensions: vec![Extension::builder().ops(vec![op_test::decl()]).build()],
+ extensions: vec![Extension::builder("test_ext")
+ .ops(vec![op_test::decl()])
+ .build()],
..Default::default()
});
let realm = runtime.create_realm().unwrap();
@@ -4275,7 +4288,9 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
let mut runtime = JsRuntime::new(RuntimeOptions {
startup_snapshot: Some(Snapshot::Boxed(snapshot)),
- extensions: vec![Extension::builder().ops(vec![op_test::decl()]).build()],
+ extensions: vec![Extension::builder("test_ext")
+ .ops(vec![op_test::decl()])
+ .build()],
..Default::default()
});
let realm = runtime.create_realm().unwrap();
@@ -4304,7 +4319,9 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
}
let mut runtime = JsRuntime::new(RuntimeOptions {
- extensions: vec![Extension::builder().ops(vec![op_test::decl()]).build()],
+ extensions: vec![Extension::builder("test_ext")
+ .ops(vec![op_test::decl()])
+ .build()],
get_error_class_fn: Some(&|error| {
crate::error::get_custom_error_class(error).unwrap()
}),