-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revert "Remove unstable native plugins (#10908)"
This reverts commit 7dd4090.
- Loading branch information
Showing
15 changed files
with
487 additions
and
4 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. | ||
|
||
[package] | ||
name = "test_plugin" | ||
version = "0.0.1" | ||
authors = ["the deno authors"] | ||
edition = "2018" | ||
publish = false | ||
|
||
[lib] | ||
crate-type = ["cdylib"] | ||
|
||
[dependencies] | ||
deno_core = { path = "../core" } | ||
futures = "0.3.15" | ||
serde = "1" | ||
|
||
[dev-dependencies] | ||
test_util = { path = "../test_util" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# `test_plugin` crate | ||
|
||
## To run this test manually | ||
|
||
``` | ||
cd test_plugin | ||
../target/debug/deno run --unstable --allow-plugin tests/test.js debug | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. | ||
|
||
use std::borrow::Cow; | ||
use std::cell::RefCell; | ||
use std::rc::Rc; | ||
|
||
use deno_core::error::bad_resource_id; | ||
use deno_core::error::AnyError; | ||
use deno_core::op_async; | ||
use deno_core::op_sync; | ||
use deno_core::Extension; | ||
use deno_core::OpState; | ||
use deno_core::Resource; | ||
use deno_core::ResourceId; | ||
use deno_core::ZeroCopyBuf; | ||
use serde::Deserialize; | ||
|
||
#[no_mangle] | ||
pub fn init() -> Extension { | ||
Extension::builder() | ||
.ops(vec![ | ||
("op_test_sync", op_sync(op_test_sync)), | ||
("op_test_async", op_async(op_test_async)), | ||
( | ||
"op_test_resource_table_add", | ||
op_sync(op_test_resource_table_add), | ||
), | ||
( | ||
"op_test_resource_table_get", | ||
op_sync(op_test_resource_table_get), | ||
), | ||
]) | ||
.build() | ||
} | ||
|
||
#[derive(Debug, Deserialize)] | ||
struct TestArgs { | ||
val: String, | ||
} | ||
|
||
fn op_test_sync( | ||
_state: &mut OpState, | ||
args: TestArgs, | ||
zero_copy: Option<ZeroCopyBuf>, | ||
) -> Result<String, AnyError> { | ||
println!("Hello from sync plugin op."); | ||
|
||
println!("args: {:?}", args); | ||
|
||
if let Some(buf) = zero_copy { | ||
let buf_str = std::str::from_utf8(&buf[..])?; | ||
println!("zero_copy: {}", buf_str); | ||
} | ||
|
||
Ok("test".to_string()) | ||
} | ||
|
||
async fn op_test_async( | ||
_state: Rc<RefCell<OpState>>, | ||
args: TestArgs, | ||
zero_copy: Option<ZeroCopyBuf>, | ||
) -> Result<String, AnyError> { | ||
println!("Hello from async plugin op."); | ||
|
||
println!("args: {:?}", args); | ||
|
||
if let Some(buf) = zero_copy { | ||
let buf_str = std::str::from_utf8(&buf[..])?; | ||
println!("zero_copy: {}", buf_str); | ||
} | ||
|
||
let (tx, rx) = futures::channel::oneshot::channel::<Result<(), ()>>(); | ||
std::thread::spawn(move || { | ||
std::thread::sleep(std::time::Duration::from_secs(1)); | ||
tx.send(Ok(())).unwrap(); | ||
}); | ||
assert!(rx.await.is_ok()); | ||
|
||
Ok("test".to_string()) | ||
} | ||
|
||
struct TestResource(String); | ||
impl Resource for TestResource { | ||
fn name(&self) -> Cow<str> { | ||
"TestResource".into() | ||
} | ||
} | ||
|
||
fn op_test_resource_table_add( | ||
state: &mut OpState, | ||
text: String, | ||
_: (), | ||
) -> Result<u32, AnyError> { | ||
println!("Hello from resource_table.add plugin op."); | ||
|
||
Ok(state.resource_table.add(TestResource(text))) | ||
} | ||
|
||
fn op_test_resource_table_get( | ||
state: &mut OpState, | ||
rid: ResourceId, | ||
_: (), | ||
) -> Result<String, AnyError> { | ||
println!("Hello from resource_table.get plugin op."); | ||
|
||
Ok( | ||
state | ||
.resource_table | ||
.get::<TestResource>(rid) | ||
.ok_or_else(bad_resource_id)? | ||
.0 | ||
.clone(), | ||
) | ||
} |
Oops, something went wrong.