diff --git a/Cargo.lock b/Cargo.lock index 6daa4b32c5b27a..62879dd4d6a9aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3564,16 +3564,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "test_plugin" -version = "0.0.1" -dependencies = [ - "deno_core", - "futures", - "serde", - "test_util", -] - [[package]] name = "test_util" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index d7025513cc49f3..3de5ef88852236 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,6 @@ members = [ "cli", "core", "runtime", - "test_plugin", "test_util", "extensions/broadcast_channel", "extensions/console", diff --git a/cli/dts/lib.deno.unstable.d.ts b/cli/dts/lib.deno.unstable.d.ts index ac03e695cb1fae..f3897407b384aa 100644 --- a/cli/dts/lib.deno.unstable.d.ts +++ b/cli/dts/lib.deno.unstable.d.ts @@ -129,37 +129,6 @@ declare namespace Deno { speed: number | undefined; } - /** **UNSTABLE**: new API, yet to be vetted. - * - * Open and initialize a plugin. - * - * ```ts - * import { assert } from "https://deno.land/std/testing/asserts.ts"; - * const rid = Deno.openPlugin("./path/to/some/plugin.so"); - * - * // The Deno.core namespace is needed to interact with plugins, but this is - * // internal so we use ts-ignore to skip type checking these calls. - * // @ts-ignore - * const { op_test_sync, op_test_async } = Deno.core.ops(); - * - * assert(op_test_sync); - * assert(op_test_async); - * - * // @ts-ignore - * const result = Deno.core.opSync("op_test_sync"); - * - * // @ts-ignore - * const result = await Deno.core.opAsync("op_test_sync"); - * ``` - * - * Requires `allow-plugin` permission. - * - * The plugin system is not stable and will change in the future, hence the - * lack of docs. For now take a look at the example - * https://github.com/denoland/deno/tree/main/test_plugin - */ - export function openPlugin(filename: string): number; - /** The log category for a diagnostic message. */ export enum DiagnosticCategory { Warning = 0, diff --git a/cli/tests/integration/lsp_tests.rs b/cli/tests/integration/lsp_tests.rs index 81eb64b7a1e164..dcfd787fbf18e2 100644 --- a/cli/tests/integration/lsp_tests.rs +++ b/cli/tests/integration/lsp_tests.rs @@ -470,7 +470,7 @@ fn lsp_hover_unstable_enabled() { "uri": "file:///a/file.ts", "languageId": "typescript", "version": 1, - "text": "console.log(Deno.openPlugin);\n" + "text": "console.log(Deno.ppid);\n" } }), ); @@ -495,9 +495,9 @@ fn lsp_hover_unstable_enabled() { "contents":[ { "language":"typescript", - "value":"function Deno.openPlugin(filename: string): number" + "value":"const Deno.ppid: number" }, - "**UNSTABLE**: new API, yet to be vetted.\n\nOpen and initialize a plugin.\n\n```ts\nimport { assert } from \"https://deno.land/std/testing/asserts.ts\";\nconst rid = Deno.openPlugin(\"./path/to/some/plugin.so\");\n\n// The Deno.core namespace is needed to interact with plugins, but this is\n// internal so we use ts-ignore to skip type checking these calls.\n// @ts-ignore\nconst { op_test_sync, op_test_async } = Deno.core.ops();\n\nassert(op_test_sync);\nassert(op_test_async);\n\n// @ts-ignore\nconst result = Deno.core.opSync(\"op_test_sync\");\n\n// @ts-ignore\nconst result = await Deno.core.opAsync(\"op_test_sync\");\n```\n\nRequires `allow-plugin` permission.\n\nThe plugin system is not stable and will change in the future, hence the\nlack of docs. For now take a look at the example\nhttps://github.com/denoland/deno/tree/main/test_plugin" + "The pid of the current process's parent." ], "range":{ "start":{ @@ -506,7 +506,7 @@ fn lsp_hover_unstable_enabled() { }, "end":{ "line":0, - "character":27 + "character":21 } } })) diff --git a/runtime/js/40_plugins.js b/runtime/js/40_plugins.js deleted file mode 100644 index 0796fd5cee4a9c..00000000000000 --- a/runtime/js/40_plugins.js +++ /dev/null @@ -1,16 +0,0 @@ -// 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 3d17fccf62c5c4..85631cd553e93a 100644 --- a/runtime/js/90_deno_ns.js +++ b/runtime/js/90_deno_ns.js @@ -109,7 +109,6 @@ 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 c9402078021030..7b08326184346d 100644 --- a/runtime/ops/mod.rs +++ b/runtime/ops/mod.rs @@ -5,7 +5,6 @@ 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 deleted file mode 100644 index cc3bf93d5cac0c..00000000000000 --- a/runtime/ops/plugin.rs +++ /dev/null @@ -1,86 +0,0 @@ -// 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 { - let filename = PathBuf::from(&filename); - - super::check_unstable(state, "Deno.openPlugin"); - let permissions = state.borrow_mut::(); - 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::("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); - -impl Resource for PluginResource { - fn name(&self) -> Cow { - "plugin".into() - } - - fn close(self: Rc) { - unimplemented!(); - } -} - -impl PluginResource { - fn new(lib: &Rc) -> Self { - Self(lib.clone()) - } -} diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index cc7b08fe0b34df..ab0cd6276bdc93 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -333,7 +333,6 @@ impl WebWorker { deno_net::init::(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 6d7d8bfca96585..de1260fa60b958 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -124,7 +124,6 @@ impl MainWorker { deno_net::init::(options.unstable), ops::os::init(), ops::permissions::init(), - ops::plugin::init(), ops::process::init(), ops::signal::init(), ops::tty::init(), diff --git a/test_plugin/Cargo.toml b/test_plugin/Cargo.toml deleted file mode 100644 index 53a94c4736dc38..00000000000000 --- a/test_plugin/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -# 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" } diff --git a/test_plugin/README.md b/test_plugin/README.md deleted file mode 100644 index b340389ce4b641..00000000000000 --- a/test_plugin/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# `test_plugin` crate - -## To run this test manually - -``` -cd test_plugin - -../target/debug/deno run --unstable --allow-plugin tests/test.js debug -``` diff --git a/test_plugin/src/lib.rs b/test_plugin/src/lib.rs deleted file mode 100644 index 88761edcf1ef5d..00000000000000 --- a/test_plugin/src/lib.rs +++ /dev/null @@ -1,114 +0,0 @@ -// 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, -) -> Result { - 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>, - args: TestArgs, - zero_copy: Option, -) -> Result { - 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::>(); - 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 { - "TestResource".into() - } -} - -fn op_test_resource_table_add( - state: &mut OpState, - text: String, - _: (), -) -> Result { - 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 { - println!("Hello from resource_table.get plugin op."); - - Ok( - state - .resource_table - .get::(rid) - .ok_or_else(bad_resource_id)? - .0 - .clone(), - ) -} diff --git a/test_plugin/tests/integration_tests.rs b/test_plugin/tests/integration_tests.rs deleted file mode 100644 index e408f59db168d5..00000000000000 --- a/test_plugin/tests/integration_tests.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use std::process::Command; -use test_util::deno_cmd; - -#[cfg(debug_assertions)] -const BUILD_VARIANT: &str = "debug"; - -#[cfg(not(debug_assertions))] -const BUILD_VARIANT: &str = "release"; - -#[test] -fn basic() { - let mut build_plugin_base = Command::new("cargo"); - let mut build_plugin = - build_plugin_base.arg("build").arg("-p").arg("test_plugin"); - if BUILD_VARIANT == "release" { - build_plugin = build_plugin.arg("--release"); - } - let build_plugin_output = build_plugin.output().unwrap(); - assert!(build_plugin_output.status.success()); - let output = deno_cmd() - .arg("run") - .arg("--allow-plugin") - .arg("--unstable") - .arg("tests/test.js") - .arg(BUILD_VARIANT) - .output() - .unwrap(); - let stdout = std::str::from_utf8(&output.stdout).unwrap(); - let stderr = std::str::from_utf8(&output.stderr).unwrap(); - if !output.status.success() { - println!("stdout {}", stdout); - println!("stderr {}", stderr); - } - println!("{:?}", output.status); - assert!(output.status.success()); - let expected = "\ - Plugin rid: 3\n\ - Hello from sync plugin op.\n\ - args: TestArgs { val: \"1\" }\n\ - zero_copy: test\n\ - op_test_sync returned: test\n\ - Hello from async plugin op.\n\ - args: TestArgs { val: \"1\" }\n\ - zero_copy: 123\n\ - op_test_async returned: test\n\ - Hello from resource_table.add plugin op.\n\ - TestResource rid: 4\n\ - Hello from resource_table.get plugin op.\n\ - TestResource get value: hello plugin!\n\ - Hello from sync plugin op.\n\ - args: TestArgs { val: \"1\" }\n\ - Ops completed count is correct!\n\ - Ops dispatched count is correct!\n"; - assert_eq!(stdout, expected); - assert_eq!(stderr, ""); -} diff --git a/test_plugin/tests/test.js b/test_plugin/tests/test.js deleted file mode 100644 index 2a2fa66b3aac41..00000000000000 --- a/test_plugin/tests/test.js +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -// deno-lint-ignore-file - -const filenameBase = "test_plugin"; - -let filenameSuffix = ".so"; -let filenamePrefix = "lib"; - -if (Deno.build.os === "windows") { - filenameSuffix = ".dll"; - filenamePrefix = ""; -} else if (Deno.build.os === "darwin") { - filenameSuffix = ".dylib"; -} - -const filename = `../target/${ - Deno.args[0] -}/${filenamePrefix}${filenameBase}${filenameSuffix}`; - -const resourcesPre = Deno.resources(); - -const pluginRid = Deno.openPlugin(filename); -console.log(`Plugin rid: ${pluginRid}`); - -const { - op_test_sync, - op_test_async, - op_test_resource_table_add, - op_test_resource_table_get, -} = Deno.core.ops(); - -if ( - op_test_sync === null || - op_test_async === null || - op_test_resource_table_add === null || - op_test_resource_table_get === null -) { - throw new Error("Not all expected ops were registered"); -} - -function runTestSync() { - const result = Deno.core.opSync( - "op_test_sync", - { val: "1" }, - new Uint8Array([116, 101, 115, 116]), - ); - - console.log(`op_test_sync returned: ${result}`); - - if (result !== "test") { - throw new Error("op_test_sync returned an unexpected value!"); - } -} - -async function runTestAsync() { - const promise = Deno.core.opAsync( - "op_test_async", - { val: "1" }, - new Uint8Array([49, 50, 51]), - ); - - if (!(promise instanceof Promise)) { - throw new Error("Expected promise!"); - } - - const result = await promise; - console.log(`op_test_async returned: ${result}`); - - if (result !== "test") { - throw new Error("op_test_async promise resolved to an unexpected value!"); - } -} - -function runTestResourceTable() { - const expect = "hello plugin!"; - - const testRid = Deno.core.opSync("op_test_resource_table_add", expect); - console.log(`TestResource rid: ${testRid}`); - - if (testRid === null || Deno.resources()[testRid] !== "TestResource") { - throw new Error("TestResource was not found!"); - } - - const testValue = Deno.core.opSync("op_test_resource_table_get", testRid); - console.log(`TestResource get value: ${testValue}`); - - if (testValue !== expect) { - throw new Error("Did not get correct resource value!"); - } - - Deno.close(testRid); -} - -function runTestOpCount() { - const start = Deno.metrics(); - - Deno.core.opSync("op_test_sync", { val: "1" }); - - const end = Deno.metrics(); - - if (end.opsCompleted - start.opsCompleted !== 1) { - throw new Error("The opsCompleted metric is not correct!"); - } - console.log("Ops completed count is correct!"); - - if (end.opsDispatched - start.opsDispatched !== 1) { - throw new Error("The opsDispatched metric is not correct!"); - } - console.log("Ops dispatched count is correct!"); -} - -function runTestPluginClose() { - // Closing does not yet work - Deno.close(pluginRid); - - const resourcesPost = Deno.resources(); - - const preStr = JSON.stringify(resourcesPre, null, 2); - const postStr = JSON.stringify(resourcesPost, null, 2); - if (preStr !== postStr) { - throw new Error( - `Difference in open resources before openPlugin and after Plugin.close(): -Before: ${preStr} -After: ${postStr}`, - ); - } - console.log("Correct number of resources"); -} - -runTestSync(); -await runTestAsync(); -runTestResourceTable(); - -runTestOpCount(); -// runTestPluginClose();