From bd481bf095f920a419ea55543f911e087f98f36f Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Wed, 16 Mar 2022 00:33:46 +0100 Subject: [PATCH] feat(ops): optional OpState (#13954) --- .github/workflows/ci.yml | 6 ++--- bench_util/benches/op_baseline.rs | 4 ++-- cli/build.rs | 4 ++-- cli/ops/errors.rs | 10 ++------ core/examples/hello_world.rs | 5 +--- core/ops_builtin.rs | 8 ++----- core/runtime.rs | 14 +++++------ ext/crypto/decrypt.rs | 5 ---- ext/crypto/encrypt.rs | 5 ---- ext/crypto/export_key.rs | 2 -- ext/crypto/generate_key.rs | 5 ---- ext/crypto/import_key.rs | 2 -- ext/crypto/lib.rs | 8 ------- ext/ffi/lib.rs | 6 +---- ext/http/lib.rs | 5 +--- ext/url/lib.rs | 4 ---- ext/url/urlpattern.rs | 2 -- ext/web/lib.rs | 23 ++++-------------- ops/lib.rs | 39 +++++++++++++++++++++++++++---- runtime/ops/signal.rs | 6 ++--- 20 files changed, 63 insertions(+), 100 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a85659fe1..fed3e09204 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -244,7 +244,7 @@ jobs: ~/.cargo/registry/index ~/.cargo/registry/cache ~/.cargo/git/db - key: 8-cargo-home-${{ matrix.os }}-${{ hashFiles('Cargo.lock') }} + key: 9-cargo-home-${{ matrix.os }}-${{ hashFiles('Cargo.lock') }} # In main branch, always creates fresh cache - name: Cache build output (main) @@ -260,7 +260,7 @@ jobs: !./target/*/*.zip !./target/*/*.tar.gz key: | - 8-cargo-target-${{ matrix.os }}-${{ matrix.profile }}-${{ github.sha }} + 9-cargo-target-${{ matrix.os }}-${{ matrix.profile }}-${{ github.sha }} # Restore cache from the latest 'main' branch build. - name: Cache build output (PR) @@ -276,7 +276,7 @@ jobs: !./target/*/*.tar.gz key: never_saved restore-keys: | - 8-cargo-target-${{ matrix.os }}-${{ matrix.profile }}- + 9-cargo-target-${{ matrix.os }}-${{ matrix.profile }}- # Don't save cache after building PRs or branches other than 'main'. - name: Skip save cache (PR) diff --git a/bench_util/benches/op_baseline.rs b/bench_util/benches/op_baseline.rs index 07c4905a9d..052ac2cb23 100644 --- a/bench_util/benches/op_baseline.rs +++ b/bench_util/benches/op_baseline.rs @@ -22,12 +22,12 @@ fn setup() -> Vec { } #[op] -fn op_nop(_: &mut OpState) -> Result<(), AnyError> { +fn op_nop() -> Result<(), AnyError> { Ok(()) } #[op] -fn op_pi_json(_: &mut OpState) -> Result { +fn op_pi_json() -> Result { Ok(314159) } diff --git a/cli/build.rs b/cli/build.rs index d118dd5b9f..98dea9b461 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -202,12 +202,12 @@ fn create_compiler_snapshot( } #[op] - fn op_cwd(_state: &mut OpState, _args: Value) -> Result { + fn op_cwd(_args: Value) -> Result { Ok(json!("cache:///")) } #[op] - fn op_exists(_state: &mut OpState, _args: Value) -> Result { + fn op_exists(_args: Value) -> Result { Ok(json!(false)) } diff --git a/cli/ops/errors.rs b/cli/ops/errors.rs index 5be6e07374..a219b462de 100644 --- a/cli/ops/errors.rs +++ b/cli/ops/errors.rs @@ -67,18 +67,12 @@ fn op_apply_source_map( } #[op] -fn op_format_diagnostic( - _state: &mut OpState, - args: Value, -) -> Result { +fn op_format_diagnostic(args: Value) -> Result { let diagnostic: Diagnostics = serde_json::from_value(args)?; Ok(json!(diagnostic.to_string())) } #[op] -fn op_format_file_name( - _state: &mut OpState, - file_name: String, -) -> Result { +fn op_format_file_name(file_name: String) -> Result { Ok(format_file_name(&file_name)) } diff --git a/core/examples/hello_world.rs b/core/examples/hello_world.rs index d5d7af94d6..e551efa558 100644 --- a/core/examples/hello_world.rs +++ b/core/examples/hello_world.rs @@ -14,10 +14,7 @@ use deno_core::RuntimeOptions; use deno_core::*; #[op] -fn op_sum( - _state: &mut OpState, - nums: Vec, -) -> Result { +fn op_sum(nums: Vec) -> Result { // Sum inputs let sum = nums.iter().fold(0.0, |a, v| a + v); // return as a Result diff --git a/core/ops_builtin.rs b/core/ops_builtin.rs index 92f77f9543..d8729688ea 100644 --- a/core/ops_builtin.rs +++ b/core/ops_builtin.rs @@ -54,7 +54,7 @@ pub fn op_resources( } #[op] -pub fn op_void_sync(_state: &mut OpState) -> Result<(), Error> { +pub fn op_void_sync() -> Result<(), Error> { Ok(()) } @@ -101,11 +101,7 @@ pub fn op_metrics( /// Builtin utility to print to stdout/stderr #[op] -pub fn op_print( - _state: &mut OpState, - msg: String, - is_err: bool, -) -> Result<(), Error> { +pub fn op_print(msg: String, is_err: bool) -> Result<(), Error> { if is_err { stderr().write_all(msg.as_bytes())?; stderr().flush().unwrap(); diff --git a/core/runtime.rs b/core/runtime.rs index 17840a2d05..8ec3dfb08d 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -2088,7 +2088,7 @@ pub mod tests { #[test] fn test_error_builder() { #[op] - fn op_err(_: &mut OpState) -> Result<(), Error> { + fn op_err() -> Result<(), Error> { Err(custom_error("DOMExceptionOperationError", "abc")) } @@ -2533,9 +2533,7 @@ assertEquals(1, notify_return_value); #[tokio::test] async fn test_set_macrotask_callback_set_next_tick_callback() { #[op] - async fn op_async_sleep( - _op_state: Rc>, - ) -> Result<(), Error> { + async fn op_async_sleep() -> Result<(), Error> { // Future must be Poll::Pending on first call tokio::time::sleep(std::time::Duration::from_millis(1)).await; Ok(()) @@ -2610,13 +2608,13 @@ assertEquals(1, notify_return_value); static NEXT_TICK: AtomicUsize = AtomicUsize::new(0); #[op] - fn op_macrotask(_: &mut OpState) -> Result<(), AnyError> { + fn op_macrotask() -> Result<(), AnyError> { MACROTASK.fetch_add(1, Ordering::Relaxed); Ok(()) } #[op] - fn op_next_tick(_: &mut OpState) -> Result<(), AnyError> { + fn op_next_tick() -> Result<(), AnyError> { NEXT_TICK.fetch_add(1, Ordering::Relaxed); Ok(()) } @@ -2747,13 +2745,13 @@ assertEquals(1, notify_return_value); static UNCAUGHT_EXCEPTION: AtomicUsize = AtomicUsize::new(0); #[op] - fn op_promise_reject(_: &mut OpState) -> Result<(), AnyError> { + fn op_promise_reject() -> Result<(), AnyError> { PROMISE_REJECT.fetch_add(1, Ordering::Relaxed); Ok(()) } #[op] - fn op_uncaught_exception(_: &mut OpState) -> Result<(), AnyError> { + fn op_uncaught_exception() -> Result<(), AnyError> { UNCAUGHT_EXCEPTION.fetch_add(1, Ordering::Relaxed); Ok(()) } diff --git a/ext/crypto/decrypt.rs b/ext/crypto/decrypt.rs index a8666de89e..b3989a7f6c 100644 --- a/ext/crypto/decrypt.rs +++ b/ext/crypto/decrypt.rs @@ -1,6 +1,3 @@ -use std::cell::RefCell; -use std::rc::Rc; - use crate::shared::*; use aes::BlockEncrypt; use aes::NewBlockCipher; @@ -25,7 +22,6 @@ use deno_core::error::custom_error; use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::op; -use deno_core::OpState; use deno_core::ZeroCopyBuf; use rsa::pkcs1::FromRsaPrivateKey; use rsa::PaddingScheme; @@ -79,7 +75,6 @@ pub enum DecryptAlgorithm { #[op] pub async fn op_crypto_decrypt( - _state: Rc>, opts: DecryptOptions, data: ZeroCopyBuf, ) -> Result { diff --git a/ext/crypto/encrypt.rs b/ext/crypto/encrypt.rs index b93ca0952b..9d0dd3565e 100644 --- a/ext/crypto/encrypt.rs +++ b/ext/crypto/encrypt.rs @@ -1,6 +1,3 @@ -use std::cell::RefCell; -use std::rc::Rc; - use crate::shared::*; use aes::cipher::NewCipher; @@ -27,7 +24,6 @@ use ctr::flavors::Ctr64BE; use ctr::flavors::CtrFlavor; use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::OpState; use deno_core::ZeroCopyBuf; use rand::rngs::OsRng; use rsa::pkcs1::FromRsaPublicKey; @@ -83,7 +79,6 @@ pub enum EncryptAlgorithm { #[op] pub async fn op_crypto_encrypt( - _state: Rc>, opts: EncryptOptions, data: ZeroCopyBuf, ) -> Result { diff --git a/ext/crypto/export_key.rs b/ext/crypto/export_key.rs index 8131f859d1..64d2d1079c 100644 --- a/ext/crypto/export_key.rs +++ b/ext/crypto/export_key.rs @@ -1,7 +1,6 @@ use deno_core::error::custom_error; use deno_core::error::AnyError; use deno_core::op; -use deno_core::OpState; use deno_core::ZeroCopyBuf; use rsa::pkcs1::UIntBytes; use serde::Deserialize; @@ -87,7 +86,6 @@ pub enum ExportKeyResult { #[op] pub fn op_crypto_export_key( - _state: &mut OpState, opts: ExportKeyOptions, key_data: RawKeyData, ) -> Result { diff --git a/ext/crypto/generate_key.rs b/ext/crypto/generate_key.rs index 22f0913ec4..99f9fac62a 100644 --- a/ext/crypto/generate_key.rs +++ b/ext/crypto/generate_key.rs @@ -1,10 +1,6 @@ -use std::cell::RefCell; -use std::rc::Rc; - use crate::shared::*; use deno_core::error::AnyError; use deno_core::op; -use deno_core::OpState; use deno_core::ZeroCopyBuf; use elliptic_curve::rand_core::OsRng; use num_traits::FromPrimitive; @@ -44,7 +40,6 @@ pub enum GenerateKeyOptions { #[op] pub async fn op_crypto_generate_key( - _state: Rc>, opts: GenerateKeyOptions, ) -> Result { let fun = || match opts { diff --git a/ext/crypto/import_key.rs b/ext/crypto/import_key.rs index 3d29c9947c..9b8a9aa5c1 100644 --- a/ext/crypto/import_key.rs +++ b/ext/crypto/import_key.rs @@ -1,6 +1,5 @@ use deno_core::error::AnyError; use deno_core::op; -use deno_core::OpState; use deno_core::ZeroCopyBuf; use elliptic_curve::pkcs8::der::Decodable as Pkcs8Decodable; use elliptic_curve::pkcs8::PrivateKeyInfo; @@ -90,7 +89,6 @@ pub enum ImportKeyResult { #[op] pub fn op_crypto_import_key( - _state: &mut OpState, opts: ImportKeyOptions, key_data: KeyData, ) -> Result { diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs index e45e3d272f..a2dc8e6260 100644 --- a/ext/crypto/lib.rs +++ b/ext/crypto/lib.rs @@ -17,9 +17,7 @@ use deno_core::ZeroCopyBuf; use serde::Deserialize; use shared::operation_error; -use std::cell::RefCell; use std::num::NonZeroU32; -use std::rc::Rc; use p256::elliptic_curve::sec1::FromEncodedPoint; use p256::pkcs8::FromPrivateKey; @@ -169,7 +167,6 @@ pub struct SignArg { #[op] pub async fn op_crypto_sign_key( - _state: Rc>, args: SignArg, zero_copy: ZeroCopyBuf, ) -> Result { @@ -324,7 +321,6 @@ pub struct VerifyArg { #[op] pub async fn op_crypto_verify_key( - _state: Rc>, args: VerifyArg, zero_copy: ZeroCopyBuf, ) -> Result { @@ -485,7 +481,6 @@ pub struct DeriveKeyArg { #[op] pub async fn op_crypto_derive_bits( - _state: Rc>, args: DeriveKeyArg, zero_copy: Option, ) -> Result { @@ -807,7 +802,6 @@ pub fn op_crypto_random_uuid(state: &mut OpState) -> Result { #[op] pub async fn op_crypto_subtle_digest( - _state: Rc>, algorithm: CryptoHash, data: ZeroCopyBuf, ) -> Result { @@ -831,7 +825,6 @@ pub struct WrapUnwrapKeyArg { #[op] pub fn op_crypto_wrap_key( - _state: &mut OpState, args: WrapUnwrapKeyArg, data: ZeroCopyBuf, ) -> Result { @@ -861,7 +854,6 @@ pub fn op_crypto_wrap_key( #[op] pub fn op_crypto_unwrap_key( - _state: &mut OpState, args: WrapUnwrapKeyArg, data: ZeroCopyBuf, ) -> Result { diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs index 07297071a5..6ddeee51c8 100644 --- a/ext/ffi/lib.rs +++ b/ext/ffi/lib.rs @@ -648,17 +648,13 @@ fn ffi_call(args: FfiCallArgs, symbol: &Symbol) -> Result { } #[op] -fn op_ffi_call_ptr( - _state: &mut deno_core::OpState, - args: FfiCallPtrArgs, -) -> Result { +fn op_ffi_call_ptr(args: FfiCallPtrArgs) -> Result { let symbol = args.get_symbol(); ffi_call(args.into(), &symbol) } #[op] async fn op_ffi_call_ptr_nonblocking( - _state: Rc>, args: FfiCallPtrArgs, ) -> Result { let symbol = args.get_symbol(); diff --git a/ext/http/lib.rs b/ext/http/lib.rs index f57132555a..535f52a6cc 100644 --- a/ext/http/lib.rs +++ b/ext/http/lib.rs @@ -797,10 +797,7 @@ async fn op_http_read( } #[op] -fn op_http_websocket_accept_header( - _: &mut OpState, - key: String, -) -> Result { +fn op_http_websocket_accept_header(key: String) -> Result { let digest = ring::digest::digest( &ring::digest::SHA1_FOR_LEGACY_USE_ONLY, format!("{}258EAFA5-E914-47DA-95CA-C5AB0DC85B11", key).as_bytes(), diff --git a/ext/url/lib.rs b/ext/url/lib.rs index 4187b76648..0fa389fb0a 100644 --- a/ext/url/lib.rs +++ b/ext/url/lib.rs @@ -58,7 +58,6 @@ type UrlParts = String; /// optional part to "set" after parsing. Return `UrlParts`. #[op] pub fn op_url_parse( - _state: &mut deno_core::OpState, href: String, base_href: Option, ) -> Result { @@ -92,7 +91,6 @@ pub enum UrlSetter { #[op] pub fn op_url_reparse( - _state: &mut deno_core::OpState, href: String, setter_opts: (UrlSetter, String), ) -> Result { @@ -162,7 +160,6 @@ fn url_result( #[op] pub fn op_url_parse_search_params( - _state: &mut deno_core::OpState, args: Option, zero_copy: Option, ) -> Result, AnyError> { @@ -182,7 +179,6 @@ pub fn op_url_parse_search_params( #[op] pub fn op_url_stringify_search_params( - _state: &mut deno_core::OpState, args: Vec<(String, String)>, ) -> Result { let search = form_urlencoded::Serializer::new(String::new()) diff --git a/ext/url/urlpattern.rs b/ext/url/urlpattern.rs index 4e6b4e4a07..99fd216644 100644 --- a/ext/url/urlpattern.rs +++ b/ext/url/urlpattern.rs @@ -9,7 +9,6 @@ use urlpattern::quirks::UrlPattern; #[op] pub fn op_urlpattern_parse( - _state: &mut deno_core::OpState, input: StringOrInit, base_url: Option, ) -> Result { @@ -27,7 +26,6 @@ pub fn op_urlpattern_parse( #[op] pub fn op_urlpattern_process_match_input( - _state: &mut deno_core::OpState, input: StringOrInit, base_url: Option, ) -> Result, AnyError> { diff --git a/ext/web/lib.rs b/ext/web/lib.rs index 75e619dfe0..d199b7bfe3 100644 --- a/ext/web/lib.rs +++ b/ext/web/lib.rs @@ -121,20 +121,14 @@ pub fn init( } #[op] -fn op_base64_decode( - _: &mut OpState, - input: String, -) -> Result { +fn op_base64_decode(input: String) -> Result { let mut input = input.into_bytes(); input.retain(|c| !c.is_ascii_whitespace()); Ok(b64_decode(&input)?.into()) } #[op] -fn op_base64_atob( - _: &mut OpState, - s: ByteString, -) -> Result { +fn op_base64_atob(s: ByteString) -> Result { let mut s = s.0; s.retain(|c| !c.is_ascii_whitespace()); @@ -184,15 +178,12 @@ fn b64_decode(input: &[u8]) -> Result, AnyError> { } #[op] -fn op_base64_encode( - _: &mut OpState, - s: ZeroCopyBuf, -) -> Result { +fn op_base64_encode(s: ZeroCopyBuf) -> Result { Ok(b64_encode(&s)) } #[op] -fn op_base64_btoa(_: &mut OpState, s: ByteString) -> Result { +fn op_base64_btoa(s: ByteString) -> Result { Ok(b64_encode(&s)) } @@ -211,10 +202,7 @@ struct DecoderOptions { } #[op] -fn op_encoding_normalize_label( - _state: &mut OpState, - label: String, -) -> Result { +fn op_encoding_normalize_label(label: String) -> Result { let encoding = Encoding::for_label_no_replacement(label.as_bytes()) .ok_or_else(|| { range_error(format!( @@ -331,7 +319,6 @@ struct EncodeIntoResult { #[op] fn op_encoding_encode_into( - _state: &mut OpState, input: String, mut buffer: ZeroCopyBuf, ) -> Result { diff --git a/ops/lib.rs b/ops/lib.rs index 718922c59b..608219a1c6 100644 --- a/ops/lib.rs +++ b/ops/lib.rs @@ -5,6 +5,7 @@ use proc_macro2::TokenStream as TokenStream2; use proc_macro_crate::crate_name; use proc_macro_crate::FoundCrate; use quote::quote; +use quote::ToTokens; use syn::Ident; // Identifer to the `deno_core` crate. @@ -94,7 +95,15 @@ pub fn op(_attr: TokenStream, item: TokenStream) -> TokenStream { /// Generate the body of a v8 func for an async op fn codegen_v8_async(core: &TokenStream2, f: &syn::ItemFn) -> TokenStream2 { - let (arg_decls, args_tail) = codegen_args(core, f, 1, 2); + let arg0 = f.sig.inputs.first(); + let uses_opstate = arg0.map(is_rc_refcell_opstate).unwrap_or_default(); + let args_head = if uses_opstate { + quote! { state, } + } else { + quote! {} + }; + let rust_i0 = if uses_opstate { 1 } else { 0 }; + let (arg_decls, args_tail) = codegen_args(core, f, rust_i0, 2); let type_params = &f.sig.generics.params; quote! { @@ -139,7 +148,7 @@ fn codegen_v8_async(core: &TokenStream2, f: &syn::ItemFn) -> TokenStream2 { }; #core::_ops::queue_async_op(scope, async move { - let result = Self::call::<#type_params>(state, #args_tail).await; + let result = Self::call::<#type_params>(#args_head #args_tail).await; (promise_id, op_id, #core::_ops::to_op_result(get_class, result)) }); } @@ -147,7 +156,15 @@ fn codegen_v8_async(core: &TokenStream2, f: &syn::ItemFn) -> TokenStream2 { /// Generate the body of a v8 func for a sync op fn codegen_v8_sync(core: &TokenStream2, f: &syn::ItemFn) -> TokenStream2 { - let (arg_decls, args_tail) = codegen_args(core, f, 1, 1); + let arg0 = f.sig.inputs.first(); + let uses_opstate = arg0.map(is_mut_ref_opstate).unwrap_or_default(); + let args_head = if uses_opstate { + quote! { op_state, } + } else { + quote! {} + }; + let rust_i0 = if uses_opstate { 1 } else { 0 }; + let (arg_decls, args_tail) = codegen_args(core, f, rust_i0, 1); let ret = codegen_sync_ret(core, &f.sig.output); let type_params = &f.sig.generics.params; @@ -168,7 +185,7 @@ fn codegen_v8_sync(core: &TokenStream2, f: &syn::ItemFn) -> TokenStream2 { let state = unsafe { &*(state_refcell_raw as *const std::cell::RefCell<#core::OpState>) }; let op_state = &mut state.borrow_mut(); - let result = Self::call::<#type_params>(op_state, #args_tail); + let result = Self::call::<#type_params>(#args_head #args_tail); op_state.tracker.track_sync(op_id); @@ -284,3 +301,17 @@ fn is_unit_result(ty: &syn::Type) -> bool { _ => false, } } + +fn is_mut_ref_opstate(arg: &syn::FnArg) -> bool { + tokens(arg).ends_with(": & mut OpState") + || tokens(arg).ends_with(": & mut deno_core :: OpState") +} + +fn is_rc_refcell_opstate(arg: &syn::FnArg) -> bool { + tokens(arg).ends_with(": Rc < RefCell < OpState > >") + || tokens(arg).ends_with(": Rc < RefCell < deno_core :: OpState > >") +} + +fn tokens(x: impl ToTokens) -> String { + x.to_token_stream().to_string() +} diff --git a/runtime/ops/signal.rs b/runtime/ops/signal.rs index efab5a932e..1da3339ac5 100644 --- a/runtime/ops/signal.rs +++ b/runtime/ops/signal.rs @@ -225,18 +225,18 @@ pub fn op_signal_unbind( #[cfg(not(unix))] #[op] -pub fn op_signal_bind(_state: &mut OpState) -> Result<(), AnyError> { +pub fn op_signal_bind() -> Result<(), AnyError> { Err(generic_error("not implemented")) } #[cfg(not(unix))] #[op] -fn op_signal_unbind(_state: &mut OpState) -> Result<(), AnyError> { +fn op_signal_unbind() -> Result<(), AnyError> { Err(generic_error("not implemented")) } #[cfg(not(unix))] #[op] -async fn op_signal_poll(_state: Rc>) -> Result<(), AnyError> { +async fn op_signal_poll() -> Result<(), AnyError> { Err(generic_error("not implemented")) }