diff --git a/cli/tests/unit/metrics_test.ts b/cli/tests/unit/metrics_test.ts index 9fa37e99bd7316..25c63dbc168bae 100644 --- a/cli/tests/unit/metrics_test.ts +++ b/cli/tests/unit/metrics_test.ts @@ -69,3 +69,12 @@ unitTest( assert(metrics.opsDispatchedAsync === metrics.opsCompletedAsync); }, ); + +// Test that ops from op_crates have metrics (via OpMiddleware) +unitTest(function metricsForOpCrates(): void { + const _ = new URL("https://deno.land"); + + const m1 = Deno.metrics().ops["op_url_parse"]; + assert(m1.opsDispatched > 0); + assert(m1.opsCompleted > 0); +}); diff --git a/core/extensions.rs b/core/extensions.rs new file mode 100644 index 00000000000000..eb6f6f719c01ef --- /dev/null +++ b/core/extensions.rs @@ -0,0 +1,105 @@ +use crate::error::AnyError; +use crate::{OpFn, OpState}; + +pub type SourcePair = (&'static str, &'static str); +pub type OpPair = (&'static str, Box); +pub type OpMiddlewareFn = dyn Fn(&'static str, Box) -> Box; +pub type OpStateFn = dyn Fn(&mut OpState) -> Result<(), AnyError>; + +#[derive(Default)] +pub struct Extension { + js_files: Option>, + ops: Option>, + opstate_fn: Option>, + middleware_fn: Option>, + initialized: bool, +} + +impl Extension { + pub fn new( + js_files: Option>, + ops: Option>, + opstate_fn: Option>, + middleware_fn: Option>, + ) -> Self { + Self { + js_files, + ops, + opstate_fn, + middleware_fn, + initialized: false, + } + } + + pub fn pure_js(js_files: Vec) -> Self { + Self::new(Some(js_files), None, None, None) + } + + pub fn with_ops( + js_files: Vec, + ops: Vec, + opstate_fn: Option>, + ) -> Self { + Self::new(Some(js_files), Some(ops), opstate_fn, None) + } +} + +// Note: this used to be a trait, but we "downgraded" it to a single concrete type +// for the initial iteration, it will likely become a trait in the future +impl Extension { + /// returns JS source code to be loaded into the isolate (either at snapshotting, + /// or at startup). as a vector of a tuple of the file name, and the source code. + pub(crate) fn init_js(&self) -> Vec { + match &self.js_files { + Some(files) => files.clone(), + None => vec![], + } + } + + /// Called at JsRuntime startup to initialize ops in the isolate. + pub(crate) fn init_ops(&mut self) -> Option> { + // TODO(@AaronO): maybe make op registration idempotent + if self.initialized { + panic!("init_ops called twice: not idempotent or correct"); + } + self.initialized = true; + + self.ops.take() + } + + /// Allows setting up the initial op-state of an isolate at startup. + pub(crate) fn init_state(&self, state: &mut OpState) -> Result<(), AnyError> { + match &self.opstate_fn { + Some(ofn) => ofn(state), + None => Ok(()), + } + } + + /// init_middleware lets us middleware op registrations, it's called before init_ops + pub(crate) fn init_middleware(&mut self) -> Option> { + self.middleware_fn.take() + } +} + +/// Helps embed JS files in an extension. Returns Vec<(&'static str, &'static str)> +/// representing the filename and source code. +/// +/// Example: +/// ```ignore +/// include_js_files!( +/// prefix "deno:op_crates/hello", +/// "01_hello.js", +/// "02_goodbye.js", +/// ) +/// ``` +#[macro_export] +macro_rules! include_js_files { + (prefix $prefix:literal, $($file:literal,)+) => { + vec![ + $(( + concat!($prefix, "/", $file), + include_str!($file), + ),)+ + ] + }; +} diff --git a/core/lib.rs b/core/lib.rs index 9b4ba230b77279..37055bcc8d7095 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -3,6 +3,7 @@ mod async_cancel; mod async_cell; mod bindings; pub mod error; +mod extensions; mod flags; mod gotham_state; mod module_specifier; @@ -75,6 +76,9 @@ pub use crate::runtime::JsErrorCreateFn; pub use crate::runtime::JsRuntime; pub use crate::runtime::RuntimeOptions; pub use crate::runtime::Snapshot; +// pub use crate::runtime_modules::include_js_files!; +pub use crate::extensions::Extension; +pub use crate::extensions::OpMiddlewareFn; pub use crate::zero_copy_buf::ZeroCopyBuf; pub fn v8_version() -> &'static str { diff --git a/core/runtime.rs b/core/runtime.rs index 7475c70209eb93..430d6fff8ee8a0 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -20,6 +20,8 @@ use crate::modules::NoopModuleLoader; use crate::modules::PrepareLoadFuture; use crate::modules::RecursiveModuleLoad; use crate::ops::*; +use crate::Extension; +use crate::OpMiddlewareFn; use crate::OpPayload; use crate::OpResponse; use crate::OpState; @@ -83,6 +85,7 @@ pub struct JsRuntime { snapshot_creator: Option, has_snapshotted: bool, allocations: IsolateAllocations, + extensions: Vec, } struct DynImportModEvaluate { @@ -186,6 +189,10 @@ pub struct RuntimeOptions { /// executed tries to load modules. pub module_loader: Option>, + /// JsRuntime extensions, not to be confused with ES modules + /// these are sets of ops and other JS code to be initialized. + pub extensions: Vec, + /// V8 snapshot that should be loaded on startup. /// /// Currently can't be used with `will_snapshot`. @@ -300,6 +307,7 @@ impl JsRuntime { snapshot_creator: maybe_snapshot_creator, has_snapshotted: false, allocations: IsolateAllocations::default(), + extensions: options.extensions, }; if !has_startup_snapshot { @@ -349,6 +357,57 @@ impl JsRuntime { .unwrap(); } + /// Initializes JS of provided Extensions + // NOTE: this will probably change when streamlining snapshot flow + pub fn init_extension_js(&mut self) -> Result<(), AnyError> { + // Take extensions to avoid double-borrow + let mut extensions: Vec = std::mem::take(&mut self.extensions); + for m in extensions.iter_mut() { + let js_files = m.init_js(); + for (filename, source) in js_files { + // TODO(@AaronO): use JsRuntime::execute_static() here to move src off heap + self.execute(filename, source)?; + } + } + // Restore extensions + self.extensions = extensions; + + Ok(()) + } + + /// Initializes ops of provided Extensions + // NOTE: this will probably change when streamlining snapshot flow + pub fn init_extension_ops(&mut self) -> Result<(), AnyError> { + let op_state = self.op_state(); + // Take extensions to avoid double-borrow + let mut extensions: Vec = std::mem::take(&mut self.extensions); + + // Middleware + let middleware: Vec> = extensions + .iter_mut() + .filter_map(|e| e.init_middleware()) + .collect(); + // macroware wraps an opfn in all the middleware + let macroware = + move |name, opfn| middleware.iter().fold(opfn, |opfn, m| m(name, opfn)); + + // Register ops + for e in extensions.iter_mut() { + e.init_state(&mut op_state.borrow_mut())?; + // Register each op after middlewaring it + let mut ops = e.init_ops().unwrap_or_default(); + for (name, opfn) in ops { + self.register_op(name, macroware(name, opfn)); + } + } + // Sync ops cache + self.sync_ops_cache(); + // Restore extensions + self.extensions = extensions; + + Ok(()) + } + /// Grabs a reference to core.js' handleAsyncMsgFromRust fn init_recv_cb(&mut self) { let context = self.global_context(); diff --git a/op_crates/console/lib.rs b/op_crates/console/lib.rs index a972f621294e40..4d6a213f280ea5 100644 --- a/op_crates/console/lib.rs +++ b/op_crates/console/lib.rs @@ -1,23 +1,15 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use deno_core::JsRuntime; +use deno_core::include_js_files; +use deno_core::Extension; use std::path::PathBuf; -/// Load and execute the javascript code. -pub fn init(isolate: &mut JsRuntime) { - let files = vec![ - ( - "deno:op_crates/console/01_colors.js", - include_str!("01_colors.js"), - ), - ( - "deno:op_crates/console/02_console.js", - include_str!("02_console.js"), - ), - ]; - for (url, source_code) in files { - isolate.execute(url, source_code).unwrap(); - } +pub fn init() -> Extension { + Extension::pure_js(include_js_files!( + prefix "deno:op_crates/console", + "01_colors.js", + "02_console.js", + )) } pub fn get_declaration() -> PathBuf { diff --git a/op_crates/crypto/lib.rs b/op_crates/crypto/lib.rs index c74b1b2c2451f8..00deadc1bc1654 100644 --- a/op_crates/crypto/lib.rs +++ b/op_crates/crypto/lib.rs @@ -4,25 +4,36 @@ use deno_core::error::null_opbuf; use deno_core::error::AnyError; -use deno_core::JsRuntime; +use deno_core::include_js_files; +use deno_core::op_sync; +use deno_core::Extension; use deno_core::OpState; use deno_core::ZeroCopyBuf; use rand::rngs::StdRng; use rand::thread_rng; use rand::Rng; +use rand::SeedableRng; use std::path::PathBuf; pub use rand; // Re-export rand -/// Execute this crates' JS source files. -pub fn init(isolate: &mut JsRuntime) { - let files = vec![( - "deno:op_crates/crypto/01_crypto.js", - include_str!("01_crypto.js"), - )]; - for (url, source_code) in files { - isolate.execute(url, source_code).unwrap(); - } +pub fn init(maybe_seed: Option) -> Extension { + Extension::with_ops( + include_js_files!( + prefix "deno:op_crates/crypto", + "01_crypto.js", + ), + vec![( + "op_crypto_get_random_values", + op_sync(op_crypto_get_random_values), + )], + Some(Box::new(move |state| { + if let Some(seed) = maybe_seed { + state.put(StdRng::seed_from_u64(seed)); + } + Ok(()) + })), + ) } pub fn op_crypto_get_random_values( diff --git a/op_crates/fetch/lib.rs b/op_crates/fetch/lib.rs index 41fb153e004d0a..c4aeca2ee2b77c 100644 --- a/op_crates/fetch/lib.rs +++ b/op_crates/fetch/lib.rs @@ -10,12 +10,15 @@ use deno_core::error::AnyError; 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_async; +use deno_core::op_sync; use deno_core::url::Url; use deno_core::AsyncRefCell; use deno_core::CancelFuture; use deno_core::CancelHandle; use deno_core::CancelTryFuture; -use deno_core::JsRuntime; +use deno_core::Extension; use deno_core::OpState; use deno_core::RcRef; use deno_core::Resource; @@ -51,49 +54,41 @@ use tokio_util::io::StreamReader; pub use reqwest; // Re-export reqwest -/// Execute this crates' JS source files. -pub fn init(isolate: &mut JsRuntime) { - let files = vec![ - ( - "deno:op_crates/fetch/01_fetch_util.js", - include_str!("01_fetch_util.js"), - ), - ( - "deno:op_crates/fetch/11_streams.js", - include_str!("11_streams.js"), - ), - ( - "deno:op_crates/fetch/20_headers.js", - include_str!("20_headers.js"), - ), - ( - "deno:op_crates/fetch/21_formdata.js", - include_str!("21_formdata.js"), - ), - ( - "deno:op_crates/fetch/22_body.js", - include_str!("22_body.js"), - ), - ( - "deno:op_crates/fetch/22_http_client.js", - include_str!("22_http_client.js"), - ), - ( - "deno:op_crates/fetch/23_request.js", - include_str!("23_request.js"), - ), - ( - "deno:op_crates/fetch/23_response.js", - include_str!("23_response.js"), - ), - ( - "deno:op_crates/fetch/26_fetch.js", - include_str!("26_fetch.js"), +pub fn init( + user_agent: String, + ca_data: Option>, +) -> Extension { + Extension::with_ops( + include_js_files!( + prefix "deno:op_crates/fetch", + "01_fetch_util.js", + "11_streams.js", + "20_headers.js", + "21_formdata.js", + "22_body.js", + "22_http_client.js", + "23_request.js", + "23_response.js", + "26_fetch.js", ), - ]; - for (url, source_code) in files { - isolate.execute(url, source_code).expect(url); - } + vec![ + ("op_fetch", op_sync(op_fetch::

)), + ("op_fetch_send", op_async(op_fetch_send)), + ("op_fetch_request_write", op_async(op_fetch_request_write)), + ("op_fetch_response_read", op_async(op_fetch_response_read)), + ("op_create_http_client", op_sync(op_create_http_client::

)), + ], + Some(Box::new(move |state| { + state.put::({ + create_http_client(user_agent.clone(), ca_data.clone()).unwrap() + }); + state.put::(HttpClientDefaults { + ca_data: ca_data.clone(), + user_agent: user_agent.clone(), + }); + Ok(()) + })), + ) } pub struct HttpClientDefaults { diff --git a/op_crates/file/lib.rs b/op_crates/file/lib.rs index ea519046f1ec7d..19bb8b19b9b7c8 100644 --- a/op_crates/file/lib.rs +++ b/op_crates/file/lib.rs @@ -2,8 +2,10 @@ use deno_core::error::null_opbuf; use deno_core::error::AnyError; +use deno_core::include_js_files; +use deno_core::op_sync; use deno_core::url::Url; -use deno_core::JsRuntime; +use deno_core::Extension; use deno_core::ModuleSpecifier; use deno_core::ZeroCopyBuf; use std::collections::HashMap; @@ -82,22 +84,35 @@ pub fn op_file_revoke_object_url( Ok(()) } -/// Load and execute the javascript code. -pub fn init(isolate: &mut JsRuntime) { - let files = vec![ - ("deno:op_crates/file/01_file.js", include_str!("01_file.js")), - ( - "deno:op_crates/file/02_filereader.js", - include_str!("02_filereader.js"), +pub fn init( + blob_url_store: BlobUrlStore, + maybe_location: Option, +) -> Extension { + Extension::with_ops( + include_js_files!( + prefix "deno:op_crates/file", + "01_file.js", + "02_filereader.js", + "03_blob_url.js", ), - ( - "deno:op_crates/file/03_blob_url.js", - include_str!("03_blob_url.js"), - ), - ]; - for (url, source_code) in files { - isolate.execute(url, source_code).unwrap(); - } + vec![ + ( + "op_file_create_object_url", + op_sync(op_file_create_object_url), + ), + ( + "op_file_revoke_object_url", + op_sync(op_file_revoke_object_url), + ), + ], + Some(Box::new(move |state| { + state.put(blob_url_store.clone()); + if let Some(location) = maybe_location.clone() { + state.put(Location(location)); + } + Ok(()) + })), + ) } pub fn get_declaration() -> PathBuf { diff --git a/op_crates/timers/lib.rs b/op_crates/timers/lib.rs index 047b6923c52df0..6359b20f0c51bd 100644 --- a/op_crates/timers/lib.rs +++ b/op_crates/timers/lib.rs @@ -13,6 +13,9 @@ use deno_core::futures; use deno_core::futures::channel::oneshot; use deno_core::futures::FutureExt; use deno_core::futures::TryFutureExt; +use deno_core::op_async; +use deno_core::op_sync; +use deno_core::Extension; use deno_core::OpState; use deno_core::ZeroCopyBuf; use std::cell::RefCell; @@ -28,12 +31,34 @@ pub trait TimersPermission { fn check_unstable(&self, state: &OpState, api_name: &'static str); } -pub fn init(rt: &mut deno_core::JsRuntime) { - rt.execute( - "deno:op_crates/timers/01_timers.js", - include_str!("01_timers.js"), +pub struct NoTimersPermission; + +impl TimersPermission for NoTimersPermission { + fn allow_hrtime(&mut self) -> bool { + false + } + fn check_unstable(&self, _: &OpState, _: &'static str) {} +} + +pub fn init() -> Extension { + Extension::with_ops( + vec![( + "deno:op_crates/timers/01_timers.js", + include_str!("01_timers.js"), + )], + vec![ + ("op_global_timer_stop", op_sync(op_global_timer_stop)), + ("op_global_timer_start", op_sync(op_global_timer_start)), + ("op_global_timer", op_async(op_global_timer)), + ("op_now", op_sync(op_now::

)), + ("op_sleep_sync", op_sync(op_sleep_sync::

)), + ], + Some(Box::new(|state| { + state.put(GlobalTimer::default()); + state.put(StartTime::now()); + Ok(()) + })), ) - .unwrap(); } pub type StartTime = Instant; diff --git a/op_crates/url/benches/url_ops.rs b/op_crates/url/benches/url_ops.rs index 7d5d32879ba7a8..3428d6684120f1 100644 --- a/op_crates/url/benches/url_ops.rs +++ b/op_crates/url/benches/url_ops.rs @@ -1,21 +1,14 @@ use bencher::{benchmark_group, benchmark_main, Bencher}; -use deno_core::op_sync; use deno_core::v8; use deno_core::JsRuntime; +use deno_core::RuntimeOptions; fn create_js_runtime() -> JsRuntime { - let mut runtime = JsRuntime::new(Default::default()); - runtime.register_op("op_url_parse", op_sync(deno_url::op_url_parse)); - runtime.register_op( - "op_url_parse_search_params", - op_sync(deno_url::op_url_parse_search_params), - ); - runtime.register_op( - "op_url_stringify_search_params", - op_sync(deno_url::op_url_stringify_search_params), - ); - runtime.sync_ops_cache(); + let mut runtime = JsRuntime::new(RuntimeOptions { + extensions: vec![deno_url::init()], + ..Default::default() + }); runtime .execute( @@ -23,7 +16,10 @@ fn create_js_runtime() -> JsRuntime { "globalThis.__bootstrap = (globalThis.__bootstrap || {});", ) .unwrap(); - deno_url::init(&mut runtime); + + runtime.init_extension_js().unwrap(); + runtime.init_extension_ops().unwrap(); + runtime .execute("setup", "const { URL } = globalThis.__bootstrap.url;") .unwrap(); diff --git a/op_crates/url/lib.rs b/op_crates/url/lib.rs index 04663e411a5102..49e34c47d59c67 100644 --- a/op_crates/url/lib.rs +++ b/op_crates/url/lib.rs @@ -4,16 +4,39 @@ use deno_core::error::generic_error; use deno_core::error::type_error; use deno_core::error::uri_error; use deno_core::error::AnyError; +use deno_core::include_js_files; +use deno_core::op_sync; use deno_core::url::form_urlencoded; use deno_core::url::quirks; use deno_core::url::Url; -use deno_core::JsRuntime; +use deno_core::Extension; use deno_core::ZeroCopyBuf; use serde::Deserialize; use serde::Serialize; use std::panic::catch_unwind; use std::path::PathBuf; +pub fn init() -> Extension { + Extension::with_ops( + include_js_files!( + prefix "deno:op_crates/url", + "00_url.js", + ), + vec![ + ("op_url_parse", op_sync(op_url_parse)), + ( + "op_url_parse_search_params", + op_sync(op_url_parse_search_params), + ), + ( + "op_url_stringify_search_params", + op_sync(op_url_stringify_search_params), + ), + ], + None, + ) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct UrlParseArgs { @@ -146,14 +169,6 @@ pub fn op_url_stringify_search_params( Ok(search) } -/// Load and execute the javascript code. -pub fn init(isolate: &mut JsRuntime) { - let files = vec![("deno:op_crates/url/00_url.js", include_str!("00_url.js"))]; - for (url, source_code) in files { - isolate.execute(url, source_code).unwrap(); - } -} - pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_url.d.ts") } diff --git a/op_crates/web/lib.rs b/op_crates/web/lib.rs index a609dc4cd3e8bf..7fd8221eb70675 100644 --- a/op_crates/web/lib.rs +++ b/op_crates/web/lib.rs @@ -1,47 +1,22 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use deno_core::JsRuntime; +use deno_core::include_js_files; +use deno_core::Extension; use std::path::PathBuf; /// Load and execute the javascript code. -pub fn init(isolate: &mut JsRuntime) { - let files = vec![ - ( - "deno:op_crates/web/00_infra.js", - include_str!("00_infra.js"), - ), - ( - "deno:op_crates/web/01_dom_exception.js", - include_str!("01_dom_exception.js"), - ), - ( - "deno:op_crates/web/01_mimesniff.js", - include_str!("01_mimesniff.js"), - ), - ( - "deno:op_crates/web/02_event.js", - include_str!("02_event.js"), - ), - ( - "deno:op_crates/web/03_abort_signal.js", - include_str!("03_abort_signal.js"), - ), - ( - "deno:op_crates/web/04_global_interfaces.js", - include_str!("04_global_interfaces.js"), - ), - ( - "deno:op_crates/web/08_text_encoding.js", - include_str!("08_text_encoding.js"), - ), - ( - "deno:op_crates/web/12_location.js", - include_str!("12_location.js"), - ), - ]; - for (url, source_code) in files { - isolate.execute(url, source_code).unwrap(); - } +pub fn init() -> Extension { + Extension::pure_js(include_js_files!( + prefix "deno:op_crates/web", + "00_infra.js", + "01_dom_exception.js", + "01_mimesniff.js", + "02_event.js", + "03_abort_signal.js", + "04_global_interfaces.js", + "08_text_encoding.js", + "12_location.js", + )) } pub fn get_declaration() -> PathBuf { diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 0dd18ca8ebe8b1..188221e83f810a 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -4,6 +4,11 @@ use deno_core::error::AnyError; use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::include_js_files; +use deno_core::op_async; +use deno_core::op_sync; +use deno_core::Extension; +use deno_core::OpFn; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; @@ -91,21 +96,23 @@ impl Resource for WebGpuQuerySet { } } -/// Execute this crates' JS source files. -pub fn init(isolate: &mut deno_core::JsRuntime) { - let files = vec![ - ( - "deno:op_crates/webgpu/01_webgpu.js", - include_str!("01_webgpu.js"), - ), - ( - "deno:op_crates/webgpu/02_idl_types.js", - include_str!("02_idl_types.js"), +pub fn init(unstable: bool) -> Extension { + Extension::with_ops( + include_js_files!( + prefix "deno:op_crates/webgpu", + "01_webgpu.js", + "02_idl_types.js", ), - ]; - for (url, source_code) in files { - isolate.execute(url, source_code).unwrap(); - } + declare_webgpu_ops(), + Some(Box::new(move |state| { + // TODO: check & possibly streamline this + // Unstable might be able to be OpMiddleware + // let unstable_checker = state.borrow::(); + // let unstable = unstable_checker.unstable; + state.put(Unstable(unstable)); + Ok(()) + })), + ) } pub fn get_declaration() -> PathBuf { @@ -539,3 +546,328 @@ pub fn op_webgpu_create_query_set( Ok(WebGpuResult::rid_err(rid, maybe_err)) } + +fn declare_webgpu_ops() -> Vec<(&'static str, Box)> { + vec![ + // Request device/adapter + ( + "op_webgpu_request_adapter", + op_async(op_webgpu_request_adapter), + ), + ( + "op_webgpu_request_device", + op_async(op_webgpu_request_device), + ), + // Query Set + ( + "op_webgpu_create_query_set", + op_sync(op_webgpu_create_query_set), + ), + // buffer + ( + "op_webgpu_create_buffer", + op_sync(buffer::op_webgpu_create_buffer), + ), + ( + "op_webgpu_buffer_get_mapped_range", + op_sync(buffer::op_webgpu_buffer_get_mapped_range), + ), + ( + "op_webgpu_buffer_unmap", + op_sync(buffer::op_webgpu_buffer_unmap), + ), + // buffer async + ( + "op_webgpu_buffer_get_map_async", + op_async(buffer::op_webgpu_buffer_get_map_async), + ), + // remaining sync ops + + // texture + ( + "op_webgpu_create_texture", + op_sync(texture::op_webgpu_create_texture), + ), + ( + "op_webgpu_create_texture_view", + op_sync(texture::op_webgpu_create_texture_view), + ), + // sampler + ( + "op_webgpu_create_sampler", + op_sync(sampler::op_webgpu_create_sampler), + ), + // binding + ( + "op_webgpu_create_bind_group_layout", + op_sync(binding::op_webgpu_create_bind_group_layout), + ), + ( + "op_webgpu_create_pipeline_layout", + op_sync(binding::op_webgpu_create_pipeline_layout), + ), + ( + "op_webgpu_create_bind_group", + op_sync(binding::op_webgpu_create_bind_group), + ), + // pipeline + ( + "op_webgpu_create_compute_pipeline", + op_sync(pipeline::op_webgpu_create_compute_pipeline), + ), + ( + "op_webgpu_compute_pipeline_get_bind_group_layout", + op_sync(pipeline::op_webgpu_compute_pipeline_get_bind_group_layout), + ), + ( + "op_webgpu_create_render_pipeline", + op_sync(pipeline::op_webgpu_create_render_pipeline), + ), + ( + "op_webgpu_render_pipeline_get_bind_group_layout", + op_sync(pipeline::op_webgpu_render_pipeline_get_bind_group_layout), + ), + // command_encoder + ( + "op_webgpu_create_command_encoder", + op_sync(command_encoder::op_webgpu_create_command_encoder), + ), + ( + "op_webgpu_command_encoder_begin_render_pass", + op_sync(command_encoder::op_webgpu_command_encoder_begin_render_pass), + ), + ( + "op_webgpu_command_encoder_begin_compute_pass", + op_sync(command_encoder::op_webgpu_command_encoder_begin_compute_pass), + ), + ( + "op_webgpu_command_encoder_copy_buffer_to_buffer", + op_sync(command_encoder::op_webgpu_command_encoder_copy_buffer_to_buffer), + ), + ( + "op_webgpu_command_encoder_copy_buffer_to_texture", + op_sync( + command_encoder::op_webgpu_command_encoder_copy_buffer_to_texture, + ), + ), + ( + "op_webgpu_command_encoder_copy_texture_to_buffer", + op_sync( + command_encoder::op_webgpu_command_encoder_copy_texture_to_buffer, + ), + ), + ( + "op_webgpu_command_encoder_copy_texture_to_texture", + op_sync( + command_encoder::op_webgpu_command_encoder_copy_texture_to_texture, + ), + ), + ( + "op_webgpu_command_encoder_push_debug_group", + op_sync(command_encoder::op_webgpu_command_encoder_push_debug_group), + ), + ( + "op_webgpu_command_encoder_pop_debug_group", + op_sync(command_encoder::op_webgpu_command_encoder_pop_debug_group), + ), + ( + "op_webgpu_command_encoder_insert_debug_marker", + op_sync(command_encoder::op_webgpu_command_encoder_insert_debug_marker), + ), + ( + "op_webgpu_command_encoder_write_timestamp", + op_sync(command_encoder::op_webgpu_command_encoder_write_timestamp), + ), + ( + "op_webgpu_command_encoder_resolve_query_set", + op_sync(command_encoder::op_webgpu_command_encoder_resolve_query_set), + ), + ( + "op_webgpu_command_encoder_finish", + op_sync(command_encoder::op_webgpu_command_encoder_finish), + ), + // render_pass + ( + "op_webgpu_render_pass_set_viewport", + op_sync(render_pass::op_webgpu_render_pass_set_viewport), + ), + ( + "op_webgpu_render_pass_set_scissor_rect", + op_sync(render_pass::op_webgpu_render_pass_set_scissor_rect), + ), + ( + "op_webgpu_render_pass_set_blend_color", + op_sync(render_pass::op_webgpu_render_pass_set_blend_color), + ), + ( + "op_webgpu_render_pass_set_stencil_reference", + op_sync(render_pass::op_webgpu_render_pass_set_stencil_reference), + ), + ( + "op_webgpu_render_pass_begin_pipeline_statistics_query", + op_sync( + render_pass::op_webgpu_render_pass_begin_pipeline_statistics_query, + ), + ), + ( + "op_webgpu_render_pass_end_pipeline_statistics_query", + op_sync(render_pass::op_webgpu_render_pass_end_pipeline_statistics_query), + ), + ( + "op_webgpu_render_pass_write_timestamp", + op_sync(render_pass::op_webgpu_render_pass_write_timestamp), + ), + ( + "op_webgpu_render_pass_execute_bundles", + op_sync(render_pass::op_webgpu_render_pass_execute_bundles), + ), + ( + "op_webgpu_render_pass_end_pass", + op_sync(render_pass::op_webgpu_render_pass_end_pass), + ), + ( + "op_webgpu_render_pass_set_bind_group", + op_sync(render_pass::op_webgpu_render_pass_set_bind_group), + ), + ( + "op_webgpu_render_pass_push_debug_group", + op_sync(render_pass::op_webgpu_render_pass_push_debug_group), + ), + ( + "op_webgpu_render_pass_pop_debug_group", + op_sync(render_pass::op_webgpu_render_pass_pop_debug_group), + ), + ( + "op_webgpu_render_pass_insert_debug_marker", + op_sync(render_pass::op_webgpu_render_pass_insert_debug_marker), + ), + ( + "op_webgpu_render_pass_set_pipeline", + op_sync(render_pass::op_webgpu_render_pass_set_pipeline), + ), + ( + "op_webgpu_render_pass_set_index_buffer", + op_sync(render_pass::op_webgpu_render_pass_set_index_buffer), + ), + ( + "op_webgpu_render_pass_set_vertex_buffer", + op_sync(render_pass::op_webgpu_render_pass_set_vertex_buffer), + ), + ( + "op_webgpu_render_pass_draw", + op_sync(render_pass::op_webgpu_render_pass_draw), + ), + ( + "op_webgpu_render_pass_draw_indexed", + op_sync(render_pass::op_webgpu_render_pass_draw_indexed), + ), + ( + "op_webgpu_render_pass_draw_indirect", + op_sync(render_pass::op_webgpu_render_pass_draw_indirect), + ), + ( + "op_webgpu_render_pass_draw_indexed_indirect", + op_sync(render_pass::op_webgpu_render_pass_draw_indexed_indirect), + ), + // compute_pass + ( + "op_webgpu_compute_pass_set_pipeline", + op_sync(compute_pass::op_webgpu_compute_pass_set_pipeline), + ), + ( + "op_webgpu_compute_pass_dispatch", + op_sync(compute_pass::op_webgpu_compute_pass_dispatch), + ), + ( + "op_webgpu_compute_pass_dispatch_indirect", + op_sync(compute_pass::op_webgpu_compute_pass_dispatch_indirect), + ), + ( + "op_webgpu_compute_pass_end_pass", + op_sync(compute_pass::op_webgpu_compute_pass_end_pass), + ), + ( + "op_webgpu_compute_pass_set_bind_group", + op_sync(compute_pass::op_webgpu_compute_pass_set_bind_group), + ), + ( + "op_webgpu_compute_pass_push_debug_group", + op_sync(compute_pass::op_webgpu_compute_pass_push_debug_group), + ), + ( + "op_webgpu_compute_pass_pop_debug_group", + op_sync(compute_pass::op_webgpu_compute_pass_pop_debug_group), + ), + ( + "op_webgpu_compute_pass_insert_debug_marker", + op_sync(compute_pass::op_webgpu_compute_pass_insert_debug_marker), + ), + // bundle + ( + "op_webgpu_create_render_bundle_encoder", + op_sync(bundle::op_webgpu_create_render_bundle_encoder), + ), + ( + "op_webgpu_render_bundle_encoder_finish", + op_sync(bundle::op_webgpu_render_bundle_encoder_finish), + ), + ( + "op_webgpu_render_bundle_encoder_set_bind_group", + op_sync(bundle::op_webgpu_render_bundle_encoder_set_bind_group), + ), + ( + "op_webgpu_render_bundle_encoder_push_debug_group", + op_sync(bundle::op_webgpu_render_bundle_encoder_push_debug_group), + ), + ( + "op_webgpu_render_bundle_encoder_pop_debug_group", + op_sync(bundle::op_webgpu_render_bundle_encoder_pop_debug_group), + ), + ( + "op_webgpu_render_bundle_encoder_insert_debug_marker", + op_sync(bundle::op_webgpu_render_bundle_encoder_insert_debug_marker), + ), + ( + "op_webgpu_render_bundle_encoder_set_pipeline", + op_sync(bundle::op_webgpu_render_bundle_encoder_set_pipeline), + ), + ( + "op_webgpu_render_bundle_encoder_set_index_buffer", + op_sync(bundle::op_webgpu_render_bundle_encoder_set_index_buffer), + ), + ( + "op_webgpu_render_bundle_encoder_set_vertex_buffer", + op_sync(bundle::op_webgpu_render_bundle_encoder_set_vertex_buffer), + ), + ( + "op_webgpu_render_bundle_encoder_draw", + op_sync(bundle::op_webgpu_render_bundle_encoder_draw), + ), + ( + "op_webgpu_render_bundle_encoder_draw_indexed", + op_sync(bundle::op_webgpu_render_bundle_encoder_draw_indexed), + ), + ( + "op_webgpu_render_bundle_encoder_draw_indirect", + op_sync(bundle::op_webgpu_render_bundle_encoder_draw_indirect), + ), + // queue + ( + "op_webgpu_queue_submit", + op_sync(queue::op_webgpu_queue_submit), + ), + ( + "op_webgpu_write_buffer", + op_sync(queue::op_webgpu_write_buffer), + ), + ( + "op_webgpu_write_texture", + op_sync(queue::op_webgpu_write_texture), + ), + // shader + ( + "op_webgpu_create_shader_module", + op_sync(shader::op_webgpu_create_shader_module), + ), + ] +} diff --git a/op_crates/webidl/lib.rs b/op_crates/webidl/lib.rs index 7e617c7a766121..a1a404dbdf3076 100644 --- a/op_crates/webidl/lib.rs +++ b/op_crates/webidl/lib.rs @@ -1,14 +1,11 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use deno_core::JsRuntime; +use deno_core::Extension; /// Load and execute the javascript code. -pub fn init(isolate: &mut JsRuntime) { - let files = vec![( +pub fn init() -> Extension { + Extension::pure_js(vec![( "deno:op_crates/webidl/00_webidl.js", include_str!("00_webidl.js"), - )]; - for (url, source_code) in files { - isolate.execute(url, source_code).unwrap(); - } + )]) } diff --git a/op_crates/websocket/lib.rs b/op_crates/websocket/lib.rs index daf61a9083e7b4..e9ba71fefb9752 100644 --- a/op_crates/websocket/lib.rs +++ b/op_crates/websocket/lib.rs @@ -8,11 +8,14 @@ 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_async; +use deno_core::op_sync; use deno_core::url; use deno_core::AsyncRefCell; use deno_core::CancelFuture; use deno_core::CancelHandle; -use deno_core::JsRuntime; +use deno_core::Extension; use deno_core::OpState; use deno_core::RcRef; use deno_core::Resource; @@ -332,14 +335,33 @@ pub async fn op_ws_next_event( Ok(res) } -/// Load and execute the javascript code. -pub fn init(isolate: &mut JsRuntime) { - isolate - .execute( - "deno:op_crates/websocket/01_websocket.js", - include_str!("01_websocket.js"), - ) - .unwrap(); +pub fn init( + user_agent: String, + ca_data: Option>, +) -> Extension { + Extension::with_ops( + include_js_files!( + prefix "deno:op_crates/websocket", + "01_websocket.js", + ), + vec![ + ( + "op_ws_check_permission", + op_sync(op_ws_check_permission::

), + ), + ("op_ws_create", op_async(op_ws_create::

)), + ("op_ws_send", op_async(op_ws_send)), + ("op_ws_close", op_async(op_ws_close)), + ("op_ws_next_event", op_async(op_ws_next_event)), + ], + Some(Box::new(move |state| { + state.put::(WsUserAgent(user_agent.clone())); + if let Some(ca_data) = ca_data.clone() { + state.put::(WsCaData(ca_data)); + } + Ok(()) + })), + ) } pub fn get_declaration() -> PathBuf { diff --git a/runtime/build.rs b/runtime/build.rs index efa9494939945c..591ebaab775a23 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -1,5 +1,6 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. +use deno_core::Extension; use deno_core::JsRuntime; use deno_core::RuntimeOptions; use std::env; @@ -13,17 +14,8 @@ fn create_snapshot( snapshot_path: &Path, files: Vec, ) { - // Initialization order matters. - deno_webidl::init(&mut js_runtime); - deno_console::init(&mut js_runtime); - deno_timers::init(&mut js_runtime); - deno_url::init(&mut js_runtime); - deno_web::init(&mut js_runtime); - deno_file::init(&mut js_runtime); - deno_fetch::init(&mut js_runtime); - deno_websocket::init(&mut js_runtime); - deno_crypto::init(&mut js_runtime); - deno_webgpu::init(&mut js_runtime); + js_runtime.init_extension_js().unwrap(); + // TODO(nayeemrmn): https://github.com/rust-lang/cargo/issues/3946 to get the // workspace root. let display_root = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap(); @@ -47,8 +39,25 @@ fn create_snapshot( } fn create_runtime_snapshot(snapshot_path: &Path, files: Vec) { + let extensions: Vec = vec![ + deno_webidl::init(), + deno_console::init(), + deno_url::init(), + deno_web::init(), + deno_file::init(Default::default(), Default::default()), + deno_fetch::init::("".to_owned(), None), + deno_websocket::init::( + "".to_owned(), + None, + ), + deno_crypto::init(None), + deno_webgpu::init(false), + deno_timers::init::(), + ]; + let js_runtime = JsRuntime::new(RuntimeOptions { will_snapshot: true, + extensions, ..Default::default() }); create_snapshot(js_runtime, snapshot_path, files); diff --git a/runtime/metrics.rs b/runtime/metrics.rs index a80ec5e21ef5f6..efc2cb4571454d 100644 --- a/runtime/metrics.rs +++ b/runtime/metrics.rs @@ -1,6 +1,51 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. +use crate::ops::UnstableChecker; +use deno_core::error::AnyError; +use deno_core::op_sync; use deno_core::serde::Serialize; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::Extension; +use deno_core::OpState; +use deno_core::ZeroCopyBuf; + +pub fn init() -> Extension { + Extension::new( + None, + Some(vec![("op_metrics", op_sync(op_metrics))]), + Some(Box::new(|state| { + state.put(RuntimeMetrics::default()); + Ok(()) + })), + Some(Box::new(metrics_op)), + ) +} + +#[derive(serde::Serialize)] +struct MetricsReturn { + combined: OpMetrics, + ops: Value, +} +#[allow(clippy::unnecessary_wraps)] +fn op_metrics( + state: &mut OpState, + _args: (), + _zero_copy: Option, +) -> Result { + let m = state.borrow::(); + let combined = m.combined_metrics(); + let unstable_checker = state.borrow::(); + let maybe_ops = if unstable_checker.unstable { + Some(&m.ops) + } else { + None + }; + Ok(MetricsReturn { + combined, + ops: json!(maybe_ops), + }) +} #[derive(Default, Debug)] pub struct RuntimeMetrics { pub ops: HashMap<&'static str, OpMetrics>, diff --git a/runtime/ops/crypto.rs b/runtime/ops/crypto.rs deleted file mode 100644 index 432cc0185c7034..00000000000000 --- a/runtime/ops/crypto.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use deno_crypto::op_crypto_get_random_values; -use deno_crypto::rand::rngs::StdRng; -use deno_crypto::rand::SeedableRng; - -pub fn init(rt: &mut deno_core::JsRuntime, maybe_seed: Option) { - if let Some(seed) = maybe_seed { - let rng = StdRng::seed_from_u64(seed); - let op_state = rt.op_state(); - let mut state = op_state.borrow_mut(); - state.put::(rng); - } - super::reg_sync( - rt, - "op_crypto_get_random_values", - op_crypto_get_random_values, - ); -} diff --git a/runtime/ops/fetch.rs b/runtime/ops/fetch.rs deleted file mode 100644 index 17656974a38334..00000000000000 --- a/runtime/ops/fetch.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use crate::permissions::Permissions; -use deno_fetch::reqwest; -use deno_fetch::HttpClientDefaults; - -pub fn init( - rt: &mut deno_core::JsRuntime, - user_agent: String, - ca_data: Option>, -) { - { - let op_state = rt.op_state(); - let mut state = op_state.borrow_mut(); - state.put::({ - deno_fetch::create_http_client(user_agent.clone(), ca_data.clone()) - .unwrap() - }); - state.put::(HttpClientDefaults { - user_agent, - ca_data, - }); - } - super::reg_sync(rt, "op_fetch", deno_fetch::op_fetch::); - super::reg_async(rt, "op_fetch_send", deno_fetch::op_fetch_send); - super::reg_async( - rt, - "op_fetch_request_write", - deno_fetch::op_fetch_request_write, - ); - super::reg_async( - rt, - "op_fetch_response_read", - deno_fetch::op_fetch_response_read, - ); - super::reg_sync( - rt, - "op_create_http_client", - deno_fetch::op_create_http_client::, - ); -} diff --git a/runtime/ops/file.rs b/runtime/ops/file.rs deleted file mode 100644 index 8f471ebbd18a48..00000000000000 --- a/runtime/ops/file.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use deno_core::url::Url; -use deno_file::op_file_create_object_url; -use deno_file::op_file_revoke_object_url; -use deno_file::BlobUrlStore; -use deno_file::Location; - -pub fn init( - rt: &mut deno_core::JsRuntime, - blob_url_store: BlobUrlStore, - maybe_location: Option, -) { - { - let op_state = rt.op_state(); - let mut op_state = op_state.borrow_mut(); - op_state.put(blob_url_store); - if let Some(location) = maybe_location { - op_state.put(Location(location)); - } - } - super::reg_sync(rt, "op_file_create_object_url", op_file_create_object_url); - super::reg_sync(rt, "op_file_revoke_object_url", op_file_revoke_object_url); -} diff --git a/runtime/ops/mod.rs b/runtime/ops/mod.rs index 825950d65e81f6..c46f82af63f899 100644 --- a/runtime/ops/mod.rs +++ b/runtime/ops/mod.rs @@ -1,8 +1,5 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -pub mod crypto; -pub mod fetch; -pub mod file; pub mod fs; pub mod fs_events; pub mod http; @@ -16,14 +13,10 @@ pub mod plugin; pub mod process; pub mod runtime; pub mod signal; -pub mod timers; pub mod tls; pub mod tty; -pub mod url; mod utils; pub mod web_worker; -pub mod webgpu; -pub mod websocket; pub mod worker_host; use crate::metrics::metrics_op; diff --git a/runtime/ops/runtime.rs b/runtime/ops/runtime.rs index a02bf4548e2032..7d84fadff6a08f 100644 --- a/runtime/ops/runtime.rs +++ b/runtime/ops/runtime.rs @@ -1,13 +1,8 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use crate::metrics::OpMetrics; -use crate::metrics::RuntimeMetrics; -use crate::ops::UnstableChecker; use crate::permissions::Permissions; use deno_core::error::AnyError; use deno_core::error::Context; -use deno_core::serde_json::json; -use deno_core::serde_json::Value; use deno_core::ModuleSpecifier; use deno_core::OpState; use deno_core::ZeroCopyBuf; @@ -19,7 +14,6 @@ pub fn init(rt: &mut deno_core::JsRuntime, main_module: ModuleSpecifier) { state.put::(main_module); } super::reg_sync(rt, "op_main_module", op_main_module); - super::reg_sync(rt, "op_metrics", op_metrics); } fn op_main_module( @@ -41,32 +35,6 @@ fn op_main_module( Ok(main) } -#[derive(serde::Serialize)] -struct MetricsReturn { - combined: OpMetrics, - ops: Value, -} - -#[allow(clippy::unnecessary_wraps)] -fn op_metrics( - state: &mut OpState, - _args: (), - _zero_copy: Option, -) -> Result { - let m = state.borrow::(); - let combined = m.combined_metrics(); - let unstable_checker = state.borrow::(); - let maybe_ops = if unstable_checker.unstable { - Some(&m.ops) - } else { - None - }; - Ok(MetricsReturn { - combined, - ops: json!(maybe_ops), - }) -} - pub fn ppid() -> i64 { #[cfg(windows)] { diff --git a/runtime/ops/timers.rs b/runtime/ops/timers.rs deleted file mode 100644 index 3401c36f1f3725..00000000000000 --- a/runtime/ops/timers.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use crate::permissions::Permissions; - -pub fn init(rt: &mut deno_core::JsRuntime) { - { - let op_state = rt.op_state(); - let mut state = op_state.borrow_mut(); - state.put(deno_timers::GlobalTimer::default()); - state.put(deno_timers::StartTime::now()); - } - super::reg_sync( - rt, - "op_global_timer_stop", - deno_timers::op_global_timer_stop, - ); - super::reg_sync( - rt, - "op_global_timer_start", - deno_timers::op_global_timer_start, - ); - super::reg_async(rt, "op_global_timer", deno_timers::op_global_timer); - super::reg_sync(rt, "op_now", deno_timers::op_now::); - super::reg_sync( - rt, - "op_sleep_sync", - deno_timers::op_sleep_sync::, - ); -} diff --git a/runtime/ops/url.rs b/runtime/ops/url.rs deleted file mode 100644 index 5168a7242a0445..00000000000000 --- a/runtime/ops/url.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use deno_url::op_url_parse; -use deno_url::op_url_parse_search_params; -use deno_url::op_url_stringify_search_params; - -pub fn init(rt: &mut deno_core::JsRuntime) { - super::reg_sync(rt, "op_url_parse", op_url_parse); - super::reg_sync(rt, "op_url_parse_search_params", op_url_parse_search_params); - super::reg_sync( - rt, - "op_url_stringify_search_params", - op_url_stringify_search_params, - ); -} diff --git a/runtime/ops/webgpu.rs b/runtime/ops/webgpu.rs deleted file mode 100644 index 55c6d18173972f..00000000000000 --- a/runtime/ops/webgpu.rs +++ /dev/null @@ -1,405 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use deno_webgpu::*; - -pub fn init(rt: &mut deno_core::JsRuntime) { - { - let op_state = rt.op_state(); - let mut state = op_state.borrow_mut(); - let unstable_checker = state.borrow::(); - let unstable = unstable_checker.unstable; - state.put(Unstable(unstable)); - } - - super::reg_async(rt, "op_webgpu_request_adapter", op_webgpu_request_adapter); - super::reg_async(rt, "op_webgpu_request_device", op_webgpu_request_device); - super::reg_sync(rt, "op_webgpu_create_query_set", op_webgpu_create_query_set); - - { - // buffer - super::reg_sync( - rt, - "op_webgpu_create_buffer", - buffer::op_webgpu_create_buffer, - ); - super::reg_async( - rt, - "op_webgpu_buffer_get_map_async", - buffer::op_webgpu_buffer_get_map_async, - ); - super::reg_sync( - rt, - "op_webgpu_buffer_get_mapped_range", - buffer::op_webgpu_buffer_get_mapped_range, - ); - super::reg_sync( - rt, - "op_webgpu_buffer_unmap", - buffer::op_webgpu_buffer_unmap, - ); - } - { - // texture - super::reg_sync( - rt, - "op_webgpu_create_texture", - texture::op_webgpu_create_texture, - ); - super::reg_sync( - rt, - "op_webgpu_create_texture_view", - texture::op_webgpu_create_texture_view, - ); - } - { - // sampler - super::reg_sync( - rt, - "op_webgpu_create_sampler", - sampler::op_webgpu_create_sampler, - ); - } - { - // binding - super::reg_sync( - rt, - "op_webgpu_create_bind_group_layout", - binding::op_webgpu_create_bind_group_layout, - ); - super::reg_sync( - rt, - "op_webgpu_create_pipeline_layout", - binding::op_webgpu_create_pipeline_layout, - ); - super::reg_sync( - rt, - "op_webgpu_create_bind_group", - binding::op_webgpu_create_bind_group, - ); - } - { - // pipeline - super::reg_sync( - rt, - "op_webgpu_create_compute_pipeline", - pipeline::op_webgpu_create_compute_pipeline, - ); - super::reg_sync( - rt, - "op_webgpu_compute_pipeline_get_bind_group_layout", - pipeline::op_webgpu_compute_pipeline_get_bind_group_layout, - ); - super::reg_sync( - rt, - "op_webgpu_create_render_pipeline", - pipeline::op_webgpu_create_render_pipeline, - ); - super::reg_sync( - rt, - "op_webgpu_render_pipeline_get_bind_group_layout", - pipeline::op_webgpu_render_pipeline_get_bind_group_layout, - ); - } - { - // command_encoder - super::reg_sync( - rt, - "op_webgpu_create_command_encoder", - command_encoder::op_webgpu_create_command_encoder, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_begin_render_pass", - command_encoder::op_webgpu_command_encoder_begin_render_pass, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_begin_compute_pass", - command_encoder::op_webgpu_command_encoder_begin_compute_pass, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_copy_buffer_to_buffer", - command_encoder::op_webgpu_command_encoder_copy_buffer_to_buffer, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_copy_buffer_to_texture", - command_encoder::op_webgpu_command_encoder_copy_buffer_to_texture, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_copy_texture_to_buffer", - command_encoder::op_webgpu_command_encoder_copy_texture_to_buffer, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_copy_texture_to_texture", - command_encoder::op_webgpu_command_encoder_copy_texture_to_texture, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_push_debug_group", - command_encoder::op_webgpu_command_encoder_push_debug_group, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_pop_debug_group", - command_encoder::op_webgpu_command_encoder_pop_debug_group, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_insert_debug_marker", - command_encoder::op_webgpu_command_encoder_insert_debug_marker, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_write_timestamp", - command_encoder::op_webgpu_command_encoder_write_timestamp, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_resolve_query_set", - command_encoder::op_webgpu_command_encoder_resolve_query_set, - ); - super::reg_sync( - rt, - "op_webgpu_command_encoder_finish", - command_encoder::op_webgpu_command_encoder_finish, - ); - } - { - // render_pass - super::reg_sync( - rt, - "op_webgpu_render_pass_set_viewport", - render_pass::op_webgpu_render_pass_set_viewport, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_set_scissor_rect", - render_pass::op_webgpu_render_pass_set_scissor_rect, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_set_blend_color", - render_pass::op_webgpu_render_pass_set_blend_color, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_set_stencil_reference", - render_pass::op_webgpu_render_pass_set_stencil_reference, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_begin_pipeline_statistics_query", - render_pass::op_webgpu_render_pass_begin_pipeline_statistics_query, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_end_pipeline_statistics_query", - render_pass::op_webgpu_render_pass_end_pipeline_statistics_query, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_write_timestamp", - render_pass::op_webgpu_render_pass_write_timestamp, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_execute_bundles", - render_pass::op_webgpu_render_pass_execute_bundles, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_end_pass", - render_pass::op_webgpu_render_pass_end_pass, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_set_bind_group", - render_pass::op_webgpu_render_pass_set_bind_group, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_push_debug_group", - render_pass::op_webgpu_render_pass_push_debug_group, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_pop_debug_group", - render_pass::op_webgpu_render_pass_pop_debug_group, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_insert_debug_marker", - render_pass::op_webgpu_render_pass_insert_debug_marker, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_set_pipeline", - render_pass::op_webgpu_render_pass_set_pipeline, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_set_index_buffer", - render_pass::op_webgpu_render_pass_set_index_buffer, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_set_vertex_buffer", - render_pass::op_webgpu_render_pass_set_vertex_buffer, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_draw", - render_pass::op_webgpu_render_pass_draw, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_draw_indexed", - render_pass::op_webgpu_render_pass_draw_indexed, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_draw_indirect", - render_pass::op_webgpu_render_pass_draw_indirect, - ); - super::reg_sync( - rt, - "op_webgpu_render_pass_draw_indexed_indirect", - render_pass::op_webgpu_render_pass_draw_indexed_indirect, - ); - } - { - // compute_pass - super::reg_sync( - rt, - "op_webgpu_compute_pass_set_pipeline", - compute_pass::op_webgpu_compute_pass_set_pipeline, - ); - super::reg_sync( - rt, - "op_webgpu_compute_pass_dispatch", - compute_pass::op_webgpu_compute_pass_dispatch, - ); - super::reg_sync( - rt, - "op_webgpu_compute_pass_dispatch_indirect", - compute_pass::op_webgpu_compute_pass_dispatch_indirect, - ); - super::reg_sync( - rt, - "op_webgpu_compute_pass_end_pass", - compute_pass::op_webgpu_compute_pass_end_pass, - ); - super::reg_sync( - rt, - "op_webgpu_compute_pass_set_bind_group", - compute_pass::op_webgpu_compute_pass_set_bind_group, - ); - super::reg_sync( - rt, - "op_webgpu_compute_pass_push_debug_group", - compute_pass::op_webgpu_compute_pass_push_debug_group, - ); - super::reg_sync( - rt, - "op_webgpu_compute_pass_pop_debug_group", - compute_pass::op_webgpu_compute_pass_pop_debug_group, - ); - super::reg_sync( - rt, - "op_webgpu_compute_pass_insert_debug_marker", - compute_pass::op_webgpu_compute_pass_insert_debug_marker, - ); - } - { - // bundle - super::reg_sync( - rt, - "op_webgpu_create_render_bundle_encoder", - bundle::op_webgpu_create_render_bundle_encoder, - ); - super::reg_sync( - rt, - "op_webgpu_render_bundle_encoder_finish", - bundle::op_webgpu_render_bundle_encoder_finish, - ); - super::reg_sync( - rt, - "op_webgpu_render_bundle_encoder_set_bind_group", - bundle::op_webgpu_render_bundle_encoder_set_bind_group, - ); - super::reg_sync( - rt, - "op_webgpu_render_bundle_encoder_push_debug_group", - bundle::op_webgpu_render_bundle_encoder_push_debug_group, - ); - super::reg_sync( - rt, - "op_webgpu_render_bundle_encoder_pop_debug_group", - bundle::op_webgpu_render_bundle_encoder_pop_debug_group, - ); - super::reg_sync( - rt, - "op_webgpu_render_bundle_encoder_insert_debug_marker", - bundle::op_webgpu_render_bundle_encoder_insert_debug_marker, - ); - super::reg_sync( - rt, - "op_webgpu_render_bundle_encoder_set_pipeline", - bundle::op_webgpu_render_bundle_encoder_set_pipeline, - ); - super::reg_sync( - rt, - "op_webgpu_render_bundle_encoder_set_index_buffer", - bundle::op_webgpu_render_bundle_encoder_set_index_buffer, - ); - super::reg_sync( - rt, - "op_webgpu_render_bundle_encoder_set_vertex_buffer", - bundle::op_webgpu_render_bundle_encoder_set_vertex_buffer, - ); - super::reg_sync( - rt, - "op_webgpu_render_bundle_encoder_draw", - bundle::op_webgpu_render_bundle_encoder_draw, - ); - super::reg_sync( - rt, - "op_webgpu_render_bundle_encoder_draw_indexed", - bundle::op_webgpu_render_bundle_encoder_draw_indexed, - ); - super::reg_sync( - rt, - "op_webgpu_render_bundle_encoder_draw_indirect", - bundle::op_webgpu_render_bundle_encoder_draw_indirect, - ); - } - { - // queue - super::reg_sync( - rt, - "op_webgpu_queue_submit", - queue::op_webgpu_queue_submit, - ); - super::reg_sync( - rt, - "op_webgpu_write_buffer", - queue::op_webgpu_write_buffer, - ); - super::reg_sync( - rt, - "op_webgpu_write_texture", - queue::op_webgpu_write_texture, - ); - } - { - // shader - super::reg_sync( - rt, - "op_webgpu_create_shader_module", - shader::op_webgpu_create_shader_module, - ); - } -} diff --git a/runtime/ops/websocket.rs b/runtime/ops/websocket.rs deleted file mode 100644 index 1c44f8b80bd0e1..00000000000000 --- a/runtime/ops/websocket.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use crate::permissions::Permissions; -use deno_websocket::op_ws_check_permission; -use deno_websocket::op_ws_close; -use deno_websocket::op_ws_create; -use deno_websocket::op_ws_next_event; -use deno_websocket::op_ws_send; -use deno_websocket::WsCaData; -use deno_websocket::WsUserAgent; - -pub fn init( - rt: &mut deno_core::JsRuntime, - user_agent: String, - ca_data: Option>, -) { - { - let op_state = rt.op_state(); - let mut state = op_state.borrow_mut(); - state.put::(WsUserAgent(user_agent)); - if let Some(ca_data) = ca_data { - state.put::(WsCaData(ca_data)); - } - } - super::reg_sync( - rt, - "op_ws_check_permission", - op_ws_check_permission::, - ); - super::reg_async(rt, "op_ws_create", op_ws_create::); - super::reg_async(rt, "op_ws_send", op_ws_send); - super::reg_async(rt, "op_ws_close", op_ws_close); - super::reg_async(rt, "op_ws_next_event", op_ws_next_event); -} diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index f6f88f59b382e8..5feb0212cecede 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -3,7 +3,7 @@ use crate::colors; use crate::inspector::DenoInspector; use crate::inspector::InspectorServer; use crate::js; -use crate::metrics::RuntimeMetrics; +use crate::metrics; use crate::ops; use crate::permissions::Permissions; use crate::tokio_util::create_basic_runtime; @@ -18,6 +18,7 @@ use deno_core::serde_json; use deno_core::serde_json::json; use deno_core::url::Url; use deno_core::v8; +use deno_core::Extension; use deno_core::GetErrorClassFn; use deno_core::JsErrorCreateFn; use deno_core::JsRuntime; @@ -176,11 +177,37 @@ impl WebWorker { worker_id: u32, options: &WebWorkerOptions, ) -> Self { + let extensions: Vec = vec![ + // Web APIs + deno_webidl::init(), + deno_console::init(), + deno_url::init(), + deno_web::init(), + deno_file::init( + options.blob_url_store.clone(), + Some(main_module.clone()), + ), + deno_fetch::init::( + options.user_agent.clone(), + options.ca_data.clone(), + ), + deno_websocket::init::( + options.user_agent.clone(), + options.ca_data.clone(), + ), + deno_crypto::init(options.seed), + deno_webgpu::init(options.unstable), + deno_timers::init::(), + // Metrics + metrics::init(), + ]; + let mut js_runtime = JsRuntime::new(RuntimeOptions { module_loader: Some(options.module_loader.clone()), startup_snapshot: Some(js::deno_isolate_init()), js_error_create_fn: options.js_error_create_fn.clone(), get_error_class_fn: options.get_error_class_fn, + extensions, ..Default::default() }); @@ -220,21 +247,16 @@ impl WebWorker { { let op_state = js_runtime.op_state(); let mut op_state = op_state.borrow_mut(); - op_state.put(RuntimeMetrics::default()); op_state.put::(permissions); op_state.put(ops::UnstableChecker { unstable: options.unstable, }); } + js_runtime.init_extension_ops().unwrap(); + ops::web_worker::init(js_runtime, sender.clone(), handle); - ops::runtime::init(js_runtime, main_module.clone()); - ops::fetch::init( - js_runtime, - options.user_agent.clone(), - options.ca_data.clone(), - ); - ops::timers::init(js_runtime); + ops::runtime::init(js_runtime, main_module); ops::worker_host::init( js_runtime, Some(sender), @@ -242,20 +264,7 @@ impl WebWorker { ); ops::reg_sync(js_runtime, "op_close", deno_core::op_close); ops::reg_sync(js_runtime, "op_resources", deno_core::op_resources); - ops::url::init(js_runtime); - ops::file::init( - js_runtime, - options.blob_url_store.clone(), - Some(main_module), - ); ops::io::init(js_runtime); - ops::webgpu::init(js_runtime); - ops::websocket::init( - js_runtime, - options.user_agent.clone(), - options.ca_data.clone(), - ); - ops::crypto::init(js_runtime, options.seed); if options.use_deno_namespace { ops::fs_events::init(js_runtime); diff --git a/runtime/worker.rs b/runtime/worker.rs index 6dbf8e7ec85bc3..fddaf1f01d8a44 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -4,7 +4,7 @@ use crate::inspector::DenoInspector; use crate::inspector::InspectorServer; use crate::inspector::InspectorSession; use crate::js; -use crate::metrics::RuntimeMetrics; +use crate::metrics; use crate::ops; use crate::permissions::Permissions; use deno_core::error::AnyError; @@ -15,6 +15,7 @@ use deno_core::futures::stream::StreamExt; use deno_core::serde_json; use deno_core::serde_json::json; use deno_core::url::Url; +use deno_core::Extension; use deno_core::GetErrorClassFn; use deno_core::JsErrorCreateFn; use deno_core::JsRuntime; @@ -77,11 +78,35 @@ impl MainWorker { permissions: Permissions, options: &WorkerOptions, ) -> Self { + // Internal modules + let extensions: Vec = vec![ + // Web APIs + deno_webidl::init(), + deno_console::init(), + deno_url::init(), + deno_web::init(), + deno_file::init(options.blob_url_store.clone(), options.location.clone()), + deno_fetch::init::( + options.user_agent.clone(), + options.ca_data.clone(), + ), + deno_websocket::init::( + options.user_agent.clone(), + options.ca_data.clone(), + ), + deno_crypto::init(options.seed), + deno_webgpu::init(options.unstable), + deno_timers::init::(), + // Metrics + metrics::init(), + ]; + let mut js_runtime = JsRuntime::new(RuntimeOptions { module_loader: Some(options.module_loader.clone()), startup_snapshot: Some(js::deno_isolate_init()), js_error_create_fn: options.js_error_create_fn.clone(), get_error_class_fn: options.get_error_class_fn, + extensions, ..Default::default() }); @@ -109,34 +134,22 @@ impl MainWorker { { let op_state = js_runtime.op_state(); let mut op_state = op_state.borrow_mut(); - op_state.put(RuntimeMetrics::default()); op_state.put::(permissions); op_state.put(ops::UnstableChecker { unstable: options.unstable, }); } + js_runtime.init_extension_ops().unwrap(); + ops::runtime::init(js_runtime, main_module); - ops::fetch::init( - js_runtime, - options.user_agent.clone(), - options.ca_data.clone(), - ); - ops::timers::init(js_runtime); ops::worker_host::init( js_runtime, None, options.create_web_worker_cb.clone(), ); - ops::crypto::init(js_runtime, options.seed); ops::reg_sync(js_runtime, "op_close", deno_core::op_close); ops::reg_sync(js_runtime, "op_resources", deno_core::op_resources); - ops::url::init(js_runtime); - ops::file::init( - js_runtime, - options.blob_url_store.clone(), - options.location.clone(), - ); ops::fs_events::init(js_runtime); ops::fs::init(js_runtime); ops::http::init(js_runtime); @@ -149,12 +162,6 @@ impl MainWorker { ops::signal::init(js_runtime); ops::tls::init(js_runtime); ops::tty::init(js_runtime); - ops::webgpu::init(js_runtime); - ops::websocket::init( - js_runtime, - options.user_agent.clone(), - options.ca_data.clone(), - ); } { let op_state = js_runtime.op_state();