summaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/js/40_plugins.js16
-rw-r--r--runtime/js/90_deno_ns.js1
-rw-r--r--runtime/ops/mod.rs1
-rw-r--r--runtime/ops/plugin.rs86
-rw-r--r--runtime/web_worker.rs1
-rw-r--r--runtime/worker.rs1
6 files changed, 106 insertions, 0 deletions
diff --git a/runtime/js/40_plugins.js b/runtime/js/40_plugins.js
new file mode 100644
index 000000000..0796fd5ce
--- /dev/null
+++ b/runtime/js/40_plugins.js
@@ -0,0 +1,16 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+"use strict";
+
+((window) => {
+ const core = window.Deno.core;
+
+ function openPlugin(filename) {
+ const rid = core.opSync("op_open_plugin", filename);
+ core.syncOpsCache();
+ return rid;
+ }
+
+ window.__bootstrap.plugins = {
+ openPlugin,
+ };
+})(this);
diff --git a/runtime/js/90_deno_ns.js b/runtime/js/90_deno_ns.js
index 89c9ef060..e4d0b00f2 100644
--- a/runtime/js/90_deno_ns.js
+++ b/runtime/js/90_deno_ns.js
@@ -109,6 +109,7 @@
Signal: __bootstrap.signals.Signal,
SignalStream: __bootstrap.signals.SignalStream,
emit: __bootstrap.compilerApi.emit,
+ openPlugin: __bootstrap.plugins.openPlugin,
kill: __bootstrap.process.kill,
setRaw: __bootstrap.tty.setRaw,
consoleSize: __bootstrap.tty.consoleSize,
diff --git a/runtime/ops/mod.rs b/runtime/ops/mod.rs
index 7b0832618..c94020780 100644
--- a/runtime/ops/mod.rs
+++ b/runtime/ops/mod.rs
@@ -5,6 +5,7 @@ pub mod fs_events;
pub mod io;
pub mod os;
pub mod permissions;
+pub mod plugin;
pub mod process;
pub mod runtime;
pub mod signal;
diff --git a/runtime/ops/plugin.rs b/runtime/ops/plugin.rs
new file mode 100644
index 000000000..cc3bf93d5
--- /dev/null
+++ b/runtime/ops/plugin.rs
@@ -0,0 +1,86 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+use crate::permissions::Permissions;
+use deno_core::error::AnyError;
+use deno_core::op_sync;
+use deno_core::Extension;
+use deno_core::OpState;
+use deno_core::Resource;
+use deno_core::ResourceId;
+use dlopen::symbor::Library;
+use log::debug;
+use std::borrow::Cow;
+use std::mem;
+use std::path::PathBuf;
+use std::rc::Rc;
+
+/// A default `init` function for plugins which mimics the way the internal
+/// extensions are initalized. Plugins currently do not support all extension
+/// features and are most likely not going to in the future. Currently only
+/// `init_state` and `init_ops` are supported while `init_middleware` and `init_js`
+/// are not. Currently the `PluginResource` does not support being closed due to
+/// certain risks in unloading the dynamic library without unloading dependent
+/// functions and resources.
+pub type InitFn = fn() -> Extension;
+
+pub fn init() -> Extension {
+ Extension::builder()
+ .ops(vec![("op_open_plugin", op_sync(op_open_plugin))])
+ .build()
+}
+
+pub fn op_open_plugin(
+ state: &mut OpState,
+ filename: String,
+ _: (),
+) -> Result<ResourceId, AnyError> {
+ let filename = PathBuf::from(&filename);
+
+ super::check_unstable(state, "Deno.openPlugin");
+ let permissions = state.borrow_mut::<Permissions>();
+ permissions.plugin.check()?;
+
+ debug!("Loading Plugin: {:#?}", filename);
+ let plugin_lib = Library::open(filename).map(Rc::new)?;
+ let plugin_resource = PluginResource::new(&plugin_lib);
+
+ // Forgets the plugin_lib value to prevent segfaults when the process exits
+ mem::forget(plugin_lib);
+
+ let init = *unsafe { plugin_resource.0.symbol::<InitFn>("init") }?;
+ let rid = state.resource_table.add(plugin_resource);
+ let mut extension = init();
+
+ if !extension.init_js().is_empty() {
+ panic!("Plugins do not support loading js");
+ }
+
+ if extension.init_middleware().is_some() {
+ panic!("Plugins do not support middleware");
+ }
+
+ extension.init_state(state)?;
+ let ops = extension.init_ops().unwrap_or_default();
+ for (name, opfn) in ops {
+ state.op_table.register_op(name, opfn);
+ }
+
+ Ok(rid)
+}
+
+struct PluginResource(Rc<Library>);
+
+impl Resource for PluginResource {
+ fn name(&self) -> Cow<str> {
+ "plugin".into()
+ }
+
+ fn close(self: Rc<Self>) {
+ unimplemented!();
+ }
+}
+
+impl PluginResource {
+ fn new(lib: &Rc<Library>) -> Self {
+ Self(lib.clone())
+ }
+}
diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs
index 1fcd57dc2..57a8142be 100644
--- a/runtime/web_worker.rs
+++ b/runtime/web_worker.rs
@@ -335,6 +335,7 @@ impl WebWorker {
deno_net::init::<Permissions>(options.unstable),
ops::os::init(),
ops::permissions::init(),
+ ops::plugin::init(),
ops::process::init(),
ops::signal::init(),
ops::tty::init(),
diff --git a/runtime/worker.rs b/runtime/worker.rs
index 543eae6f6..91810449d 100644
--- a/runtime/worker.rs
+++ b/runtime/worker.rs
@@ -126,6 +126,7 @@ impl MainWorker {
deno_net::init::<Permissions>(options.unstable),
ops::os::init(),
ops::permissions::init(),
+ ops::plugin::init(),
ops::process::init(),
ops::signal::init(),
ops::tty::init(),