diff --git a/cli/build.rs b/cli/build.rs index 4435cd243d..f01c006be5 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -376,22 +376,17 @@ fn create_cli_snapshot(snapshot_path: PathBuf) -> CreateSnapshotOutput { 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::deno_ffi::init_ops::(false), - deno_net::deno_net::init_ops::( - None, false, // No --unstable. - None, ), + deno_ffi::deno_ffi::init_ops::(), + deno_net::deno_net::init_ops::(None, None), deno_tls::deno_tls::init_ops(), - deno_kv::deno_kv::init_ops( - SqliteDbHandler::::new(None), - false, // No --unstable. - ), + deno_kv::deno_kv::init_ops(SqliteDbHandler::::new( + None, + )), deno_napi::deno_napi::init_ops::(), deno_http::deno_http::init_ops::(), deno_io::deno_io::init_ops(Default::default()), - deno_fs::deno_fs::init_ops::(false, fs.clone()), + deno_fs::deno_fs::init_ops::(fs.clone()), deno_node::deno_node::init_ops::(None, fs), deno_runtime::runtime::init_ops(), cli::init_ops_and_esm(), // NOTE: This needs to be init_ops_and_esm! diff --git a/ext/broadcast_channel/lib.rs b/ext/broadcast_channel/lib.rs index 6ee10f9c02..49cc784159 100644 --- a/ext/broadcast_channel/lib.rs +++ b/ext/broadcast_channel/lib.rs @@ -40,8 +40,6 @@ pub trait BroadcastChannel: Clone { pub type Message = (String, Vec); -struct Unstable(bool); // --unstable - #[op2(fast)] #[smi] pub fn op_broadcast_subscribe( @@ -50,15 +48,9 @@ pub fn op_broadcast_subscribe( where BC: BroadcastChannel + 'static, { - let unstable = state.borrow::().0; - - if !unstable { - eprintln!( - "Unstable API 'BroadcastChannel'. The --unstable flag must be provided.", - ); - std::process::exit(70); - } - + state + .feature_checker + .check_legacy_unstable_or_exit("BroadcastChannel"); let bc = state.borrow::(); let resource = bc.subscribe()?; Ok(state.resource_table.add(resource)) @@ -118,11 +110,9 @@ deno_core::extension!(deno_broadcast_channel, esm = [ "01_broadcast_channel.js" ], options = { bc: BC, - unstable: bool, }, state = |state, options| { state.put(options.bc); - state.put(Unstable(options.unstable)); }, ); diff --git a/ext/ffi/call.rs b/ext/ffi/call.rs index ad12d09856..ea78751083 100644 --- a/ext/ffi/call.rs +++ b/ext/ffi/call.rs @@ -1,7 +1,7 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use crate::callback::PtrSymbol; -use crate::check_unstable2; +use crate::check_unstable; use crate::dlfcn::DynamicLibraryResource; use crate::ir::*; use crate::symbol::NativeType; @@ -285,7 +285,7 @@ pub fn op_ffi_call_ptr_nonblocking( where FP: FfiPermissions + 'static, { - check_unstable2(&state, "Deno.UnsafeFnPointer#call"); + check_unstable(&state.borrow(), "Deno.UnsafeFnPointer#call"); { let mut state = state.borrow_mut(); let permissions = state.borrow_mut::(); @@ -381,7 +381,7 @@ pub fn op_ffi_call_ptr( where FP: FfiPermissions + 'static, { - check_unstable2(&state, "Deno.UnsafeFnPointer#call"); + check_unstable(&state.borrow(), "Deno.UnsafeFnPointer#call"); { let mut state = state.borrow_mut(); let permissions = state.borrow_mut::(); diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs index b5a2a3bd57..1ca921119e 100644 --- a/ext/ffi/lib.rs +++ b/ext/ffi/lib.rs @@ -45,22 +45,10 @@ const _: () = { pub(crate) const MAX_SAFE_INTEGER: isize = 9007199254740991; pub(crate) const MIN_SAFE_INTEGER: isize = -9007199254740991; -pub struct Unstable(pub bool); - fn check_unstable(state: &OpState, api_name: &str) { - let unstable = state.borrow::(); - - if !unstable.0 { - eprintln!( - "Unstable API '{api_name}'. The --unstable flag must be provided." - ); - std::process::exit(70); - } -} - -pub fn check_unstable2(state: &Rc>, api_name: &str) { - let state = state.borrow(); - check_unstable(&state, api_name) + state + .feature_checker + .check_legacy_unstable_or_exit(api_name); } pub trait FfiPermissions { @@ -108,13 +96,6 @@ deno_core::extension!(deno_ffi, op_ffi_unsafe_callback_ref, ], esm = [ "00_ffi.js" ], - options = { - unstable: bool, - }, - state = |state, options| { - // Stolen from deno_webgpu, is there a better option? - state.put(Unstable(options.unstable)); - }, event_loop_middleware = event_loop_middleware, ); diff --git a/ext/fs/lib.rs b/ext/fs/lib.rs index b028b12c16..ab19540b5b 100644 --- a/ext/fs/lib.rs +++ b/ext/fs/lib.rs @@ -18,9 +18,7 @@ use crate::ops::*; use deno_core::error::AnyError; use deno_core::OpState; -use std::cell::RefCell; use std::path::Path; -use std::rc::Rc; pub trait FsPermissions { fn check_read(&mut self, path: &Path, api_name: &str) @@ -66,31 +64,11 @@ pub trait FsPermissions { } } -struct UnstableChecker { - pub unstable: bool, -} - -impl UnstableChecker { - // NOTE(bartlomieju): keep in sync with `cli/program_state.rs` - pub fn check_unstable(&self, api_name: &str) { - if !self.unstable { - eprintln!( - "Unstable API '{api_name}'. The --unstable flag must be provided." - ); - std::process::exit(70); - } - } -} - /// Helper for checking unstable features. Used for sync ops. -pub(crate) fn check_unstable(state: &OpState, api_name: &str) { - state.borrow::().check_unstable(api_name) -} - -/// Helper for checking unstable features. Used for async ops. -pub(crate) fn check_unstable2(state: &Rc>, api_name: &str) { - let state = state.borrow(); - state.borrow::().check_unstable(api_name) +fn check_unstable(state: &OpState, api_name: &str) { + state + .feature_checker + .check_legacy_unstable_or_exit(api_name); } deno_core::extension!(deno_fs, @@ -164,11 +142,9 @@ deno_core::extension!(deno_fs, ], esm = [ "30_fs.js" ], options = { - unstable: bool, fs: FileSystemRc, }, state = |state, options| { - state.put(UnstableChecker { unstable: options.unstable }); state.put(options.fs); }, ); diff --git a/ext/fs/ops.rs b/ext/fs/ops.rs index bc09a4a250..9fa8cf9188 100644 --- a/ext/fs/ops.rs +++ b/ext/fs/ops.rs @@ -27,7 +27,6 @@ use rand::Rng; use serde::Serialize; use crate::check_unstable; -use crate::check_unstable2; use crate::interface::FileSystemRc; use crate::interface::FsDirEntry; use crate::interface::FsFileType; @@ -1422,7 +1421,7 @@ pub async fn op_fs_flock_async( #[smi] rid: ResourceId, exclusive: bool, ) -> Result<(), AnyError> { - check_unstable2(&state, "Deno.flock"); + check_unstable(&state.borrow(), "Deno.flock"); let file = FileResource::get_file(&state.borrow(), rid)?; file.lock_async(exclusive).await?; Ok(()) @@ -1444,7 +1443,7 @@ pub async fn op_fs_funlock_async( state: Rc>, #[smi] rid: ResourceId, ) -> Result<(), AnyError> { - check_unstable2(&state, "Deno.funlock"); + check_unstable(&state.borrow(), "Deno.funlock"); let file = FileResource::get_file(&state.borrow(), rid)?; file.unlock_async().await?; Ok(()) diff --git a/ext/http/http_next.rs b/ext/http/http_next.rs index 880925603f..90f7f0b1db 100644 --- a/ext/http/http_next.rs +++ b/ext/http/http_next.rs @@ -1105,7 +1105,10 @@ pub async fn op_http_close( .take::(rid)?; if graceful { - deno_net::check_unstable2(&state, "Deno.Server.shutdown"); + state + .borrow() + .feature_checker + .check_legacy_unstable_or_exit("Deno.Server.shutdown"); // In a graceful shutdown, we close the listener and allow all the remaining connections to drain join_handle.listen_cancel_handle().cancel(); } else { diff --git a/ext/kv/lib.rs b/ext/kv/lib.rs index 762009d2a4..3056e4660f 100644 --- a/ext/kv/lib.rs +++ b/ext/kv/lib.rs @@ -44,22 +44,6 @@ const MAX_MUTATIONS: usize = 1000; const MAX_TOTAL_MUTATION_SIZE_BYTES: usize = 800 * 1024; const MAX_TOTAL_KEY_SIZE_BYTES: usize = 80 * 1024; -struct UnstableChecker { - pub unstable: bool, -} - -impl UnstableChecker { - // NOTE(bartlomieju): keep in sync with `cli/program_state.rs` - pub fn check_unstable(&self, api_name: &str) { - if !self.unstable { - eprintln!( - "Unstable API '{api_name}'. The --unstable flag must be provided." - ); - std::process::exit(70); - } - } -} - deno_core::extension!(deno_kv, deps = [ deno_console ], parameters = [ DBH: DatabaseHandler ], @@ -74,11 +58,9 @@ deno_core::extension!(deno_kv, esm = [ "01_db.ts" ], options = { handler: DBH, - unstable: bool, }, state = |state, options| { state.put(Rc::new(options.handler)); - state.put(UnstableChecker { unstable: options.unstable }) } ); @@ -108,8 +90,8 @@ where let handler = { let state = state.borrow(); state - .borrow::() - .check_unstable("Deno.openKv"); + .feature_checker + .check_legacy_unstable_or_exit("Deno.openKv"); state.borrow::>().clone() }; let db = handler.open(state.clone(), path).await?; diff --git a/ext/net/lib.rs b/ext/net/lib.rs index 0e3778d5a8..1fc7e34205 100644 --- a/ext/net/lib.rs +++ b/ext/net/lib.rs @@ -12,10 +12,8 @@ use deno_core::error::AnyError; use deno_core::OpState; use deno_tls::rustls::RootCertStore; use deno_tls::RootCertStoreProvider; -use std::cell::RefCell; use std::path::Path; use std::path::PathBuf; -use std::rc::Rc; use std::sync::Arc; pub trait NetPermissions { @@ -29,38 +27,11 @@ pub trait NetPermissions { -> Result<(), AnyError>; } -/// `UnstableChecker` is a struct so it can be placed inside `GothamState`; -/// using type alias for a bool could work, but there's a high chance -/// that there might be another type alias pointing to a bool, which -/// would override previously used alias. -pub struct UnstableChecker { - pub unstable: bool, -} - -impl UnstableChecker { - /// Quits the process if the --unstable flag was not provided. - /// - /// This is intentionally a non-recoverable check so that people cannot probe - /// for unstable APIs from stable programs. - // NOTE(bartlomieju): keep in sync with `cli/program_state.rs` - pub fn check_unstable(&self, api_name: &str) { - if !self.unstable { - eprintln!( - "Unstable API '{api_name}'. The --unstable flag must be provided." - ); - std::process::exit(70); - } - } -} /// Helper for checking unstable features. Used for sync ops. -pub fn check_unstable(state: &OpState, api_name: &str) { - state.borrow::().check_unstable(api_name) -} - -/// Helper for checking unstable features. Used for async ops. -pub fn check_unstable2(state: &Rc>, api_name: &str) { - let state = state.borrow(); - state.borrow::().check_unstable(api_name) +fn check_unstable(state: &OpState, api_name: &str) { + state + .feature_checker + .check_legacy_unstable_or_exit(api_name); } pub fn get_declaration() -> PathBuf { @@ -125,14 +96,12 @@ deno_core::extension!(deno_net, esm = [ "01_net.js", "02_tls.js" ], options = { root_cert_store_provider: Option>, - unstable: bool, unsafely_ignore_certificate_errors: Option>, }, state = |state, options| { state.put(DefaultTlsOptions { root_cert_store_provider: options.root_cert_store_provider, }); - state.put(UnstableChecker { unstable: options.unstable }); state.put(UnsafelyIgnoreCertificateErrors( options.unsafely_ignore_certificate_errors, )); diff --git a/ext/net/ops.rs b/ext/net/ops.rs index 5deaeb61e0..5738620f8c 100644 --- a/ext/net/ops.rs +++ b/ext/net/ops.rs @@ -771,7 +771,6 @@ fn rdata_to_return_record( #[cfg(test)] mod tests { use super::*; - use crate::UnstableChecker; use deno_core::futures::FutureExt; use deno_core::JsRuntime; use deno_core::RuntimeOptions; @@ -1039,7 +1038,6 @@ mod tests { test_ext, state = |state| { state.put(TestPermission {}); - state.put(UnstableChecker { unstable: true }); } ); @@ -1049,6 +1047,10 @@ mod tests { }); let conn_state = runtime.op_state(); + conn_state + .borrow_mut() + .feature_checker + .enable_legacy_unstable(); let server_addr: Vec<&str> = clone_addr.split(':').collect(); let ip_addr = IpAddr { diff --git a/ext/net/ops_tls.rs b/ext/net/ops_tls.rs index 0b84415b91..fe0e70a5cf 100644 --- a/ext/net/ops_tls.rs +++ b/ext/net/ops_tls.rs @@ -878,10 +878,10 @@ where .and_then(|it| it.0.clone()); if args.cert_chain.is_some() { - super::check_unstable2(&state, "ConnectTlsOptions.certChain"); + super::check_unstable(&state.borrow(), "ConnectTlsOptions.certChain"); } if args.private_key.is_some() { - super::check_unstable2(&state, "ConnectTlsOptions.privateKey"); + super::check_unstable(&state.borrow(), "ConnectTlsOptions.privateKey"); } { diff --git a/ext/net/ops_unix.rs b/ext/net/ops_unix.rs index 7a5da9fa1b..a36f1c30bc 100644 --- a/ext/net/ops_unix.rs +++ b/ext/net/ops_unix.rs @@ -114,7 +114,7 @@ where NP: NetPermissions + 'static, { let address_path = Path::new(&path); - super::check_unstable2(&state, "Deno.connect"); + super::check_unstable(&state.borrow(), "Deno.connect"); { let mut state_ = state.borrow_mut(); state_ diff --git a/runtime/build.rs b/runtime/build.rs index 5134c9d7a3..6684afe09e 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -224,22 +224,17 @@ mod startup_snapshot { 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::deno_ffi::init_ops_and_esm::(false), - deno_net::deno_net::init_ops_and_esm::( - None, false, // No --unstable. - None, ), + deno_ffi::deno_ffi::init_ops_and_esm::(), + deno_net::deno_net::init_ops_and_esm::(None, None), deno_tls::deno_tls::init_ops_and_esm(), - deno_kv::deno_kv::init_ops_and_esm( - deno_kv::sqlite::SqliteDbHandler::::new(None), - false, // No --unstable - ), + deno_kv::deno_kv::init_ops_and_esm(deno_kv::sqlite::SqliteDbHandler::< + Permissions, + >::new(None)), deno_napi::deno_napi::init_ops_and_esm::(), deno_http::deno_http::init_ops_and_esm::(), deno_io::deno_io::init_ops_and_esm(Default::default()), - deno_fs::deno_fs::init_ops_and_esm::(false, fs.clone()), + deno_fs::deno_fs::init_ops_and_esm::(fs.clone()), deno_node::deno_node::init_ops_and_esm::(None, fs), runtime::init_ops_and_esm(), ]; diff --git a/runtime/ops/mod.rs b/runtime/ops/mod.rs index 5cb7dcbff2..cdafd61ecd 100644 --- a/runtime/ops/mod.rs +++ b/runtime/ops/mod.rs @@ -13,41 +13,12 @@ pub mod web_worker; pub mod worker_host; use deno_core::OpState; -use std::cell::RefCell; -use std::rc::Rc; -/// `UnstableChecker` is a struct so it can be placed inside `GothamState`; -/// using type alias for a bool could work, but there's a high chance -/// that there might be another type alias pointing to a bool, which -/// would override previously used alias. -pub struct UnstableChecker { - pub unstable: bool, -} - -impl UnstableChecker { - /// Quits the process if the --unstable flag was not provided. - /// - /// This is intentionally a non-recoverable check so that people cannot probe - /// for unstable APIs from stable programs. - // NOTE(bartlomieju): keep in sync with `cli/program_state.rs` - pub fn check_unstable(&self, api_name: &str) { - if !self.unstable { - eprintln!( - "Unstable API '{api_name}'. The --unstable flag must be provided." - ); - std::process::exit(70); - } - } -} /// Helper for checking unstable features. Used for sync ops. pub fn check_unstable(state: &OpState, api_name: &str) { - state.borrow::().check_unstable(api_name) -} - -/// Helper for checking unstable features. Used for async ops. -pub fn check_unstable2(state: &Rc>, api_name: &str) { - let state = state.borrow(); - state.borrow::().check_unstable(api_name) + state + .feature_checker + .check_legacy_unstable_or_exit(api_name); } pub struct TestingFeaturesEnabled(pub bool); diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 6fcc7aa9ce..f37a77d889 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -376,12 +376,10 @@ impl WebWorker { deno_core::extension!(deno_permissions_web_worker, options = { permissions: PermissionsContainer, - unstable: bool, enable_testing_features: bool, }, state = |state, options| { state.put::(options.permissions); - state.put(ops::UnstableChecker { unstable: options.unstable }); state.put(ops::TestingFeaturesEnabled(options.enable_testing_features)); }, ); @@ -429,24 +427,20 @@ impl WebWorker { deno_crypto::deno_crypto::init_ops_and_esm(options.seed), deno_broadcast_channel::deno_broadcast_channel::init_ops_and_esm( options.broadcast_channel.clone(), - unstable, ), - deno_ffi::deno_ffi::init_ops_and_esm::(unstable), + deno_ffi::deno_ffi::init_ops_and_esm::(), deno_net::deno_net::init_ops_and_esm::( options.root_cert_store_provider.clone(), - unstable, options.unsafely_ignore_certificate_errors.clone(), ), deno_tls::deno_tls::init_ops_and_esm(), deno_kv::deno_kv::init_ops_and_esm( MultiBackendDbHandler::remote_or_sqlite::(None), - unstable, ), deno_napi::deno_napi::init_ops_and_esm::(), deno_http::deno_http::init_ops_and_esm::(), deno_io::deno_io::init_ops_and_esm(Some(options.stdio)), deno_fs::deno_fs::init_ops_and_esm::( - unstable, options.fs.clone(), ), deno_node::deno_node::init_ops_and_esm::( @@ -469,7 +463,6 @@ impl WebWorker { ops::http::deno_http_runtime::init_ops_and_esm(), deno_permissions_web_worker::init_ops_and_esm( permissions, - unstable, enable_testing_features, ), runtime::init_ops_and_esm(), @@ -519,6 +512,14 @@ impl WebWorker { ..Default::default() }); + if unstable { + let op_state = js_runtime.op_state(); + op_state + .borrow_mut() + .feature_checker + .enable_legacy_unstable(); + } + if let Some(server) = options.maybe_inspector_server.clone() { server.register_inspector( main_module.to_string(), diff --git a/runtime/worker.rs b/runtime/worker.rs index 6b9fca5614..e8874575aa 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -196,12 +196,10 @@ impl MainWorker { deno_core::extension!(deno_permissions_worker, options = { permissions: PermissionsContainer, - unstable: bool, enable_testing_features: bool, }, state = |state, options| { state.put::(options.permissions); - state.put(ops::UnstableChecker { unstable: options.unstable }); state.put(ops::TestingFeaturesEnabled(options.enable_testing_features)); }, ); @@ -251,12 +249,10 @@ impl MainWorker { deno_crypto::deno_crypto::init_ops_and_esm(options.seed), deno_broadcast_channel::deno_broadcast_channel::init_ops_and_esm( options.broadcast_channel.clone(), - unstable, ), - deno_ffi::deno_ffi::init_ops_and_esm::(unstable), + deno_ffi::deno_ffi::init_ops_and_esm::(), deno_net::deno_net::init_ops_and_esm::( options.root_cert_store_provider.clone(), - unstable, options.unsafely_ignore_certificate_errors.clone(), ), deno_tls::deno_tls::init_ops_and_esm(), @@ -264,13 +260,11 @@ impl MainWorker { MultiBackendDbHandler::remote_or_sqlite::( options.origin_storage_dir.clone(), ), - unstable, ), deno_napi::deno_napi::init_ops_and_esm::(), deno_http::deno_http::init_ops_and_esm::(), deno_io::deno_io::init_ops_and_esm(Some(options.stdio)), deno_fs::deno_fs::init_ops_and_esm::( - unstable, options.fs.clone(), ), deno_node::deno_node::init_ops_and_esm::( @@ -292,7 +286,6 @@ impl MainWorker { ops::http::deno_http_runtime::init_ops_and_esm(), deno_permissions_worker::init_ops_and_esm( permissions, - unstable, enable_testing_features, ), runtime::init_ops_and_esm(), @@ -344,6 +337,14 @@ impl MainWorker { ..Default::default() }); + if unstable { + let op_state = js_runtime.op_state(); + op_state + .borrow_mut() + .feature_checker + .enable_legacy_unstable(); + } + if let Some(server) = options.maybe_inspector_server.clone() { server.register_inspector( main_module.to_string(),