1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-24 08:09:08 -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::Extension;
deno_core::extension!(bench_setup, ops = [op_pi_json, op_pi_async, op_nop]);
fn setup() -> Vec<Extension> {
vec![Extension::builder("bench_setup")
.ops(vec![
op_pi_json::decl(),
op_pi_async::decl(),
op_nop::decl(),
])
.build()]
vec![bench_setup::init_ops()]
}
#[op]

View file

@ -1,11 +1,13 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use std::cell::RefCell;
use std::env;
use std::path::PathBuf;
use std::rc::Rc;
use deno_core::include_js_files;
use deno_core::snapshot_util::*;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::ExtensionFileSource;
use deno_core::ExtensionFileSourceCode;
use deno_runtime::deno_cache::SqliteBackedCache;
@ -33,6 +35,105 @@ mod ts {
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) {
// libs that are being provided by op crates.
let mut op_crate_libs = HashMap::new();
@ -158,110 +259,15 @@ mod ts {
)
.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 {
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
snapshot_path,
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
// ~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) {
// NOTE(bartlomieju): ordering is important here, keep it in sync with
// `runtime/worker.rs`, `runtime/web_worker.rs` and `runtime/build.rs`!
let mut extensions: Vec<Extension> = vec![
deno_webidl::init(),
deno_console::init(),
deno_url::init_ops(),
deno_web::init_ops::<PermissionsContainer>(
let extensions: Vec<Extension> = vec![
deno_webidl::deno_webidl::init_ops(),
deno_console::deno_console::init_ops(),
deno_url::deno_url::init_ops(),
deno_web::deno_web::init_ops::<PermissionsContainer>(
deno_web::BlobStore::default(),
Default::default(),
),
deno_fetch::init_ops::<PermissionsContainer>(Default::default()),
deno_cache::init_ops::<SqliteBackedCache>(None),
deno_websocket::init_ops::<PermissionsContainer>("".to_owned(), None, None),
deno_webstorage::init_ops(None),
deno_crypto::init_ops(None),
deno_broadcast_channel::init_ops(
deno_fetch::deno_fetch::init_ops::<PermissionsContainer>(Default::default()),
deno_cache::deno_cache::init_ops::<SqliteBackedCache>(None),
deno_websocket::deno_websocket::init_ops::<PermissionsContainer>(
"".to_owned(),
None,
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(),
false, // No --unstable.
),
deno_ffi::init_ops::<PermissionsContainer>(false),
deno_net::init_ops::<PermissionsContainer>(
deno_ffi::deno_ffi::init_ops::<PermissionsContainer>(false),
deno_net::deno_net::init_ops::<PermissionsContainer>(
None, false, // No --unstable.
None,
),
deno_tls::init_ops(),
deno_napi::init_ops::<PermissionsContainer>(),
deno_http::init_ops(),
deno_io::init_ops(Default::default()),
deno_fs::init_ops::<PermissionsContainer>(false),
deno_flash::init_ops::<PermissionsContainer>(false), // No --unstable
deno_node::init_ops::<PermissionsContainer>(None), // No --unstable.
deno_node::init_polyfill_ops(),
deno_tls::deno_tls::init_ops(),
deno_napi::deno_napi::init_ops::<PermissionsContainer>(),
deno_http::deno_http::init_ops(),
deno_io::deno_io::init_ops(Rc::new(RefCell::new(Some(Default::default())))),
deno_fs::deno_fs::init_ops::<PermissionsContainer>(false),
deno_flash::deno_flash::init_ops::<PermissionsContainer>(false), // No --unstable
deno_node::deno_node_loading::init_ops::<PermissionsContainer>(None), // No --unstable.
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 {
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
snapshot_path,

View file

@ -165,7 +165,11 @@ async fn test_specifier(
&ps,
specifier.clone(),
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 {
stdin: StdioPipe::Inherit,
stdout,

View file

@ -37,7 +37,6 @@ use deno_core::serde_json;
use deno_core::serde_json::json;
use deno_core::serde_json::Value;
use deno_core::url::Url;
use deno_core::Extension;
use deno_core::JsRuntime;
use deno_core::ModuleSpecifier;
use deno_core::OpState;
@ -2819,31 +2818,32 @@ fn op_script_version(
/// server.
fn js_runtime(performance: Arc<Performance>) -> JsRuntime {
JsRuntime::new(RuntimeOptions {
extensions: vec![init_extension(performance)],
extensions: vec![deno_tsc::init_ops(performance)],
startup_snapshot: Some(tsc::compiler_snapshot()),
..Default::default()
})
}
fn init_extension(performance: Arc<Performance>) -> Extension {
Extension::builder("deno_tsc")
.ops(vec![
op_is_cancelled::decl(),
op_is_node_file::decl(),
op_load::decl(),
op_resolve::decl(),
op_respond::decl(),
op_script_names::decl(),
op_script_version::decl(),
])
.state(move |state| {
state.put(State::new(
Arc::new(StateSnapshot::default()),
performance.clone(),
));
})
.build()
}
deno_core::extension!(deno_tsc,
ops = [
op_is_cancelled,
op_is_node_file,
op_load,
op_resolve,
op_respond,
op_script_names,
op_script_version,
],
config = {
performance: Arc<Performance>
},
state = |state, performance| {
state.put(State::new(
Arc::new(StateSnapshot::default()),
performance,
));
},
);
/// Instruct a language server runtime to start the language server and provide
/// 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::AnyError;
use deno_core::op;
use deno_core::Extension;
use deno_core::ModuleSpecifier;
use deno_core::OpState;
use deno_runtime::permissions::create_child_permissions;
@ -22,25 +21,24 @@ use crate::tools::bench::BenchDescription;
use crate::tools::bench::BenchEvent;
use crate::tools::test::TestFilter;
pub fn init(
sender: UnboundedSender<BenchEvent>,
filter: TestFilter,
) -> Extension {
Extension::builder("deno_bench")
.ops(vec![
op_pledge_test_permissions::decl(),
op_restore_test_permissions::decl(),
op_get_bench_origin::decl(),
op_register_bench::decl(),
op_dispatch_bench_event::decl(),
op_bench_now::decl(),
])
.state(move |state| {
state.put(sender.clone());
state.put(filter.clone());
})
.build()
}
deno_core::extension!(deno_bench,
ops = [
op_pledge_test_permissions,
op_restore_test_permissions,
op_get_bench_origin,
op_register_bench,
op_dispatch_bench_event,
op_bench_now,
],
config = {
sender: UnboundedSender<BenchEvent>,
filter: TestFilter,
},
state = |state, sender, filter| {
state.put(sender);
state.put(filter);
},
);
#[derive(Clone)]
struct PermissionsHolder(Uuid, PermissionsContainer);

View file

@ -10,17 +10,18 @@ pub mod bench;
pub mod testing;
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 {
Extension::builder("deno_cli")
.ops(vec![op_npm_process_state::decl()])
.state(move |state| {
state.put(ps.clone());
})
.build()
}
deno_core::extension!(deno_cli,
ops = [op_npm_process_state],
config = {
ps: ProcState,
},
state = |state, ps| {
state.put(ps);
},
);
#[op]
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::AnyError;
use deno_core::op;
use deno_core::Extension;
use deno_core::ModuleSpecifier;
use deno_core::OpState;
use deno_runtime::permissions::create_child_permissions;
@ -25,28 +24,27 @@ use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use uuid::Uuid;
pub fn init(
sender: TestEventSender,
fail_fast_tracker: FailFastTracker,
filter: TestFilter,
) -> Extension {
Extension::builder("deno_test")
.ops(vec![
op_pledge_test_permissions::decl(),
op_restore_test_permissions::decl(),
op_get_test_origin::decl(),
op_register_test::decl(),
op_register_test_step::decl(),
op_dispatch_test_event::decl(),
op_tests_should_stop::decl(),
])
.state(move |state| {
state.put(sender.clone());
state.put(fail_fast_tracker.clone());
state.put(filter.clone());
})
.build()
}
deno_core::extension!(deno_test,
ops = [
op_pledge_test_permissions,
op_restore_test_permissions,
op_get_test_origin,
op_register_test,
op_register_test_step,
op_dispatch_test_event,
op_tests_should_stop,
],
config = {
sender: TestEventSender,
fail_fast_tracker: FailFastTracker,
filter: TestFilter,
},
state = |state, sender, fail_fast_tracker, filter| {
state.put(sender);
state.put(fail_fast_tracker);
state.put(filter);
},
);
#[derive(Clone)]
struct PermissionsHolder(Uuid, PermissionsContainer);

View file

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

View file

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

View file

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

View file

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

View file

@ -1,13 +1,11 @@
use crate::ExtensionBuilder;
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use crate::error::format_file_name;
use crate::error::type_error;
use crate::include_js_files;
use crate::io::BufMutView;
use crate::io::BufView;
use crate::ops_builtin_v8;
use crate::ops_metrics::OpMetrics;
use crate::resources::ResourceId;
use crate::Extension;
use crate::OpState;
use crate::Resource;
use crate::ZeroCopyBuf;
@ -19,49 +17,62 @@ use std::io::stdout;
use std::io::Write;
use std::rc::Rc;
fn ext() -> ExtensionBuilder {
Extension::builder("core")
}
fn ops(ext: &mut ExtensionBuilder) -> &mut ExtensionBuilder {
let mut ops = vec![
op_close::decl(),
op_try_close::decl(),
op_print::decl(),
op_resources::decl(),
op_wasm_streaming_feed::decl(),
op_wasm_streaming_set_url::decl(),
op_void_sync::decl(),
op_void_async::decl(),
op_add::decl(),
// // TODO(@AaronO): track IO metrics for builtin streams
op_read::decl(),
op_read_all::decl(),
op_write::decl(),
op_write_all::decl(),
op_shutdown::decl(),
op_metrics::decl(),
op_format_file_name::decl(),
op_is_proxy::decl(),
op_str_byte_length::decl(),
];
ops.extend(crate::ops_builtin_v8::init_builtins_v8());
ext.ops(ops)
}
pub(crate) fn init_builtin_ops_and_esm() -> Extension {
ops(&mut ext())
.js(include_js_files!(
"00_primordials.js",
"01_core.js",
"02_error.js",
))
.build()
}
pub(crate) fn init_builtin_ops() -> Extension {
ops(&mut ext()).build()
}
crate::extension!(
core,
ops = [
op_close,
op_try_close,
op_print,
op_resources,
op_wasm_streaming_feed,
op_wasm_streaming_set_url,
op_void_sync,
op_void_async,
op_add,
// TODO(@AaronO): track IO metrics for builtin streams
op_read,
op_read_all,
op_write,
op_write_all,
op_shutdown,
op_metrics,
op_format_file_name,
op_is_proxy,
op_str_byte_length,
ops_builtin_v8::op_ref_op,
ops_builtin_v8::op_unref_op,
ops_builtin_v8::op_set_macrotask_callback,
ops_builtin_v8::op_set_next_tick_callback,
ops_builtin_v8::op_set_promise_reject_callback,
ops_builtin_v8::op_run_microtasks,
ops_builtin_v8::op_has_tick_scheduled,
ops_builtin_v8::op_set_has_tick_scheduled,
ops_builtin_v8::op_eval_context,
ops_builtin_v8::op_queue_microtask,
ops_builtin_v8::op_create_host_object,
ops_builtin_v8::op_encode,
ops_builtin_v8::op_decode,
ops_builtin_v8::op_serialize,
ops_builtin_v8::op_deserialize,
ops_builtin_v8::op_set_promise_hooks,
ops_builtin_v8::op_get_promise_details,
ops_builtin_v8::op_get_proxy_details,
ops_builtin_v8::op_memory_usage,
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
/// 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::JsRealm;
use crate::JsRuntime;
use crate::OpDecl;
use crate::ZeroCopyBuf;
use anyhow::Error;
use deno_ops::op;
@ -21,42 +20,6 @@ use std::cell::RefCell;
use v8::ValueDeserializerHelper;
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(
scope: &mut v8::HandleScope,
value: serde_v8::Value,

View file

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

View file

@ -2,7 +2,6 @@
mod in_memory_broadcast_channel;
use deno_core::ExtensionBuilder;
pub use in_memory_broadcast_channel::InMemoryBroadcastChannel;
pub use in_memory_broadcast_channel::InMemoryBroadcastChannelResource;
@ -12,9 +11,7 @@ use std::rc::Rc;
use async_trait::async_trait;
use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op;
use deno_core::Extension;
use deno_core::OpState;
use deno_core::Resource;
use deno_core::ResourceId;
@ -107,46 +104,25 @@ where
bc.recv(&resource).await
}
fn ext() -> ExtensionBuilder {
Extension::builder_with_deps(
env!("CARGO_PKG_NAME"),
&["deno_webidl", "deno_web"],
)
}
fn ops<BC: BroadcastChannel + 'static>(
ext: &mut ExtensionBuilder,
bc: BC,
unstable: bool,
) -> &mut ExtensionBuilder {
ext
.ops(vec![
op_broadcast_subscribe::decl::<BC>(),
op_broadcast_unsubscribe::decl::<BC>(),
op_broadcast_send::decl::<BC>(),
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()
}
deno_core::extension!(deno_broadcast_channel,
deps = [ deno_webidl, deno_web ],
parameters = [BC: BroadcastChannel],
ops = [
op_broadcast_subscribe<BC>,
op_broadcast_unsubscribe<BC>,
op_broadcast_send<BC>,
op_broadcast_recv<BC>,
],
esm = [ "01_broadcast_channel.js" ],
config = {
bc: BC,
unstable: bool,
},
state = |state, bc, unstable| {
state.put(bc);
state.put(Unstable(unstable));
},
);
pub fn get_declaration() -> PathBuf {
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 deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op;
use deno_core::serde::Deserialize;
use deno_core::serde::Serialize;
use deno_core::ByteString;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState;
use deno_core::Resource;
use deno_core::ResourceId;
@ -23,46 +20,27 @@ pub use sqlite::SqliteBackedCache;
#[derive(Clone)]
pub struct CreateCache<C: Cache + 'static>(pub Arc<dyn Fn() -> C>);
fn ext() -> ExtensionBuilder {
Extension::builder_with_deps(
env!("CARGO_PKG_NAME"),
&["deno_webidl", "deno_web", "deno_url", "deno_fetch"],
)
}
fn ops<CA: Cache + 'static>(
ext: &mut ExtensionBuilder,
maybe_create_cache: Option<CreateCache<CA>>,
) -> &mut ExtensionBuilder {
ext
.ops(vec![
op_cache_storage_open::decl::<CA>(),
op_cache_storage_has::decl::<CA>(),
op_cache_storage_delete::decl::<CA>(),
op_cache_put::decl::<CA>(),
op_cache_match::decl::<CA>(),
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()
}
deno_core::extension!(deno_cache,
deps = [ deno_webidl, deno_web, deno_url, deno_fetch ],
parameters=[CA: Cache],
ops = [
op_cache_storage_open<CA>,
op_cache_storage_has<CA>,
op_cache_storage_delete<CA>,
op_cache_put<CA>,
op_cache_match<CA>,
op_cache_delete<CA>,
],
esm = [ "01_cache.js" ],
config = {
maybe_create_cache: Option<CreateCache<CA>>,
},
state = |state, maybe_create_cache| {
if let Some(create_cache) = maybe_create_cache {
state.put(create_cache);
}
},
);
pub fn get_declaration() -> PathBuf {
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.
use deno_core::include_js_files;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use std::path::PathBuf;
fn ext() -> ExtensionBuilder {
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()
}
deno_core::extension!(deno_console, esm = ["01_colors.js", "02_console.js"],);
pub fn get_declaration() -> PathBuf {
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::type_error;
use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op;
use deno_core::ExtensionBuilder;
use deno_core::Extension;
use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use serde::Deserialize;
@ -73,65 +70,49 @@ use crate::key::CryptoNamedCurve;
use crate::key::HkdfOutput;
use crate::shared::RawKeyData;
fn ext() -> ExtensionBuilder {
Extension::builder_with_deps(
env!("CARGO_PKG_NAME"),
&["deno_webidl", "deno_web"],
)
}
fn ops(
ext: &mut ExtensionBuilder,
maybe_seed: Option<u64>,
) -> &mut ExtensionBuilder {
ext
.ops(vec![
op_crypto_get_random_values::decl(),
op_crypto_generate_key::decl(),
op_crypto_sign_key::decl(),
op_crypto_verify_key::decl(),
op_crypto_derive_bits::decl(),
op_crypto_import_key::decl(),
op_crypto_export_key::decl(),
op_crypto_encrypt::decl(),
op_crypto_decrypt::decl(),
op_crypto_subtle_digest::decl(),
op_crypto_random_uuid::decl(),
op_crypto_wrap_key::decl(),
op_crypto_unwrap_key::decl(),
op_crypto_base64url_decode::decl(),
op_crypto_base64url_encode::decl(),
x25519::op_generate_x25519_keypair::decl(),
x25519::op_derive_bits_x25519::decl(),
x25519::op_import_spki_x25519::decl(),
x25519::op_import_pkcs8_x25519::decl(),
ed25519::op_generate_ed25519_keypair::decl(),
ed25519::op_import_spki_ed25519::decl(),
ed25519::op_import_pkcs8_ed25519::decl(),
ed25519::op_sign_ed25519::decl(),
ed25519::op_verify_ed25519::decl(),
ed25519::op_export_spki_ed25519::decl(),
ed25519::op_export_pkcs8_ed25519::decl(),
ed25519::op_jwk_x_ed25519::decl(),
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()
}
deno_core::extension!(deno_crypto,
deps = [ deno_webidl, deno_web ],
ops = [
op_crypto_get_random_values,
op_crypto_generate_key,
op_crypto_sign_key,
op_crypto_verify_key,
op_crypto_derive_bits,
op_crypto_import_key,
op_crypto_export_key,
op_crypto_encrypt,
op_crypto_decrypt,
op_crypto_subtle_digest,
op_crypto_random_uuid,
op_crypto_wrap_key,
op_crypto_unwrap_key,
op_crypto_base64url_decode,
op_crypto_base64url_encode,
x25519::op_generate_x25519_keypair,
x25519::op_derive_bits_x25519,
x25519::op_import_spki_x25519,
x25519::op_import_pkcs8_x25519,
ed25519::op_generate_ed25519_keypair,
ed25519::op_import_spki_ed25519,
ed25519::op_import_pkcs8_ed25519,
ed25519::op_sign_ed25519,
ed25519::op_verify_ed25519,
ed25519::op_export_spki_ed25519,
ed25519::op_export_pkcs8_ed25519,
ed25519::op_jwk_x_ed25519,
x25519::op_export_spki_x25519,
x25519::op_export_pkcs8_x25519,
],
esm = [ "00_crypto.js", "01_webidl.js" ],
config = {
maybe_seed: Option<u64>,
},
state = |state, maybe_seed| {
if let Some(seed) = maybe_seed {
state.put(StdRng::seed_from_u64(seed));
}
},
);
#[op]
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::Stream;
use deno_core::futures::StreamExt;
use deno_core::include_js_files;
use deno_core::op;
use deno_core::BufView;
use deno_core::ExtensionBuilder;
use deno_core::WriteOutcome;
use deno_core::url::Url;
@ -24,7 +22,6 @@ use deno_core::CancelFuture;
use deno_core::CancelHandle;
use deno_core::CancelTryFuture;
use deno_core::Canceled;
use deno_core::Extension;
use deno_core::OpState;
use deno_core::RcRef;
use deno_core::Resource;
@ -93,65 +90,41 @@ impl Default for Options {
}
}
fn ext() -> ExtensionBuilder {
Extension::builder_with_deps(
env!("CARGO_PKG_NAME"),
&["deno_webidl", "deno_web", "deno_url", "deno_console"],
)
}
fn ops<FP>(
ext: &mut ExtensionBuilder,
options: Options,
) -> &mut ExtensionBuilder
where
FP: FetchPermissions + 'static,
{
ext
.ops(vec![
op_fetch::decl::<FP>(),
op_fetch_send::decl(),
op_fetch_custom_client::decl::<FP>(),
])
.state(move |state| {
state.put::<Options>(options.clone());
state.put::<reqwest::Client>({
create_http_client(
options.user_agent.clone(),
options.root_cert_store.clone(),
vec![],
options.proxy.clone(),
options.unsafely_ignore_certificate_errors.clone(),
options.client_cert_chain_and_key.clone(),
)
.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()
}
deno_core::extension!(deno_fetch,
deps = [ deno_webidl, deno_web, deno_url, deno_console ],
parameters = [FP: FetchPermissions],
ops = [
op_fetch<FP>,
op_fetch_send,
op_fetch_custom_client<FP>,
],
esm = [
"20_headers.js",
"21_formdata.js",
"22_body.js",
"22_http_client.js",
"23_request.js",
"23_response.js",
"26_fetch.js"
],
config = {
options: Options,
},
state = |state, options| {
state.put::<Options>(options.clone());
state.put::<reqwest::Client>({
create_http_client(
options.user_agent,
options.root_cert_store,
vec![],
options.proxy,
options.unsafely_ignore_certificate_errors,
options.client_cert_chain_and_key
)
.unwrap()
});
},
);
pub type CancelableResponseFuture =
Pin<Box<dyn Future<Output = CancelableResponseResult>>>;

View file

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

View file

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

View file

@ -4,12 +4,9 @@
use deno_core::error::custom_error;
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op;
use deno_core::CancelFuture;
use deno_core::CancelHandle;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState;
use deno_core::ResourceId;
use deno_core::ZeroCopyBuf;
@ -118,92 +115,78 @@ use deno_core::error::generic_error;
#[cfg(not(unix))]
use deno_core::error::not_supported;
fn ext() -> ExtensionBuilder {
Extension::builder("deno_fs")
}
fn ops<P: FsPermissions + 'static>(
ext: &mut ExtensionBuilder,
unstable: bool,
) -> &mut ExtensionBuilder {
ext
.state(move |state| {
state.put(UnstableChecker { unstable });
})
.ops(vec![
op_open_sync::decl::<P>(),
op_open_async::decl::<P>(),
op_write_file_sync::decl::<P>(),
op_write_file_async::decl::<P>(),
op_seek_sync::decl(),
op_seek_async::decl(),
op_fdatasync_sync::decl(),
op_fdatasync_async::decl(),
op_fsync_sync::decl(),
op_fsync_async::decl(),
op_fstat_sync::decl(),
op_fstat_async::decl(),
op_flock_sync::decl(),
op_flock_async::decl(),
op_funlock_sync::decl(),
op_funlock_async::decl(),
op_umask::decl(),
op_chdir::decl::<P>(),
op_mkdir_sync::decl::<P>(),
op_mkdir_async::decl::<P>(),
op_chmod_sync::decl::<P>(),
op_chmod_async::decl::<P>(),
op_chown_sync::decl::<P>(),
op_chown_async::decl::<P>(),
op_remove_sync::decl::<P>(),
op_remove_async::decl::<P>(),
op_copy_file_sync::decl::<P>(),
op_copy_file_async::decl::<P>(),
op_stat_sync::decl::<P>(),
op_stat_async::decl::<P>(),
op_realpath_sync::decl::<P>(),
op_realpath_async::decl::<P>(),
op_read_dir_sync::decl::<P>(),
op_read_dir_async::decl::<P>(),
op_rename_sync::decl::<P>(),
op_rename_async::decl::<P>(),
op_link_sync::decl::<P>(),
op_link_async::decl::<P>(),
op_symlink_sync::decl::<P>(),
op_symlink_async::decl::<P>(),
op_read_link_sync::decl::<P>(),
op_read_link_async::decl::<P>(),
op_ftruncate_sync::decl(),
op_ftruncate_async::decl(),
op_truncate_sync::decl::<P>(),
op_truncate_async::decl::<P>(),
op_make_temp_dir_sync::decl::<P>(),
op_make_temp_dir_async::decl::<P>(),
op_make_temp_file_sync::decl::<P>(),
op_make_temp_file_async::decl::<P>(),
op_cwd::decl::<P>(),
op_futime_sync::decl(),
op_futime_async::decl(),
op_utime_sync::decl::<P>(),
op_utime_async::decl::<P>(),
op_readfile_sync::decl::<P>(),
op_readfile_text_sync::decl::<P>(),
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()
}
deno_core::extension!(deno_fs,
deps = [ deno_web, deno_io ],
parameters = [P: FsPermissions],
ops = [
op_open_sync<P>,
op_open_async<P>,
op_write_file_sync<P>,
op_write_file_async<P>,
op_seek_sync,
op_seek_async,
op_fdatasync_sync,
op_fdatasync_async,
op_fsync_sync,
op_fsync_async,
op_fstat_sync,
op_fstat_async,
op_flock_sync,
op_flock_async,
op_funlock_sync,
op_funlock_async,
op_umask,
op_chdir<P>,
op_mkdir_sync<P>,
op_mkdir_async<P>,
op_chmod_sync<P>,
op_chmod_async<P>,
op_chown_sync<P>,
op_chown_async<P>,
op_remove_sync<P>,
op_remove_async<P>,
op_copy_file_sync<P>,
op_copy_file_async<P>,
op_stat_sync<P>,
op_stat_async<P>,
op_realpath_sync<P>,
op_realpath_async<P>,
op_read_dir_sync<P>,
op_read_dir_async<P>,
op_rename_sync<P>,
op_rename_async<P>,
op_link_sync<P>,
op_link_async<P>,
op_symlink_sync<P>,
op_symlink_async<P>,
op_read_link_sync<P>,
op_read_link_async<P>,
op_ftruncate_sync,
op_ftruncate_async,
op_truncate_sync<P>,
op_truncate_async<P>,
op_make_temp_dir_sync<P>,
op_make_temp_dir_async<P>,
op_make_temp_file_sync<P>,
op_make_temp_file_async<P>,
op_cwd<P>,
op_futime_sync,
op_futime_async,
op_utime_sync<P>,
op_utime_async<P>,
op_readfile_sync<P>,
op_readfile_text_sync<P>,
op_readfile_async<P>,
op_readfile_text_async<P>,
],
esm = [ "30_fs.js" ],
config = {
unstable: bool
},
state = |state, unstable| {
state.put(UnstableChecker { unstable });
},
);
fn default_err_mapper(err: Error, desc: String) -> Error {
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::StreamExt;
use deno_core::futures::TryFutureExt;
use deno_core::include_js_files;
use deno_core::op;
use deno_core::AsyncRefCell;
use deno_core::AsyncResult;
@ -28,8 +27,6 @@ use deno_core::ByteString;
use deno_core::CancelFuture;
use deno_core::CancelHandle;
use deno_core::CancelTryFuture;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState;
use deno_core::RcRef;
use deno_core::Resource;
@ -78,35 +75,21 @@ use crate::reader_stream::ShutdownHandle;
pub mod compressible;
mod reader_stream;
fn ext() -> ExtensionBuilder {
Extension::builder_with_deps(
env!("CARGO_PKG_NAME"),
&["deno_web", "deno_net", "deno_fetch", "deno_websocket"],
)
}
fn ops(ext: &mut ExtensionBuilder) -> &mut ExtensionBuilder {
ext.ops(vec![
op_http_accept::decl(),
op_http_write_headers::decl(),
op_http_headers::decl(),
op_http_write::decl(),
op_http_write_resource::decl(),
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()
}
deno_core::extension!(
deno_http,
deps = [deno_web, deno_net, deno_fetch, deno_websocket],
ops = [
op_http_accept,
op_http_write_headers,
op_http_headers,
op_http_write,
op_http_write_resource,
op_http_shutdown,
op_http_websocket_accept_header,
op_http_upgrade_websocket,
],
esm = ["01_http.js"],
);
pub enum HttpSocketAddr {
IpSocket(std::net::SocketAddr),

View file

@ -2,7 +2,6 @@
use deno_core::error::resource_unavailable;
use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op;
use deno_core::parking_lot::Mutex;
use deno_core::AsyncMutFuture;
@ -12,8 +11,6 @@ use deno_core::BufMutView;
use deno_core::BufView;
use deno_core::CancelHandle;
use deno_core::CancelTryFuture;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState;
use deno_core::RcRef;
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)) }
});
fn ext() -> ExtensionBuilder {
Extension::builder_with_deps("deno_io", &["deno_web"])
}
deno_core::extension!(deno_io,
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(
ext: &mut ExtensionBuilder,
stdio: Rc<RefCell<Option<Stdio>>>,
) -> &mut ExtensionBuilder {
ext
.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),
let rid = t.add(StdFileResource::stdio(
match stdio.stdin {
StdioPipe::Inherit => StdFileResourceInner {
kind: StdFileResourceKind::Stdin,
file: STDIN_HANDLE.try_clone().unwrap(),
},
"stdin",
));
assert_eq!(rid, 0, "stdin must have ResourceId 0");
StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
},
"stdin",
));
assert_eq!(rid, 0, "stdin must have ResourceId 0");
let rid = t.add(StdFileResource::stdio(
match stdio.stdout {
StdioPipe::Inherit => StdFileResourceInner {
kind: StdFileResourceKind::Stdout,
file: STDOUT_HANDLE.try_clone().unwrap(),
},
StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
let rid = t.add(StdFileResource::stdio(
match stdio.stdout {
StdioPipe::Inherit => StdFileResourceInner {
kind: StdFileResourceKind::Stdout,
file: STDOUT_HANDLE.try_clone().unwrap(),
},
"stdout",
));
assert_eq!(rid, 1, "stdout must have ResourceId 1");
StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
},
"stdout",
));
assert_eq!(rid, 1, "stdout must have ResourceId 1");
let rid = t.add(StdFileResource::stdio(
match stdio.stderr {
StdioPipe::Inherit => StdFileResourceInner {
kind: StdFileResourceKind::Stderr,
file: STDERR_HANDLE.try_clone().unwrap(),
},
StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
let rid = t.add(StdFileResource::stdio(
match stdio.stderr {
StdioPipe::Inherit => StdFileResourceInner {
kind: StdFileResourceKind::Stderr,
file: STDERR_HANDLE.try_clone().unwrap(),
},
"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()
}
StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
},
"stderr",
));
assert_eq!(rid, 2, "stderr must have ResourceId 2");
},
);
pub enum StdioPipe {
Inherit,

View file

@ -13,7 +13,6 @@ use deno_core::futures::StreamExt;
use deno_core::op;
use deno_core::parking_lot::Mutex;
use deno_core::serde_v8;
use deno_core::Extension;
use deno_core::OpState;
use std::cell::RefCell;
use std::ffi::CString;
@ -514,72 +513,78 @@ impl Env {
}
}
pub fn init_ops<P: NapiPermissions + 'static>() -> Extension {
Extension::builder(env!("CARGO_PKG_NAME"))
.ops(vec![op_napi_open::decl::<P>()])
.event_loop_middleware(|op_state_rc, cx| {
// `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;
deno_core::extension!(deno_napi,
parameters = [P: NapiPermissions],
ops = [
op_napi_open<P>
],
state = |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![])),
});
},
event_loop_middleware = event_loop_middleware,
);
{
let mut op_state = op_state_rc.borrow_mut();
let napi_state = op_state.borrow_mut::<NapiState>();
fn event_loop_middleware(
op_state_rc: Rc<RefCell<OpState>>,
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)
{
napi_state.pending_async_work.push(async_work_fut);
}
{
let mut op_state = op_state_rc.borrow_mut();
let napi_state = op_state.borrow_mut::<NapiState>();
if napi_state.active_threadsafe_functions > 0 {
maybe_scheduling = true;
}
while let Poll::Ready(Some(async_work_fut)) =
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();
for (_id, counter) in tsfn_ref_counters.iter() {
if counter.load(std::sync::atomic::Ordering::SeqCst) > 0 {
maybe_scheduling = true;
break;
}
}
if napi_state.active_threadsafe_functions > 0 {
maybe_scheduling = true;
}
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 {
let maybe_work = {
let mut op_state = op_state_rc.borrow_mut();
let napi_state = op_state.borrow_mut::<NapiState>();
napi_state.pending_async_work.pop()
};
loop {
let maybe_work = {
let mut op_state = op_state_rc.borrow_mut();
let napi_state = op_state.borrow_mut::<NapiState>();
napi_state.pending_async_work.pop()
};
if let Some(work) = maybe_work {
work();
maybe_scheduling = true;
} else {
break;
}
}
if let Some(work) = maybe_work {
work();
maybe_scheduling = true;
} else {
break;
}
}
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()
maybe_scheduling
}
pub trait NapiPermissions {

View file

@ -8,9 +8,6 @@ pub mod ops_unix;
pub mod resolve_addr;
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_tls::rustls::RootCertStore;
use std::cell::RefCell;
@ -78,55 +75,48 @@ pub struct DefaultTlsOptions {
/// would override previously used alias.
pub struct UnsafelyIgnoreCertificateErrors(pub Option<Vec<String>>);
fn ext() -> ExtensionBuilder {
Extension::builder_with_deps(env!("CARGO_PKG_NAME"), &["deno_web"])
}
deno_core::extension!(deno_net,
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>(
ext: &mut ExtensionBuilder,
root_cert_store: Option<RootCertStore>,
unstable: bool,
unsafely_ignore_certificate_errors: Option<Vec<String>>,
) -> &mut ExtensionBuilder {
let mut ops = ops::init::<P>();
ops.extend(ops_tls::init::<P>());
ops_tls::op_tls_start<P>,
ops_tls::op_net_connect_tls<P>,
ops_tls::op_net_listen_tls<P>,
ops_tls::op_net_accept_tls,
ops_tls::op_tls_handshake,
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 {
root_cert_store: root_cert_store.clone(),
root_cert_store,
});
state.put(UnstableChecker { unstable });
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::CancelHandle;
use deno_core::CancelTryFuture;
use deno_core::OpDecl;
use deno_core::OpState;
use deno_core::RcRef;
use deno_core::Resource;
@ -44,35 +43,6 @@ use trust_dns_resolver::error::ResolveErrorKind;
use trust_dns_resolver::system_conf;
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)]
#[serde(rename_all = "camelCase")]
pub struct TlsHandshakeInfo {
@ -650,7 +620,6 @@ fn rdata_to_return_record(
mod tests {
use super::*;
use crate::UnstableChecker;
use deno_core::Extension;
use deno_core::JsRuntime;
use deno_core::RuntimeOptions;
use socket2::SockRef;
@ -906,15 +875,17 @@ mod tests {
let listener = TcpListener::bind(addr).await.unwrap();
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(UnstableChecker { unstable: true });
})
.build();
}
);
let mut runtime = JsRuntime::new(RuntimeOptions {
extensions: vec![my_ext],
extensions: vec![test_ext::init_ops()],
..Default::default()
});

View file

@ -31,7 +31,6 @@ use deno_core::AsyncResult;
use deno_core::ByteString;
use deno_core::CancelHandle;
use deno_core::CancelTryFuture;
use deno_core::OpDecl;
use deno_core::OpState;
use deno_core::RcRef;
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)]
pub struct TlsStreamResource {
rd: AsyncRefCell<ReadHalf>,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,14 +1,3 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use deno_core::include_js_files;
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()
}
deno_core::extension!(deno_webidl, esm = ["00_webidl.js"],);

View file

@ -7,16 +7,13 @@ use deno_core::futures::stream::SplitSink;
use deno_core::futures::stream::SplitStream;
use deno_core::futures::SinkExt;
use deno_core::futures::StreamExt;
use deno_core::include_js_files;
use deno_core::op;
use deno_core::ExtensionBuilder;
use deno_core::url;
use deno_core::AsyncRefCell;
use deno_core::ByteString;
use deno_core::CancelFuture;
use deno_core::CancelHandle;
use deno_core::Extension;
use deno_core::OpState;
use deno_core::RcRef;
use deno_core::Resource;
@ -498,67 +495,30 @@ pub async fn op_ws_next_event(
Ok(res)
}
fn ext() -> ExtensionBuilder {
Extension::builder_with_deps(
env!("CARGO_PKG_NAME"),
&["deno_url", "deno_webidl"],
)
}
fn ops<P: WebSocketPermissions + 'static>(
ext: &mut ExtensionBuilder,
user_agent: String,
root_cert_store: Option<RootCertStore>,
unsafely_ignore_certificate_errors: Option<Vec<String>>,
) -> &mut ExtensionBuilder {
ext
.ops(vec![
op_ws_check_permission_and_cancel_handle::decl::<P>(),
op_ws_create::decl::<P>(),
op_ws_send::decl(),
op_ws_close::decl(),
op_ws_next_event::decl(),
])
.state(move |state| {
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()
}
deno_core::extension!(deno_websocket,
deps = [ deno_url, deno_webidl ],
parameters = [P: WebSocketPermissions],
ops = [
op_ws_check_permission_and_cancel_handle<P>,
op_ws_create<P>,
op_ws_send,
op_ws_close,
op_ws_next_event,
],
esm = [ "01_websocket.js", "02_websocketstream.js" ],
config = {
user_agent: String,
root_cert_store: Option<RootCertStore>,
unsafely_ignore_certificate_errors: Option<Vec<String>>
},
state = |state, user_agent, root_cert_store, unsafely_ignore_certificate_errors| {
state.put::<WsUserAgent>(WsUserAgent(user_agent));
state.put(UnsafelyIgnoreCertificateErrors(
unsafely_ignore_certificate_errors,
));
state.put::<WsRootStore>(WsRootStore(root_cert_store));
},
);
pub fn get_declaration() -> PathBuf {
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 deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op;
use deno_core::Extension;
use deno_core::ExtensionBuilder;
use deno_core::OpState;
use rusqlite::params;
use rusqlite::Connection;
@ -22,40 +19,27 @@ struct OriginStorageDir(PathBuf);
const MAX_STORAGE_BYTES: usize = 10 * 1024 * 1024;
fn ext() -> ExtensionBuilder {
Extension::builder_with_deps(env!("CARGO_PKG_NAME"), &["deno_webidl"])
}
fn ops(
ext: &mut ExtensionBuilder,
origin_storage_dir: Option<PathBuf>,
) -> &mut ExtensionBuilder {
ext
.ops(vec![
op_webstorage_length::decl(),
op_webstorage_key::decl(),
op_webstorage_set::decl(),
op_webstorage_get::decl(),
op_webstorage_remove::decl(),
op_webstorage_clear::decl(),
op_webstorage_iterate_keys::decl(),
])
.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()
}
deno_core::extension!(deno_webstorage,
deps = [ deno_webidl ],
ops = [
op_webstorage_length,
op_webstorage_key,
op_webstorage_set,
op_webstorage_get,
op_webstorage_remove,
op_webstorage_clear,
op_webstorage_iterate_keys,
],
esm = [ "01_webstorage.js" ],
config = {
origin_storage_dir: Option<PathBuf>
},
state = |state, origin_storage_dir| {
if let Some(origin_storage_dir) = origin_storage_dir {
state.put(OriginStorageDir(origin_storage_dir));
}
},
);
pub fn get_declaration() -> PathBuf {
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")
))]
mod startup_snapshot {
use std::path::Path;
use super::*;
use deno_ast::MediaType;
use deno_ast::ParseParams;
use deno_ast::SourceTextInfo;
use deno_cache::SqliteBackedCache;
use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::snapshot_util::*;
use deno_core::Extension;
use deno_core::ExtensionFileSource;
use std::cell::RefCell;
use std::path::Path;
use std::rc::Rc;
fn transpile_ts_for_snapshotting(
file_source: &ExtensionFileSource,
@ -58,6 +58,7 @@ mod startup_snapshot {
Ok(transpiled_source.text)
}
#[derive(Clone)]
struct Permissions;
impl deno_fetch::FetchPermissions for Permissions {
@ -200,36 +201,30 @@ mod startup_snapshot {
}
}
fn create_runtime_snapshot(
snapshot_path: PathBuf,
maybe_additional_extension: Option<Extension>,
) {
let runtime_extension = Extension::builder_with_deps(
"runtime",
&[
"deno_webidl",
"deno_console",
"deno_url",
"deno_tls",
"deno_web",
"deno_fetch",
"deno_cache",
"deno_websocket",
"deno_webstorage",
"deno_crypto",
"deno_broadcast_channel",
// FIXME(bartlomieju): this should be reenabled
// "deno_node",
"deno_ffi",
"deno_net",
"deno_napi",
"deno_http",
"deno_flash",
"deno_io",
"deno_fs",
],
)
.esm(include_js_files!(
deno_core::extension!(runtime,
deps = [
deno_webidl,
deno_console,
deno_url,
deno_tls,
deno_web,
deno_fetch,
deno_cache,
deno_websocket,
deno_webstorage,
deno_crypto,
deno_broadcast_channel,
// FIXME(bartlomieju): this should be reenabled
// "deno_node",
deno_ffi,
deno_net,
deno_napi,
deno_http,
deno_flash,
deno_io,
deno_fs
],
esm = [
dir "js",
"01_errors.js",
"01_version.ts",
@ -245,55 +240,72 @@ mod startup_snapshot {
"40_tty.js",
"41_prompt.js",
"90_deno_ns.js",
"98_global_scope.js",
))
.build();
"98_global_scope.js"
],
);
#[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
// `runtime/worker.rs`, `runtime/web_worker.rs` and `cli/build.rs`!
let mut extensions: Vec<Extension> = vec![
deno_webidl::init_esm(),
deno_console::init_esm(),
deno_url::init_ops_and_esm(),
deno_web::init_ops_and_esm::<Permissions>(
let extensions: Vec<Extension> = vec![
deno_webidl::deno_webidl::init_ops_and_esm(),
deno_console::deno_console::init_ops_and_esm(),
deno_url::deno_url::init_ops_and_esm(),
deno_web::deno_web::init_ops_and_esm::<Permissions>(
deno_web::BlobStore::default(),
Default::default(),
),
deno_fetch::init_ops_and_esm::<Permissions>(Default::default()),
deno_cache::init_ops_and_esm::<SqliteBackedCache>(None),
deno_websocket::init_ops_and_esm::<Permissions>(
deno_fetch::deno_fetch::init_ops_and_esm::<Permissions>(
Default::default(),
),
deno_cache::deno_cache::init_ops_and_esm::<SqliteBackedCache>(None),
deno_websocket::deno_websocket::init_ops_and_esm::<Permissions>(
"".to_owned(),
None,
None,
),
deno_webstorage::init_ops_and_esm(None),
deno_crypto::init_ops_and_esm(None),
deno_broadcast_channel::init_ops_and_esm(
deno_webstorage::deno_webstorage::init_ops_and_esm(None),
deno_crypto::deno_crypto::init_ops_and_esm(None),
deno_broadcast_channel::deno_broadcast_channel::init_ops_and_esm(
deno_broadcast_channel::InMemoryBroadcastChannel::default(),
false, // No --unstable.
),
deno_ffi::init_ops_and_esm::<Permissions>(false),
deno_net::init_ops_and_esm::<Permissions>(
deno_ffi::deno_ffi::init_ops_and_esm::<Permissions>(false),
deno_net::deno_net::init_ops_and_esm::<Permissions>(
None, false, // No --unstable.
None,
),
deno_tls::init_ops(),
deno_napi::init_ops::<Permissions>(),
deno_http::init_ops_and_esm(),
deno_io::init_ops_and_esm(Default::default()),
deno_fs::init_ops_and_esm::<Permissions>(false),
deno_flash::init_ops_and_esm::<Permissions>(false), // No --unstable
runtime_extension,
deno_tls::deno_tls::init_ops_and_esm(),
deno_napi::deno_napi::init_ops_and_esm::<Permissions>(),
deno_http::deno_http::init_ops_and_esm(),
deno_io::deno_io::init_ops_and_esm(Rc::new(RefCell::new(Some(
Default::default(),
)))),
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
// depend on `runtime`, even though it should be other way around
deno_node::init_ops_and_esm::<Permissions>(None),
deno_node::init_polyfill_ops_and_esm(),
deno_node::deno_node_loading::init_ops_and_esm::<Permissions>(None),
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 {
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
snapshot_path,
@ -303,28 +315,6 @@ mod startup_snapshot {
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() {
@ -351,5 +341,5 @@ fn main() {
not(feature = "docsrs"),
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::Extension;
use notify::event::Event as NotifyEvent;
use notify::Error as NotifyError;
use notify::EventKind;
@ -29,11 +28,10 @@ use std::path::PathBuf;
use std::rc::Rc;
use tokio::sync::mpsc;
pub fn init() -> Extension {
Extension::builder("deno_fs_events")
.ops(vec![op_fs_events_open::decl(), op_fs_events_poll::decl()])
.build()
}
deno_core::extension!(
deno_fs_events,
ops = [op_fs_events_open, op_fs_events_poll]
);
struct FsEventsResource {
#[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::AnyError;
use deno_core::op;
use deno_core::Extension;
use deno_core::OpState;
use deno_core::RcRef;
use deno_core::ResourceId;
@ -28,15 +27,10 @@ use deno_net::io::UnixStreamResource;
#[cfg(unix)]
use tokio::net::UnixStream;
pub fn init() -> Extension {
Extension::builder("deno_http_runtime")
.ops(vec![
op_http_start::decl(),
op_http_upgrade::decl(),
op_flash_upgrade_http::decl(),
])
.build()
}
deno_core::extension!(
deno_http_runtime,
ops = [op_http_start, op_http_upgrade, op_flash_upgrade_http],
);
#[op]
fn op_http_start(

View file

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

View file

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

View file

@ -3,18 +3,17 @@
use crate::permissions::PermissionsContainer;
use deno_core::error::AnyError;
use deno_core::op;
use deno_core::Extension;
use deno_core::ModuleSpecifier;
use deno_core::OpState;
pub fn init(main_module: ModuleSpecifier) -> Extension {
Extension::builder("deno_runtime")
.ops(vec![op_main_module::decl()])
.state(move |state| {
state.put::<ModuleSpecifier>(main_module.clone());
})
.build()
}
deno_core::extension!(
deno_runtime,
ops = [op_main_module],
config = { main_module: ModuleSpecifier },
state = |state, main_module| {
state.put::<ModuleSpecifier>(main_module);
}
);
#[op]
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::CancelFuture;
use deno_core::CancelHandle;
use deno_core::Extension;
use deno_core::OpState;
use deno_core::RcRef;
use deno_core::Resource;
@ -30,15 +29,10 @@ use tokio::signal::windows::CtrlBreak;
#[cfg(windows)]
use tokio::signal::windows::CtrlC;
pub fn init() -> Extension {
Extension::builder("deno_signal")
.ops(vec![
op_signal_bind::decl(),
op_signal_unbind::decl(),
op_signal_poll::decl(),
])
.build()
}
deno_core::extension!(
deno_signal,
ops = [op_signal_bind, op_signal_unbind, op_signal_poll]
);
#[cfg(unix)]
/// The resource for signal stream.

View file

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

View file

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

View file

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

View file

@ -368,16 +368,22 @@ impl WebWorker {
worker_id: WorkerId,
mut options: WebWorkerOptions,
) -> (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
let unstable = options.bootstrap.unstable;
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_fn = move || SqliteBackedCache::new(storage_dir.clone());
CreateCache(Arc::new(create_cache_fn))
@ -387,68 +393,75 @@ impl WebWorker {
// `runtime/build.rs`, `runtime/worker.rs` and `cli/build.rs`!
let mut extensions: Vec<Extension> = vec![
// Web APIs
deno_webidl::init(),
deno_console::init(),
deno_url::init_ops(),
deno_web::init_ops::<PermissionsContainer>(
deno_webidl::deno_webidl::init_ops(),
deno_console::deno_console::init_ops(),
deno_url::deno_url::init_ops(),
deno_web::deno_web::init_ops::<PermissionsContainer>(
options.blob_store.clone(),
Some(main_module.clone()),
),
deno_fetch::init_ops::<PermissionsContainer>(deno_fetch::Options {
user_agent: options.bootstrap.user_agent.clone(),
root_cert_store: options.root_cert_store.clone(),
unsafely_ignore_certificate_errors: options
.unsafely_ignore_certificate_errors
.clone(),
file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler),
..Default::default()
}),
deno_cache::init_ops::<SqliteBackedCache>(create_cache),
deno_websocket::init_ops::<PermissionsContainer>(
deno_fetch::deno_fetch::init_ops::<PermissionsContainer>(
deno_fetch::Options {
user_agent: options.bootstrap.user_agent.clone(),
root_cert_store: options.root_cert_store.clone(),
unsafely_ignore_certificate_errors: options
.unsafely_ignore_certificate_errors
.clone(),
file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler),
..Default::default()
},
),
deno_cache::deno_cache::init_ops::<SqliteBackedCache>(create_cache),
deno_websocket::deno_websocket::init_ops::<PermissionsContainer>(
options.bootstrap.user_agent.clone(),
options.root_cert_store.clone(),
options.unsafely_ignore_certificate_errors.clone(),
),
deno_webstorage::init_ops(None).disable(),
deno_crypto::init_ops(options.seed),
deno_broadcast_channel::init_ops(
deno_webstorage::deno_webstorage::init_ops(None).disable(),
deno_crypto::deno_crypto::init_ops(options.seed),
deno_broadcast_channel::deno_broadcast_channel::init_ops(
options.broadcast_channel.clone(),
unstable,
),
deno_ffi::init_ops::<PermissionsContainer>(unstable),
deno_net::init_ops::<PermissionsContainer>(
deno_ffi::deno_ffi::init_ops::<PermissionsContainer>(unstable),
deno_net::deno_net::init_ops::<PermissionsContainer>(
options.root_cert_store.clone(),
unstable,
options.unsafely_ignore_certificate_errors.clone(),
),
deno_tls::init_ops(),
deno_napi::init_ops::<PermissionsContainer>(),
deno_http::init_ops(),
deno_io::init_ops(options.stdio),
deno_fs::init_ops::<PermissionsContainer>(unstable),
deno_flash::init_ops::<PermissionsContainer>(unstable),
deno_node::init_ops::<PermissionsContainer>(options.npm_resolver),
deno_node::init_polyfill_ops(),
deno_tls::deno_tls::init_ops(),
deno_napi::deno_napi::init_ops::<PermissionsContainer>(),
deno_http::deno_http::init_ops(),
deno_io::deno_io::init_ops(Rc::new(RefCell::new(Some(options.stdio)))),
deno_fs::deno_fs::init_ops::<PermissionsContainer>(unstable),
deno_flash::deno_flash::init_ops::<PermissionsContainer>(unstable),
deno_node::deno_node_loading::init_ops::<PermissionsContainer>(
options.npm_resolver,
),
deno_node::deno_node::init_ops(),
// Runtime ops that are always initialized for WebWorkers
ops::web_worker::init(),
ops::runtime::init(main_module.clone()),
ops::worker_host::init(
ops::web_worker::deno_web_worker::init_ops(),
ops::runtime::deno_runtime::init_ops(main_module.clone()),
ops::worker_host::deno_worker_host::init_ops(
options.create_web_worker_cb.clone(),
options.preload_module_cb.clone(),
options.pre_execute_module_cb.clone(),
options.format_js_error_fn.clone(),
),
ops::fs_events::init(),
ops::os::init_for_worker(),
ops::permissions::init(),
ops::process::init_ops(),
ops::signal::init(),
ops::tty::init(),
ops::http::init(),
ops::fs_events::deno_fs_events::init_ops(),
ops::os::deno_os_worker::init_ops(),
ops::permissions::deno_permissions::init_ops(),
ops::process::deno_process::init_ops(),
ops::signal::deno_signal::init_ops(),
ops::tty::deno_tty::init_ops(),
ops::http::deno_http_runtime::init_ops(),
deno_permissions_web_worker::init_ops(
permissions,
unstable,
enable_testing_features,
),
];
extensions.push(perm_ext);
// Append exts
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.
use std::cell::RefCell;
use std::pin::Pin;
use std::rc::Rc;
use std::sync::atomic::AtomicI32;
@ -187,16 +188,22 @@ impl MainWorker {
permissions: PermissionsContainer,
mut options: WorkerOptions,
) -> 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
let unstable = options.bootstrap.unstable;
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 create_cache = options.cache_storage_dir.map(|storage_dir| {
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`!
let mut extensions = vec![
// Web APIs
deno_webidl::init(),
deno_console::init(),
deno_url::init_ops(),
deno_web::init_ops::<PermissionsContainer>(
deno_webidl::deno_webidl::init_ops(),
deno_console::deno_console::init_ops(),
deno_url::deno_url::init_ops(),
deno_web::deno_web::init_ops::<PermissionsContainer>(
options.blob_store.clone(),
options.bootstrap.location.clone(),
),
deno_fetch::init_ops::<PermissionsContainer>(deno_fetch::Options {
user_agent: options.bootstrap.user_agent.clone(),
root_cert_store: options.root_cert_store.clone(),
unsafely_ignore_certificate_errors: options
.unsafely_ignore_certificate_errors
.clone(),
file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler),
..Default::default()
}),
deno_cache::init_ops::<SqliteBackedCache>(create_cache),
deno_websocket::init_ops::<PermissionsContainer>(
deno_fetch::deno_fetch::init_ops::<PermissionsContainer>(
deno_fetch::Options {
user_agent: options.bootstrap.user_agent.clone(),
root_cert_store: options.root_cert_store.clone(),
unsafely_ignore_certificate_errors: options
.unsafely_ignore_certificate_errors
.clone(),
file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler),
..Default::default()
},
),
deno_cache::deno_cache::init_ops::<SqliteBackedCache>(create_cache),
deno_websocket::deno_websocket::init_ops::<PermissionsContainer>(
options.bootstrap.user_agent.clone(),
options.root_cert_store.clone(),
options.unsafely_ignore_certificate_errors.clone(),
),
deno_webstorage::init_ops(options.origin_storage_dir.clone()),
deno_crypto::init_ops(options.seed),
deno_broadcast_channel::init_ops(
deno_webstorage::deno_webstorage::init_ops(
options.origin_storage_dir.clone(),
),
deno_crypto::deno_crypto::init_ops(options.seed),
deno_broadcast_channel::deno_broadcast_channel::init_ops(
options.broadcast_channel.clone(),
unstable,
),
deno_ffi::init_ops::<PermissionsContainer>(unstable),
deno_net::init_ops::<PermissionsContainer>(
deno_ffi::deno_ffi::init_ops::<PermissionsContainer>(unstable),
deno_net::deno_net::init_ops::<PermissionsContainer>(
options.root_cert_store.clone(),
unstable,
options.unsafely_ignore_certificate_errors.clone(),
),
deno_tls::init_ops(),
deno_napi::init_ops::<PermissionsContainer>(),
deno_http::init_ops(),
deno_io::init_ops(options.stdio),
deno_fs::init_ops::<PermissionsContainer>(unstable),
deno_flash::init_ops::<PermissionsContainer>(unstable),
deno_node::init_ops::<PermissionsContainer>(options.npm_resolver),
deno_node::init_polyfill_ops(),
deno_tls::deno_tls::init_ops(),
deno_napi::deno_napi::init_ops::<PermissionsContainer>(),
deno_http::deno_http::init_ops(),
deno_io::deno_io::init_ops(Rc::new(RefCell::new(Some(options.stdio)))),
deno_fs::deno_fs::init_ops::<PermissionsContainer>(unstable),
deno_flash::deno_flash::init_ops::<PermissionsContainer>(unstable),
deno_node::deno_node_loading::init_ops::<PermissionsContainer>(
options.npm_resolver,
),
deno_node::deno_node::init_ops(),
// Ops from this crate
ops::runtime::init(main_module.clone()),
ops::worker_host::init(
ops::runtime::deno_runtime::init_ops(main_module.clone()),
ops::worker_host::deno_worker_host::init_ops(
options.create_web_worker_cb.clone(),
options.web_worker_preload_module_cb.clone(),
options.web_worker_pre_execute_module_cb.clone(),
options.format_js_error_fn.clone(),
),
ops::fs_events::init(),
ops::os::init(exit_code.clone()),
ops::permissions::init(),
ops::process::init_ops(),
ops::signal::init(),
ops::tty::init(),
ops::http::init(),
ops::fs_events::deno_fs_events::init_ops(),
ops::os::deno_os::init_ops(exit_code.clone()),
ops::permissions::deno_permissions::init_ops(),
ops::process::deno_process::init_ops(),
ops::signal::deno_signal::init_ops(),
ops::tty::deno_tty::init_ops(),
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));
#[cfg(not(feature = "dont_create_runtime_snapshot"))]