feat(ops): optional OpState (#13954)

This commit is contained in:
Aaron O'Mullan 2022-03-16 00:33:46 +01:00 committed by GitHub
parent 672f66dde1
commit bd481bf095
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 63 additions and 100 deletions

View file

@ -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)

View file

@ -22,12 +22,12 @@ fn setup() -> Vec<Extension> {
}
#[op]
fn op_nop(_: &mut OpState) -> Result<(), AnyError> {
fn op_nop() -> Result<(), AnyError> {
Ok(())
}
#[op]
fn op_pi_json(_: &mut OpState) -> Result<i64, AnyError> {
fn op_pi_json() -> Result<i64, AnyError> {
Ok(314159)
}

View file

@ -202,12 +202,12 @@ fn create_compiler_snapshot(
}
#[op]
fn op_cwd(_state: &mut OpState, _args: Value) -> Result<Value, AnyError> {
fn op_cwd(_args: Value) -> Result<Value, AnyError> {
Ok(json!("cache:///"))
}
#[op]
fn op_exists(_state: &mut OpState, _args: Value) -> Result<Value, AnyError> {
fn op_exists(_args: Value) -> Result<Value, AnyError> {
Ok(json!(false))
}

View file

@ -67,18 +67,12 @@ fn op_apply_source_map(
}
#[op]
fn op_format_diagnostic(
_state: &mut OpState,
args: Value,
) -> Result<Value, AnyError> {
fn op_format_diagnostic(args: Value) -> Result<Value, AnyError> {
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<String, AnyError> {
fn op_format_file_name(file_name: String) -> Result<String, AnyError> {
Ok(format_file_name(&file_name))
}

View file

@ -14,10 +14,7 @@ use deno_core::RuntimeOptions;
use deno_core::*;
#[op]
fn op_sum(
_state: &mut OpState,
nums: Vec<f64>,
) -> Result<f64, deno_core::error::AnyError> {
fn op_sum(nums: Vec<f64>) -> Result<f64, deno_core::error::AnyError> {
// Sum inputs
let sum = nums.iter().fold(0.0, |a, v| a + v);
// return as a Result<f64, AnyError>

View file

@ -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();

View file

@ -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<RefCell<OpState>>,
) -> 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(())
}

View file

@ -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<RefCell<OpState>>,
opts: DecryptOptions,
data: ZeroCopyBuf,
) -> Result<ZeroCopyBuf, AnyError> {

View file

@ -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<RefCell<OpState>>,
opts: EncryptOptions,
data: ZeroCopyBuf,
) -> Result<ZeroCopyBuf, AnyError> {

View file

@ -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<ExportKeyResult, AnyError> {

View file

@ -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<RefCell<OpState>>,
opts: GenerateKeyOptions,
) -> Result<ZeroCopyBuf, AnyError> {
let fun = || match opts {

View file

@ -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<ImportKeyResult, AnyError> {

View file

@ -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<RefCell<OpState>>,
args: SignArg,
zero_copy: ZeroCopyBuf,
) -> Result<ZeroCopyBuf, AnyError> {
@ -324,7 +321,6 @@ pub struct VerifyArg {
#[op]
pub async fn op_crypto_verify_key(
_state: Rc<RefCell<OpState>>,
args: VerifyArg,
zero_copy: ZeroCopyBuf,
) -> Result<bool, AnyError> {
@ -485,7 +481,6 @@ pub struct DeriveKeyArg {
#[op]
pub async fn op_crypto_derive_bits(
_state: Rc<RefCell<OpState>>,
args: DeriveKeyArg,
zero_copy: Option<ZeroCopyBuf>,
) -> Result<ZeroCopyBuf, AnyError> {
@ -807,7 +802,6 @@ pub fn op_crypto_random_uuid(state: &mut OpState) -> Result<String, AnyError> {
#[op]
pub async fn op_crypto_subtle_digest(
_state: Rc<RefCell<OpState>>,
algorithm: CryptoHash,
data: ZeroCopyBuf,
) -> Result<ZeroCopyBuf, AnyError> {
@ -831,7 +825,6 @@ pub struct WrapUnwrapKeyArg {
#[op]
pub fn op_crypto_wrap_key(
_state: &mut OpState,
args: WrapUnwrapKeyArg,
data: ZeroCopyBuf,
) -> Result<ZeroCopyBuf, AnyError> {
@ -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<ZeroCopyBuf, AnyError> {

View file

@ -648,17 +648,13 @@ fn ffi_call(args: FfiCallArgs, symbol: &Symbol) -> Result<Value, AnyError> {
}
#[op]
fn op_ffi_call_ptr(
_state: &mut deno_core::OpState,
args: FfiCallPtrArgs,
) -> Result<Value, AnyError> {
fn op_ffi_call_ptr(args: FfiCallPtrArgs) -> Result<Value, AnyError> {
let symbol = args.get_symbol();
ffi_call(args.into(), &symbol)
}
#[op]
async fn op_ffi_call_ptr_nonblocking(
_state: Rc<RefCell<deno_core::OpState>>,
args: FfiCallPtrArgs,
) -> Result<Value, AnyError> {
let symbol = args.get_symbol();

View file

@ -797,10 +797,7 @@ async fn op_http_read(
}
#[op]
fn op_http_websocket_accept_header(
_: &mut OpState,
key: String,
) -> Result<String, AnyError> {
fn op_http_websocket_accept_header(key: String) -> Result<String, AnyError> {
let digest = ring::digest::digest(
&ring::digest::SHA1_FOR_LEGACY_USE_ONLY,
format!("{}258EAFA5-E914-47DA-95CA-C5AB0DC85B11", key).as_bytes(),

View file

@ -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<String>,
) -> Result<UrlParts, AnyError> {
@ -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<UrlParts, AnyError> {
@ -162,7 +160,6 @@ fn url_result(
#[op]
pub fn op_url_parse_search_params(
_state: &mut deno_core::OpState,
args: Option<String>,
zero_copy: Option<ZeroCopyBuf>,
) -> Result<Vec<(String, String)>, 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<String, AnyError> {
let search = form_urlencoded::Serializer::new(String::new())

View file

@ -9,7 +9,6 @@ use urlpattern::quirks::UrlPattern;
#[op]
pub fn op_urlpattern_parse(
_state: &mut deno_core::OpState,
input: StringOrInit,
base_url: Option<String>,
) -> Result<UrlPattern, AnyError> {
@ -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<String>,
) -> Result<Option<(MatchInput, quirks::Inputs)>, AnyError> {

View file

@ -121,20 +121,14 @@ pub fn init<P: TimersPermission + 'static>(
}
#[op]
fn op_base64_decode(
_: &mut OpState,
input: String,
) -> Result<ZeroCopyBuf, AnyError> {
fn op_base64_decode(input: String) -> Result<ZeroCopyBuf, AnyError> {
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<ByteString, AnyError> {
fn op_base64_atob(s: ByteString) -> Result<ByteString, AnyError> {
let mut s = s.0;
s.retain(|c| !c.is_ascii_whitespace());
@ -184,15 +178,12 @@ fn b64_decode(input: &[u8]) -> Result<Vec<u8>, AnyError> {
}
#[op]
fn op_base64_encode(
_: &mut OpState,
s: ZeroCopyBuf,
) -> Result<String, AnyError> {
fn op_base64_encode(s: ZeroCopyBuf) -> Result<String, AnyError> {
Ok(b64_encode(&s))
}
#[op]
fn op_base64_btoa(_: &mut OpState, s: ByteString) -> Result<String, AnyError> {
fn op_base64_btoa(s: ByteString) -> Result<String, AnyError> {
Ok(b64_encode(&s))
}
@ -211,10 +202,7 @@ struct DecoderOptions {
}
#[op]
fn op_encoding_normalize_label(
_state: &mut OpState,
label: String,
) -> Result<String, AnyError> {
fn op_encoding_normalize_label(label: String) -> Result<String, AnyError> {
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<EncodeIntoResult, AnyError> {

View file

@ -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()
}

View file

@ -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<RefCell<OpState>>) -> Result<(), AnyError> {
async fn op_signal_poll() -> Result<(), AnyError> {
Err(generic_error("not implemented"))
}