0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 17:34:47 -05:00

feat(core) deno_core::extension! macro to simplify extension registration (#18210)

This implements two macros to simplify extension registration and centralize a lot of the boilerplate as a base for future improvements:

* `deno_core::ops!` registers a block of `#[op]`s, optionally with type
parameters, useful for places where we share lists of ops
* `deno_core::extension!` is used to register an extension, and creates
two methods that can be used at runtime/snapshot generation time:
`init_ops` and `init_ops_and_esm`.

---------

Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
Matt Mastracci 2023-03-17 12:22:15 -06:00 committed by GitHub
parent 0bc6bf5d33
commit e55b448730
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 1690 additions and 1851 deletions

View file

@ -9,14 +9,10 @@ use deno_bench_util::bencher::Bencher;
use deno_core::op; use deno_core::op;
use deno_core::Extension; use deno_core::Extension;
deno_core::extension!(bench_setup, ops = [op_pi_json, op_pi_async, op_nop]);
fn setup() -> Vec<Extension> { fn setup() -> Vec<Extension> {
vec![Extension::builder("bench_setup") vec![bench_setup::init_ops()]
.ops(vec![
op_pi_json::decl(),
op_pi_async::decl(),
op_nop::decl(),
])
.build()]
} }
#[op] #[op]

View file

@ -1,11 +1,13 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use std::cell::RefCell;
use std::env; use std::env;
use std::path::PathBuf; use std::path::PathBuf;
use std::rc::Rc;
use deno_core::include_js_files;
use deno_core::snapshot_util::*; use deno_core::snapshot_util::*;
use deno_core::Extension; use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::ExtensionFileSource; use deno_core::ExtensionFileSource;
use deno_core::ExtensionFileSourceCode; use deno_core::ExtensionFileSourceCode;
use deno_runtime::deno_cache::SqliteBackedCache; use deno_runtime::deno_cache::SqliteBackedCache;
@ -33,6 +35,105 @@ mod ts {
specifier: String, specifier: String,
} }
#[op]
fn op_build_info(state: &mut OpState) -> Value {
let build_specifier = "asset:///bootstrap.ts";
let node_built_in_module_names = SUPPORTED_BUILTIN_NODE_MODULES
.iter()
.map(|s| s.name)
.collect::<Vec<&str>>();
let build_libs = state.borrow::<Vec<&str>>();
json!({
"buildSpecifier": build_specifier,
"libs": build_libs,
"nodeBuiltInModuleNames": node_built_in_module_names,
})
}
#[op]
fn op_is_node_file() -> bool {
false
}
#[op]
fn op_script_version(
_state: &mut OpState,
_args: Value,
) -> Result<Option<String>, AnyError> {
Ok(Some("1".to_string()))
}
#[op]
// using the same op that is used in `tsc.rs` for loading modules and reading
// files, but a slightly different implementation at build time.
fn op_load(state: &mut OpState, args: LoadArgs) -> Result<Value, AnyError> {
let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
let path_dts = state.borrow::<PathBuf>();
let re_asset =
Regex::new(r"asset:/{3}lib\.(\S+)\.d\.ts").expect("bad regex");
let build_specifier = "asset:///bootstrap.ts";
// we need a basic file to send to tsc to warm it up.
if args.specifier == build_specifier {
Ok(json!({
"data": r#"Deno.writeTextFile("hello.txt", "hello deno!");"#,
"version": "1",
// this corresponds to `ts.ScriptKind.TypeScript`
"scriptKind": 3
}))
// specifiers come across as `asset:///lib.{lib_name}.d.ts` and we need to
// parse out just the name so we can lookup the asset.
} else if let Some(caps) = re_asset.captures(&args.specifier) {
if let Some(lib) = caps.get(1).map(|m| m.as_str()) {
// if it comes from an op crate, we were supplied with the path to the
// file.
let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
PathBuf::from(op_crate_lib).canonicalize()?
// otherwise we will generate the path ourself
} else {
path_dts.join(format!("lib.{lib}.d.ts"))
};
let data = std::fs::read_to_string(path)?;
Ok(json!({
"data": data,
"version": "1",
// this corresponds to `ts.ScriptKind.TypeScript`
"scriptKind": 3
}))
} else {
Err(custom_error(
"InvalidSpecifier",
format!("An invalid specifier was requested: {}", args.specifier),
))
}
} else {
Err(custom_error(
"InvalidSpecifier",
format!("An invalid specifier was requested: {}", args.specifier),
))
}
}
deno_core::extension!(deno_tsc,
ops = [op_build_info, op_is_node_file, op_load, op_script_version],
js = [
dir "tsc",
"00_typescript.js",
"99_main_compiler.js",
],
config = {
op_crate_libs: HashMap<&'static str, PathBuf>,
build_libs: Vec<&'static str>,
path_dts: PathBuf,
},
state = |state, op_crate_libs, build_libs, path_dts| {
state.put(op_crate_libs);
state.put(build_libs);
state.put(path_dts);
},
);
pub fn create_compiler_snapshot(snapshot_path: PathBuf, cwd: &Path) { pub fn create_compiler_snapshot(snapshot_path: PathBuf, cwd: &Path) {
// libs that are being provided by op crates. // libs that are being provided by op crates.
let mut op_crate_libs = HashMap::new(); let mut op_crate_libs = HashMap::new();
@ -158,110 +259,15 @@ mod ts {
) )
.unwrap(); .unwrap();
#[op]
fn op_build_info(state: &mut OpState) -> Value {
let build_specifier = "asset:///bootstrap.ts";
let node_built_in_module_names = SUPPORTED_BUILTIN_NODE_MODULES
.iter()
.map(|s| s.name)
.collect::<Vec<&str>>();
let build_libs = state.borrow::<Vec<&str>>();
json!({
"buildSpecifier": build_specifier,
"libs": build_libs,
"nodeBuiltInModuleNames": node_built_in_module_names,
})
}
#[op]
fn op_is_node_file() -> bool {
false
}
#[op]
fn op_script_version(
_state: &mut OpState,
_args: Value,
) -> Result<Option<String>, AnyError> {
Ok(Some("1".to_string()))
}
#[op]
// using the same op that is used in `tsc.rs` for loading modules and reading
// files, but a slightly different implementation at build time.
fn op_load(state: &mut OpState, args: LoadArgs) -> Result<Value, AnyError> {
let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
let path_dts = state.borrow::<PathBuf>();
let re_asset =
Regex::new(r"asset:/{3}lib\.(\S+)\.d\.ts").expect("bad regex");
let build_specifier = "asset:///bootstrap.ts";
// we need a basic file to send to tsc to warm it up.
if args.specifier == build_specifier {
Ok(json!({
"data": r#"Deno.writeTextFile("hello.txt", "hello deno!");"#,
"version": "1",
// this corresponds to `ts.ScriptKind.TypeScript`
"scriptKind": 3
}))
// specifiers come across as `asset:///lib.{lib_name}.d.ts` and we need to
// parse out just the name so we can lookup the asset.
} else if let Some(caps) = re_asset.captures(&args.specifier) {
if let Some(lib) = caps.get(1).map(|m| m.as_str()) {
// if it comes from an op crate, we were supplied with the path to the
// file.
let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
PathBuf::from(op_crate_lib).canonicalize()?
// otherwise we are will generate the path ourself
} else {
path_dts.join(format!("lib.{lib}.d.ts"))
};
let data = std::fs::read_to_string(path)?;
Ok(json!({
"data": data,
"version": "1",
// this corresponds to `ts.ScriptKind.TypeScript`
"scriptKind": 3
}))
} else {
Err(custom_error(
"InvalidSpecifier",
format!("An invalid specifier was requested: {}", args.specifier),
))
}
} else {
Err(custom_error(
"InvalidSpecifier",
format!("An invalid specifier was requested: {}", args.specifier),
))
}
}
let tsc_extension = Extension::builder("deno_tsc")
.ops(vec![
op_build_info::decl(),
op_is_node_file::decl(),
op_load::decl(),
op_script_version::decl(),
])
.js(include_js_files! {
dir "tsc",
"00_typescript.js",
"99_main_compiler.js",
})
.state(move |state| {
state.put(op_crate_libs.clone());
state.put(build_libs.clone());
state.put(path_dts.clone());
})
.build();
create_snapshot(CreateSnapshotOptions { create_snapshot(CreateSnapshotOptions {
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"), cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
snapshot_path, snapshot_path,
startup_snapshot: None, startup_snapshot: None,
extensions: vec![tsc_extension], extensions: vec![deno_tsc::init_ops_and_esm(
op_crate_libs,
build_libs,
path_dts,
)],
// NOTE(bartlomieju): Compressing the TSC snapshot in debug build took // NOTE(bartlomieju): Compressing the TSC snapshot in debug build took
// ~45s on M1 MacBook Pro; without compression it took ~1s. // ~45s on M1 MacBook Pro; without compression it took ~1s.
@ -304,61 +310,66 @@ mod ts {
} }
} }
// FIXME(bartlomieju): information about which extensions were
// already snapshotted is not preserved in the snapshot. This should be
// fixed, so we can reliably depend on that information.
// deps = [runtime]
deno_core::extension!(
cli,
esm = [
dir "js",
"40_testing.js"
],
customizer = |ext: &mut ExtensionBuilder| {
ext.esm(vec![ExtensionFileSource {
specifier: "runtime/js/99_main.js".to_string(),
code: ExtensionFileSourceCode::LoadedFromFsDuringSnapshot(
std::path::PathBuf::from(deno_runtime::js::PATH_FOR_99_MAIN_JS),
),
}]);
}
);
fn create_cli_snapshot(snapshot_path: PathBuf) { fn create_cli_snapshot(snapshot_path: PathBuf) {
// NOTE(bartlomieju): ordering is important here, keep it in sync with // NOTE(bartlomieju): ordering is important here, keep it in sync with
// `runtime/worker.rs`, `runtime/web_worker.rs` and `runtime/build.rs`! // `runtime/worker.rs`, `runtime/web_worker.rs` and `runtime/build.rs`!
let mut extensions: Vec<Extension> = vec![ let extensions: Vec<Extension> = vec![
deno_webidl::init(), deno_webidl::deno_webidl::init_ops(),
deno_console::init(), deno_console::deno_console::init_ops(),
deno_url::init_ops(), deno_url::deno_url::init_ops(),
deno_web::init_ops::<PermissionsContainer>( deno_web::deno_web::init_ops::<PermissionsContainer>(
deno_web::BlobStore::default(), deno_web::BlobStore::default(),
Default::default(), Default::default(),
), ),
deno_fetch::init_ops::<PermissionsContainer>(Default::default()), deno_fetch::deno_fetch::init_ops::<PermissionsContainer>(Default::default()),
deno_cache::init_ops::<SqliteBackedCache>(None), deno_cache::deno_cache::init_ops::<SqliteBackedCache>(None),
deno_websocket::init_ops::<PermissionsContainer>("".to_owned(), None, None), deno_websocket::deno_websocket::init_ops::<PermissionsContainer>(
deno_webstorage::init_ops(None), "".to_owned(),
deno_crypto::init_ops(None), None,
deno_broadcast_channel::init_ops( None,
),
deno_webstorage::deno_webstorage::init_ops(None),
deno_crypto::deno_crypto::init_ops(None),
deno_broadcast_channel::deno_broadcast_channel::init_ops(
deno_broadcast_channel::InMemoryBroadcastChannel::default(), deno_broadcast_channel::InMemoryBroadcastChannel::default(),
false, // No --unstable. false, // No --unstable.
), ),
deno_ffi::init_ops::<PermissionsContainer>(false), deno_ffi::deno_ffi::init_ops::<PermissionsContainer>(false),
deno_net::init_ops::<PermissionsContainer>( deno_net::deno_net::init_ops::<PermissionsContainer>(
None, false, // No --unstable. None, false, // No --unstable.
None, None,
), ),
deno_tls::init_ops(), deno_tls::deno_tls::init_ops(),
deno_napi::init_ops::<PermissionsContainer>(), deno_napi::deno_napi::init_ops::<PermissionsContainer>(),
deno_http::init_ops(), deno_http::deno_http::init_ops(),
deno_io::init_ops(Default::default()), deno_io::deno_io::init_ops(Rc::new(RefCell::new(Some(Default::default())))),
deno_fs::init_ops::<PermissionsContainer>(false), deno_fs::deno_fs::init_ops::<PermissionsContainer>(false),
deno_flash::init_ops::<PermissionsContainer>(false), // No --unstable deno_flash::deno_flash::init_ops::<PermissionsContainer>(false), // No --unstable
deno_node::init_ops::<PermissionsContainer>(None), // No --unstable. deno_node::deno_node_loading::init_ops::<PermissionsContainer>(None), // No --unstable.
deno_node::init_polyfill_ops(), deno_node::deno_node::init_ops(),
cli::init_ops_and_esm(), // NOTE: This needs to be init_ops_and_esm!
]; ];
let mut esm_files = include_js_files!(
dir "js",
"40_testing.js",
);
esm_files.push(ExtensionFileSource {
specifier: "runtime/js/99_main.js".to_string(),
code: ExtensionFileSourceCode::LoadedFromFsDuringSnapshot(
std::path::PathBuf::from(deno_runtime::js::PATH_FOR_99_MAIN_JS),
),
});
extensions.push(
Extension::builder("cli")
// FIXME(bartlomieju): information about which extensions were
// already snapshotted is not preserved in the snapshot. This should be
// fixed, so we can reliably depend on that information.
// .dependencies(vec!["runtime"])
.esm(esm_files)
.build(),
);
create_snapshot(CreateSnapshotOptions { create_snapshot(CreateSnapshotOptions {
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"), cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
snapshot_path, snapshot_path,

View file

@ -165,7 +165,11 @@ async fn test_specifier(
&ps, &ps,
specifier.clone(), specifier.clone(),
PermissionsContainer::new(permissions), PermissionsContainer::new(permissions),
vec![ops::testing::init(sender, fail_fast_tracker, filter)], vec![ops::testing::deno_test::init_ops(
sender,
fail_fast_tracker,
filter,
)],
Stdio { Stdio {
stdin: StdioPipe::Inherit, stdin: StdioPipe::Inherit,
stdout, stdout,

View file

@ -37,7 +37,6 @@ use deno_core::serde_json;
use deno_core::serde_json::json; use deno_core::serde_json::json;
use deno_core::serde_json::Value; use deno_core::serde_json::Value;
use deno_core::url::Url; use deno_core::url::Url;
use deno_core::Extension;
use deno_core::JsRuntime; use deno_core::JsRuntime;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_core::OpState; use deno_core::OpState;
@ -2819,31 +2818,32 @@ fn op_script_version(
/// server. /// server.
fn js_runtime(performance: Arc<Performance>) -> JsRuntime { fn js_runtime(performance: Arc<Performance>) -> JsRuntime {
JsRuntime::new(RuntimeOptions { JsRuntime::new(RuntimeOptions {
extensions: vec![init_extension(performance)], extensions: vec![deno_tsc::init_ops(performance)],
startup_snapshot: Some(tsc::compiler_snapshot()), startup_snapshot: Some(tsc::compiler_snapshot()),
..Default::default() ..Default::default()
}) })
} }
fn init_extension(performance: Arc<Performance>) -> Extension { deno_core::extension!(deno_tsc,
Extension::builder("deno_tsc") ops = [
.ops(vec![ op_is_cancelled,
op_is_cancelled::decl(), op_is_node_file,
op_is_node_file::decl(), op_load,
op_load::decl(), op_resolve,
op_resolve::decl(), op_respond,
op_respond::decl(), op_script_names,
op_script_names::decl(), op_script_version,
op_script_version::decl(), ],
]) config = {
.state(move |state| { performance: Arc<Performance>
state.put(State::new( },
Arc::new(StateSnapshot::default()), state = |state, performance| {
performance.clone(), state.put(State::new(
)); Arc::new(StateSnapshot::default()),
}) performance,
.build() ));
} },
);
/// Instruct a language server runtime to start the language server and provide /// Instruct a language server runtime to start the language server and provide
/// it with a minimal bootstrap configuration. /// it with a minimal bootstrap configuration.

View file

@ -7,7 +7,6 @@ use std::time;
use deno_core::error::generic_error; use deno_core::error::generic_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op; use deno_core::op;
use deno_core::Extension;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_core::OpState; use deno_core::OpState;
use deno_runtime::permissions::create_child_permissions; use deno_runtime::permissions::create_child_permissions;
@ -22,25 +21,24 @@ use crate::tools::bench::BenchDescription;
use crate::tools::bench::BenchEvent; use crate::tools::bench::BenchEvent;
use crate::tools::test::TestFilter; use crate::tools::test::TestFilter;
pub fn init( deno_core::extension!(deno_bench,
sender: UnboundedSender<BenchEvent>, ops = [
filter: TestFilter, op_pledge_test_permissions,
) -> Extension { op_restore_test_permissions,
Extension::builder("deno_bench") op_get_bench_origin,
.ops(vec![ op_register_bench,
op_pledge_test_permissions::decl(), op_dispatch_bench_event,
op_restore_test_permissions::decl(), op_bench_now,
op_get_bench_origin::decl(), ],
op_register_bench::decl(), config = {
op_dispatch_bench_event::decl(), sender: UnboundedSender<BenchEvent>,
op_bench_now::decl(), filter: TestFilter,
]) },
.state(move |state| { state = |state, sender, filter| {
state.put(sender.clone()); state.put(sender);
state.put(filter.clone()); state.put(filter);
}) },
.build() );
}
#[derive(Clone)] #[derive(Clone)]
struct PermissionsHolder(Uuid, PermissionsContainer); struct PermissionsHolder(Uuid, PermissionsContainer);

View file

@ -10,17 +10,18 @@ pub mod bench;
pub mod testing; pub mod testing;
pub fn cli_exts(ps: ProcState) -> Vec<Extension> { pub fn cli_exts(ps: ProcState) -> Vec<Extension> {
vec![init_proc_state(ps)] vec![deno_cli::init_ops(ps)]
} }
fn init_proc_state(ps: ProcState) -> Extension { deno_core::extension!(deno_cli,
Extension::builder("deno_cli") ops = [op_npm_process_state],
.ops(vec![op_npm_process_state::decl()]) config = {
.state(move |state| { ps: ProcState,
state.put(ps.clone()); },
}) state = |state, ps| {
.build() state.put(ps);
} },
);
#[op] #[op]
fn op_npm_process_state(state: &mut OpState) -> Result<String, AnyError> { fn op_npm_process_state(state: &mut OpState) -> Result<String, AnyError> {

View file

@ -12,7 +12,6 @@ use crate::tools::test::TestStepDescription;
use deno_core::error::generic_error; use deno_core::error::generic_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op; use deno_core::op;
use deno_core::Extension;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_core::OpState; use deno_core::OpState;
use deno_runtime::permissions::create_child_permissions; use deno_runtime::permissions::create_child_permissions;
@ -25,28 +24,27 @@ use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use uuid::Uuid; use uuid::Uuid;
pub fn init( deno_core::extension!(deno_test,
sender: TestEventSender, ops = [
fail_fast_tracker: FailFastTracker, op_pledge_test_permissions,
filter: TestFilter, op_restore_test_permissions,
) -> Extension { op_get_test_origin,
Extension::builder("deno_test") op_register_test,
.ops(vec![ op_register_test_step,
op_pledge_test_permissions::decl(), op_dispatch_test_event,
op_restore_test_permissions::decl(), op_tests_should_stop,
op_get_test_origin::decl(), ],
op_register_test::decl(), config = {
op_register_test_step::decl(), sender: TestEventSender,
op_dispatch_test_event::decl(), fail_fast_tracker: FailFastTracker,
op_tests_should_stop::decl(), filter: TestFilter,
]) },
.state(move |state| { state = |state, sender, fail_fast_tracker, filter| {
state.put(sender.clone()); state.put(sender);
state.put(fail_fast_tracker.clone()); state.put(fail_fast_tracker);
state.put(filter.clone()); state.put(filter);
}) },
.build() );
}
#[derive(Clone)] #[derive(Clone)]
struct PermissionsHolder(Uuid, PermissionsContainer); struct PermissionsHolder(Uuid, PermissionsContainer);

View file

@ -441,7 +441,7 @@ async fn bench_specifier(
&ps, &ps,
specifier, specifier,
PermissionsContainer::new(permissions), PermissionsContainer::new(permissions),
vec![ops::bench::init(channel, filter)], vec![ops::bench::deno_bench::init_ops(channel, filter)],
Default::default(), Default::default(),
) )
.await?; .await?;

View file

@ -723,7 +723,7 @@ async fn test_specifier(
ps, ps,
specifier, specifier,
PermissionsContainer::new(permissions), PermissionsContainer::new(permissions),
vec![ops::testing::init( vec![ops::testing::deno_test::init_ops(
sender, sender,
fail_fast_tracker, fail_fast_tracker,
options.filter, options.filter,

View file

@ -22,7 +22,6 @@ use deno_core::serde_json;
use deno_core::serde_json::json; use deno_core::serde_json::json;
use deno_core::serde_json::Value; use deno_core::serde_json::Value;
use deno_core::serde_v8; use deno_core::serde_v8;
use deno_core::Extension;
use deno_core::JsRuntime; use deno_core::JsRuntime;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_core::OpState; use deno_core::OpState;
@ -35,12 +34,14 @@ use deno_graph::ModuleGraph;
use deno_graph::ResolutionResolved; use deno_graph::ResolutionResolved;
use deno_runtime::deno_node::NodeResolutionMode; use deno_runtime::deno_node::NodeResolutionMode;
use deno_runtime::permissions::PermissionsContainer; use deno_runtime::permissions::PermissionsContainer;
use lsp_types::Url;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
mod diagnostics; mod diagnostics;
@ -114,12 +115,12 @@ pub fn get_types_declaration_file_text(unstable: bool) -> String {
} }
fn get_asset_texts_from_new_runtime() -> Result<Vec<AssetText>, AnyError> { fn get_asset_texts_from_new_runtime() -> Result<Vec<AssetText>, AnyError> {
deno_core::extension!(deno_cli_tsc, ops_fn = deno_ops,);
// the assets are stored within the typescript isolate, so take them out of there // the assets are stored within the typescript isolate, so take them out of there
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
startup_snapshot: Some(compiler_snapshot()), startup_snapshot: Some(compiler_snapshot()),
extensions: vec![Extension::builder("deno_cli_tsc") extensions: vec![deno_cli_tsc::init_ops()],
.ops(get_tsc_ops())
.build()],
..Default::default() ..Default::default()
}); });
let global = let global =
@ -825,26 +826,28 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
} }
}) })
.collect(); .collect();
let mut runtime = JsRuntime::new(RuntimeOptions {
startup_snapshot: Some(compiler_snapshot()), deno_core::extension!(deno_cli_tsc,
extensions: vec![Extension::builder("deno_cli_tsc") ops_fn = deno_ops,
.ops(get_tsc_ops()) config = {
.state(move |state| { request: Rc<Request>,
state.put(State::new( root_map: HashMap<String, Url>,
request.graph.clone(), remapped_specifiers: HashMap<String, Url>,
request.hash_data.clone(), },
request.maybe_npm_resolver.clone(), state = |state, request, root_map, remapped_specifiers| {
request.maybe_tsbuildinfo.clone(), state.put(State::new(
root_map.clone(), request.graph.clone(),
remapped_specifiers.clone(), request.hash_data.clone(),
std::env::current_dir() request.maybe_npm_resolver.clone(),
.context("Unable to get CWD") request.maybe_tsbuildinfo.clone(),
.unwrap(), root_map,
)); remapped_specifiers,
}) std::env::current_dir()
.build()], .context("Unable to get CWD")
..Default::default() .unwrap(),
}); ));
},
);
let startup_source = "globalThis.startup({ legacyFlag: false })"; let startup_source = "globalThis.startup({ legacyFlag: false })";
let request_value = json!({ let request_value = json!({
@ -855,6 +858,16 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
let request_str = request_value.to_string(); let request_str = request_value.to_string();
let exec_source = format!("globalThis.exec({request_str})"); let exec_source = format!("globalThis.exec({request_str})");
let mut runtime = JsRuntime::new(RuntimeOptions {
startup_snapshot: Some(compiler_snapshot()),
extensions: vec![deno_cli_tsc::init_ops(
Rc::new(request),
root_map,
remapped_specifiers,
)],
..Default::default()
});
runtime runtime
.execute_script(&located_script_name!(), startup_source) .execute_script(&located_script_name!(), startup_source)
.context("Could not properly start the compiler runtime.")?; .context("Could not properly start the compiler runtime.")?;
@ -879,16 +892,17 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
} }
} }
fn get_tsc_ops() -> Vec<deno_core::OpDecl> { deno_core::ops!(
vec![ deno_ops,
op_create_hash::decl(), [
op_emit::decl(), op_create_hash,
op_is_node_file::decl(), op_emit,
op_load::decl(), op_is_node_file,
op_resolve::decl(), op_load,
op_respond::decl(), op_resolve,
op_respond,
] ]
} );
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View file

@ -65,6 +65,263 @@ impl OpDecl {
} }
} }
/// Declares a block of Deno `#[op]`s. The first parameter determines the name of the
/// op declaration block, and is usually `deno_ops`. This block generates a function that
/// returns a [`Vec<OpDecl>`].
///
/// This can be either a compact form like:
///
/// ```no_compile
/// # use deno_core::*;
/// #[op]
/// fn op_xyz() {}
///
/// deno_core::ops!(deno_ops, [
/// op_xyz
/// ]);
///
/// // Use the ops:
/// deno_ops()
/// ```
///
/// ... or a parameterized form like so that allows passing a number of type parameters
/// to each `#[op]`:
///
/// ```no_compile
/// # use deno_core::*;
/// #[op]
/// fn op_xyz<P>() where P: Clone {}
///
/// deno_core::ops!(deno_ops,
/// parameters = [P: Clone],
/// ops = [
/// op_xyz<P>
/// ]
/// );
///
/// // Use the ops, with `String` as the parameter `P`:
/// deno_ops::<String>()
/// ```
#[macro_export]
macro_rules! ops {
($name:ident, parameters = [ $( $param:ident : $type:ident ),+ ], ops = [ $( $(#[$m:meta])* $( $op:ident )::+ $( < $op_param:ident > )? ),+ $(,)? ]) => {
pub(crate) fn $name < $( $param : $type + 'static ),+ > () -> Vec<$crate::OpDecl> {
vec![
$(
$( #[ $m ] )*
$( $op )::+ :: decl $( :: <$op_param> )? () ,
)+
]
}
};
($name:ident, [ $( $(#[$m:meta])* $( $op:ident )::+ ),+ $(,)? ] ) => {
pub(crate) fn $name() -> Vec<$crate::OpDecl> {
vec![
$( $( #[ $m ] )* $( $op )::+ :: decl(), )+
]
}
}
}
/// Defines a Deno extension. The first parameter is the name of the extension symbol namespace to create. This is the symbol you
/// will use to refer to the extension.
///
/// Most extensions will define a combination of ops and ESM files, like so:
///
/// ```no_compile
/// #[op]
/// fn op_xyz() {
/// }
///
/// deno_core::extension!(
/// my_extension,
/// ops = [ op_xyz ],
/// esm = [ "my_script.js" ],
/// );
/// ```
///
/// The following options are available for the [`extension`] macro:
///
/// * deps: a comma-separated list of module dependencies, eg: `deps = [ my_other_extension ]`
/// * parameters: a comma-separated list of parameters and base traits, eg: `parameters = [ P: MyTrait ]`
/// * ops: a comma-separated list of [`OpDecl`]s to provide, eg: `ops = [ op_foo, op_bar ]`
/// * esm: a comma-separated list of ESM module filenames (see [`include_js_files`]), eg: `esm = [ dir "dir", "my_file.js" ]`
/// * esm_setup_script: see [`ExtensionBuilder::esm_setup_script`]
/// * js: a comma-separated list of JS filenames (see [`include_js_files`]), eg: `js = [ dir "dir", "my_file.js" ]`
/// * config: a structure-like definition for configuration parameters which will be required when initializing this extension, eg: `config = { my_param: Option<usize> }`
/// * middleware: an [`OpDecl`] middleware function with the signature `fn (OpDecl) -> OpDecl`
/// * state: a state initialization function, with the signature `fn (&mut OpState, ...) -> ()`, where `...` are parameters matching the fields of the config struct
/// * event_loop_middleware: an event-loop middleware function (see [`ExtensionBuilder::event_loop_middleware`])
#[macro_export]
macro_rules! extension {
(
$name:ident
$(, deps = [ $( $dep:ident ),* ] )?
$(, parameters = [ $( $param:ident : $type:ident ),+ ] )?
$(, ops_fn = $ops_symbol:ident $( < $ops_param:ident > )? )?
$(, ops = [ $( $(#[$m:meta])* $( $op:ident )::+ $( < $op_param:ident > )? ),+ $(,)? ] )?
$(, esm_entry_point = $esm_entry_point:literal )?
$(, esm = [ $( dir $dir_esm:literal , )? $( $esm:literal ),* $(,)? ] )?
$(, esm_setup_script = $esm_setup_script:expr )?
$(, js = [ $( dir $dir_js:literal , )? $( $js:literal ),* $(,)? ] )?
$(, config = { $( $config_id:ident : $config_type:ty ),* $(,)? } )?
$(, middleware = $middleware_fn:expr )?
$(, state = $state_fn:expr )?
$(, event_loop_middleware = $event_loop_middleware_fn:ident )?
$(, customizer = $customizer_fn:expr )?
$(,)?
) => {
/// Extension struct for
#[doc = stringify!($name)]
/// .
#[allow(non_camel_case_types)]
pub struct $name {
}
impl $name {
#[inline(always)]
fn ext() -> $crate::ExtensionBuilder {
$crate::Extension::builder_with_deps(stringify!($name), &[ $( $( stringify!($dep) ),* )? ])
}
/// If ESM or JS was specified, add those files to the extension.
#[inline(always)]
#[allow(unused_variables)]
fn with_js(ext: &mut $crate::ExtensionBuilder) {
$( ext.esm(
$crate::include_js_files!( $( dir $dir_esm , )? $( $esm , )* )
); )?
$(
ext.esm(vec![ExtensionFileSource {
specifier: "ext:setup".to_string(),
code: ExtensionFileSourceCode::IncludedInBinary($esm_setup_script),
}]);
)?
$(
ext.esm_entry_point($esm_entry_point);
)?
$( ext.js(
$crate::include_js_files!( $( dir $dir_js , )? $( $js , )* )
); )?
}
// If ops were specified, add those ops to the extension.
#[inline(always)]
#[allow(unused_variables)]
fn with_ops $( < $( $param : $type + Clone + 'static ),+ > )?(ext: &mut $crate::ExtensionBuilder) {
// If individual ops are specified, roll them up into a vector and apply them
$(
let v = vec![
$(
$( #[ $m ] )*
$( $op )::+ :: decl $( :: <$op_param> )? ()
),+
];
ext.ops(v);
)?
// Otherwise use the ops_fn, if provided
$crate::extension!(! __ops__ ext $( $ops_symbol $( < $ops_param > )? )? __eot__);
}
// Includes the state and middleware functions, if defined.
#[inline(always)]
#[allow(unused_variables)]
fn with_state_and_middleware$( < $( $param : $type + Clone + 'static ),+ > )?(ext: &mut $crate::ExtensionBuilder, $( $( $config_id : $config_type ),* )? ) {
#[allow(unused_variables)]
let config = $crate::extension!(! __config__ $( parameters = [ $( $param : $type ),* ] )? $( config = { $( $config_id : $config_type ),* } )? );
$(
ext.state(move |state: &mut $crate::OpState| {
config.clone().call_callback(state, $state_fn)
});
)?
$(
ext.event_loop_middleware($event_loop_middleware_fn);
)?
$(
ext.middleware($middleware_fn);
)?
}
#[inline(always)]
#[allow(unused_variables)]
fn with_customizer(ext: &mut $crate::ExtensionBuilder) {
$( ($customizer_fn)(ext); )?
}
#[allow(dead_code)]
pub fn init_js_only $( < $( $param : $type + Clone + 'static ),+ > )? () -> $crate::Extension {
let mut ext = Self::ext();
// If esm or JS was specified, add JS files
Self::with_js(&mut ext);
Self::with_ops $( ::<($( $param ),+)> )?(&mut ext);
Self::with_customizer(&mut ext);
ext.build()
}
#[allow(dead_code)]
pub fn init_ops_and_esm $( < $( $param : $type + Clone + 'static ),+ > )? ( $( $( $config_id : $config_type ),* )? ) -> $crate::Extension {
let mut ext = Self::ext();
// If esm or JS was specified, add JS files
Self::with_js(&mut ext);
Self::with_ops $( ::<($( $param ),+)> )?(&mut ext);
Self::with_state_and_middleware $( ::<($( $param ),+)> )?(&mut ext, $( $( $config_id , )* )? );
Self::with_customizer(&mut ext);
ext.build()
}
#[allow(dead_code)]
pub fn init_ops $( < $( $param : $type + Clone + 'static ),+ > )? ( $( $( $config_id : $config_type ),* )? ) -> $crate::Extension {
let mut ext = Self::ext();
Self::with_ops $( ::<($( $param ),+)> )?(&mut ext);
Self::with_state_and_middleware $( ::<($( $param ),+)> )?(&mut ext, $( $( $config_id , )* )? );
Self::with_customizer(&mut ext);
ext.build()
}
}
};
(! __config__ $( parameters = [ $( $param:ident : $type:ident ),+ ] )? $( config = { $( $config_id:ident : $config_type:ty ),* } )? ) => {
{
#[doc(hidden)]
#[derive(Clone)]
struct Config $( < $( $param : $type + Clone + 'static ),+ > )? {
$( $( pub $config_id : $config_type , )* )?
$( __phantom_data: ::std::marker::PhantomData<($( $param ),+)>, )?
}
impl $( < $( $param : $type + Clone + 'static ),+ > )? Config $( < $( $param ),+ > )? {
/// Call a function of |state, ...| using the fields of this configuration structure.
#[allow(dead_code)]
#[doc(hidden)]
#[inline(always)]
fn call_callback<F: Fn(&mut $crate::OpState, $( $( $config_type ),* )?)>(self, state: &mut $crate::OpState, f: F) {
f(state, $( $( self. $config_id ),* )? )
}
}
Config {
$( $( $config_id , )* )?
$( __phantom_data: ::std::marker::PhantomData::<($( $param ),+)>::default() )?
}
}
};
(! __ops__ $ext:ident __eot__) => {
};
(! __ops__ $ext:ident $ops_symbol:ident __eot__) => {
$ext.ops($ops_symbol())
};
(! __ops__ $ext:ident $ops_symbol:ident < $ops_param:ident > __eot__) => {
$ext.ops($ops_symbol::<$ops_param>())
};
}
#[derive(Default)] #[derive(Default)]
pub struct Extension { pub struct Extension {
js_files: Option<Vec<ExtensionFileSource>>, js_files: Option<Vec<ExtensionFileSource>>,

View file

@ -1649,7 +1649,6 @@ impl ModuleMap {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::Extension;
use crate::JsRuntime; use crate::JsRuntime;
use crate::RuntimeOptions; use crate::RuntimeOptions;
use crate::Snapshot; use crate::Snapshot;
@ -1990,12 +1989,10 @@ import "/a.js";
43 43
} }
let ext = Extension::builder("test_ext") deno_core::extension!(test_ext, ops = [op_test]);
.ops(vec![op_test::decl()])
.build();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext], extensions: vec![test_ext::init_ops()],
module_loader: Some(loader), module_loader: Some(loader),
..Default::default() ..Default::default()
}); });

View file

@ -1,13 +1,11 @@
use crate::ExtensionBuilder;
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use crate::error::format_file_name; use crate::error::format_file_name;
use crate::error::type_error; use crate::error::type_error;
use crate::include_js_files;
use crate::io::BufMutView; use crate::io::BufMutView;
use crate::io::BufView; use crate::io::BufView;
use crate::ops_builtin_v8;
use crate::ops_metrics::OpMetrics; use crate::ops_metrics::OpMetrics;
use crate::resources::ResourceId; use crate::resources::ResourceId;
use crate::Extension;
use crate::OpState; use crate::OpState;
use crate::Resource; use crate::Resource;
use crate::ZeroCopyBuf; use crate::ZeroCopyBuf;
@ -19,49 +17,62 @@ use std::io::stdout;
use std::io::Write; use std::io::Write;
use std::rc::Rc; use std::rc::Rc;
fn ext() -> ExtensionBuilder { crate::extension!(
Extension::builder("core") core,
} ops = [
op_close,
fn ops(ext: &mut ExtensionBuilder) -> &mut ExtensionBuilder { op_try_close,
let mut ops = vec![ op_print,
op_close::decl(), op_resources,
op_try_close::decl(), op_wasm_streaming_feed,
op_print::decl(), op_wasm_streaming_set_url,
op_resources::decl(), op_void_sync,
op_wasm_streaming_feed::decl(), op_void_async,
op_wasm_streaming_set_url::decl(), op_add,
op_void_sync::decl(), // TODO(@AaronO): track IO metrics for builtin streams
op_void_async::decl(), op_read,
op_add::decl(), op_read_all,
// // TODO(@AaronO): track IO metrics for builtin streams op_write,
op_read::decl(), op_write_all,
op_read_all::decl(), op_shutdown,
op_write::decl(), op_metrics,
op_write_all::decl(), op_format_file_name,
op_shutdown::decl(), op_is_proxy,
op_metrics::decl(), op_str_byte_length,
op_format_file_name::decl(), ops_builtin_v8::op_ref_op,
op_is_proxy::decl(), ops_builtin_v8::op_unref_op,
op_str_byte_length::decl(), ops_builtin_v8::op_set_macrotask_callback,
]; ops_builtin_v8::op_set_next_tick_callback,
ops.extend(crate::ops_builtin_v8::init_builtins_v8()); ops_builtin_v8::op_set_promise_reject_callback,
ext.ops(ops) ops_builtin_v8::op_run_microtasks,
} ops_builtin_v8::op_has_tick_scheduled,
ops_builtin_v8::op_set_has_tick_scheduled,
pub(crate) fn init_builtin_ops_and_esm() -> Extension { ops_builtin_v8::op_eval_context,
ops(&mut ext()) ops_builtin_v8::op_queue_microtask,
.js(include_js_files!( ops_builtin_v8::op_create_host_object,
"00_primordials.js", ops_builtin_v8::op_encode,
"01_core.js", ops_builtin_v8::op_decode,
"02_error.js", ops_builtin_v8::op_serialize,
)) ops_builtin_v8::op_deserialize,
.build() ops_builtin_v8::op_set_promise_hooks,
} ops_builtin_v8::op_get_promise_details,
ops_builtin_v8::op_get_proxy_details,
pub(crate) fn init_builtin_ops() -> Extension { ops_builtin_v8::op_memory_usage,
ops(&mut ext()).build() ops_builtin_v8::op_set_wasm_streaming_callback,
} ops_builtin_v8::op_abort_wasm_streaming,
ops_builtin_v8::op_destructure_error,
ops_builtin_v8::op_dispatch_exception,
ops_builtin_v8::op_op_names,
ops_builtin_v8::op_apply_source_map,
ops_builtin_v8::op_set_format_exception_callback,
ops_builtin_v8::op_event_loop_has_more_work,
ops_builtin_v8::op_store_pending_promise_rejection,
ops_builtin_v8::op_remove_pending_promise_rejection,
ops_builtin_v8::op_has_pending_promise_rejection,
ops_builtin_v8::op_arraybuffer_was_detached,
],
js = ["00_primordials.js", "01_core.js", "02_error.js"],
);
/// Return map of resources with id as key /// Return map of resources with id as key
/// and string representation as value. /// and string representation as value.

View file

@ -11,7 +11,6 @@ use crate::serde_v8::from_v8;
use crate::source_map::apply_source_map as apply_source_map_; use crate::source_map::apply_source_map as apply_source_map_;
use crate::JsRealm; use crate::JsRealm;
use crate::JsRuntime; use crate::JsRuntime;
use crate::OpDecl;
use crate::ZeroCopyBuf; use crate::ZeroCopyBuf;
use anyhow::Error; use anyhow::Error;
use deno_ops::op; use deno_ops::op;
@ -21,42 +20,6 @@ use std::cell::RefCell;
use v8::ValueDeserializerHelper; use v8::ValueDeserializerHelper;
use v8::ValueSerializerHelper; use v8::ValueSerializerHelper;
pub(crate) fn init_builtins_v8() -> Vec<OpDecl> {
vec![
op_ref_op::decl(),
op_unref_op::decl(),
op_set_macrotask_callback::decl(),
op_set_next_tick_callback::decl(),
op_set_promise_reject_callback::decl(),
op_run_microtasks::decl(),
op_has_tick_scheduled::decl(),
op_set_has_tick_scheduled::decl(),
op_eval_context::decl(),
op_queue_microtask::decl(),
op_create_host_object::decl(),
op_encode::decl(),
op_decode::decl(),
op_serialize::decl(),
op_deserialize::decl(),
op_set_promise_hooks::decl(),
op_get_promise_details::decl(),
op_get_proxy_details::decl(),
op_memory_usage::decl(),
op_set_wasm_streaming_callback::decl(),
op_abort_wasm_streaming::decl(),
op_destructure_error::decl(),
op_dispatch_exception::decl(),
op_op_names::decl(),
op_apply_source_map::decl(),
op_set_format_exception_callback::decl(),
op_event_loop_has_more_work::decl(),
op_store_pending_promise_rejection::decl(),
op_remove_pending_promise_rejection::decl(),
op_has_pending_promise_rejection::decl(),
op_arraybuffer_was_detached::decl(),
]
}
fn to_v8_fn( fn to_v8_fn(
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
value: serde_v8::Value, value: serde_v8::Value,

View file

@ -323,11 +323,11 @@ impl JsRuntime {
if !has_startup_snapshot { if !has_startup_snapshot {
options options
.extensions .extensions
.insert(0, crate::ops_builtin::init_builtin_ops_and_esm()); .insert(0, crate::ops_builtin::core::init_ops_and_esm());
} else { } else {
options options
.extensions .extensions
.insert(0, crate::ops_builtin::init_builtin_ops()); .insert(0, crate::ops_builtin::core::init_ops());
} }
let ops = Self::collect_ops(&mut options.extensions); let ops = Self::collect_ops(&mut options.extensions);
@ -2683,7 +2683,7 @@ pub mod tests {
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
enum Mode { pub enum Mode {
Async, Async,
AsyncDeferred, AsyncDeferred,
AsyncZeroCopy(bool), AsyncZeroCopy(bool),
@ -2728,18 +2728,22 @@ pub mod tests {
fn setup(mode: Mode) -> (JsRuntime, Arc<AtomicUsize>) { fn setup(mode: Mode) -> (JsRuntime, Arc<AtomicUsize>) {
let dispatch_count = Arc::new(AtomicUsize::new(0)); let dispatch_count = Arc::new(AtomicUsize::new(0));
let dispatch_count2 = dispatch_count.clone(); deno_core::extension!(
let ext = Extension::builder("test_ext") test_ext,
.ops(vec![op_test::decl()]) ops = [op_test],
.state(move |state| { config = {
mode: Mode,
dispatch_count: Arc<AtomicUsize>,
},
state = |state, mode, dispatch_count| {
state.put(TestState { state.put(TestState {
mode, mode,
dispatch_count: dispatch_count2.clone(), dispatch_count
}); })
}) }
.build(); );
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext], extensions: vec![test_ext::init_ops(mode, dispatch_count.clone())],
get_error_class_fn: Some(&|error| { get_error_class_fn: Some(&|error| {
crate::error::get_custom_error_class(error).unwrap() crate::error::get_custom_error_class(error).unwrap()
}), }),
@ -3149,11 +3153,9 @@ pub mod tests {
"DOMExceptionOperationError" "DOMExceptionOperationError"
} }
let ext = Extension::builder("test_ext") deno_core::extension!(test_ext, ops = [op_err]);
.ops(vec![op_err::decl()])
.build();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext], extensions: vec![test_ext::init_ops()],
get_error_class_fn: Some(&get_error_class_name), get_error_class_fn: Some(&get_error_class_name),
..Default::default() ..Default::default()
}); });
@ -3720,11 +3722,9 @@ main();
Err(anyhow!("original async error").context("higher-level async error")) Err(anyhow!("original async error").context("higher-level async error"))
} }
let ext = Extension::builder("test_ext") deno_core::extension!(test_ext, ops = [op_err_sync, op_err_async]);
.ops(vec![op_err_sync::decl(), op_err_async::decl()])
.build();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
@ -3889,15 +3889,13 @@ assertEquals(1, notify_return_value);
Ok(()) Ok(())
} }
let extension = Extension::builder("test_ext") deno_core::extension!(
.ops(vec![op_async_borrow::decl()]) test_ext,
.state(|state| { ops = [op_async_borrow],
state.put(InnerState(42)); state = |state| state.put(InnerState(42))
}) );
.build();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![extension], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
@ -3923,12 +3921,12 @@ assertEquals(1, notify_return_value);
Ok(()) Ok(())
} }
let extension = Extension::builder("test_ext") deno_core::extension!(
.ops(vec![op_sync_serialize_object_with_numbers_as_keys::decl()]) test_ext,
.build(); ops = [op_sync_serialize_object_with_numbers_as_keys]
);
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![extension], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
@ -3965,12 +3963,12 @@ Deno.core.ops.op_sync_serialize_object_with_numbers_as_keys({
Ok(()) Ok(())
} }
let extension = Extension::builder("test_ext") deno_core::extension!(
.ops(vec![op_async_serialize_object_with_numbers_as_keys::decl()]) test_ext,
.build(); ops = [op_async_serialize_object_with_numbers_as_keys]
);
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![extension], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
@ -4004,12 +4002,9 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
Ok(()) Ok(())
} }
let extension = Extension::builder("test_ext") deno_core::extension!(test_ext, ops = [op_async_sleep]);
.ops(vec![op_async_sleep::decl()])
.build();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![extension], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
@ -4084,12 +4079,9 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
Ok(()) Ok(())
} }
let extension = Extension::builder("test_ext") deno_core::extension!(test_ext, ops = [op_macrotask, op_next_tick]);
.ops(vec![op_macrotask::decl(), op_next_tick::decl()])
.build();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![extension], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
@ -4214,12 +4206,9 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
Ok(()) Ok(())
} }
let extension = Extension::builder("test_ext") deno_core::extension!(test_ext, ops = [op_promise_reject]);
.ops(vec![op_promise_reject::decl()])
.build();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![extension], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
@ -4321,9 +4310,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
Ok(()) Ok(())
} }
let extension = Extension::builder("test_ext") deno_core::extension!(test_ext, ops = [op_promise_reject]);
.ops(vec![op_promise_reject::decl()])
.build();
#[derive(Default)] #[derive(Default)]
struct ModsLoader; struct ModsLoader;
@ -4367,7 +4354,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
} }
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![extension], extensions: vec![test_ext::init_ops()],
module_loader: Some(Rc::new(ModsLoader)), module_loader: Some(Rc::new(ModsLoader)),
..Default::default() ..Default::default()
}); });
@ -4390,11 +4377,9 @@ Deno.core.opAsync("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 Ok([(1, 2), (3, 4)].into_iter().collect()) // Maps can't have non-string keys in serde_v8
} }
let ext = Extension::builder("test_ext") deno_core::extension!(test_ext, ops = [op_err]);
.ops(vec![op_err::decl()])
.build();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
assert!(runtime assert!(runtime
@ -4417,11 +4402,9 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
Ok(x1 + x2 + x3 + x4) Ok(x1 + x2 + x3 + x4)
} }
let ext = Extension::builder("test_ext") deno_core::extension!(test_ext, ops = [op_add_4]);
.ops(vec![op_add_4::decl()])
.build();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
let r = runtime let r = runtime
@ -4438,11 +4421,13 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
Ok(42) Ok(42)
} }
let ext = Extension::builder("test_ext") fn ops() -> Vec<OpDecl> {
.ops(vec![op_foo::decl().disable()]) vec![op_foo::decl().disable()]
.build(); }
deno_core::extension!(test_ext, ops_fn = ops);
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
let r = runtime let r = runtime
@ -4468,12 +4453,9 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
Ok(b) Ok(b)
} }
let ext = Extension::builder("test_ext") deno_core::extension!(test_ext, ops = [op_sum_take, op_boomerang]);
.ops(vec![op_sum_take::decl(), op_boomerang::decl()])
.build();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
@ -4536,12 +4518,13 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
Ok(42) Ok(42)
} }
let ext = Extension::builder("test_ext") deno_core::extension!(
.ops(vec![op_foo::decl(), op_bar::decl()]) test_ext,
.middleware(|op| if op.is_unstable { op.disable() } else { op }) ops = [op_foo, op_bar],
.build(); middleware = |op| if op.is_unstable { op.disable() } else { op }
);
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![ext], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });
runtime runtime
@ -4587,10 +4570,9 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
Ok(String::from("Test")) Ok(String::from("Test"))
} }
deno_core::extension!(test_ext, ops = [op_test]);
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![Extension::builder("test_ext") extensions: vec![test_ext::init_ops()],
.ops(vec![op_test::decl()])
.build()],
..Default::default() ..Default::default()
}); });
let realm = runtime.create_realm().unwrap(); let realm = runtime.create_realm().unwrap();
@ -4618,11 +4600,10 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
Ok(String::from("Test")) Ok(String::from("Test"))
} }
deno_core::extension!(test_ext, ops = [op_test]);
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
startup_snapshot: Some(Snapshot::Boxed(snapshot)), startup_snapshot: Some(Snapshot::Boxed(snapshot)),
extensions: vec![Extension::builder("test_ext") extensions: vec![test_ext::init_ops()],
.ops(vec![op_test::decl()])
.build()],
..Default::default() ..Default::default()
}); });
let realm = runtime.create_realm().unwrap(); let realm = runtime.create_realm().unwrap();
@ -4650,10 +4631,9 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
} }
} }
deno_core::extension!(test_ext, ops = [op_test]);
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![Extension::builder("test_ext") extensions: vec![test_ext::init_ops()],
.ops(vec![op_test::decl()])
.build()],
get_error_class_fn: Some(&|error| { get_error_class_fn: Some(&|error| {
crate::error::get_custom_error_class(error).unwrap() crate::error::get_custom_error_class(error).unwrap()
}), }),
@ -4699,10 +4679,9 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
} }
} }
deno_core::extension!(test_ext, ops = [op_test]);
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![Extension::builder("test_ext") extensions: vec![test_ext::init_ops()],
.ops(vec![op_test::decl()])
.build()],
get_error_class_fn: Some(&|error| { get_error_class_fn: Some(&|error| {
crate::error::get_custom_error_class(error).unwrap() crate::error::get_custom_error_class(error).unwrap()
}), }),
@ -4759,10 +4738,9 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
futures::future::pending().await futures::future::pending().await
} }
deno_core::extension!(test_ext, ops = [op_pending]);
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![Extension::builder("test_ext") extensions: vec![test_ext::init_ops()],
.ops(vec![op_pending::decl()])
.build()],
..Default::default() ..Default::default()
}); });

View file

@ -2,7 +2,6 @@
mod in_memory_broadcast_channel; mod in_memory_broadcast_channel;
use deno_core::ExtensionBuilder;
pub use in_memory_broadcast_channel::InMemoryBroadcastChannel; pub use in_memory_broadcast_channel::InMemoryBroadcastChannel;
pub use in_memory_broadcast_channel::InMemoryBroadcastChannelResource; pub use in_memory_broadcast_channel::InMemoryBroadcastChannelResource;
@ -12,9 +11,7 @@ use std::rc::Rc;
use async_trait::async_trait; use async_trait::async_trait;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op; use deno_core::op;
use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
use deno_core::Resource; use deno_core::Resource;
use deno_core::ResourceId; use deno_core::ResourceId;
@ -107,46 +104,25 @@ where
bc.recv(&resource).await bc.recv(&resource).await
} }
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_broadcast_channel,
Extension::builder_with_deps( deps = [ deno_webidl, deno_web ],
env!("CARGO_PKG_NAME"), parameters = [BC: BroadcastChannel],
&["deno_webidl", "deno_web"], ops = [
) op_broadcast_subscribe<BC>,
} op_broadcast_unsubscribe<BC>,
op_broadcast_send<BC>,
fn ops<BC: BroadcastChannel + 'static>( op_broadcast_recv<BC>,
ext: &mut ExtensionBuilder, ],
bc: BC, esm = [ "01_broadcast_channel.js" ],
unstable: bool, config = {
) -> &mut ExtensionBuilder { bc: BC,
ext unstable: bool,
.ops(vec![ },
op_broadcast_subscribe::decl::<BC>(), state = |state, bc, unstable| {
op_broadcast_unsubscribe::decl::<BC>(), state.put(bc);
op_broadcast_send::decl::<BC>(), state.put(Unstable(unstable));
op_broadcast_recv::decl::<BC>(), },
]) );
.state(move |state| {
state.put(bc.clone());
state.put(Unstable(unstable));
})
}
pub fn init_ops_and_esm<BC: BroadcastChannel + 'static>(
bc: BC,
unstable: bool,
) -> Extension {
ops::<BC>(&mut ext(), bc, unstable)
.esm(include_js_files!("01_broadcast_channel.js",))
.build()
}
pub fn init_ops<BC: BroadcastChannel + 'static>(
bc: BC,
unstable: bool,
) -> Extension {
ops::<BC>(&mut ext(), bc, unstable).build()
}
pub fn get_declaration() -> PathBuf { pub fn get_declaration() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")) PathBuf::from(env!("CARGO_MANIFEST_DIR"))

64
ext/cache/lib.rs vendored
View file

@ -7,13 +7,10 @@ use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op; use deno_core::op;
use deno_core::serde::Deserialize; use deno_core::serde::Deserialize;
use deno_core::serde::Serialize; use deno_core::serde::Serialize;
use deno_core::ByteString; use deno_core::ByteString;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState; use deno_core::OpState;
use deno_core::Resource; use deno_core::Resource;
use deno_core::ResourceId; use deno_core::ResourceId;
@ -23,46 +20,27 @@ pub use sqlite::SqliteBackedCache;
#[derive(Clone)] #[derive(Clone)]
pub struct CreateCache<C: Cache + 'static>(pub Arc<dyn Fn() -> C>); pub struct CreateCache<C: Cache + 'static>(pub Arc<dyn Fn() -> C>);
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_cache,
Extension::builder_with_deps( deps = [ deno_webidl, deno_web, deno_url, deno_fetch ],
env!("CARGO_PKG_NAME"), parameters=[CA: Cache],
&["deno_webidl", "deno_web", "deno_url", "deno_fetch"], ops = [
) op_cache_storage_open<CA>,
} op_cache_storage_has<CA>,
op_cache_storage_delete<CA>,
fn ops<CA: Cache + 'static>( op_cache_put<CA>,
ext: &mut ExtensionBuilder, op_cache_match<CA>,
maybe_create_cache: Option<CreateCache<CA>>, op_cache_delete<CA>,
) -> &mut ExtensionBuilder { ],
ext esm = [ "01_cache.js" ],
.ops(vec![ config = {
op_cache_storage_open::decl::<CA>(), maybe_create_cache: Option<CreateCache<CA>>,
op_cache_storage_has::decl::<CA>(), },
op_cache_storage_delete::decl::<CA>(), state = |state, maybe_create_cache| {
op_cache_put::decl::<CA>(), if let Some(create_cache) = maybe_create_cache {
op_cache_match::decl::<CA>(), state.put(create_cache);
op_cache_delete::decl::<CA>(), }
]) },
.state(move |state| { );
if let Some(create_cache) = maybe_create_cache.clone() {
state.put(create_cache);
}
})
}
pub fn init_ops_and_esm<CA: Cache + 'static>(
maybe_create_cache: Option<CreateCache<CA>>,
) -> Extension {
ops::<CA>(&mut ext(), maybe_create_cache)
.esm(include_js_files!("01_cache.js",))
.build()
}
pub fn init_ops<CA: Cache + 'static>(
maybe_create_cache: Option<CreateCache<CA>>,
) -> Extension {
ops::<CA>(&mut ext(), maybe_create_cache).build()
}
pub fn get_declaration() -> PathBuf { pub fn get_declaration() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_cache.d.ts") PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_cache.d.ts")

View file

@ -1,22 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use deno_core::include_js_files;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use std::path::PathBuf; use std::path::PathBuf;
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_console, esm = ["01_colors.js", "02_console.js"],);
Extension::builder(env!("CARGO_PKG_NAME"))
}
pub fn init() -> Extension {
ext().build()
}
pub fn init_esm() -> Extension {
ext()
.esm(include_js_files!("01_colors.js", "02_console.js",))
.build()
}
pub fn get_declaration() -> PathBuf { pub fn get_declaration() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_console.d.ts") PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_console.d.ts")

View file

@ -8,11 +8,8 @@ use deno_core::error::custom_error;
use deno_core::error::not_supported; use deno_core::error::not_supported;
use deno_core::error::type_error; use deno_core::error::type_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op; use deno_core::op;
use deno_core::ExtensionBuilder;
use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
use deno_core::ZeroCopyBuf; use deno_core::ZeroCopyBuf;
use serde::Deserialize; use serde::Deserialize;
@ -73,65 +70,49 @@ use crate::key::CryptoNamedCurve;
use crate::key::HkdfOutput; use crate::key::HkdfOutput;
use crate::shared::RawKeyData; use crate::shared::RawKeyData;
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_crypto,
Extension::builder_with_deps( deps = [ deno_webidl, deno_web ],
env!("CARGO_PKG_NAME"), ops = [
&["deno_webidl", "deno_web"], op_crypto_get_random_values,
) op_crypto_generate_key,
} op_crypto_sign_key,
op_crypto_verify_key,
fn ops( op_crypto_derive_bits,
ext: &mut ExtensionBuilder, op_crypto_import_key,
maybe_seed: Option<u64>, op_crypto_export_key,
) -> &mut ExtensionBuilder { op_crypto_encrypt,
ext op_crypto_decrypt,
.ops(vec![ op_crypto_subtle_digest,
op_crypto_get_random_values::decl(), op_crypto_random_uuid,
op_crypto_generate_key::decl(), op_crypto_wrap_key,
op_crypto_sign_key::decl(), op_crypto_unwrap_key,
op_crypto_verify_key::decl(), op_crypto_base64url_decode,
op_crypto_derive_bits::decl(), op_crypto_base64url_encode,
op_crypto_import_key::decl(), x25519::op_generate_x25519_keypair,
op_crypto_export_key::decl(), x25519::op_derive_bits_x25519,
op_crypto_encrypt::decl(), x25519::op_import_spki_x25519,
op_crypto_decrypt::decl(), x25519::op_import_pkcs8_x25519,
op_crypto_subtle_digest::decl(), ed25519::op_generate_ed25519_keypair,
op_crypto_random_uuid::decl(), ed25519::op_import_spki_ed25519,
op_crypto_wrap_key::decl(), ed25519::op_import_pkcs8_ed25519,
op_crypto_unwrap_key::decl(), ed25519::op_sign_ed25519,
op_crypto_base64url_decode::decl(), ed25519::op_verify_ed25519,
op_crypto_base64url_encode::decl(), ed25519::op_export_spki_ed25519,
x25519::op_generate_x25519_keypair::decl(), ed25519::op_export_pkcs8_ed25519,
x25519::op_derive_bits_x25519::decl(), ed25519::op_jwk_x_ed25519,
x25519::op_import_spki_x25519::decl(), x25519::op_export_spki_x25519,
x25519::op_import_pkcs8_x25519::decl(), x25519::op_export_pkcs8_x25519,
ed25519::op_generate_ed25519_keypair::decl(), ],
ed25519::op_import_spki_ed25519::decl(), esm = [ "00_crypto.js", "01_webidl.js" ],
ed25519::op_import_pkcs8_ed25519::decl(), config = {
ed25519::op_sign_ed25519::decl(), maybe_seed: Option<u64>,
ed25519::op_verify_ed25519::decl(), },
ed25519::op_export_spki_ed25519::decl(), state = |state, maybe_seed| {
ed25519::op_export_pkcs8_ed25519::decl(), if let Some(seed) = maybe_seed {
ed25519::op_jwk_x_ed25519::decl(), state.put(StdRng::seed_from_u64(seed));
x25519::op_export_spki_x25519::decl(), }
x25519::op_export_pkcs8_x25519::decl(), },
]) );
.state(move |state| {
if let Some(seed) = maybe_seed {
state.put(StdRng::seed_from_u64(seed));
}
})
}
pub fn init_ops_and_esm(maybe_seed: Option<u64>) -> Extension {
ops(&mut ext(), maybe_seed)
.esm(include_js_files!("00_crypto.js", "01_webidl.js",))
.build()
}
pub fn init_ops(maybe_seed: Option<u64>) -> Extension {
ops(&mut ext(), maybe_seed).build()
}
#[op] #[op]
pub fn op_crypto_base64url_decode(data: String) -> ZeroCopyBuf { pub fn op_crypto_base64url_decode(data: String) -> ZeroCopyBuf {

View file

@ -10,10 +10,8 @@ use deno_core::futures::stream::Peekable;
use deno_core::futures::Future; use deno_core::futures::Future;
use deno_core::futures::Stream; use deno_core::futures::Stream;
use deno_core::futures::StreamExt; use deno_core::futures::StreamExt;
use deno_core::include_js_files;
use deno_core::op; use deno_core::op;
use deno_core::BufView; use deno_core::BufView;
use deno_core::ExtensionBuilder;
use deno_core::WriteOutcome; use deno_core::WriteOutcome;
use deno_core::url::Url; use deno_core::url::Url;
@ -24,7 +22,6 @@ use deno_core::CancelFuture;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::CancelTryFuture; use deno_core::CancelTryFuture;
use deno_core::Canceled; use deno_core::Canceled;
use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
use deno_core::RcRef; use deno_core::RcRef;
use deno_core::Resource; use deno_core::Resource;
@ -93,65 +90,41 @@ impl Default for Options {
} }
} }
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_fetch,
Extension::builder_with_deps( deps = [ deno_webidl, deno_web, deno_url, deno_console ],
env!("CARGO_PKG_NAME"), parameters = [FP: FetchPermissions],
&["deno_webidl", "deno_web", "deno_url", "deno_console"], ops = [
) op_fetch<FP>,
} op_fetch_send,
op_fetch_custom_client<FP>,
fn ops<FP>( ],
ext: &mut ExtensionBuilder, esm = [
options: Options, "20_headers.js",
) -> &mut ExtensionBuilder "21_formdata.js",
where "22_body.js",
FP: FetchPermissions + 'static, "22_http_client.js",
{ "23_request.js",
ext "23_response.js",
.ops(vec![ "26_fetch.js"
op_fetch::decl::<FP>(), ],
op_fetch_send::decl(), config = {
op_fetch_custom_client::decl::<FP>(), options: Options,
]) },
.state(move |state| { state = |state, options| {
state.put::<Options>(options.clone()); state.put::<Options>(options.clone());
state.put::<reqwest::Client>({ state.put::<reqwest::Client>({
create_http_client( create_http_client(
options.user_agent.clone(), options.user_agent,
options.root_cert_store.clone(), options.root_cert_store,
vec![], vec![],
options.proxy.clone(), options.proxy,
options.unsafely_ignore_certificate_errors.clone(), options.unsafely_ignore_certificate_errors,
options.client_cert_chain_and_key.clone(), options.client_cert_chain_and_key
) )
.unwrap() .unwrap()
}); });
}) },
} );
pub fn init_ops_and_esm<FP>(options: Options) -> Extension
where
FP: FetchPermissions + 'static,
{
ops::<FP>(&mut ext(), options)
.esm(include_js_files!(
"20_headers.js",
"21_formdata.js",
"22_body.js",
"22_http_client.js",
"23_request.js",
"23_response.js",
"26_fetch.js",
))
.build()
}
pub fn init_ops<FP>(options: Options) -> Extension
where
FP: FetchPermissions + 'static,
{
ops::<FP>(&mut ext(), options).build()
}
pub type CancelableResponseFuture = pub type CancelableResponseFuture =
Pin<Box<dyn Future<Output = CancelableResponseResult>>>; Pin<Box<dyn Future<Output = CancelableResponseResult>>>;

View file

@ -2,10 +2,7 @@
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::futures::channel::mpsc; use deno_core::futures::channel::mpsc;
use deno_core::include_js_files;
use deno_core::v8; use deno_core::v8;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState; use deno_core::OpState;
use std::cell::RefCell; use std::cell::RefCell;
@ -82,92 +79,83 @@ pub(crate) struct FfiState {
pub(crate) async_work_receiver: mpsc::UnboundedReceiver<PendingFfiAsyncWork>, pub(crate) async_work_receiver: mpsc::UnboundedReceiver<PendingFfiAsyncWork>,
} }
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_ffi,
Extension::builder_with_deps(env!("CARGO_PKG_NAME"), &["deno_web"]) deps = [ deno_web ],
} parameters = [P: FfiPermissions],
ops = [
fn ops<P: FfiPermissions + 'static>( op_ffi_load<P>,
ext: &mut ExtensionBuilder, op_ffi_get_static,
unstable: bool, op_ffi_call_nonblocking,
) -> &mut ExtensionBuilder { op_ffi_call_ptr<P>,
ext op_ffi_call_ptr_nonblocking<P>,
.ops(vec![ op_ffi_ptr_create<P>,
op_ffi_load::decl::<P>(), op_ffi_ptr_equals<P>,
op_ffi_get_static::decl(), op_ffi_ptr_of<P>,
op_ffi_call_nonblocking::decl(), op_ffi_ptr_offset<P>,
op_ffi_call_ptr::decl::<P>(), op_ffi_ptr_value<P>,
op_ffi_call_ptr_nonblocking::decl::<P>(), op_ffi_get_buf<P>,
op_ffi_ptr_create::decl::<P>(), op_ffi_buf_copy_into<P>,
op_ffi_ptr_equals::decl::<P>(), op_ffi_cstr_read<P>,
op_ffi_ptr_of::decl::<P>(), op_ffi_read_bool<P>,
op_ffi_ptr_offset::decl::<P>(), op_ffi_read_u8<P>,
op_ffi_ptr_value::decl::<P>(), op_ffi_read_i8<P>,
op_ffi_get_buf::decl::<P>(), op_ffi_read_u16<P>,
op_ffi_buf_copy_into::decl::<P>(), op_ffi_read_i16<P>,
op_ffi_cstr_read::decl::<P>(), op_ffi_read_u32<P>,
op_ffi_read_bool::decl::<P>(), op_ffi_read_i32<P>,
op_ffi_read_u8::decl::<P>(), op_ffi_read_u64<P>,
op_ffi_read_i8::decl::<P>(), op_ffi_read_i64<P>,
op_ffi_read_u16::decl::<P>(), op_ffi_read_f32<P>,
op_ffi_read_i16::decl::<P>(), op_ffi_read_f64<P>,
op_ffi_read_u32::decl::<P>(), op_ffi_read_ptr<P>,
op_ffi_read_i32::decl::<P>(), op_ffi_unsafe_callback_create<P>,
op_ffi_read_u64::decl::<P>(), op_ffi_unsafe_callback_ref,
op_ffi_read_i64::decl::<P>(), ],
op_ffi_read_f32::decl::<P>(), esm = [ "00_ffi.js" ],
op_ffi_read_f64::decl::<P>(), config = {
op_ffi_read_ptr::decl::<P>(), unstable: bool,
op_ffi_unsafe_callback_create::decl::<P>(), },
op_ffi_unsafe_callback_ref::decl(), state = |state, unstable| {
]) // Stolen from deno_webgpu, is there a better option?
.event_loop_middleware(|op_state_rc, _cx| { state.put(Unstable(unstable));
// FFI callbacks coming in from other threads will call in and get queued.
let mut maybe_scheduling = false; let (async_work_sender, async_work_receiver) =
mpsc::unbounded::<PendingFfiAsyncWork>();
let mut work_items: Vec<PendingFfiAsyncWork> = vec![];
state.put(FfiState {
{ async_work_receiver,
let mut op_state = op_state_rc.borrow_mut(); async_work_sender,
let ffi_state = op_state.borrow_mut::<FfiState>(); });
},
while let Ok(Some(async_work_fut)) = event_loop_middleware = event_loop_middleware,
ffi_state.async_work_receiver.try_next() );
{
// Move received items to a temporary vector so that we can drop the `op_state` borrow before we do the work. fn event_loop_middleware(
work_items.push(async_work_fut); op_state_rc: Rc<RefCell<OpState>>,
maybe_scheduling = true; _cx: &mut std::task::Context,
} ) -> bool {
// FFI callbacks coming in from other threads will call in and get queued.
drop(op_state); let mut maybe_scheduling = false;
}
while let Some(async_work_fut) = work_items.pop() { let mut work_items: Vec<PendingFfiAsyncWork> = vec![];
async_work_fut();
} {
let mut op_state = op_state_rc.borrow_mut();
maybe_scheduling let ffi_state = op_state.borrow_mut::<FfiState>();
})
.state(move |state| { while let Ok(Some(async_work_fut)) =
// Stolen from deno_webgpu, is there a better option? ffi_state.async_work_receiver.try_next()
state.put(Unstable(unstable)); {
// Move received items to a temporary vector so that we can drop the `op_state` borrow before we do the work.
let (async_work_sender, async_work_receiver) = work_items.push(async_work_fut);
mpsc::unbounded::<PendingFfiAsyncWork>(); maybe_scheduling = true;
}
state.put(FfiState {
async_work_receiver, drop(op_state);
async_work_sender, }
}); while let Some(async_work_fut) = work_items.pop() {
}) async_work_fut();
} }
pub fn init_ops_and_esm<P: FfiPermissions + 'static>( maybe_scheduling
unstable: bool,
) -> Extension {
ops::<P>(&mut ext(), unstable)
.esm(include_js_files!("00_ffi.js",))
.build()
}
pub fn init_ops<P: FfiPermissions + 'static>(unstable: bool) -> Extension {
ops::<P>(&mut ext(), unstable).build()
} }

View file

@ -16,8 +16,6 @@ use deno_core::v8::fast_api;
use deno_core::ByteString; use deno_core::ByteString;
use deno_core::CancelFuture; use deno_core::CancelFuture;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState; use deno_core::OpState;
use deno_core::StringOrBuffer; use deno_core::StringOrBuffer;
use deno_core::ZeroCopyBuf; use deno_core::ZeroCopyBuf;
@ -1527,66 +1525,49 @@ pub trait FlashPermissions {
) -> Result<(), AnyError>; ) -> Result<(), AnyError>;
} }
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_flash,
Extension::builder_with_deps( deps = [
env!("CARGO_PKG_NAME"), deno_web,
&[ deno_net,
"deno_web", deno_fetch,
"deno_net", deno_websocket,
"deno_fetch", deno_http
"deno_websocket", ],
"deno_http", parameters = [P: FlashPermissions],
], ops = [
) op_flash_serve<P>,
} op_node_unstable_flash_serve<P>,
op_flash_respond,
fn ops<P: FlashPermissions + 'static>( op_flash_respond_async,
ext: &mut ExtensionBuilder, op_flash_respond_chunked,
unstable: bool, op_flash_method,
) -> &mut ExtensionBuilder { op_flash_path,
ext op_flash_headers,
.ops(vec![ op_flash_addr,
op_flash_serve::decl::<P>(), op_flash_next,
op_node_unstable_flash_serve::decl::<P>(), op_flash_next_server,
op_flash_respond::decl(), op_flash_next_async,
op_flash_respond_async::decl(), op_flash_read_body,
op_flash_respond_chunked::decl(), op_flash_upgrade_websocket,
op_flash_method::decl(), op_flash_drive_server,
op_flash_path::decl(), op_flash_wait_for_listening,
op_flash_headers::decl(), op_flash_first_packet,
op_flash_addr::decl(), op_flash_has_body_stream,
op_flash_next::decl(), op_flash_close_server,
op_flash_next_server::decl(), op_flash_make_request,
op_flash_next_async::decl(), op_flash_write_resource,
op_flash_read_body::decl(), op_try_flash_respond_chunked,
op_flash_upgrade_websocket::decl(), ],
op_flash_drive_server::decl(), esm = [ "01_http.js" ],
op_flash_wait_for_listening::decl(), config = {
op_flash_first_packet::decl(), unstable: bool,
op_flash_has_body_stream::decl(), },
op_flash_close_server::decl(), state = |state, unstable| {
op_flash_make_request::decl(), state.put(Unstable(unstable));
op_flash_write_resource::decl(), state.put(FlashContext {
op_try_flash_respond_chunked::decl(), next_server_id: 0,
]) join_handles: HashMap::default(),
.state(move |op_state| { servers: HashMap::default(),
op_state.put(Unstable(unstable)); });
op_state.put(FlashContext { },
next_server_id: 0, );
join_handles: HashMap::default(),
servers: HashMap::default(),
});
})
}
pub fn init_ops_and_esm<P: FlashPermissions + 'static>(
unstable: bool,
) -> Extension {
ops::<P>(&mut ext(), unstable)
.esm(deno_core::include_js_files!("01_http.js",))
.build()
}
pub fn init_ops<P: FlashPermissions + 'static>(unstable: bool) -> Extension {
ops::<P>(&mut ext(), unstable).build()
}

View file

@ -4,12 +4,9 @@
use deno_core::error::custom_error; use deno_core::error::custom_error;
use deno_core::error::type_error; use deno_core::error::type_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op; use deno_core::op;
use deno_core::CancelFuture; use deno_core::CancelFuture;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState; use deno_core::OpState;
use deno_core::ResourceId; use deno_core::ResourceId;
use deno_core::ZeroCopyBuf; use deno_core::ZeroCopyBuf;
@ -118,92 +115,78 @@ use deno_core::error::generic_error;
#[cfg(not(unix))] #[cfg(not(unix))]
use deno_core::error::not_supported; use deno_core::error::not_supported;
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_fs,
Extension::builder("deno_fs") deps = [ deno_web, deno_io ],
} parameters = [P: FsPermissions],
ops = [
fn ops<P: FsPermissions + 'static>( op_open_sync<P>,
ext: &mut ExtensionBuilder, op_open_async<P>,
unstable: bool, op_write_file_sync<P>,
) -> &mut ExtensionBuilder { op_write_file_async<P>,
ext op_seek_sync,
.state(move |state| { op_seek_async,
state.put(UnstableChecker { unstable }); op_fdatasync_sync,
}) op_fdatasync_async,
.ops(vec![ op_fsync_sync,
op_open_sync::decl::<P>(), op_fsync_async,
op_open_async::decl::<P>(), op_fstat_sync,
op_write_file_sync::decl::<P>(), op_fstat_async,
op_write_file_async::decl::<P>(), op_flock_sync,
op_seek_sync::decl(), op_flock_async,
op_seek_async::decl(), op_funlock_sync,
op_fdatasync_sync::decl(), op_funlock_async,
op_fdatasync_async::decl(), op_umask,
op_fsync_sync::decl(), op_chdir<P>,
op_fsync_async::decl(), op_mkdir_sync<P>,
op_fstat_sync::decl(), op_mkdir_async<P>,
op_fstat_async::decl(), op_chmod_sync<P>,
op_flock_sync::decl(), op_chmod_async<P>,
op_flock_async::decl(), op_chown_sync<P>,
op_funlock_sync::decl(), op_chown_async<P>,
op_funlock_async::decl(), op_remove_sync<P>,
op_umask::decl(), op_remove_async<P>,
op_chdir::decl::<P>(), op_copy_file_sync<P>,
op_mkdir_sync::decl::<P>(), op_copy_file_async<P>,
op_mkdir_async::decl::<P>(), op_stat_sync<P>,
op_chmod_sync::decl::<P>(), op_stat_async<P>,
op_chmod_async::decl::<P>(), op_realpath_sync<P>,
op_chown_sync::decl::<P>(), op_realpath_async<P>,
op_chown_async::decl::<P>(), op_read_dir_sync<P>,
op_remove_sync::decl::<P>(), op_read_dir_async<P>,
op_remove_async::decl::<P>(), op_rename_sync<P>,
op_copy_file_sync::decl::<P>(), op_rename_async<P>,
op_copy_file_async::decl::<P>(), op_link_sync<P>,
op_stat_sync::decl::<P>(), op_link_async<P>,
op_stat_async::decl::<P>(), op_symlink_sync<P>,
op_realpath_sync::decl::<P>(), op_symlink_async<P>,
op_realpath_async::decl::<P>(), op_read_link_sync<P>,
op_read_dir_sync::decl::<P>(), op_read_link_async<P>,
op_read_dir_async::decl::<P>(), op_ftruncate_sync,
op_rename_sync::decl::<P>(), op_ftruncate_async,
op_rename_async::decl::<P>(), op_truncate_sync<P>,
op_link_sync::decl::<P>(), op_truncate_async<P>,
op_link_async::decl::<P>(), op_make_temp_dir_sync<P>,
op_symlink_sync::decl::<P>(), op_make_temp_dir_async<P>,
op_symlink_async::decl::<P>(), op_make_temp_file_sync<P>,
op_read_link_sync::decl::<P>(), op_make_temp_file_async<P>,
op_read_link_async::decl::<P>(), op_cwd<P>,
op_ftruncate_sync::decl(), op_futime_sync,
op_ftruncate_async::decl(), op_futime_async,
op_truncate_sync::decl::<P>(), op_utime_sync<P>,
op_truncate_async::decl::<P>(), op_utime_async<P>,
op_make_temp_dir_sync::decl::<P>(), op_readfile_sync<P>,
op_make_temp_dir_async::decl::<P>(), op_readfile_text_sync<P>,
op_make_temp_file_sync::decl::<P>(), op_readfile_async<P>,
op_make_temp_file_async::decl::<P>(), op_readfile_text_async<P>,
op_cwd::decl::<P>(), ],
op_futime_sync::decl(), esm = [ "30_fs.js" ],
op_futime_async::decl(), config = {
op_utime_sync::decl::<P>(), unstable: bool
op_utime_async::decl::<P>(), },
op_readfile_sync::decl::<P>(), state = |state, unstable| {
op_readfile_text_sync::decl::<P>(), state.put(UnstableChecker { unstable });
op_readfile_async::decl::<P>(), },
op_readfile_text_async::decl::<P>(), );
])
}
pub fn init_ops_and_esm<P: FsPermissions + 'static>(
unstable: bool,
) -> Extension {
ops::<P>(&mut ext(), unstable)
.esm(include_js_files!("30_fs.js",))
.build()
}
pub fn init_ops<P: FsPermissions + 'static>(unstable: bool) -> Extension {
ops::<P>(&mut ext(), unstable).build()
}
fn default_err_mapper(err: Error, desc: String) -> Error { fn default_err_mapper(err: Error, desc: String) -> Error {
Error::new(err.kind(), format!("{err}, {desc}")) Error::new(err.kind(), format!("{err}, {desc}"))

View file

@ -19,7 +19,6 @@ use deno_core::futures::stream::Peekable;
use deno_core::futures::FutureExt; use deno_core::futures::FutureExt;
use deno_core::futures::StreamExt; use deno_core::futures::StreamExt;
use deno_core::futures::TryFutureExt; use deno_core::futures::TryFutureExt;
use deno_core::include_js_files;
use deno_core::op; use deno_core::op;
use deno_core::AsyncRefCell; use deno_core::AsyncRefCell;
use deno_core::AsyncResult; use deno_core::AsyncResult;
@ -28,8 +27,6 @@ use deno_core::ByteString;
use deno_core::CancelFuture; use deno_core::CancelFuture;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::CancelTryFuture; use deno_core::CancelTryFuture;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState; use deno_core::OpState;
use deno_core::RcRef; use deno_core::RcRef;
use deno_core::Resource; use deno_core::Resource;
@ -78,35 +75,21 @@ use crate::reader_stream::ShutdownHandle;
pub mod compressible; pub mod compressible;
mod reader_stream; mod reader_stream;
fn ext() -> ExtensionBuilder { deno_core::extension!(
Extension::builder_with_deps( deno_http,
env!("CARGO_PKG_NAME"), deps = [deno_web, deno_net, deno_fetch, deno_websocket],
&["deno_web", "deno_net", "deno_fetch", "deno_websocket"], ops = [
) op_http_accept,
} op_http_write_headers,
op_http_headers,
fn ops(ext: &mut ExtensionBuilder) -> &mut ExtensionBuilder { op_http_write,
ext.ops(vec![ op_http_write_resource,
op_http_accept::decl(), op_http_shutdown,
op_http_write_headers::decl(), op_http_websocket_accept_header,
op_http_headers::decl(), op_http_upgrade_websocket,
op_http_write::decl(), ],
op_http_write_resource::decl(), esm = ["01_http.js"],
op_http_shutdown::decl(), );
op_http_websocket_accept_header::decl(),
op_http_upgrade_websocket::decl(),
])
}
pub fn init_ops_and_esm() -> Extension {
ops(&mut ext())
.esm(include_js_files!("01_http.js",))
.build()
}
pub fn init_ops() -> Extension {
ops(&mut ext()).build()
}
pub enum HttpSocketAddr { pub enum HttpSocketAddr {
IpSocket(std::net::SocketAddr), IpSocket(std::net::SocketAddr),

View file

@ -2,7 +2,6 @@
use deno_core::error::resource_unavailable; use deno_core::error::resource_unavailable;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op; use deno_core::op;
use deno_core::parking_lot::Mutex; use deno_core::parking_lot::Mutex;
use deno_core::AsyncMutFuture; use deno_core::AsyncMutFuture;
@ -12,8 +11,6 @@ use deno_core::BufMutView;
use deno_core::BufView; use deno_core::BufView;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::CancelTryFuture; use deno_core::CancelTryFuture;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState; use deno_core::OpState;
use deno_core::RcRef; use deno_core::RcRef;
use deno_core::Resource; use deno_core::Resource;
@ -79,80 +76,61 @@ pub static STDERR_HANDLE: Lazy<StdFile> = Lazy::new(|| {
unsafe { StdFile::from_raw_handle(GetStdHandle(winbase::STD_ERROR_HANDLE)) } unsafe { StdFile::from_raw_handle(GetStdHandle(winbase::STD_ERROR_HANDLE)) }
}); });
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_io,
Extension::builder_with_deps("deno_io", &["deno_web"]) deps = [ deno_web ],
} ops = [op_read_sync, op_write_sync],
esm = [ "12_io.js" ],
config = {
stdio: Rc<RefCell<Option<Stdio>>>,
},
middleware = |op| match op.name {
"op_print" => op_print::decl(),
_ => op,
},
state = |state, stdio| {
let stdio = stdio
.borrow_mut()
.take()
.expect("Extension only supports being used once.");
let t = &mut state.resource_table;
fn ops( let rid = t.add(StdFileResource::stdio(
ext: &mut ExtensionBuilder, match stdio.stdin {
stdio: Rc<RefCell<Option<Stdio>>>, StdioPipe::Inherit => StdFileResourceInner {
) -> &mut ExtensionBuilder { kind: StdFileResourceKind::Stdin,
ext file: STDIN_HANDLE.try_clone().unwrap(),
.ops(vec![op_read_sync::decl(), op_write_sync::decl()])
.middleware(|op| match op.name {
"op_print" => op_print::decl(),
_ => op,
})
.state(move |state| {
let stdio = stdio
.borrow_mut()
.take()
.expect("Extension only supports being used once.");
let t = &mut state.resource_table;
let rid = t.add(StdFileResource::stdio(
match stdio.stdin {
StdioPipe::Inherit => StdFileResourceInner {
kind: StdFileResourceKind::Stdin,
file: STDIN_HANDLE.try_clone().unwrap(),
},
StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
}, },
"stdin", StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
)); },
assert_eq!(rid, 0, "stdin must have ResourceId 0"); "stdin",
));
assert_eq!(rid, 0, "stdin must have ResourceId 0");
let rid = t.add(StdFileResource::stdio( let rid = t.add(StdFileResource::stdio(
match stdio.stdout { match stdio.stdout {
StdioPipe::Inherit => StdFileResourceInner { StdioPipe::Inherit => StdFileResourceInner {
kind: StdFileResourceKind::Stdout, kind: StdFileResourceKind::Stdout,
file: STDOUT_HANDLE.try_clone().unwrap(), file: STDOUT_HANDLE.try_clone().unwrap(),
},
StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
}, },
"stdout", StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
)); },
assert_eq!(rid, 1, "stdout must have ResourceId 1"); "stdout",
));
assert_eq!(rid, 1, "stdout must have ResourceId 1");
let rid = t.add(StdFileResource::stdio( let rid = t.add(StdFileResource::stdio(
match stdio.stderr { match stdio.stderr {
StdioPipe::Inherit => StdFileResourceInner { StdioPipe::Inherit => StdFileResourceInner {
kind: StdFileResourceKind::Stderr, kind: StdFileResourceKind::Stderr,
file: STDERR_HANDLE.try_clone().unwrap(), file: STDERR_HANDLE.try_clone().unwrap(),
},
StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
}, },
"stderr", StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
)); },
assert_eq!(rid, 2, "stderr must have ResourceId 2"); "stderr",
}) ));
} assert_eq!(rid, 2, "stderr must have ResourceId 2");
},
pub fn init_ops_and_esm(stdio: Stdio) -> Extension { );
// todo(dsheret): don't do this? Taking out the writers was necessary to prevent invalid handle panics
let stdio = Rc::new(RefCell::new(Some(stdio)));
ops(&mut ext(), stdio)
.esm(include_js_files!("12_io.js",))
.build()
}
pub fn init_ops(stdio: Stdio) -> Extension {
// todo(dsheret): don't do this? Taking out the writers was necessary to prevent invalid handle panics
let stdio = Rc::new(RefCell::new(Some(stdio)));
ops(&mut ext(), stdio).build()
}
pub enum StdioPipe { pub enum StdioPipe {
Inherit, Inherit,

View file

@ -13,7 +13,6 @@ use deno_core::futures::StreamExt;
use deno_core::op; use deno_core::op;
use deno_core::parking_lot::Mutex; use deno_core::parking_lot::Mutex;
use deno_core::serde_v8; use deno_core::serde_v8;
use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
use std::cell::RefCell; use std::cell::RefCell;
use std::ffi::CString; use std::ffi::CString;
@ -514,72 +513,78 @@ impl Env {
} }
} }
pub fn init_ops<P: NapiPermissions + 'static>() -> Extension { deno_core::extension!(deno_napi,
Extension::builder(env!("CARGO_PKG_NAME")) parameters = [P: NapiPermissions],
.ops(vec![op_napi_open::decl::<P>()]) ops = [
.event_loop_middleware(|op_state_rc, cx| { op_napi_open<P>
// `work` can call back into the runtime. It can also schedule an async task ],
// but we don't know that now. We need to make the runtime re-poll to make state = |state| {
// sure no pending NAPI tasks exist. let (async_work_sender, async_work_receiver) =
let mut maybe_scheduling = false; mpsc::unbounded::<PendingNapiAsyncWork>();
let (threadsafe_function_sender, threadsafe_function_receiver) =
mpsc::unbounded::<ThreadSafeFunctionStatus>();
state.put(NapiState {
pending_async_work: Vec::new(),
async_work_sender,
async_work_receiver,
threadsafe_function_sender,
threadsafe_function_receiver,
active_threadsafe_functions: 0,
env_cleanup_hooks: Rc::new(RefCell::new(vec![])),
tsfn_ref_counters: Arc::new(Mutex::new(vec![])),
});
},
event_loop_middleware = event_loop_middleware,
);
{ fn event_loop_middleware(
let mut op_state = op_state_rc.borrow_mut(); op_state_rc: Rc<RefCell<OpState>>,
let napi_state = op_state.borrow_mut::<NapiState>(); cx: &mut std::task::Context,
) -> bool {
// `work` can call back into the runtime. It can also schedule an async task
// but we don't know that now. We need to make the runtime re-poll to make
// sure no pending NAPI tasks exist.
let mut maybe_scheduling = false;
while let Poll::Ready(Some(async_work_fut)) = {
napi_state.async_work_receiver.poll_next_unpin(cx) let mut op_state = op_state_rc.borrow_mut();
{ let napi_state = op_state.borrow_mut::<NapiState>();
napi_state.pending_async_work.push(async_work_fut);
}
if napi_state.active_threadsafe_functions > 0 { while let Poll::Ready(Some(async_work_fut)) =
maybe_scheduling = true; napi_state.async_work_receiver.poll_next_unpin(cx)
} {
napi_state.pending_async_work.push(async_work_fut);
}
let tsfn_ref_counters = napi_state.tsfn_ref_counters.lock().clone(); if napi_state.active_threadsafe_functions > 0 {
for (_id, counter) in tsfn_ref_counters.iter() { maybe_scheduling = true;
if counter.load(std::sync::atomic::Ordering::SeqCst) > 0 { }
maybe_scheduling = true;
break; let tsfn_ref_counters = napi_state.tsfn_ref_counters.lock().clone();
} for (_id, counter) in tsfn_ref_counters.iter() {
} if counter.load(std::sync::atomic::Ordering::SeqCst) > 0 {
maybe_scheduling = true;
break;
} }
}
}
loop { loop {
let maybe_work = { let maybe_work = {
let mut op_state = op_state_rc.borrow_mut(); let mut op_state = op_state_rc.borrow_mut();
let napi_state = op_state.borrow_mut::<NapiState>(); let napi_state = op_state.borrow_mut::<NapiState>();
napi_state.pending_async_work.pop() napi_state.pending_async_work.pop()
}; };
if let Some(work) = maybe_work { if let Some(work) = maybe_work {
work(); work();
maybe_scheduling = true; maybe_scheduling = true;
} else { } else {
break; break;
} }
} }
maybe_scheduling maybe_scheduling
})
.state(move |state| {
let (async_work_sender, async_work_receiver) =
mpsc::unbounded::<PendingNapiAsyncWork>();
let (threadsafe_function_sender, threadsafe_function_receiver) =
mpsc::unbounded::<ThreadSafeFunctionStatus>();
state.put(NapiState {
pending_async_work: Vec::new(),
async_work_sender,
async_work_receiver,
threadsafe_function_sender,
threadsafe_function_receiver,
active_threadsafe_functions: 0,
env_cleanup_hooks: Rc::new(RefCell::new(vec![])),
tsfn_ref_counters: Arc::new(Mutex::new(vec![])),
});
})
.build()
} }
pub trait NapiPermissions { pub trait NapiPermissions {

View file

@ -8,9 +8,6 @@ pub mod ops_unix;
pub mod resolve_addr; pub mod resolve_addr;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState; use deno_core::OpState;
use deno_tls::rustls::RootCertStore; use deno_tls::rustls::RootCertStore;
use std::cell::RefCell; use std::cell::RefCell;
@ -78,55 +75,48 @@ pub struct DefaultTlsOptions {
/// would override previously used alias. /// would override previously used alias.
pub struct UnsafelyIgnoreCertificateErrors(pub Option<Vec<String>>); pub struct UnsafelyIgnoreCertificateErrors(pub Option<Vec<String>>);
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_net,
Extension::builder_with_deps(env!("CARGO_PKG_NAME"), &["deno_web"]) deps = [ deno_web ],
} parameters = [ P: NetPermissions ],
ops = [
ops::op_net_accept_tcp,
ops::op_net_connect_tcp<P>,
ops::op_net_listen_tcp<P>,
ops::op_net_listen_udp<P>,
ops::op_node_unstable_net_listen_udp<P>,
ops::op_net_recv_udp,
ops::op_net_send_udp<P>,
ops::op_dns_resolve<P>,
ops::op_set_nodelay,
ops::op_set_keepalive,
fn ops<P: NetPermissions + 'static>( ops_tls::op_tls_start<P>,
ext: &mut ExtensionBuilder, ops_tls::op_net_connect_tls<P>,
root_cert_store: Option<RootCertStore>, ops_tls::op_net_listen_tls<P>,
unstable: bool, ops_tls::op_net_accept_tls,
unsafely_ignore_certificate_errors: Option<Vec<String>>, ops_tls::op_tls_handshake,
) -> &mut ExtensionBuilder {
let mut ops = ops::init::<P>();
ops.extend(ops_tls::init::<P>());
ext.ops(ops).state(move |state| { #[cfg(unix)] ops_unix::op_net_accept_unix,
#[cfg(unix)] ops_unix::op_net_connect_unix<P>,
#[cfg(unix)] ops_unix::op_net_listen_unix<P>,
#[cfg(unix)] ops_unix::op_net_listen_unixpacket<P>,
#[cfg(unix)] ops_unix::op_node_unstable_net_listen_unixpacket<P>,
#[cfg(unix)] ops_unix::op_net_recv_unixpacket,
#[cfg(unix)] ops_unix::op_net_send_unixpacket<P>,
],
esm = [ "01_net.js", "02_tls.js" ],
config = {
root_cert_store: Option<RootCertStore>,
unstable: bool,
unsafely_ignore_certificate_errors: Option<Vec<String>>,
},
state = |state, root_cert_store, unstable, unsafely_ignore_certificate_errors| {
state.put(DefaultTlsOptions { state.put(DefaultTlsOptions {
root_cert_store: root_cert_store.clone(), root_cert_store,
}); });
state.put(UnstableChecker { unstable }); state.put(UnstableChecker { unstable });
state.put(UnsafelyIgnoreCertificateErrors( state.put(UnsafelyIgnoreCertificateErrors(
unsafely_ignore_certificate_errors.clone(), unsafely_ignore_certificate_errors,
)); ));
}) },
} );
pub fn init_ops_and_esm<P: NetPermissions + 'static>(
root_cert_store: Option<RootCertStore>,
unstable: bool,
unsafely_ignore_certificate_errors: Option<Vec<String>>,
) -> Extension {
ops::<P>(
&mut ext(),
root_cert_store,
unstable,
unsafely_ignore_certificate_errors,
)
.esm(include_js_files!("01_net.js", "02_tls.js",))
.build()
}
pub fn init_ops<P: NetPermissions + 'static>(
root_cert_store: Option<RootCertStore>,
unstable: bool,
unsafely_ignore_certificate_errors: Option<Vec<String>>,
) -> Extension {
ops::<P>(
&mut ext(),
root_cert_store,
unstable,
unsafely_ignore_certificate_errors,
)
.build()
}

View file

@ -15,7 +15,6 @@ use deno_core::AsyncRefCell;
use deno_core::ByteString; use deno_core::ByteString;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::CancelTryFuture; use deno_core::CancelTryFuture;
use deno_core::OpDecl;
use deno_core::OpState; use deno_core::OpState;
use deno_core::RcRef; use deno_core::RcRef;
use deno_core::Resource; use deno_core::Resource;
@ -44,35 +43,6 @@ use trust_dns_resolver::error::ResolveErrorKind;
use trust_dns_resolver::system_conf; use trust_dns_resolver::system_conf;
use trust_dns_resolver::AsyncResolver; use trust_dns_resolver::AsyncResolver;
pub fn init<P: NetPermissions + 'static>() -> Vec<OpDecl> {
vec![
op_net_accept_tcp::decl(),
#[cfg(unix)]
crate::ops_unix::op_net_accept_unix::decl(),
op_net_connect_tcp::decl::<P>(),
#[cfg(unix)]
crate::ops_unix::op_net_connect_unix::decl::<P>(),
op_net_listen_tcp::decl::<P>(),
op_net_listen_udp::decl::<P>(),
op_node_unstable_net_listen_udp::decl::<P>(),
#[cfg(unix)]
crate::ops_unix::op_net_listen_unix::decl::<P>(),
#[cfg(unix)]
crate::ops_unix::op_net_listen_unixpacket::decl::<P>(),
#[cfg(unix)]
crate::ops_unix::op_node_unstable_net_listen_unixpacket::decl::<P>(),
op_net_recv_udp::decl(),
#[cfg(unix)]
crate::ops_unix::op_net_recv_unixpacket::decl(),
op_net_send_udp::decl::<P>(),
#[cfg(unix)]
crate::ops_unix::op_net_send_unixpacket::decl::<P>(),
op_dns_resolve::decl::<P>(),
op_set_nodelay::decl(),
op_set_keepalive::decl(),
]
}
#[derive(Serialize, Clone, Debug)] #[derive(Serialize, Clone, Debug)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct TlsHandshakeInfo { pub struct TlsHandshakeInfo {
@ -650,7 +620,6 @@ fn rdata_to_return_record(
mod tests { mod tests {
use super::*; use super::*;
use crate::UnstableChecker; use crate::UnstableChecker;
use deno_core::Extension;
use deno_core::JsRuntime; use deno_core::JsRuntime;
use deno_core::RuntimeOptions; use deno_core::RuntimeOptions;
use socket2::SockRef; use socket2::SockRef;
@ -906,15 +875,17 @@ mod tests {
let listener = TcpListener::bind(addr).await.unwrap(); let listener = TcpListener::bind(addr).await.unwrap();
let _ = listener.accept().await; let _ = listener.accept().await;
}); });
let my_ext = Extension::builder("test_ext")
.state(move |state| { deno_core::extension!(
test_ext,
state = |state| {
state.put(TestPermission {}); state.put(TestPermission {});
state.put(UnstableChecker { unstable: true }); state.put(UnstableChecker { unstable: true });
}) }
.build(); );
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![my_ext], extensions: vec![test_ext::init_ops()],
..Default::default() ..Default::default()
}); });

View file

@ -31,7 +31,6 @@ use deno_core::AsyncResult;
use deno_core::ByteString; use deno_core::ByteString;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::CancelTryFuture; use deno_core::CancelTryFuture;
use deno_core::OpDecl;
use deno_core::OpState; use deno_core::OpState;
use deno_core::RcRef; use deno_core::RcRef;
use deno_core::Resource; use deno_core::Resource;
@ -653,16 +652,6 @@ impl Write for ImplementWriteTrait<'_, TcpStream> {
} }
} }
pub fn init<P: NetPermissions + 'static>() -> Vec<OpDecl> {
vec![
op_tls_start::decl::<P>(),
op_net_connect_tls::decl::<P>(),
op_net_listen_tls::decl::<P>(),
op_net_accept_tls::decl(),
op_tls_handshake::decl(),
]
}
#[derive(Debug)] #[derive(Debug)]
pub struct TlsStreamResource { pub struct TlsStreamResource {
rd: AsyncRefCell<ReadHalf>, rd: AsyncRefCell<ReadHalf>,

View file

@ -1,11 +1,8 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::located_script_name; use deno_core::located_script_name;
use deno_core::op; use deno_core::op;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::JsRuntime; use deno_core::JsRuntime;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::collections::HashSet; use std::collections::HashSet;
@ -96,41 +93,32 @@ fn op_node_build_os() -> String {
.to_string() .to_string()
} }
fn ext_polyfill() -> ExtensionBuilder { deno_core::extension!(deno_node,
Extension::builder_with_deps(env!("CARGO_PKG_NAME"), &["deno_io", "deno_fs"]) deps = [ deno_io, deno_fs ],
} ops = [
crypto::op_node_cipheriv_encrypt,
fn ops_polyfill(ext: &mut ExtensionBuilder) -> &mut ExtensionBuilder { crypto::op_node_cipheriv_final,
ext.ops(vec![ crypto::op_node_create_cipheriv,
crypto::op_node_cipheriv_encrypt::decl(), crypto::op_node_create_hash,
crypto::op_node_cipheriv_final::decl(), crypto::op_node_hash_update,
crypto::op_node_create_cipheriv::decl(), crypto::op_node_hash_update_str,
crypto::op_node_create_hash::decl(), crypto::op_node_hash_digest,
crypto::op_node_hash_update::decl(), crypto::op_node_hash_digest_hex,
crypto::op_node_hash_update_str::decl(), crypto::op_node_hash_clone,
crypto::op_node_hash_digest::decl(), crypto::op_node_private_encrypt,
crypto::op_node_hash_digest_hex::decl(), crypto::op_node_private_decrypt,
crypto::op_node_hash_clone::decl(), crypto::op_node_public_encrypt,
crypto::op_node_private_encrypt::decl(), winerror::op_node_sys_to_uv_error,
crypto::op_node_private_decrypt::decl(), v8::op_v8_cached_data_version_tag,
crypto::op_node_public_encrypt::decl(), v8::op_v8_get_heap_statistics,
winerror::op_node_sys_to_uv_error::decl(), idna::op_node_idna_domain_to_ascii,
v8::op_v8_cached_data_version_tag::decl(), idna::op_node_idna_domain_to_unicode,
v8::op_v8_get_heap_statistics::decl(), idna::op_node_idna_punycode_decode,
idna::op_node_idna_domain_to_ascii::decl(), idna::op_node_idna_punycode_encode,
idna::op_node_idna_domain_to_unicode::decl(), op_node_build_os,
idna::op_node_idna_punycode_decode::decl(), ],
idna::op_node_idna_punycode_encode::decl(), esm_entry_point = "ext:deno_node/module_all.ts",
op_node_build_os::decl(), esm = [
])
}
pub fn init_polyfill_ops() -> Extension {
ops_polyfill(&mut ext_polyfill()).build()
}
pub fn init_polyfill_ops_and_esm() -> Extension {
let esm_files = include_js_files!(
dir "polyfills", dir "polyfills",
"_core.ts", "_core.ts",
"_events.mjs", "_events.mjs",
@ -352,71 +340,45 @@ pub fn init_polyfill_ops_and_esm() -> Extension {
"wasi.ts", "wasi.ts",
"worker_threads.ts", "worker_threads.ts",
"zlib.ts", "zlib.ts",
); ],
);
ops_polyfill(&mut ext_polyfill()) deno_core::extension!(deno_node_loading,
.esm(esm_files) parameters = [P: NodePermissions],
.esm_entry_point("ext:deno_node/module_all.ts") ops = [
.build() ops::op_require_init_paths,
} ops::op_require_node_module_paths<P>,
ops::op_require_proxy_path,
fn ext() -> ExtensionBuilder { ops::op_require_is_deno_dir_package,
Extension::builder("deno_node_loading") ops::op_require_resolve_deno_dir,
} ops::op_require_is_request_relative,
ops::op_require_resolve_lookup_paths,
fn ops<P: NodePermissions + 'static>( ops::op_require_try_self_parent_path<P>,
ext: &mut ExtensionBuilder, ops::op_require_try_self<P>,
maybe_npm_resolver: Option<Rc<dyn RequireNpmResolver>>, ops::op_require_real_path<P>,
) -> &mut ExtensionBuilder { ops::op_require_path_is_absolute,
ext ops::op_require_path_dirname,
.ops(vec![ ops::op_require_stat<P>,
ops::op_require_init_paths::decl(), ops::op_require_path_resolve,
ops::op_require_node_module_paths::decl::<P>(), ops::op_require_path_basename,
ops::op_require_proxy_path::decl(), ops::op_require_read_file<P>,
ops::op_require_is_deno_dir_package::decl(), ops::op_require_as_file_path,
ops::op_require_resolve_deno_dir::decl(), ops::op_require_resolve_exports<P>,
ops::op_require_is_request_relative::decl(), ops::op_require_read_closest_package_json<P>,
ops::op_require_resolve_lookup_paths::decl(), ops::op_require_read_package_scope<P>,
ops::op_require_try_self_parent_path::decl::<P>(), ops::op_require_package_imports_resolve<P>,
ops::op_require_try_self::decl::<P>(), ops::op_require_break_on_next_statement,
ops::op_require_real_path::decl::<P>(), ],
ops::op_require_path_is_absolute::decl(), esm = ["01_node.js", "02_require.js", "module_es_shim.js"],
ops::op_require_path_dirname::decl(), config = {
ops::op_require_stat::decl::<P>(), maybe_npm_resolver: Option<Rc<dyn RequireNpmResolver>>,
ops::op_require_path_resolve::decl(), },
ops::op_require_path_basename::decl(), state = |state, maybe_npm_resolver| {
ops::op_require_read_file::decl::<P>(), if let Some(npm_resolver) = maybe_npm_resolver.clone() {
ops::op_require_as_file_path::decl(), state.put(npm_resolver);
ops::op_require_resolve_exports::decl::<P>(), }
ops::op_require_read_closest_package_json::decl::<P>(), },
ops::op_require_read_package_scope::decl::<P>(), );
ops::op_require_package_imports_resolve::decl::<P>(),
ops::op_require_break_on_next_statement::decl(),
])
.state(move |state| {
if let Some(npm_resolver) = maybe_npm_resolver.clone() {
state.put(npm_resolver);
}
})
}
pub fn init_ops_and_esm<P: NodePermissions + 'static>(
maybe_npm_resolver: Option<Rc<dyn RequireNpmResolver>>,
) -> Extension {
ops::<P>(&mut ext(), maybe_npm_resolver)
.esm(include_js_files!(
"01_node.js",
"02_require.js",
"module_es_shim.js",
))
.build()
}
pub fn init_ops<P: NodePermissions + 'static>(
maybe_npm_resolver: Option<Rc<dyn RequireNpmResolver>>,
) -> Extension {
ops::<P>(&mut ext(), maybe_npm_resolver).build()
}
pub async fn initialize_runtime( pub async fn initialize_runtime(
js_runtime: &mut JsRuntime, js_runtime: &mut JsRuntime,

View file

@ -10,7 +10,6 @@ use deno_core::anyhow::anyhow;
use deno_core::error::custom_error; use deno_core::error::custom_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex; use deno_core::parking_lot::Mutex;
use deno_core::Extension;
use rustls::client::HandshakeSignatureValid; use rustls::client::HandshakeSignatureValid;
use rustls::client::ServerCertVerified; use rustls::client::ServerCertVerified;
@ -35,10 +34,8 @@ use std::io::Cursor;
use std::sync::Arc; use std::sync::Arc;
use std::time::SystemTime; use std::time::SystemTime;
/// This extension has no runtime apis, it only exports some shared native functions. // This extension has no runtime apis, it only exports some shared native functions.
pub fn init_ops() -> Extension { deno_core::extension!(deno_tls);
Extension::builder(env!("CARGO_PKG_NAME")).build()
}
struct DefaultSignatureVerification; struct DefaultSignatureVerification;

View file

@ -11,8 +11,8 @@ use deno_core::ExtensionFileSourceCode;
fn setup() -> Vec<Extension> { fn setup() -> Vec<Extension> {
vec![ vec![
deno_webidl::init_esm(), deno_webidl::deno_webidl::init_ops_and_esm(),
deno_url::init_ops_and_esm(), deno_url::deno_url::init_ops_and_esm(),
Extension::builder("bench_setup") Extension::builder("bench_setup")
.esm(vec![ExtensionFileSource { .esm(vec![ExtensionFileSource {
specifier: "ext:setup".to_string(), specifier: "ext:setup".to_string(),

View file

@ -4,13 +4,10 @@ mod urlpattern;
use deno_core::error::type_error; use deno_core::error::type_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op; use deno_core::op;
use deno_core::url::form_urlencoded; use deno_core::url::form_urlencoded;
use deno_core::url::quirks; use deno_core::url::quirks;
use deno_core::url::Url; use deno_core::url::Url;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState; use deno_core::OpState;
use deno_core::ZeroCopyBuf; use deno_core::ZeroCopyBuf;
use std::path::PathBuf; use std::path::PathBuf;
@ -18,32 +15,21 @@ use std::path::PathBuf;
use crate::urlpattern::op_urlpattern_parse; use crate::urlpattern::op_urlpattern_parse;
use crate::urlpattern::op_urlpattern_process_match_input; use crate::urlpattern::op_urlpattern_process_match_input;
fn ext() -> ExtensionBuilder { deno_core::extension!(
Extension::builder_with_deps(env!("CARGO_PKG_NAME"), &["deno_webidl"]) deno_url,
} deps = [deno_webidl],
ops = [
fn ops(ext: &mut ExtensionBuilder) -> &mut ExtensionBuilder { op_url_reparse,
ext.ops(vec![ op_url_parse,
op_url_reparse::decl(), op_url_get_serialization,
op_url_parse::decl(), op_url_parse_with_base,
op_url_get_serialization::decl(), op_url_parse_search_params,
op_url_parse_with_base::decl(), op_url_stringify_search_params,
op_url_parse_search_params::decl(), op_urlpattern_parse,
op_url_stringify_search_params::decl(), op_urlpattern_process_match_input
op_urlpattern_parse::decl(), ],
op_urlpattern_process_match_input::decl(), esm = ["00_url.js", "01_urlpattern.js"],
]) );
}
pub fn init_ops_and_esm() -> Extension {
ops(&mut ext())
.esm(include_js_files!("00_url.js", "01_urlpattern.js",))
.build()
}
pub fn init_ops() -> Extension {
ops(&mut ext()).build()
}
/// Parse `href` with a `base_href`. Fills the out `buf` with URL components. /// Parse `href` with a `base_href`. Fills the out `buf` with URL components.
#[op] #[op]

View file

@ -10,6 +10,7 @@ use deno_core::ExtensionFileSourceCode;
use deno_core::OpState; use deno_core::OpState;
use deno_web::BlobStore; use deno_web::BlobStore;
#[derive(Clone)]
struct Permissions; struct Permissions;
impl deno_web::TimersPermission for Permissions { impl deno_web::TimersPermission for Permissions {
@ -23,10 +24,13 @@ impl deno_web::TimersPermission for Permissions {
fn setup() -> Vec<Extension> { fn setup() -> Vec<Extension> {
vec![ vec![
deno_webidl::init_esm(), deno_webidl::deno_webidl::init_ops_and_esm(),
deno_url::init_ops_and_esm(), deno_url::deno_url::init_ops_and_esm(),
deno_console::init_esm(), deno_console::deno_console::init_ops_and_esm(),
deno_web::init_ops_and_esm::<Permissions>(BlobStore::default(), None), deno_web::deno_web::init_ops_and_esm::<Permissions>(
BlobStore::default(),
None,
),
Extension::builder("bench_setup") Extension::builder("bench_setup")
.esm(vec![ExtensionFileSource { .esm(vec![ExtensionFileSource {
specifier: "ext:setup".to_string(), specifier: "ext:setup".to_string(),

View file

@ -10,6 +10,7 @@ use deno_core::ExtensionFileSourceCode;
use deno_core::OpState; use deno_core::OpState;
use deno_web::BlobStore; use deno_web::BlobStore;
#[derive(Clone)]
struct Permissions; struct Permissions;
impl deno_web::TimersPermission for Permissions { impl deno_web::TimersPermission for Permissions {
@ -21,10 +22,10 @@ impl deno_web::TimersPermission for Permissions {
fn setup() -> Vec<Extension> { fn setup() -> Vec<Extension> {
vec![ vec![
deno_webidl::init_esm(), deno_webidl::deno_webidl::init_ops_and_esm(),
deno_url::init_ops_and_esm(), deno_url::deno_url::init_ops_and_esm(),
deno_console::init_esm(), deno_console::deno_console::init_ops_and_esm(),
deno_web::init_ops_and_esm::<Permissions>(BlobStore::default(), None), deno_web::deno_web::init_ops_and_esm::<Permissions>(BlobStore::default(), None),
Extension::builder("bench_setup") Extension::builder("bench_setup")
.esm(vec![ .esm(vec![
ExtensionFileSource { ExtensionFileSource {

View file

@ -8,15 +8,12 @@ mod timers;
use deno_core::error::range_error; use deno_core::error::range_error;
use deno_core::error::type_error; use deno_core::error::type_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op; use deno_core::op;
use deno_core::serde_v8; use deno_core::serde_v8;
use deno_core::url::Url; use deno_core::url::Url;
use deno_core::v8; use deno_core::v8;
use deno_core::ByteString; use deno_core::ByteString;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState; use deno_core::OpState;
use deno_core::Resource; use deno_core::Resource;
use deno_core::ResourceId; use deno_core::ResourceId;
@ -58,93 +55,72 @@ use crate::timers::op_timer_handle;
use crate::timers::StartTime; use crate::timers::StartTime;
pub use crate::timers::TimersPermission; pub use crate::timers::TimersPermission;
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_web,
Extension::builder_with_deps( deps = [ deno_webidl, deno_console, deno_url ],
env!("CARGO_PKG_NAME"), parameters = [P: TimersPermission],
&["deno_webidl", "deno_console", "deno_url"], ops = [
) op_base64_decode,
} op_base64_encode,
op_base64_atob,
fn ops<P: TimersPermission + 'static>( op_base64_btoa,
ext: &mut ExtensionBuilder, op_encoding_normalize_label,
blob_store: BlobStore, op_encoding_decode_single,
maybe_location: Option<Url>, op_encoding_decode_utf8,
) -> &mut ExtensionBuilder { op_encoding_new_decoder,
ext op_encoding_decode,
.ops(vec![ op_encoding_encode_into,
op_base64_decode::decl(), op_encode_binary_string,
op_base64_encode::decl(), op_blob_create_part,
op_base64_atob::decl(), op_blob_slice_part,
op_base64_btoa::decl(), op_blob_read_part,
op_encoding_normalize_label::decl(), op_blob_remove_part,
op_encoding_decode_single::decl(), op_blob_create_object_url,
op_encoding_decode_utf8::decl(), op_blob_revoke_object_url,
op_encoding_new_decoder::decl(), op_blob_from_object_url,
op_encoding_decode::decl(), op_message_port_create_entangled,
op_encoding_encode_into::decl(), op_message_port_post_message,
op_encode_binary_string::decl(), op_message_port_recv_message,
op_blob_create_part::decl(), compression::op_compression_new,
op_blob_slice_part::decl(), compression::op_compression_write,
op_blob_read_part::decl(), compression::op_compression_finish,
op_blob_remove_part::decl(), op_now<P>,
op_blob_create_object_url::decl(), op_timer_handle,
op_blob_revoke_object_url::decl(), op_cancel_handle,
op_blob_from_object_url::decl(), op_sleep,
op_message_port_create_entangled::decl(), op_transfer_arraybuffer,
op_message_port_post_message::decl(), ],
op_message_port_recv_message::decl(), esm = [
compression::op_compression_new::decl(), "00_infra.js",
compression::op_compression_write::decl(), "01_dom_exception.js",
compression::op_compression_finish::decl(), "01_mimesniff.js",
op_now::decl::<P>(), "02_event.js",
op_timer_handle::decl(), "02_structured_clone.js",
op_cancel_handle::decl(), "02_timers.js",
op_sleep::decl(), "03_abort_signal.js",
op_transfer_arraybuffer::decl(), "04_global_interfaces.js",
]) "05_base64.js",
.state(move |state| { "06_streams.js",
state.put(blob_store.clone()); "08_text_encoding.js",
if let Some(location) = maybe_location.clone() { "09_file.js",
state.put(Location(location)); "10_filereader.js",
} "11_blob_url.js",
state.put(StartTime::now()); "12_location.js",
}) "13_message_port.js",
} "14_compression.js",
"15_performance.js",
pub fn init_ops_and_esm<P: TimersPermission + 'static>( ],
blob_store: BlobStore, config = {
maybe_location: Option<Url>, blob_store: BlobStore,
) -> Extension { maybe_location: Option<Url>,
ops::<P>(&mut ext(), blob_store, maybe_location) },
.esm(include_js_files!( state = |state, blob_store, maybe_location| {
"00_infra.js", state.put(blob_store);
"01_dom_exception.js", if let Some(location) = maybe_location {
"01_mimesniff.js", state.put(Location(location));
"02_event.js", }
"02_structured_clone.js", state.put(StartTime::now());
"02_timers.js", }
"03_abort_signal.js", );
"04_global_interfaces.js",
"05_base64.js",
"06_streams.js",
"08_text_encoding.js",
"09_file.js",
"10_filereader.js",
"11_blob_url.js",
"12_location.js",
"13_message_port.js",
"14_compression.js",
"15_performance.js",
))
.build()
}
pub fn init_ops<P: TimersPermission + 'static>(
blob_store: BlobStore,
maybe_location: Option<Url>,
) -> Extension {
ops::<P>(&mut ext(), blob_store, maybe_location).build()
}
#[op] #[op]
fn op_base64_decode(input: String) -> Result<ZeroCopyBuf, AnyError> { fn op_base64_decode(input: String) -> Result<ZeroCopyBuf, AnyError> {

View file

@ -11,7 +11,7 @@ use deno_core::ExtensionFileSourceCode;
fn setup() -> Vec<Extension> { fn setup() -> Vec<Extension> {
vec![ vec![
deno_webidl::init_esm(), deno_webidl::deno_webidl::init_ops_and_esm(),
Extension::builder("deno_webidl_bench") Extension::builder("deno_webidl_bench")
.esm(vec![ExtensionFileSource { .esm(vec![ExtensionFileSource {
specifier: "ext:setup".to_string(), specifier: "ext:setup".to_string(),

View file

@ -1,14 +1,3 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use deno_core::include_js_files; deno_core::extension!(deno_webidl, esm = ["00_webidl.js"],);
use deno_core::Extension;
pub fn init() -> Extension {
Extension::builder(env!("CARGO_PKG_NAME")).build()
}
pub fn init_esm() -> Extension {
Extension::builder(env!("CARGO_PKG_NAME"))
.esm(include_js_files!("00_webidl.js",))
.build()
}

View file

@ -7,16 +7,13 @@ use deno_core::futures::stream::SplitSink;
use deno_core::futures::stream::SplitStream; use deno_core::futures::stream::SplitStream;
use deno_core::futures::SinkExt; use deno_core::futures::SinkExt;
use deno_core::futures::StreamExt; use deno_core::futures::StreamExt;
use deno_core::include_js_files;
use deno_core::op; use deno_core::op;
use deno_core::ExtensionBuilder;
use deno_core::url; use deno_core::url;
use deno_core::AsyncRefCell; use deno_core::AsyncRefCell;
use deno_core::ByteString; use deno_core::ByteString;
use deno_core::CancelFuture; use deno_core::CancelFuture;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
use deno_core::RcRef; use deno_core::RcRef;
use deno_core::Resource; use deno_core::Resource;
@ -498,67 +495,30 @@ pub async fn op_ws_next_event(
Ok(res) Ok(res)
} }
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_websocket,
Extension::builder_with_deps( deps = [ deno_url, deno_webidl ],
env!("CARGO_PKG_NAME"), parameters = [P: WebSocketPermissions],
&["deno_url", "deno_webidl"], ops = [
) op_ws_check_permission_and_cancel_handle<P>,
} op_ws_create<P>,
op_ws_send,
fn ops<P: WebSocketPermissions + 'static>( op_ws_close,
ext: &mut ExtensionBuilder, op_ws_next_event,
user_agent: String, ],
root_cert_store: Option<RootCertStore>, esm = [ "01_websocket.js", "02_websocketstream.js" ],
unsafely_ignore_certificate_errors: Option<Vec<String>>, config = {
) -> &mut ExtensionBuilder { user_agent: String,
ext root_cert_store: Option<RootCertStore>,
.ops(vec![ unsafely_ignore_certificate_errors: Option<Vec<String>>
op_ws_check_permission_and_cancel_handle::decl::<P>(), },
op_ws_create::decl::<P>(), state = |state, user_agent, root_cert_store, unsafely_ignore_certificate_errors| {
op_ws_send::decl(), state.put::<WsUserAgent>(WsUserAgent(user_agent));
op_ws_close::decl(), state.put(UnsafelyIgnoreCertificateErrors(
op_ws_next_event::decl(), unsafely_ignore_certificate_errors,
]) ));
.state(move |state| { state.put::<WsRootStore>(WsRootStore(root_cert_store));
state.put::<WsUserAgent>(WsUserAgent(user_agent.clone())); },
state.put(UnsafelyIgnoreCertificateErrors( );
unsafely_ignore_certificate_errors.clone(),
));
state.put::<WsRootStore>(WsRootStore(root_cert_store.clone()));
})
}
pub fn init_ops_and_esm<P: WebSocketPermissions + 'static>(
user_agent: String,
root_cert_store: Option<RootCertStore>,
unsafely_ignore_certificate_errors: Option<Vec<String>>,
) -> Extension {
ops::<P>(
&mut ext(),
user_agent,
root_cert_store,
unsafely_ignore_certificate_errors,
)
.esm(include_js_files!(
"01_websocket.js",
"02_websocketstream.js",
))
.build()
}
pub fn init_ops<P: WebSocketPermissions + 'static>(
user_agent: String,
root_cert_store: Option<RootCertStore>,
unsafely_ignore_certificate_errors: Option<Vec<String>>,
) -> Extension {
ops::<P>(
&mut ext(),
user_agent,
root_cert_store,
unsafely_ignore_certificate_errors,
)
.build()
}
pub fn get_declaration() -> PathBuf { pub fn get_declaration() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_websocket.d.ts") PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_websocket.d.ts")

View file

@ -6,10 +6,7 @@ use std::fmt;
use std::path::PathBuf; use std::path::PathBuf;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op; use deno_core::op;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState; use deno_core::OpState;
use rusqlite::params; use rusqlite::params;
use rusqlite::Connection; use rusqlite::Connection;
@ -22,40 +19,27 @@ struct OriginStorageDir(PathBuf);
const MAX_STORAGE_BYTES: usize = 10 * 1024 * 1024; const MAX_STORAGE_BYTES: usize = 10 * 1024 * 1024;
fn ext() -> ExtensionBuilder { deno_core::extension!(deno_webstorage,
Extension::builder_with_deps(env!("CARGO_PKG_NAME"), &["deno_webidl"]) deps = [ deno_webidl ],
} ops = [
op_webstorage_length,
fn ops( op_webstorage_key,
ext: &mut ExtensionBuilder, op_webstorage_set,
origin_storage_dir: Option<PathBuf>, op_webstorage_get,
) -> &mut ExtensionBuilder { op_webstorage_remove,
ext op_webstorage_clear,
.ops(vec![ op_webstorage_iterate_keys,
op_webstorage_length::decl(), ],
op_webstorage_key::decl(), esm = [ "01_webstorage.js" ],
op_webstorage_set::decl(), config = {
op_webstorage_get::decl(), origin_storage_dir: Option<PathBuf>
op_webstorage_remove::decl(), },
op_webstorage_clear::decl(), state = |state, origin_storage_dir| {
op_webstorage_iterate_keys::decl(), if let Some(origin_storage_dir) = origin_storage_dir {
]) state.put(OriginStorageDir(origin_storage_dir));
.state(move |state| { }
if let Some(origin_storage_dir) = &origin_storage_dir { },
state.put(OriginStorageDir(origin_storage_dir.clone())); );
}
})
}
pub fn init_ops_and_esm(origin_storage_dir: Option<PathBuf>) -> Extension {
ops(&mut ext(), origin_storage_dir)
.esm(include_js_files!("01_webstorage.js",))
.build()
}
pub fn init_ops(origin_storage_dir: Option<PathBuf>) -> Extension {
ops(&mut ext(), origin_storage_dir).build()
}
pub fn get_declaration() -> PathBuf { pub fn get_declaration() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_webstorage.d.ts") PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_webstorage.d.ts")

View file

@ -8,18 +8,18 @@ use std::path::PathBuf;
not(feature = "dont_create_runtime_snapshot") not(feature = "dont_create_runtime_snapshot")
))] ))]
mod startup_snapshot { mod startup_snapshot {
use std::path::Path;
use super::*; use super::*;
use deno_ast::MediaType; use deno_ast::MediaType;
use deno_ast::ParseParams; use deno_ast::ParseParams;
use deno_ast::SourceTextInfo; use deno_ast::SourceTextInfo;
use deno_cache::SqliteBackedCache; use deno_cache::SqliteBackedCache;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::snapshot_util::*; use deno_core::snapshot_util::*;
use deno_core::Extension; use deno_core::Extension;
use deno_core::ExtensionFileSource; use deno_core::ExtensionFileSource;
use std::cell::RefCell;
use std::path::Path;
use std::rc::Rc;
fn transpile_ts_for_snapshotting( fn transpile_ts_for_snapshotting(
file_source: &ExtensionFileSource, file_source: &ExtensionFileSource,
@ -58,6 +58,7 @@ mod startup_snapshot {
Ok(transpiled_source.text) Ok(transpiled_source.text)
} }
#[derive(Clone)]
struct Permissions; struct Permissions;
impl deno_fetch::FetchPermissions for Permissions { impl deno_fetch::FetchPermissions for Permissions {
@ -200,36 +201,30 @@ mod startup_snapshot {
} }
} }
fn create_runtime_snapshot( deno_core::extension!(runtime,
snapshot_path: PathBuf, deps = [
maybe_additional_extension: Option<Extension>, deno_webidl,
) { deno_console,
let runtime_extension = Extension::builder_with_deps( deno_url,
"runtime", deno_tls,
&[ deno_web,
"deno_webidl", deno_fetch,
"deno_console", deno_cache,
"deno_url", deno_websocket,
"deno_tls", deno_webstorage,
"deno_web", deno_crypto,
"deno_fetch", deno_broadcast_channel,
"deno_cache", // FIXME(bartlomieju): this should be reenabled
"deno_websocket", // "deno_node",
"deno_webstorage", deno_ffi,
"deno_crypto", deno_net,
"deno_broadcast_channel", deno_napi,
// FIXME(bartlomieju): this should be reenabled deno_http,
// "deno_node", deno_flash,
"deno_ffi", deno_io,
"deno_net", deno_fs
"deno_napi", ],
"deno_http", esm = [
"deno_flash",
"deno_io",
"deno_fs",
],
)
.esm(include_js_files!(
dir "js", dir "js",
"01_errors.js", "01_errors.js",
"01_version.ts", "01_version.ts",
@ -245,55 +240,72 @@ mod startup_snapshot {
"40_tty.js", "40_tty.js",
"41_prompt.js", "41_prompt.js",
"90_deno_ns.js", "90_deno_ns.js",
"98_global_scope.js", "98_global_scope.js"
)) ],
.build(); );
#[cfg(not(feature = "snapshot_from_snapshot"))]
deno_core::extension!(
runtime_main,
deps = [runtime],
customizer = |ext: &mut deno_core::ExtensionBuilder| {
ext.esm(vec![ExtensionFileSource {
specifier: "js/99_main.js".to_string(),
code: deno_core::ExtensionFileSourceCode::IncludedInBinary(
include_str!("js/99_main.js"),
),
}]);
}
);
pub fn create_runtime_snapshot(snapshot_path: PathBuf) {
// NOTE(bartlomieju): ordering is important here, keep it in sync with // NOTE(bartlomieju): ordering is important here, keep it in sync with
// `runtime/worker.rs`, `runtime/web_worker.rs` and `cli/build.rs`! // `runtime/worker.rs`, `runtime/web_worker.rs` and `cli/build.rs`!
let mut extensions: Vec<Extension> = vec![ let extensions: Vec<Extension> = vec![
deno_webidl::init_esm(), deno_webidl::deno_webidl::init_ops_and_esm(),
deno_console::init_esm(), deno_console::deno_console::init_ops_and_esm(),
deno_url::init_ops_and_esm(), deno_url::deno_url::init_ops_and_esm(),
deno_web::init_ops_and_esm::<Permissions>( deno_web::deno_web::init_ops_and_esm::<Permissions>(
deno_web::BlobStore::default(), deno_web::BlobStore::default(),
Default::default(), Default::default(),
), ),
deno_fetch::init_ops_and_esm::<Permissions>(Default::default()), deno_fetch::deno_fetch::init_ops_and_esm::<Permissions>(
deno_cache::init_ops_and_esm::<SqliteBackedCache>(None), Default::default(),
deno_websocket::init_ops_and_esm::<Permissions>( ),
deno_cache::deno_cache::init_ops_and_esm::<SqliteBackedCache>(None),
deno_websocket::deno_websocket::init_ops_and_esm::<Permissions>(
"".to_owned(), "".to_owned(),
None, None,
None, None,
), ),
deno_webstorage::init_ops_and_esm(None), deno_webstorage::deno_webstorage::init_ops_and_esm(None),
deno_crypto::init_ops_and_esm(None), deno_crypto::deno_crypto::init_ops_and_esm(None),
deno_broadcast_channel::init_ops_and_esm( deno_broadcast_channel::deno_broadcast_channel::init_ops_and_esm(
deno_broadcast_channel::InMemoryBroadcastChannel::default(), deno_broadcast_channel::InMemoryBroadcastChannel::default(),
false, // No --unstable. false, // No --unstable.
), ),
deno_ffi::init_ops_and_esm::<Permissions>(false), deno_ffi::deno_ffi::init_ops_and_esm::<Permissions>(false),
deno_net::init_ops_and_esm::<Permissions>( deno_net::deno_net::init_ops_and_esm::<Permissions>(
None, false, // No --unstable. None, false, // No --unstable.
None, None,
), ),
deno_tls::init_ops(), deno_tls::deno_tls::init_ops_and_esm(),
deno_napi::init_ops::<Permissions>(), deno_napi::deno_napi::init_ops_and_esm::<Permissions>(),
deno_http::init_ops_and_esm(), deno_http::deno_http::init_ops_and_esm(),
deno_io::init_ops_and_esm(Default::default()), deno_io::deno_io::init_ops_and_esm(Rc::new(RefCell::new(Some(
deno_fs::init_ops_and_esm::<Permissions>(false), Default::default(),
deno_flash::init_ops_and_esm::<Permissions>(false), // No --unstable )))),
runtime_extension, deno_fs::deno_fs::init_ops_and_esm::<Permissions>(false),
deno_flash::deno_flash::init_ops_and_esm::<Permissions>(false), // No --unstable
runtime::init_ops_and_esm(),
// FIXME(bartlomieju): these extensions are specified last, because they // FIXME(bartlomieju): these extensions are specified last, because they
// depend on `runtime`, even though it should be other way around // depend on `runtime`, even though it should be other way around
deno_node::init_ops_and_esm::<Permissions>(None), deno_node::deno_node_loading::init_ops_and_esm::<Permissions>(None),
deno_node::init_polyfill_ops_and_esm(), deno_node::deno_node::init_ops_and_esm(),
#[cfg(not(feature = "snapshot_from_snapshot"))]
runtime_main::init_ops_and_esm(),
]; ];
if let Some(additional_extension) = maybe_additional_extension {
extensions.push(additional_extension);
}
create_snapshot(CreateSnapshotOptions { create_snapshot(CreateSnapshotOptions {
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"), cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
snapshot_path, snapshot_path,
@ -303,28 +315,6 @@ mod startup_snapshot {
snapshot_module_load_cb: Some(Box::new(transpile_ts_for_snapshotting)), snapshot_module_load_cb: Some(Box::new(transpile_ts_for_snapshotting)),
}); });
} }
pub fn build_snapshot(runtime_snapshot_path: PathBuf) {
#[allow(unused_mut, unused_assignments)]
let mut maybe_additional_extension = None;
#[cfg(not(feature = "snapshot_from_snapshot"))]
{
use deno_core::ExtensionFileSourceCode;
maybe_additional_extension = Some(
Extension::builder_with_deps("runtime_main", &["runtime"])
.esm(vec![ExtensionFileSource {
specifier: "js/99_main.js".to_string(),
code: ExtensionFileSourceCode::IncludedInBinary(include_str!(
"js/99_main.js"
)),
}])
.build(),
);
}
create_runtime_snapshot(runtime_snapshot_path, maybe_additional_extension);
}
} }
fn main() { fn main() {
@ -351,5 +341,5 @@ fn main() {
not(feature = "docsrs"), not(feature = "docsrs"),
not(feature = "dont_create_runtime_snapshot") not(feature = "dont_create_runtime_snapshot")
))] ))]
startup_snapshot::build_snapshot(runtime_snapshot_path) startup_snapshot::create_runtime_snapshot(runtime_snapshot_path)
} }

View file

@ -13,7 +13,6 @@ use deno_core::ResourceId;
use deno_core::op; use deno_core::op;
use deno_core::Extension;
use notify::event::Event as NotifyEvent; use notify::event::Event as NotifyEvent;
use notify::Error as NotifyError; use notify::Error as NotifyError;
use notify::EventKind; use notify::EventKind;
@ -29,11 +28,10 @@ use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use tokio::sync::mpsc; use tokio::sync::mpsc;
pub fn init() -> Extension { deno_core::extension!(
Extension::builder("deno_fs_events") deno_fs_events,
.ops(vec![op_fs_events_open::decl(), op_fs_events_poll::decl()]) ops = [op_fs_events_open, op_fs_events_poll]
.build() );
}
struct FsEventsResource { struct FsEventsResource {
#[allow(unused)] #[allow(unused)]

View file

@ -8,7 +8,6 @@ use deno_core::error::bad_resource_id;
use deno_core::error::custom_error; use deno_core::error::custom_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op; use deno_core::op;
use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
use deno_core::RcRef; use deno_core::RcRef;
use deno_core::ResourceId; use deno_core::ResourceId;
@ -28,15 +27,10 @@ use deno_net::io::UnixStreamResource;
#[cfg(unix)] #[cfg(unix)]
use tokio::net::UnixStream; use tokio::net::UnixStream;
pub fn init() -> Extension { deno_core::extension!(
Extension::builder("deno_http_runtime") deno_http_runtime,
.ops(vec![ ops = [op_http_start, op_http_upgrade, op_flash_upgrade_http],
op_http_start::decl(), );
op_http_upgrade::decl(),
op_flash_upgrade_http::decl(),
])
.build()
}
#[op] #[op]
fn op_http_start( fn op_http_start(

View file

@ -8,8 +8,6 @@ use deno_core::error::AnyError;
use deno_core::op; use deno_core::op;
use deno_core::url::Url; use deno_core::url::Url;
use deno_core::v8; use deno_core::v8;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState; use deno_core::OpState;
use deno_node::NODE_ENV_VAR_ALLOWLIST; use deno_node::NODE_ENV_VAR_ALLOWLIST;
use serde::Serialize; use serde::Serialize;
@ -18,47 +16,49 @@ use std::env;
mod sys_info; mod sys_info;
fn init_ops(builder: &mut ExtensionBuilder) -> &mut ExtensionBuilder { deno_core::ops!(
builder.ops(vec![ deno_ops,
op_env::decl(), [
op_exec_path::decl(), op_env,
op_exit::decl(), op_exec_path,
op_delete_env::decl(), op_exit,
op_get_env::decl(), op_delete_env,
op_gid::decl(), op_get_env,
op_hostname::decl(), op_gid,
op_loadavg::decl(), op_hostname,
op_network_interfaces::decl(), op_loadavg,
op_os_release::decl(), op_network_interfaces,
op_os_uptime::decl(), op_os_release,
op_node_unstable_os_uptime::decl(), op_os_uptime,
op_set_env::decl(), op_node_unstable_os_uptime,
op_set_exit_code::decl(), op_set_env,
op_system_memory_info::decl(), op_set_exit_code,
op_uid::decl(), op_system_memory_info,
op_runtime_memory_usage::decl(), op_uid,
]) op_runtime_memory_usage,
} ]
);
pub fn init(exit_code: ExitCode) -> Extension { deno_core::extension!(
let mut builder = Extension::builder("deno_os"); deno_os,
init_ops(&mut builder) ops_fn = deno_ops,
.state(move |state| { config = {
state.put::<ExitCode>(exit_code.clone()); exit_code: ExitCode,
}) },
.build() state = |state, exit_code| {
} state.put::<ExitCode>(exit_code);
},
);
pub fn init_for_worker() -> Extension { deno_core::extension!(
let mut builder = Extension::builder("deno_os_worker"); deno_os_worker,
init_ops(&mut builder) ops_fn = deno_ops,
.middleware(|op| match op.name { middleware = |op| match op.name {
"op_exit" => noop_op::decl(), "op_exit" => noop_op::decl(),
"op_set_exit_code" => noop_op::decl(), "op_set_exit_code" => noop_op::decl(),
_ => op, _ => op,
}) },
.build() );
}
#[op] #[op]
fn noop_op() -> Result<(), AnyError> { fn noop_op() -> Result<(), AnyError> {

View file

@ -7,20 +7,18 @@ use deno_core::error::uri_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op; use deno_core::op;
use deno_core::url; use deno_core::url;
use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
use serde::Deserialize; use serde::Deserialize;
use std::path::Path; use std::path::Path;
pub fn init() -> Extension { deno_core::extension!(
Extension::builder("deno_permissions") deno_permissions,
.ops(vec![ ops = [
op_query_permission::decl(), op_query_permission,
op_revoke_permission::decl(), op_revoke_permission,
op_request_permission::decl(), op_request_permission,
]) ]
.build() );
}
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct PermissionArgs { pub struct PermissionArgs {

View file

@ -7,7 +7,6 @@ use deno_core::op;
use deno_core::serde_json; use deno_core::serde_json;
use deno_core::AsyncMutFuture; use deno_core::AsyncMutFuture;
use deno_core::AsyncRefCell; use deno_core::AsyncRefCell;
use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
use deno_core::RcRef; use deno_core::RcRef;
use deno_core::Resource; use deno_core::Resource;
@ -99,18 +98,17 @@ impl StdioOrRid {
} }
} }
pub fn init_ops() -> Extension { deno_core::extension!(
Extension::builder("deno_process") deno_process,
.ops(vec![ ops = [
op_spawn_child::decl(), op_spawn_child,
op_spawn_wait::decl(), op_spawn_wait,
op_spawn_sync::decl(), op_spawn_sync,
deprecated::op_run::decl(), deprecated::op_run,
deprecated::op_run_status::decl(), deprecated::op_run_status,
deprecated::op_kill::decl(), deprecated::op_kill,
]) ]
.build() );
}
struct ChildResource(tokio::process::Child); struct ChildResource(tokio::process::Child);

View file

@ -3,18 +3,17 @@
use crate::permissions::PermissionsContainer; use crate::permissions::PermissionsContainer;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op; use deno_core::op;
use deno_core::Extension;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_core::OpState; use deno_core::OpState;
pub fn init(main_module: ModuleSpecifier) -> Extension { deno_core::extension!(
Extension::builder("deno_runtime") deno_runtime,
.ops(vec![op_main_module::decl()]) ops = [op_main_module],
.state(move |state| { config = { main_module: ModuleSpecifier },
state.put::<ModuleSpecifier>(main_module.clone()); state = |state, main_module| {
}) state.put::<ModuleSpecifier>(main_module);
.build() }
} );
#[op] #[op]
fn op_main_module(state: &mut OpState) -> Result<String, AnyError> { fn op_main_module(state: &mut OpState) -> Result<String, AnyError> {

View file

@ -5,7 +5,6 @@ use deno_core::op;
use deno_core::AsyncRefCell; use deno_core::AsyncRefCell;
use deno_core::CancelFuture; use deno_core::CancelFuture;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
use deno_core::RcRef; use deno_core::RcRef;
use deno_core::Resource; use deno_core::Resource;
@ -30,15 +29,10 @@ use tokio::signal::windows::CtrlBreak;
#[cfg(windows)] #[cfg(windows)]
use tokio::signal::windows::CtrlC; use tokio::signal::windows::CtrlC;
pub fn init() -> Extension { deno_core::extension!(
Extension::builder("deno_signal") deno_signal,
.ops(vec![ ops = [op_signal_bind, op_signal_unbind, op_signal_poll]
op_signal_bind::decl(), );
op_signal_unbind::decl(),
op_signal_poll::decl(),
])
.build()
}
#[cfg(unix)] #[cfg(unix)]
/// The resource for signal stream. /// The resource for signal stream.

View file

@ -2,7 +2,6 @@
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op; use deno_core::op;
use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
use deno_io::StdFileResource; use deno_io::StdFileResource;
use std::io::Error; use std::io::Error;
@ -33,15 +32,10 @@ fn get_windows_handle(
Ok(handle) Ok(handle)
} }
pub fn init() -> Extension { deno_core::extension!(
Extension::builder("deno_tty") deno_tty,
.ops(vec![ ops = [op_stdin_set_raw, op_isatty, op_console_size]
op_stdin_set_raw::decl(), );
op_isatty::decl(),
op_console_size::decl(),
])
.build()
}
// ref: <https://learn.microsoft.com/en-us/windows/console/setconsolemode> // ref: <https://learn.microsoft.com/en-us/windows/console/setconsolemode>
#[cfg(windows)] #[cfg(windows)]

View file

@ -8,7 +8,6 @@ use deno_core::error::AnyError;
use deno_core::op; use deno_core::op;
use deno_core::CancelFuture; use deno_core::CancelFuture;
use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
use deno_web::JsMessageData; use deno_web::JsMessageData;
use std::cell::RefCell; use std::cell::RefCell;
@ -16,18 +15,17 @@ use std::rc::Rc;
use self::sync_fetch::op_worker_sync_fetch; use self::sync_fetch::op_worker_sync_fetch;
pub fn init() -> Extension { deno_core::extension!(
Extension::builder("deno_web_worker") deno_web_worker,
.ops(vec![ ops = [
op_worker_post_message::decl(), op_worker_post_message,
op_worker_recv_message::decl(), op_worker_recv_message,
// Notify host that guest worker closes. // Notify host that guest worker closes.
op_worker_close::decl(), op_worker_close,
op_worker_get_type::decl(), op_worker_get_type,
op_worker_sync_fetch::decl(), op_worker_sync_fetch,
]) ]
.build() );
}
#[op] #[op]
fn op_worker_post_message( fn op_worker_post_message(

View file

@ -18,7 +18,6 @@ use deno_core::op;
use deno_core::serde::Deserialize; use deno_core::serde::Deserialize;
use deno_core::CancelFuture; use deno_core::CancelFuture;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::Extension;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_core::OpState; use deno_core::OpState;
use deno_web::JsMessageData; use deno_web::JsMessageData;
@ -88,39 +87,39 @@ impl Drop for WorkerThread {
pub type WorkersTable = HashMap<WorkerId, WorkerThread>; pub type WorkersTable = HashMap<WorkerId, WorkerThread>;
pub fn init( deno_core::extension!(
create_web_worker_cb: Arc<CreateWebWorkerCb>, deno_worker_host,
preload_module_cb: Arc<WorkerEventCb>, ops = [
pre_execute_module_cb: Arc<WorkerEventCb>, op_create_worker,
format_js_error_fn: Option<Arc<FormatJsErrorFn>>, op_host_terminate_worker,
) -> Extension { op_host_post_message,
Extension::builder("deno_worker_host") op_host_recv_ctrl,
.state(move |state| { op_host_recv_message,
state.put::<WorkersTable>(WorkersTable::default()); ],
state.put::<WorkerId>(WorkerId::default()); config = {
create_web_worker_cb: Arc<CreateWebWorkerCb>,
preload_module_cb: Arc<WorkerEventCb>,
pre_execute_module_cb: Arc<WorkerEventCb>,
format_js_error_fn: Option<Arc<FormatJsErrorFn>>,
},
state = |state, create_web_worker_cb, preload_module_cb, pre_execute_module_cb, format_js_error_fn| {
state.put::<WorkersTable>(WorkersTable::default());
state.put::<WorkerId>(WorkerId::default());
let create_web_worker_cb_holder = let create_web_worker_cb_holder =
CreateWebWorkerCbHolder(create_web_worker_cb.clone()); CreateWebWorkerCbHolder(create_web_worker_cb.clone());
state.put::<CreateWebWorkerCbHolder>(create_web_worker_cb_holder); state.put::<CreateWebWorkerCbHolder>(create_web_worker_cb_holder);
let preload_module_cb_holder = let preload_module_cb_holder =
PreloadModuleCbHolder(preload_module_cb.clone()); PreloadModuleCbHolder(preload_module_cb.clone());
state.put::<PreloadModuleCbHolder>(preload_module_cb_holder); state.put::<PreloadModuleCbHolder>(preload_module_cb_holder);
let pre_execute_module_cb_holder = let pre_execute_module_cb_holder =
PreExecuteModuleCbHolder(pre_execute_module_cb.clone()); PreExecuteModuleCbHolder(pre_execute_module_cb.clone());
state.put::<PreExecuteModuleCbHolder>(pre_execute_module_cb_holder); state.put::<PreExecuteModuleCbHolder>(pre_execute_module_cb_holder);
let format_js_error_fn_holder = let format_js_error_fn_holder =
FormatJsErrorFnHolder(format_js_error_fn.clone()); FormatJsErrorFnHolder(format_js_error_fn.clone());
state.put::<FormatJsErrorFnHolder>(format_js_error_fn_holder); state.put::<FormatJsErrorFnHolder>(format_js_error_fn_holder);
}) }
.ops(vec![ );
op_create_worker::decl(),
op_host_terminate_worker::decl(),
op_host_post_message::decl(),
op_host_recv_ctrl::decl(),
op_host_recv_message::decl(),
])
.build()
}
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]

View file

@ -368,16 +368,22 @@ impl WebWorker {
worker_id: WorkerId, worker_id: WorkerId,
mut options: WebWorkerOptions, mut options: WebWorkerOptions,
) -> (Self, SendableWebWorkerHandle) { ) -> (Self, SendableWebWorkerHandle) {
deno_core::extension!(deno_permissions_web_worker,
config = {
permissions: PermissionsContainer,
unstable: bool,
enable_testing_features: bool,
},
state = |state, permissions, unstable, enable_testing_features| {
state.put::<PermissionsContainer>(permissions);
state.put(ops::UnstableChecker { unstable });
state.put(ops::TestingFeaturesEnabled(enable_testing_features));
},
);
// Permissions: many ops depend on this // Permissions: many ops depend on this
let unstable = options.bootstrap.unstable; let unstable = options.bootstrap.unstable;
let enable_testing_features = options.bootstrap.enable_testing_features; let enable_testing_features = options.bootstrap.enable_testing_features;
let perm_ext = Extension::builder("deno_permissions_web_worker")
.state(move |state| {
state.put::<PermissionsContainer>(permissions.clone());
state.put(ops::UnstableChecker { unstable });
state.put(ops::TestingFeaturesEnabled(enable_testing_features));
})
.build();
let create_cache = options.cache_storage_dir.map(|storage_dir| { let create_cache = options.cache_storage_dir.map(|storage_dir| {
let create_cache_fn = move || SqliteBackedCache::new(storage_dir.clone()); let create_cache_fn = move || SqliteBackedCache::new(storage_dir.clone());
CreateCache(Arc::new(create_cache_fn)) CreateCache(Arc::new(create_cache_fn))
@ -387,68 +393,75 @@ impl WebWorker {
// `runtime/build.rs`, `runtime/worker.rs` and `cli/build.rs`! // `runtime/build.rs`, `runtime/worker.rs` and `cli/build.rs`!
let mut extensions: Vec<Extension> = vec![ let mut extensions: Vec<Extension> = vec![
// Web APIs // Web APIs
deno_webidl::init(), deno_webidl::deno_webidl::init_ops(),
deno_console::init(), deno_console::deno_console::init_ops(),
deno_url::init_ops(), deno_url::deno_url::init_ops(),
deno_web::init_ops::<PermissionsContainer>( deno_web::deno_web::init_ops::<PermissionsContainer>(
options.blob_store.clone(), options.blob_store.clone(),
Some(main_module.clone()), Some(main_module.clone()),
), ),
deno_fetch::init_ops::<PermissionsContainer>(deno_fetch::Options { deno_fetch::deno_fetch::init_ops::<PermissionsContainer>(
user_agent: options.bootstrap.user_agent.clone(), deno_fetch::Options {
root_cert_store: options.root_cert_store.clone(), user_agent: options.bootstrap.user_agent.clone(),
unsafely_ignore_certificate_errors: options root_cert_store: options.root_cert_store.clone(),
.unsafely_ignore_certificate_errors unsafely_ignore_certificate_errors: options
.clone(), .unsafely_ignore_certificate_errors
file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler), .clone(),
..Default::default() file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler),
}), ..Default::default()
deno_cache::init_ops::<SqliteBackedCache>(create_cache), },
deno_websocket::init_ops::<PermissionsContainer>( ),
deno_cache::deno_cache::init_ops::<SqliteBackedCache>(create_cache),
deno_websocket::deno_websocket::init_ops::<PermissionsContainer>(
options.bootstrap.user_agent.clone(), options.bootstrap.user_agent.clone(),
options.root_cert_store.clone(), options.root_cert_store.clone(),
options.unsafely_ignore_certificate_errors.clone(), options.unsafely_ignore_certificate_errors.clone(),
), ),
deno_webstorage::init_ops(None).disable(), deno_webstorage::deno_webstorage::init_ops(None).disable(),
deno_crypto::init_ops(options.seed), deno_crypto::deno_crypto::init_ops(options.seed),
deno_broadcast_channel::init_ops( deno_broadcast_channel::deno_broadcast_channel::init_ops(
options.broadcast_channel.clone(), options.broadcast_channel.clone(),
unstable, unstable,
), ),
deno_ffi::init_ops::<PermissionsContainer>(unstable), deno_ffi::deno_ffi::init_ops::<PermissionsContainer>(unstable),
deno_net::init_ops::<PermissionsContainer>( deno_net::deno_net::init_ops::<PermissionsContainer>(
options.root_cert_store.clone(), options.root_cert_store.clone(),
unstable, unstable,
options.unsafely_ignore_certificate_errors.clone(), options.unsafely_ignore_certificate_errors.clone(),
), ),
deno_tls::init_ops(), deno_tls::deno_tls::init_ops(),
deno_napi::init_ops::<PermissionsContainer>(), deno_napi::deno_napi::init_ops::<PermissionsContainer>(),
deno_http::init_ops(), deno_http::deno_http::init_ops(),
deno_io::init_ops(options.stdio), deno_io::deno_io::init_ops(Rc::new(RefCell::new(Some(options.stdio)))),
deno_fs::init_ops::<PermissionsContainer>(unstable), deno_fs::deno_fs::init_ops::<PermissionsContainer>(unstable),
deno_flash::init_ops::<PermissionsContainer>(unstable), deno_flash::deno_flash::init_ops::<PermissionsContainer>(unstable),
deno_node::init_ops::<PermissionsContainer>(options.npm_resolver), deno_node::deno_node_loading::init_ops::<PermissionsContainer>(
deno_node::init_polyfill_ops(), options.npm_resolver,
),
deno_node::deno_node::init_ops(),
// Runtime ops that are always initialized for WebWorkers // Runtime ops that are always initialized for WebWorkers
ops::web_worker::init(), ops::web_worker::deno_web_worker::init_ops(),
ops::runtime::init(main_module.clone()), ops::runtime::deno_runtime::init_ops(main_module.clone()),
ops::worker_host::init( ops::worker_host::deno_worker_host::init_ops(
options.create_web_worker_cb.clone(), options.create_web_worker_cb.clone(),
options.preload_module_cb.clone(), options.preload_module_cb.clone(),
options.pre_execute_module_cb.clone(), options.pre_execute_module_cb.clone(),
options.format_js_error_fn.clone(), options.format_js_error_fn.clone(),
), ),
ops::fs_events::init(), ops::fs_events::deno_fs_events::init_ops(),
ops::os::init_for_worker(), ops::os::deno_os_worker::init_ops(),
ops::permissions::init(), ops::permissions::deno_permissions::init_ops(),
ops::process::init_ops(), ops::process::deno_process::init_ops(),
ops::signal::init(), ops::signal::deno_signal::init_ops(),
ops::tty::init(), ops::tty::deno_tty::init_ops(),
ops::http::init(), ops::http::deno_http_runtime::init_ops(),
deno_permissions_web_worker::init_ops(
permissions,
unstable,
enable_testing_features,
),
]; ];
extensions.push(perm_ext);
// Append exts // Append exts
extensions.extend(std::mem::take(&mut options.extensions)); extensions.extend(std::mem::take(&mut options.extensions));

View file

@ -1,5 +1,6 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use std::cell::RefCell;
use std::pin::Pin; use std::pin::Pin;
use std::rc::Rc; use std::rc::Rc;
use std::sync::atomic::AtomicI32; use std::sync::atomic::AtomicI32;
@ -187,16 +188,22 @@ impl MainWorker {
permissions: PermissionsContainer, permissions: PermissionsContainer,
mut options: WorkerOptions, mut options: WorkerOptions,
) -> Self { ) -> Self {
deno_core::extension!(deno_permissions_worker,
config = {
permissions: PermissionsContainer,
unstable: bool,
enable_testing_features: bool,
},
state = |state, permissions, unstable, enable_testing_features| {
state.put::<PermissionsContainer>(permissions);
state.put(ops::UnstableChecker { unstable });
state.put(ops::TestingFeaturesEnabled(enable_testing_features));
},
);
// Permissions: many ops depend on this // Permissions: many ops depend on this
let unstable = options.bootstrap.unstable; let unstable = options.bootstrap.unstable;
let enable_testing_features = options.bootstrap.enable_testing_features; let enable_testing_features = options.bootstrap.enable_testing_features;
let perm_ext = Extension::builder("deno_permissions_worker")
.state(move |state| {
state.put::<PermissionsContainer>(permissions.clone());
state.put(ops::UnstableChecker { unstable });
state.put(ops::TestingFeaturesEnabled(enable_testing_features));
})
.build();
let exit_code = ExitCode(Arc::new(AtomicI32::new(0))); let exit_code = ExitCode(Arc::new(AtomicI32::new(0)));
let create_cache = options.cache_storage_dir.map(|storage_dir| { let create_cache = options.cache_storage_dir.map(|storage_dir| {
let create_cache_fn = move || SqliteBackedCache::new(storage_dir.clone()); let create_cache_fn = move || SqliteBackedCache::new(storage_dir.clone());
@ -207,67 +214,76 @@ impl MainWorker {
// `runtime/build.rs`, `runtime/web_worker.rs` and `cli/build.rs`! // `runtime/build.rs`, `runtime/web_worker.rs` and `cli/build.rs`!
let mut extensions = vec![ let mut extensions = vec![
// Web APIs // Web APIs
deno_webidl::init(), deno_webidl::deno_webidl::init_ops(),
deno_console::init(), deno_console::deno_console::init_ops(),
deno_url::init_ops(), deno_url::deno_url::init_ops(),
deno_web::init_ops::<PermissionsContainer>( deno_web::deno_web::init_ops::<PermissionsContainer>(
options.blob_store.clone(), options.blob_store.clone(),
options.bootstrap.location.clone(), options.bootstrap.location.clone(),
), ),
deno_fetch::init_ops::<PermissionsContainer>(deno_fetch::Options { deno_fetch::deno_fetch::init_ops::<PermissionsContainer>(
user_agent: options.bootstrap.user_agent.clone(), deno_fetch::Options {
root_cert_store: options.root_cert_store.clone(), user_agent: options.bootstrap.user_agent.clone(),
unsafely_ignore_certificate_errors: options root_cert_store: options.root_cert_store.clone(),
.unsafely_ignore_certificate_errors unsafely_ignore_certificate_errors: options
.clone(), .unsafely_ignore_certificate_errors
file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler), .clone(),
..Default::default() file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler),
}), ..Default::default()
deno_cache::init_ops::<SqliteBackedCache>(create_cache), },
deno_websocket::init_ops::<PermissionsContainer>( ),
deno_cache::deno_cache::init_ops::<SqliteBackedCache>(create_cache),
deno_websocket::deno_websocket::init_ops::<PermissionsContainer>(
options.bootstrap.user_agent.clone(), options.bootstrap.user_agent.clone(),
options.root_cert_store.clone(), options.root_cert_store.clone(),
options.unsafely_ignore_certificate_errors.clone(), options.unsafely_ignore_certificate_errors.clone(),
), ),
deno_webstorage::init_ops(options.origin_storage_dir.clone()), deno_webstorage::deno_webstorage::init_ops(
deno_crypto::init_ops(options.seed), options.origin_storage_dir.clone(),
deno_broadcast_channel::init_ops( ),
deno_crypto::deno_crypto::init_ops(options.seed),
deno_broadcast_channel::deno_broadcast_channel::init_ops(
options.broadcast_channel.clone(), options.broadcast_channel.clone(),
unstable, unstable,
), ),
deno_ffi::init_ops::<PermissionsContainer>(unstable), deno_ffi::deno_ffi::init_ops::<PermissionsContainer>(unstable),
deno_net::init_ops::<PermissionsContainer>( deno_net::deno_net::init_ops::<PermissionsContainer>(
options.root_cert_store.clone(), options.root_cert_store.clone(),
unstable, unstable,
options.unsafely_ignore_certificate_errors.clone(), options.unsafely_ignore_certificate_errors.clone(),
), ),
deno_tls::init_ops(), deno_tls::deno_tls::init_ops(),
deno_napi::init_ops::<PermissionsContainer>(), deno_napi::deno_napi::init_ops::<PermissionsContainer>(),
deno_http::init_ops(), deno_http::deno_http::init_ops(),
deno_io::init_ops(options.stdio), deno_io::deno_io::init_ops(Rc::new(RefCell::new(Some(options.stdio)))),
deno_fs::init_ops::<PermissionsContainer>(unstable), deno_fs::deno_fs::init_ops::<PermissionsContainer>(unstable),
deno_flash::init_ops::<PermissionsContainer>(unstable), deno_flash::deno_flash::init_ops::<PermissionsContainer>(unstable),
deno_node::init_ops::<PermissionsContainer>(options.npm_resolver), deno_node::deno_node_loading::init_ops::<PermissionsContainer>(
deno_node::init_polyfill_ops(), options.npm_resolver,
),
deno_node::deno_node::init_ops(),
// Ops from this crate // Ops from this crate
ops::runtime::init(main_module.clone()), ops::runtime::deno_runtime::init_ops(main_module.clone()),
ops::worker_host::init( ops::worker_host::deno_worker_host::init_ops(
options.create_web_worker_cb.clone(), options.create_web_worker_cb.clone(),
options.web_worker_preload_module_cb.clone(), options.web_worker_preload_module_cb.clone(),
options.web_worker_pre_execute_module_cb.clone(), options.web_worker_pre_execute_module_cb.clone(),
options.format_js_error_fn.clone(), options.format_js_error_fn.clone(),
), ),
ops::fs_events::init(), ops::fs_events::deno_fs_events::init_ops(),
ops::os::init(exit_code.clone()), ops::os::deno_os::init_ops(exit_code.clone()),
ops::permissions::init(), ops::permissions::deno_permissions::init_ops(),
ops::process::init_ops(), ops::process::deno_process::init_ops(),
ops::signal::init(), ops::signal::deno_signal::init_ops(),
ops::tty::init(), ops::tty::deno_tty::init_ops(),
ops::http::init(), ops::http::deno_http_runtime::init_ops(),
deno_permissions_worker::init_ops(
permissions,
unstable,
enable_testing_features,
),
]; ];
extensions.push(perm_ext);
extensions.extend(std::mem::take(&mut options.extensions)); extensions.extend(std::mem::take(&mut options.extensions));
#[cfg(not(feature = "dont_create_runtime_snapshot"))] #[cfg(not(feature = "dont_create_runtime_snapshot"))]