Skip to content

Commit

Permalink
feat: ffi to replace plugins (#11152)
Browse files Browse the repository at this point in the history
This commit removes implementation of "native plugins" and replaces
it with FFI API.

Effectively "Deno.openPlugin" API was replaced with "Deno.dlopen" API.
  • Loading branch information
eliassjogreen committed Aug 6, 2021
1 parent 0d1a522 commit 33c8d79
Show file tree
Hide file tree
Showing 44 changed files with 860 additions and 511 deletions.
12 changes: 7 additions & 5 deletions .github/workflows/ci.yml
Expand Up @@ -164,11 +164,13 @@ jobs:
sudo apt-get update
sudo apt-get install debootstrap
# Note: git, nc, strace, and time, are needed to run the benchmarks.
sudo debootstrap \
--include=ca-certificates,curl,git,netcat-openbsd,strace,time \
--no-merged-usr --variant=minbase bionic /sysroot \
http://azure.archive.ubuntu.com/ubuntu
# `file` and `make` are needed to build libffi-sys.
# `curl` is needed to build rusty_v8.
# `git`, `nc`, `strace`, and `time`, are needed to run the benchmarks.
sudo debootstrap \
--include=ca-certificates,curl,file,git,make,netcat-openbsd,strace,time \
--no-merged-usr --variant=minbase bionic /sysroot \
http://azure.archive.ubuntu.com/ubuntu
sudo mount --rbind /dev /sysroot/dev
sudo mount --rbind /sys /sysroot/sys
sudo mount --rbind /home /sysroot/home
Expand Down
52 changes: 47 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Expand Up @@ -6,12 +6,13 @@ members = [
"cli",
"core",
"runtime",
"test_plugin",
"test_ffi",
"test_util",
"extensions/broadcast_channel",
"extensions/console",
"extensions/crypto",
"extensions/fetch",
"extensions/ffi",
"extensions/http",
"extensions/net",
"extensions/timers",
Expand Down
1 change: 1 addition & 0 deletions cli/Cargo.toml
Expand Up @@ -25,6 +25,7 @@ deno_console = { version = "0.13.0", path = "../extensions/console" }
deno_core = { version = "0.95.0", path = "../core" }
deno_crypto = { version = "0.27.0", path = "../extensions/crypto" }
deno_fetch = { version = "0.36.0", path = "../extensions/fetch" }
deno_ffi = { version = "0.1.0", path = "../extensions/ffi" }
deno_http = { version = "0.4.0", path = "../extensions/http" }
deno_net = { version = "0.4.0", path = "../extensions/net" }
deno_timers = { version = "0.11.0", path = "../extensions/timers" }
Expand Down
2 changes: 1 addition & 1 deletion cli/diagnostics.rs
Expand Up @@ -54,7 +54,7 @@ const UNSTABLE_DENO_PROPS: &[&str] = &[
"listen",
"listenDatagram",
"loadavg",
"openPlugin",
"dlopen",
"osRelease",
"ppid",
"resolveDns",
Expand Down
8 changes: 4 additions & 4 deletions cli/dts/lib.deno.ns.d.ts
Expand Up @@ -2131,7 +2131,7 @@ declare namespace Deno {
| "write"
| "net"
| "env"
| "plugin"
| "ffi"
| "hrtime";

/** The current status of the permission. */
Expand Down Expand Up @@ -2167,8 +2167,8 @@ declare namespace Deno {
variable?: string;
}

export interface PluginPermissionDescriptor {
name: "plugin";
export interface FFIPermissionDescriptor {
name: "ffi";
}

export interface HrtimePermissionDescriptor {
Expand All @@ -2183,7 +2183,7 @@ declare namespace Deno {
| WritePermissionDescriptor
| NetPermissionDescriptor
| EnvPermissionDescriptor
| PluginPermissionDescriptor
| FFIPermissionDescriptor
| HrtimePermissionDescriptor;

export interface PermissionStatusEventMap {
Expand Down
76 changes: 42 additions & 34 deletions cli/dts/lib.deno.unstable.d.ts
Expand Up @@ -107,36 +107,44 @@ declare namespace Deno {
swapFree: number;
}

/** **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.
/** All possible types for interfacing with foreign functions */
export type NativeType =
| "void"
| "u8"
| "i8"
| "u16"
| "i16"
| "u32"
| "i32"
| "u64"
| "i64"
| "usize"
| "isize"
| "f32"
| "f64";

/** A foreign function as defined by its parameter and result types */
export interface ForeignFunction {
parameters: NativeType[];
result: NativeType;
}

/** A dynamic library resource */
export interface DynamicLibrary<S extends Record<string, ForeignFunction>> {
/** All of the registered symbols along with functions for calling them */
symbols: { [K in keyof S]: (...args: unknown[]) => unknown };

close(): void;
}

/** **UNSTABLE**: new API
*
* 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
* Opens a dynamic library and registers symbols
*/
export function openPlugin(filename: string): number;
export function dlopen<S extends Record<string, ForeignFunction>>(
filename: string,
symbols: S,
): DynamicLibrary<S>;

/** The log category for a diagnostic message. */
export enum DiagnosticCategory {
Expand Down Expand Up @@ -1043,14 +1051,14 @@ declare namespace Deno {
*/
net?: "inherit" | boolean | string[];

/** Specifies if the `plugin` permission should be requested or revoked.
* If set to `"inherit"`, the current `plugin` permission will be inherited.
* If set to `true`, the global `plugin` permission will be requested.
* If set to `false`, the global `plugin` permission will be revoked.
/** Specifies if the `ffi` permission should be requested or revoked.
* If set to `"inherit"`, the current `ffi` permission will be inherited.
* If set to `true`, the global `ffi` permission will be requested.
* If set to `false`, the global `ffi` permission will be revoked.
*
* Defaults to "inherit".
*/
plugin?: "inherit" | boolean;
ffi?: "inherit" | boolean;

/** Specifies if the `read` permission should be requested or revoked.
* If set to `"inherit"`, the current `read` permission will be inherited.
Expand Down Expand Up @@ -1137,7 +1145,7 @@ declare interface WorkerOptions {
* For example: `["https://deno.land", "localhost:8080"]`.
*/
net?: "inherit" | boolean | string[];
plugin?: "inherit" | boolean;
ffi?: "inherit" | boolean;
read?: "inherit" | boolean | Array<string | URL>;
run?: "inherit" | boolean | Array<string | URL>;
write?: "inherit" | boolean | Array<string | URL>;
Expand Down

0 comments on commit 33c8d79

Please sign in to comment.