diff options
Diffstat (limited to 'ops')
131 files changed, 0 insertions, 9951 deletions
diff --git a/ops/Cargo.toml b/ops/Cargo.toml deleted file mode 100644 index f9951f4e6..000000000 --- a/ops/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -[package] -name = "deno_ops" -version = "0.69.0" -authors.workspace = true -edition.workspace = true -license.workspace = true -readme = "README.md" -repository.workspace = true -description = "Proc macro for writing Deno Ops" - -[lib] -path = "./lib.rs" -proc-macro = true - -[dependencies] -deno-proc-macro-rules.workspace = true -lazy-regex.workspace = true -once_cell.workspace = true -pmutil = "0.5.3" -proc-macro-crate = "1.1.3" -proc-macro2.workspace = true -quote.workspace = true -regex.workspace = true -strum.workspace = true -strum_macros.workspace = true -syn.workspace = true -syn2.workspace = true -thiserror.workspace = true -v8.workspace = true - -[dev-dependencies] -pretty_assertions.workspace = true -prettyplease = "0.1.21" -testing_macros = "0.2.7" -trybuild = "1.0.71" diff --git a/ops/README.md b/ops/README.md deleted file mode 100644 index 39d860663..000000000 --- a/ops/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# deno_ops - -`proc_macro` for generating highly optimized V8 functions from Deno ops. - -```rust -// Declare an op. -#[op(fast)] -pub fn op_add(_: &mut OpState, a: i32, b: i32) -> i32 { - a + b -} - -// Register with an extension. -Extension::builder() - .ops(vec![op_add::decl()]) - .build(); -``` - -## Performance - -The macro can optimize away code, short circuit fast paths and generate a Fast -API impl. - -Cases where code is optimized away: - -- `-> ()` skips serde_v8 and `rv.set` calls. -- `-> Result<(), E>` skips serde_v8 and `rv.set` calls for `Ok()` branch. -- `-> ResourceId` or `-> [int]` types will use specialized method like - `v8::ReturnValue::set_uint32`. A fast path for SMI. -- `-> Result<ResourceId, E>` or `-> Result<[int], E>` types will be optimized - like above for the `Ok()` branch. - -### Fast calls - -The macro will infer and try to auto generate V8 fast API call trait impl for -`sync` ops with: - -- arguments: integers, bool, `&mut OpState`, `&[u8]`, `&mut [u8]`, `&[u32]`, - `&mut [u32]` -- return_type: integers, bool - -The `#[op(fast)]` attribute should be used to enforce fast call generation at -compile time. - -Trait gen for `async` ops & a ZeroCopyBuf equivalent type is planned and will be -added soon. - -### Wasm calls - -The `#[op(wasm)]` attribute should be used for calls expected to be called from -Wasm. This enables the fast call generation and allows seamless `WasmMemory` -integration for generic and fast calls. - -```rust -#[op(wasm)] -pub fn op_args_get( - offset: i32, - buffer_offset: i32, - memory: Option<&[u8]>, // Must be last parameter. Some(..) when entered from Wasm. -) { - // ... -} -``` diff --git a/ops/attrs.rs b/ops/attrs.rs deleted file mode 100644 index d0182fc69..000000000 --- a/ops/attrs.rs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use syn::parse::Parse; -use syn::parse::ParseStream; -use syn::Error; -use syn::Ident; -use syn::Result; -use syn::Token; - -#[derive(Clone, Debug, Default)] -pub struct Attributes { - pub is_unstable: bool, - pub is_v8: bool, - pub must_be_fast: bool, - pub deferred: bool, - pub is_wasm: bool, - pub relation: Option<Ident>, -} - -impl Parse for Attributes { - fn parse(input: ParseStream) -> Result<Self> { - let mut self_ = Self::default(); - let mut fast = false; - while let Ok(v) = input.parse::<Ident>() { - match v.to_string().as_str() { - "unstable" => self_.is_unstable = true, - "v8" => self_.is_v8 = true, - "fast" => fast = true, - "deferred" => self_.deferred = true, - "wasm" => self_.is_wasm = true, - "slow" => { - if !fast { - return Err(Error::new( - input.span(), - "relational attributes can only be used with fast attribute", - )); - } - input.parse::<Token![=]>()?; - self_.relation = Some(input.parse()?); - } - _ => { - return Err(Error::new( - input.span(), - "invalid attribute, expected one of: unstable, v8, fast, deferred, wasm", - )); - } - }; - let _ = input.parse::<Token![,]>(); - } - - self_.must_be_fast = self_.is_wasm || fast; - - Ok(self_) - } -} diff --git a/ops/deno.rs b/ops/deno.rs deleted file mode 100644 index fbaf2a9e6..000000000 --- a/ops/deno.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -#![cfg(not(test))] - -use proc_macro2::Span; -use proc_macro2::TokenStream; -use proc_macro_crate::crate_name; -use proc_macro_crate::FoundCrate; -use quote::quote; -use syn::Ident; - -/// Identifier to the `deno_core` crate. -/// -/// If macro called in deno_core, `crate` is used. -/// If macro called outside deno_core, `deno_core` OR the renamed -/// version from Cargo.toml is used. -pub(crate) fn import() -> TokenStream { - let found_crate = - crate_name("deno_core").expect("deno_core not present in `Cargo.toml`"); - - match found_crate { - FoundCrate::Itself => { - // TODO(@littledivy): This won't work for `deno_core` examples - // since `crate` does not refer to `deno_core`. - // examples must re-export deno_core to make this work - // until Span inspection APIs are stabilized. - // - // https://github.com/rust-lang/rust/issues/54725 - quote!(crate) - } - FoundCrate::Name(name) => { - let ident = Ident::new(&name, Span::call_site()); - quote!(#ident) - } - } -} diff --git a/ops/fast_call.rs b/ops/fast_call.rs deleted file mode 100644 index 63cff4c62..000000000 --- a/ops/fast_call.rs +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -//! Code generation for V8 fast calls. - -use pmutil::q; -use pmutil::Quote; -use pmutil::ToTokensExt; -use proc_macro2::Span; -use proc_macro2::TokenStream; -use quote::quote; -use syn::parse_quote; -use syn::punctuated::Punctuated; -use syn::token::Comma; -use syn::Generics; -use syn::Ident; -use syn::ItemFn; - -use crate::optimizer::FastValue; -use crate::optimizer::Optimizer; - -pub(crate) struct FastImplItems { - pub(crate) impl_and_fn: TokenStream, - pub(crate) decl: TokenStream, - pub(crate) active: bool, -} - -pub(crate) fn generate( - core: &TokenStream, - optimizer: &mut Optimizer, - item_fn: &ItemFn, -) -> FastImplItems { - if !optimizer.fast_compatible { - return FastImplItems { - impl_and_fn: TokenStream::new(), - decl: quote! { None }, - active: false, - }; - } - - // TODO(@littledivy): Use `let..else` on 1.65.0 - let output_ty = match &optimizer.fast_result { - // Assert that the optimizer did not set a return type. - // - // @littledivy: This *could* potentially be used to optimize resolving - // promises but knowing the return type at compile time instead of - // serde_v8 serialization. - Some(_) if optimizer.is_async => &FastValue::Void, - Some(ty) => ty, - None if optimizer.is_async => &FastValue::Void, - None => { - return FastImplItems { - impl_and_fn: TokenStream::new(), - decl: quote! { None }, - active: false, - } - } - }; - - // We've got 2 idents. - // - // - op_foo, the public op declaration contains the user function. - // - op_foo_fast_fn, the fast call function. - let ident = item_fn.sig.ident.clone(); - let fast_fn_ident = - Ident::new(&format!("{ident}_fast_fn"), Span::call_site()); - - // Deal with generics. - let generics = &item_fn.sig.generics; - let (impl_generics, _, where_clause) = generics.split_for_impl(); - - // This goes in the FastFunction impl block. - // let mut segments = Punctuated::new(); - // { - // let mut arguments = PathArguments::None; - // if let Some(ref struct_generics) = struct_generics { - // arguments = PathArguments::AngleBracketed(parse_quote! { - // #struct_generics - // }); - // } - // segments.push_value(PathSegment { - // ident: fast_ident.clone(), - // arguments, - // }); - // } - - // Original inputs. - let mut inputs = item_fn.sig.inputs.clone(); - let mut transforms = q!({}); - let mut pre_transforms = q!({}); - - // Apply parameter transforms - for (index, input) in inputs.iter_mut().enumerate() { - if let Some(transform) = optimizer.transforms.get(&index) { - let quo: Quote = transform.apply_for_fast_call(core, input); - transforms.push_tokens(&quo); - } - } - - // Collect idents to be passed into function call, we can now freely - // modify the inputs. - let idents = inputs - .iter() - .map(|input| match input { - syn::FnArg::Typed(pat_type) => match &*pat_type.pat { - syn::Pat::Ident(pat_ident) => pat_ident.ident.clone(), - _ => panic!("unexpected pattern"), - }, - _ => panic!("unexpected argument"), - }) - .collect::<Punctuated<_, Comma>>(); - - // Retain only *pure* parameters. - let mut fast_fn_inputs = if optimizer.has_opstate_in_parameters() { - inputs.into_iter().skip(1).collect() - } else { - inputs - }; - - let mut input_variants = optimizer - .fast_parameters - .iter() - .map(q_fast_ty_variant) - .collect::<Punctuated<_, Comma>>(); - - // Apply *hard* optimizer hints. - if optimizer.has_fast_callback_option - || optimizer.has_wasm_memory - || optimizer.needs_opstate() - || optimizer.is_async - || optimizer.needs_fast_callback_option - { - let decl = parse_quote! { - fast_api_callback_options: *mut #core::v8::fast_api::FastApiCallbackOptions - }; - - if optimizer.has_fast_callback_option || optimizer.has_wasm_memory { - // Replace last parameter. - assert!(fast_fn_inputs.pop().is_some()); - fast_fn_inputs.push(decl); - } else { - fast_fn_inputs.push(decl); - } - - input_variants.push(q!({ CallbackOptions })); - } - - // (recv, p_id, ...) - // - // Optimizer has already set it in the fast parameter variant list. - if optimizer.is_async { - if fast_fn_inputs.is_empty() { - fast_fn_inputs.push(parse_quote! { __promise_id: i32 }); - } else { - fast_fn_inputs.insert(0, parse_quote! { __promise_id: i32 }); - } - } - - let mut output_transforms = q!({}); - - if optimizer.needs_opstate() - || optimizer.is_async - || optimizer.has_fast_callback_option - || optimizer.has_wasm_memory - { - // Dark arts 🪄 ✨ - // - // - V8 calling convention guarantees that the callback options pointer is non-null. - // - `data` union is always initialized as the `v8::Local<v8::Value>` variant. - // - deno_core guarantees that `data` is a v8 External pointing to an OpCtx for the - // isolate's lifetime. - let prelude = q!({ - let __opts: &mut v8::fast_api::FastApiCallbackOptions = - unsafe { &mut *fast_api_callback_options }; - }); - - pre_transforms.push_tokens(&prelude); - } - - if optimizer.needs_opstate() || optimizer.is_async { - // Grab the op_state identifier, the first one. ¯\_(ツ)_/¯ - let op_state = match idents.first() { - Some(ident) if optimizer.has_opstate_in_parameters() => ident.clone(), - // fn op_foo() -> Result<...> - _ => Ident::new("op_state", Span::call_site()), - }; - - let ctx = q!({ - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - }); - - pre_transforms.push_tokens(&ctx); - pre_transforms.push_tokens(&match optimizer.is_async { - false => q!( - Vars { - op_state: &op_state - }, - { - let op_state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state); - } - ), - true => q!( - Vars { - op_state: &op_state - }, - { - let op_state = __ctx.state.clone(); - } - ), - }); - - if optimizer.returns_result && !optimizer.is_async { - // Magic fallback 🪄 - // - // If Result<T, E> is Ok(T), return T as fast value. - // - // Err(E) gets put into `last_fast_op_error` slot and - // - // V8 calls the slow path so we can take the slot - // value and throw. - let default = optimizer.fast_result.as_ref().unwrap().default_value(); - let result_wrap = q!(Vars { op_state, default }, { - match result { - Ok(result) => result, - Err(err) => { - op_state.last_fast_op_error.replace(err); - __opts.fallback = true; - default - } - } - }); - - output_transforms.push_tokens(&result_wrap); - } - } - - if optimizer.is_async { - let queue_future = if optimizer.returns_result { - q!({ - let result = _ops::queue_fast_async_op(__ctx, __promise_id, result); - }) - } else { - q!({ - let result = - _ops::queue_fast_async_op(__ctx, __promise_id, async move { - Ok(result.await) - }); - }) - }; - - output_transforms.push_tokens(&queue_future); - } - - if !optimizer.returns_result { - let default_output = q!({ result }); - output_transforms.push_tokens(&default_output); - } - - let output = q_fast_ty(output_ty); - // Generate the function body. - // - // fn f <S> (_: Local<Object>, a: T, b: U) -> R { - // /* Transforms */ - // let a = a.into(); - // let b = b.into(); - // - // let r = op::call(a, b); - // - // /* Return transform */ - // r.into() - // } - let fast_fn = q!( - Vars { core, pre_transforms, op_name_fast: &fast_fn_ident, op_name: &ident, fast_fn_inputs, generics, where_clause, idents, transforms, output_transforms, output: &output }, - { - impl generics op_name generics where_clause { - #[allow(clippy::too_many_arguments)] - fn op_name_fast (_: core::v8::Local<core::v8::Object>, fast_fn_inputs) -> output { - use core::v8; - use core::_ops; - pre_transforms - transforms - let result = Self::call (idents); - output_transforms - } - } - } - ); - - let output_variant = q_fast_ty_variant(output_ty); - let mut generics: Generics = parse_quote! { #impl_generics }; - generics.where_clause = where_clause.cloned(); - - // fast_api::FastFunction::new(&[ CType::T, CType::U ], CType::T, f::<P> as *const ::std::ffi::c_void) - let decl = q!( - Vars { - core: core, - fast_fn_ident: fast_fn_ident, - inputs: input_variants, - output: output_variant - }, - { - { - use core::v8::fast_api::CType; - use core::v8::fast_api::Type::*; - Some(core::v8::fast_api::FastFunction::new( - &[inputs], - CType::output, - Self::fast_fn_ident as *const ::std::ffi::c_void, - )) - } - } - ) - .dump(); - - let impl_and_fn = fast_fn.dump(); - - FastImplItems { - impl_and_fn, - decl, - active: true, - } -} - -/// Quote fast value type. -fn q_fast_ty(v: &FastValue) -> Quote { - match v { - FastValue::Void => q!({ () }), - FastValue::Bool => q!({ bool }), - FastValue::U32 => q!({ u32 }), - FastValue::I32 => q!({ i32 }), - FastValue::U64 => q!({ u64 }), - FastValue::I64 => q!({ i64 }), - FastValue::F32 => q!({ f32 }), - FastValue::F64 => q!({ f64 }), - FastValue::Pointer => q!({ *mut ::std::ffi::c_void }), - FastValue::V8Value => q!({ v8::Local<v8::Value> }), - FastValue::Uint8Array - | FastValue::Uint32Array - | FastValue::Float64Array - | FastValue::SeqOneByteString => unreachable!(), - } -} - -/// Quote fast value type's variant. -fn q_fast_ty_variant(v: &FastValue) -> Quote { - match v { - FastValue::Void => q!({ Void }), - FastValue::Bool => q!({ Bool }), - FastValue::U32 => q!({ Uint32 }), - FastValue::I32 => q!({ Int32 }), - FastValue::U64 => q!({ Uint64 }), - FastValue::I64 => q!({ Int64 }), - FastValue::F32 => q!({ Float32 }), - FastValue::F64 => q!({ Float64 }), - FastValue::Pointer => q!({ Pointer }), - FastValue::V8Value => q!({ V8Value }), - FastValue::Uint8Array => q!({ TypedArray(CType::Uint8) }), - FastValue::Uint32Array => q!({ TypedArray(CType::Uint32) }), - FastValue::Float64Array => q!({ TypedArray(CType::Float64) }), - FastValue::SeqOneByteString => q!({ SeqOneByteString }), - } -} diff --git a/ops/lib.rs b/ops/lib.rs deleted file mode 100644 index 31398a14d..000000000 --- a/ops/lib.rs +++ /dev/null @@ -1,1025 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -use attrs::Attributes; -use optimizer::BailoutReason; -use optimizer::Optimizer; -use proc_macro::TokenStream; -use proc_macro2::Span; -use proc_macro2::TokenStream as TokenStream2; -use quote::quote; -use quote::ToTokens; -use std::error::Error; -use syn::parse; -use syn::parse_macro_input; -use syn::punctuated::Punctuated; -use syn::token::Comma; -use syn::FnArg; -use syn::GenericParam; -use syn::Ident; -use syn::ItemFn; -use syn::Lifetime; -use syn::LifetimeDef; - -mod attrs; -mod deno; -mod fast_call; -mod op2; -mod optimizer; - -const SCOPE_LIFETIME: &str = "'scope"; - -/// Add the 'scope lifetime to the function signature. -fn add_scope_lifetime(func: &mut ItemFn) { - let span = Span::call_site(); - let lifetime = LifetimeDef::new(Lifetime::new(SCOPE_LIFETIME, span)); - let generics = &mut func.sig.generics; - if !generics.lifetimes().any(|def| *def == lifetime) { - generics.params.push(GenericParam::Lifetime(lifetime)); - } -} - -struct Op { - orig: ItemFn, - item: ItemFn, - /// Is this an async op? - /// - `async fn` - /// - returns a Future - is_async: bool, - // optimizer: Optimizer, - core: TokenStream2, - attrs: Attributes, -} - -impl Op { - fn new(item: ItemFn, attrs: Attributes) -> Self { - // Preserve the original function. Change the name to `call`. - // - // impl op_foo { - // fn call() {} - // ... - // } - let mut orig = item.clone(); - orig.sig.ident = Ident::new("call", Span::call_site()); - - let is_async = item.sig.asyncness.is_some() || is_future(&item.sig.output); - let scope_params = exclude_non_lifetime_params(&item.sig.generics.params); - orig.sig.generics.params = scope_params; - orig.sig.generics.where_clause.take(); - add_scope_lifetime(&mut orig); - - #[cfg(test)] - let core = quote!(deno_core); - #[cfg(not(test))] - let core = deno::import(); - - Self { - orig, - item, - is_async, - core, - attrs, - } - } - - fn gen(mut self) -> TokenStream2 { - let mut optimizer = Optimizer::new(); - match optimizer.analyze(&mut self) { - Err(BailoutReason::MustBeSingleSegment) - | Err(BailoutReason::FastUnsupportedParamType) => { - optimizer.fast_compatible = false; - } - _ => {} - }; - - let Self { - core, - item, - is_async, - orig, - attrs, - } = self; - let name = &item.sig.ident; - - // TODO(mmastrac): this code is a little awkward but eventually it'll disappear in favour of op2 - let mut generics = item.sig.generics.clone(); - generics.where_clause.take(); - generics.params = exclude_lifetime_params(&generics.params); - let params = &generics.params.iter().collect::<Vec<_>>(); - let where_clause = &item.sig.generics.where_clause; - - // First generate fast call bindings to opt-in to error handling in slow call - let fast_call::FastImplItems { - impl_and_fn, - decl, - active, - } = fast_call::generate(&core, &mut optimizer, &item); - - let docline = format!("Use `{name}::decl()` to get an op-declaration"); - - let is_v8 = attrs.is_v8; - let is_unstable = attrs.is_unstable; - - if let Some(v8_fn) = attrs.relation { - return quote! { - #[allow(non_camel_case_types)] - #[doc="Auto-generated by `deno_ops`, i.e: `#[op]`"] - #[doc=""] - #[doc=#docline] - #[doc="you can include in a `deno_core::Extension`."] - pub struct #name #generics { - _phantom_data: ::std::marker::PhantomData<(#(#params),*)> - } - - impl #generics #core::_ops::Op for #name #generics #where_clause { - const NAME: &'static str = stringify!(#name); - const DECL: #core::OpDecl = #core::OpDecl { - name: Self::name(), - v8_fn_ptr: #v8_fn::v8_fn_ptr as _, - enabled: true, - fast_fn: #decl, - is_async: #is_async, - is_unstable: #is_unstable, - is_v8: #is_v8, - // TODO(mmastrac) - arg_count: 0, - }; - } - - #[doc(hidden)] - impl #generics #name #generics #where_clause { - pub const fn name() -> &'static str { - stringify!(#name) - } - - pub const fn decl () -> #core::OpDecl { - #core::OpDecl { - name: Self::name(), - v8_fn_ptr: #v8_fn::v8_fn_ptr as _, - enabled: true, - fast_fn: #decl, - is_async: #is_async, - is_unstable: #is_unstable, - is_v8: #is_v8, - // TODO(mmastrac) - arg_count: 0, - } - } - - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - #orig - } - - #impl_and_fn - }; - } - - let has_fallible_fast_call = active && optimizer.returns_result; - - let (v8_body, arg_count) = if is_async { - let deferred: bool = attrs.deferred; - codegen_v8_async( - &core, - &item, - attrs, - item.sig.asyncness.is_some(), - deferred, - ) - } else { - codegen_v8_sync(&core, &item, attrs, has_fallible_fast_call) - }; - - // Generate wrapper - quote! { - #[allow(non_camel_case_types)] - #[doc="Auto-generated by `deno_ops`, i.e: `#[op]`"] - #[doc=""] - #[doc=#docline] - #[doc="you can include in a `deno_core::Extension`."] - pub struct #name #generics { - _phantom_data: ::std::marker::PhantomData<(#(#params),*)> - } - - impl #generics #core::_ops::Op for #name #generics #where_clause { - const NAME: &'static str = stringify!(#name); - const DECL: #core::OpDecl = #core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: #decl, - is_async: #is_async, - is_unstable: #is_unstable, - is_v8: #is_v8, - // TODO(mmastrac) - arg_count: 0, - }; - } - - #[doc(hidden)] - impl #generics #name #generics #where_clause { - pub const fn name() -> &'static str { - stringify!(#name) - } - - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr (info: *const #core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { #core::v8::CallbackScope::new(info) }; - let args = #core::v8::FunctionCallbackArguments::from_function_callback_info(info); - let rv = #core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - - pub const fn decl () -> #core::OpDecl { - #core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: #decl, - is_async: #is_async, - is_unstable: #is_unstable, - is_v8: #is_v8, - arg_count: #arg_count as u8, - } - } - - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - #orig - - pub fn v8_func<'scope>( - scope: &mut #core::v8::HandleScope<'scope>, - args: #core::v8::FunctionCallbackArguments, - mut rv: #core::v8::ReturnValue, - ) { - #v8_body - } - } - - #impl_and_fn - } - } -} - -#[proc_macro_attribute] -pub fn op(attr: TokenStream, item: TokenStream) -> TokenStream { - let margs = parse_macro_input!(attr as Attributes); - let func = parse::<ItemFn>(item).expect("expected a function"); - let op = Op::new(func, margs); - op.gen().into() -} - -#[proc_macro_attribute] -pub fn op2(attr: TokenStream, item: TokenStream) -> TokenStream { - match crate::op2::op2(attr.into(), item.into()) { - Ok(output) => output.into(), - Err(err) => { - let mut err: &dyn Error = &err; - let mut output = "Failed to parse #[op2]:\n".to_owned(); - loop { - output += &format!(" - {err}\n"); - if let Some(source) = err.source() { - err = source; - } else { - break; - } - } - panic!("{output}"); - } - } -} - -/// Generate the body of a v8 func for an async op -fn codegen_v8_async( - core: &TokenStream2, - f: &syn::ItemFn, - margs: Attributes, - asyncness: bool, - deferred: bool, -) -> (TokenStream2, usize) { - let Attributes { is_v8, .. } = margs; - let special_args = f - .sig - .inputs - .iter() - .map_while(|a| { - (if is_v8 { scope_arg(a) } else { None }) - .or_else(|| rc_refcell_opstate_arg(a)) - }) - .collect::<Vec<_>>(); - let rust_i0 = special_args.len(); - let args_head = special_args.into_iter().collect::<TokenStream2>(); - - let (arg_decls, args_tail, _) = codegen_args(core, f, rust_i0, 1, asyncness); - - let wrapper = match (asyncness, is_result(&f.sig.output)) { - (true, true) => { - quote! { - let fut = #core::_ops::map_async_op1(ctx, Self::call(#args_head #args_tail)); - let maybe_response = #core::_ops::queue_async_op( - ctx, - scope, - #deferred, - promise_id, - fut, - ); - } - } - (true, false) => { - quote! { - let fut = #core::_ops::map_async_op2(ctx, Self::call(#args_head #args_tail)); - let maybe_response = #core::_ops::queue_async_op( - ctx, - scope, - #deferred, - promise_id, - fut, - ); - } - } - (false, true) => { - quote! { - let fut = #core::_ops::map_async_op3(ctx, Self::call(#args_head #args_tail)); - let maybe_response = #core::_ops::queue_async_op( - ctx, - scope, - #deferred, - promise_id, - fut, - ); - } - } - (false, false) => { - quote! { - let fut = #core::_ops::map_async_op4(ctx, Self::call(#args_head #args_tail)); - let maybe_response = #core::_ops::queue_async_op( - ctx, - scope, - #deferred, - promise_id, - fut, - ); - } - } - }; - - let token_stream = quote! { - use #core::futures::FutureExt; - // SAFETY: #core guarantees args.data() is a v8 External pointing to an OpCtx for the isolates lifetime - let ctx = unsafe { - &*(#core::v8::Local::<#core::v8::External>::cast(args.data()).value() - as *const #core::_ops::OpCtx) - }; - - let promise_id = args.get(0); - let promise_id = #core::v8::Local::<#core::v8::Integer>::try_from(promise_id) - .map(|l| l.value() as #core::PromiseId) - .map_err(#core::anyhow::Error::from); - // Fail if promise id invalid (not an int) - let promise_id: #core::PromiseId = match promise_id { - Ok(promise_id) => promise_id, - Err(err) => { - #core::_ops::throw_type_error(scope, format!("invalid promise id: {}", err)); - return; - } - }; - - #arg_decls - #wrapper - - if let Some(response) = maybe_response { - rv.set(response); - } - }; - - // +1 arg for the promise ID - (token_stream, 1 + f.sig.inputs.len() - rust_i0) -} - -fn scope_arg(arg: &FnArg) -> Option<TokenStream2> { - if is_handle_scope(arg) { - Some(quote! { scope, }) - } else { - None - } -} - -fn opstate_arg(arg: &FnArg) -> Option<TokenStream2> { - match arg { - arg if is_rc_refcell_opstate(arg) => Some(quote! { ctx.state.clone(), }), - arg if is_mut_ref_opstate(arg) => { - Some(quote! { &mut std::cell::RefCell::borrow_mut(&ctx.state), }) - } - _ => None, - } -} - -fn rc_refcell_opstate_arg(arg: &FnArg) -> Option<TokenStream2> { - match arg { - arg if is_rc_refcell_opstate(arg) => Some(quote! { ctx.state.clone(), }), - arg if is_mut_ref_opstate(arg) => Some( - quote! { compile_error!("mutable opstate is not supported in async ops"), }, - ), - _ => None, - } -} - -/// Generate the body of a v8 func for a sync op -fn codegen_v8_sync( - core: &TokenStream2, - f: &syn::ItemFn, - margs: Attributes, - has_fallible_fast_call: bool, -) -> (TokenStream2, usize) { - let Attributes { is_v8, .. } = margs; - let special_args = f - .sig - .inputs - .iter() - .map_while(|a| { - (if is_v8 { scope_arg(a) } else { None }).or_else(|| opstate_arg(a)) - }) - .collect::<Vec<_>>(); - let rust_i0 = special_args.len(); - let args_head = special_args.into_iter().collect::<TokenStream2>(); - let (arg_decls, args_tail, _) = codegen_args(core, f, rust_i0, 0, false); - let ret = codegen_sync_ret(core, &f.sig.output); - - let fast_error_handler = if has_fallible_fast_call { - quote! { - { - let op_state = &mut std::cell::RefCell::borrow_mut(&ctx.state); - if let Some(err) = op_state.last_fast_op_error.take() { - let exception = #core::error::to_v8_error(scope, op_state.get_error_class_fn, &err); - scope.throw_exception(exception); - return; - } - } - } - } else { - quote! {} - }; - - let token_stream = quote! { - // SAFETY: #core guarantees args.data() is a v8 External pointing to an OpCtx for the isolates lifetime - let ctx = unsafe { - &*(#core::v8::Local::<#core::v8::External>::cast(args.data()).value() - as *const #core::_ops::OpCtx) - }; - - #fast_error_handler - #arg_decls - - let result = Self::call(#args_head #args_tail); - - // use RefCell::borrow instead of state.borrow to avoid clash with std::borrow::Borrow - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - - #ret - }; - - (token_stream, f.sig.inputs.len() - rust_i0) -} - -/// (full declarations, idents, v8 argument count) -type ArgumentDecl = (TokenStream2, TokenStream2, usize); - -fn codegen_args( - core: &TokenStream2, - f: &syn::ItemFn, - rust_i0: usize, // Index of first generic arg in rust - v8_i0: usize, // Index of first generic arg in v8/js - asyncness: bool, -) -> ArgumentDecl { - let inputs = &f.sig.inputs.iter().skip(rust_i0).enumerate(); - let ident_seq: TokenStream2 = inputs - .clone() - .map(|(i, _)| format!("arg_{i}")) - .collect::<Vec<_>>() - .join(", ") - .parse() - .unwrap(); - let decls: TokenStream2 = inputs - .clone() - .map(|(i, arg)| { - codegen_arg(core, arg, format!("arg_{i}").as_ref(), v8_i0 + i, asyncness) - }) - .collect(); - (decls, ident_seq, inputs.len()) -} - -fn codegen_arg( - core: &TokenStream2, - arg: &syn::FnArg, - name: &str, - idx: usize, - asyncness: bool, -) -> TokenStream2 { - let ident = quote::format_ident!("{name}"); - let (pat, ty) = match arg { - syn::FnArg::Typed(pat) => { - if is_optional_fast_callback_option(&pat.ty) - || is_optional_wasm_memory(&pat.ty) - { - return quote! { let #ident = None; }; - } - (&pat.pat, &pat.ty) - } - _ => unreachable!(), - }; - // Fast path if arg should be skipped - if matches!(**pat, syn::Pat::Wild(_)) { - return quote! { let #ident = (); }; - } - // Fast path for `String` - if let Some(is_ref) = is_string(&**ty) { - let ref_block = if is_ref { - quote! { let #ident = #ident.as_ref(); } - } else { - quote! {} - }; - return quote! { - let #ident = match #core::v8::Local::<#core::v8::String>::try_from(args.get(#idx as i32)) { - Ok(v8_string) => #core::serde_v8::to_utf8(v8_string, scope), - Err(_) => { - return #core::_ops::throw_type_error(scope, format!("Expected string at position {}", #idx)); - } - }; - #ref_block - }; - } - // Fast path for `Cow<'_, str>` - if is_cow_str(&**ty) { - return quote! { - let #ident = match #core::v8::Local::<#core::v8::String>::try_from(args.get(#idx as i32)) { - Ok(v8_string) => ::std::borrow::Cow::Owned(#core::serde_v8::to_utf8(v8_string, scope)), - Err(_) => { - return #core::_ops::throw_type_error(scope, format!("Expected string at position {}", #idx)); - } - }; - }; - } - // Fast path for `Option<String>` - if is_option_string(&**ty) { - return quote! { - let #ident = match #core::v8::Local::<#core::v8::String>::try_from(args.get(#idx as i32)) { - Ok(v8_string) => Some(#core::serde_v8::to_utf8(v8_string, scope)), - Err(_) => None - }; - }; - } - // Fast path for &/&mut [u8] and &/&mut [u32] - match is_ref_slice(&**ty) { - None => {} - Some(SliceType::U32Mut) => { - assert!(!asyncness, "Memory slices are not allowed in async ops"); - let blck = codegen_u32_mut_slice(core, idx); - return quote! { - let #ident = #blck; - }; - } - Some(SliceType::F64Mut) => { - assert!(!asyncness, "Memory slices are not allowed in async ops"); - let blck = codegen_f64_mut_slice(core, idx); - return quote! { - let #ident = #blck; - }; - } - Some(_) => { - assert!(!asyncness, "Memory slices are not allowed in async ops"); - let blck = codegen_u8_slice(core, idx); - return quote! { - let #ident = #blck; - }; - } - } - // Fast path for `*const u8` - if is_ptr_u8(&**ty) { - let blk = codegen_u8_ptr(core, idx); - return quote! { - let #ident = #blk; - }; - } - // Fast path for `*const c_void` and `*mut c_void` - if is_ptr_cvoid(&**ty) { - let blk = codegen_cvoid_ptr(core, idx); - return quote! { - let #ident = #blk; - }; - } - // Otherwise deserialize it via serde_v8 - quote! { - let #ident = args.get(#idx as i32); - let #ident = match #core::serde_v8::from_v8(scope, #ident) { - Ok(v) => v, - Err(err) => { - let msg = format!("Error parsing args at position {}: {}", #idx, #core::anyhow::Error::from(err)); - return #core::_ops::throw_type_error(scope, msg); - } - }; - } -} - -fn codegen_u8_slice(core: &TokenStream2, idx: usize) -> TokenStream2 { - quote! {{ - let value = args.get(#idx as i32); - match #core::v8::Local::<#core::v8::ArrayBuffer>::try_from(value) { - Ok(b) => { - let byte_length = b.byte_length(); - if let Some(data) = b.data() { - let store = data.cast::<u8>().as_ptr(); - // SAFETY: rust guarantees that lifetime of slice is no longer than the call. - unsafe { ::std::slice::from_raw_parts_mut(store, byte_length) } - } else { - &mut [] - } - }, - Err(_) => { - if let Ok(view) = #core::v8::Local::<#core::v8::ArrayBufferView>::try_from(value) { - let len = view.byte_length(); - let offset = view.byte_offset(); - let buffer = match view.buffer(scope) { - Some(v) => v, - None => { - return #core::_ops::throw_type_error(scope, format!("Expected ArrayBufferView at position {}", #idx)); - } - }; - if let Some(data) = buffer.data() { - let store = data.cast::<u8>().as_ptr(); - // SAFETY: rust guarantees that lifetime of slice is no longer than the call. - unsafe { ::std::slice::from_raw_parts_mut(store.add(offset), len) } - } else { - &mut [] - } - } else { - return #core::_ops::throw_type_error(scope, format!("Expected ArrayBufferView at position {}", #idx)); - } - } - }} - } -} - -fn codegen_u8_ptr(core: &TokenStream2, idx: usize) -> TokenStream2 { - quote! {{ - let value = args.get(#idx as i32); - match #core::v8::Local::<#core::v8::ArrayBuffer>::try_from(value) { - Ok(b) => { - if let Some(data) = b.data() { - data.cast::<u8>().as_ptr() - } else { - std::ptr::null::<u8>() - } - }, - Err(_) => { - if let Ok(view) = #core::v8::Local::<#core::v8::ArrayBufferView>::try_from(value) { - let offset = view.byte_offset(); - let buffer = match view.buffer(scope) { - Some(v) => v, - None => { - return #core::_ops::throw_type_error(scope, format!("Expected ArrayBufferView at position {}", #idx)); - } - }; - let store = if let Some(data) = buffer.data() { - data.cast::<u8>().as_ptr() - } else { - std::ptr::null_mut::<u8>() - }; - unsafe { store.add(offset) } - } else { - return #core::_ops::throw_type_error(scope, format!("Expected ArrayBufferView at position {}", #idx)); - } - } - } - }} -} - -fn codegen_cvoid_ptr(core: &TokenStream2, idx: usize) -> TokenStream2 { - quote! {{ - let value = args.get(#idx as i32); - if value.is_null() { - std::ptr::null_mut() - } else if let Ok(b) = #core::v8::Local::<#core::v8::External>::try_from(value) { - b.value() - } else { - return #core::_ops::throw_type_error(scope, format!("Expected External at position {}", #idx)); - } - }} -} - -fn codegen_u32_mut_slice(core: &TokenStream2, idx: usize) -> TokenStream2 { - quote! { - if let Ok(view) = #core::v8::Local::<#core::v8::Uint32Array>::try_from(args.get(#idx as i32)) { - let (offset, len) = (view.byte_offset(), view.byte_length()); - let buffer = match view.buffer(scope) { - Some(v) => v, - None => { - return #core::_ops::throw_type_error(scope, format!("Expected Uint32Array at position {}", #idx)); - } - }; - if let Some(data) = buffer.data() { - let store = data.cast::<u8>().as_ptr(); - // SAFETY: buffer from Uint32Array. Rust guarantees that lifetime of slice is no longer than the call. - unsafe { ::std::slice::from_raw_parts_mut(store.add(offset) as *mut u32, len / 4) } - } else { - &mut [] - } - } else { - return #core::_ops::throw_type_error(scope, format!("Expected Uint32Array at position {}", #idx)); - } - } -} - -fn codegen_f64_mut_slice(core: &TokenStream2, idx: usize) -> TokenStream2 { - quote! { - if let Ok(view) = #core::v8::Local::<#core::v8::Float64Array>::try_from(args.get(#idx as i32)) { - let (offset, len) = (view.byte_offset(), view.byte_length()); - let buffer = match view.buffer(scope) { - Some(v) => v, - None => { - return #core::_ops::throw_type_error(scope, format!("Expected Float64Array at position {}", #idx)); - } - }; - if let Some(data) = buffer.data() { - let store = data.cast::<u8>().as_ptr(); - unsafe { ::std::slice::from_raw_parts_mut(store.add(offset) as *mut f64, len / 8) } - } else { - &mut [] - } - } else { - return #core::_ops::throw_type_error(scope, format!("Expected Float64Array at position {}", #idx)); - } - } -} - -fn codegen_sync_ret( - core: &TokenStream2, - output: &syn::ReturnType, -) -> TokenStream2 { - if is_void(output) { - return quote! {}; - } - - if is_u32_rv(output) { - return quote! { - rv.set_uint32(result as u32); - }; - } - - // Optimize Result<(), Err> to skip serde_v8 when Ok(...) - let ok_block = if is_unit_result(output) { - quote! {} - } else if is_u32_rv_result(output) { - quote! { - rv.set_uint32(result as u32); - } - } else if is_ptr_cvoid(output) || is_ptr_cvoid_rv(output) { - quote! { - if result.is_null() { - // External cannot contain a null pointer, null pointers are instead represented as null. - rv.set_null(); - } else { - rv.set(v8::External::new(scope, result as *mut ::std::ffi::c_void).into()); - } - } - } else { - quote! { - match #core::serde_v8::to_v8(scope, result) { - Ok(ret) => rv.set(ret), - Err(err) => #core::_ops::throw_type_error( - scope, - format!("Error serializing return: {}", #core::anyhow::Error::from(err)), - ), - }; - } - }; - - if !is_result(output) { - return ok_block; - } - - quote! { - match result { - Ok(result) => { - #ok_block - }, - Err(err) => { - let exception = #core::error::to_v8_error(scope, op_state.get_error_class_fn, &err); - scope.throw_exception(exception); - }, - }; - } -} - -fn is_void(ty: impl ToTokens) -> bool { - tokens(ty).is_empty() -} - -fn is_result(ty: impl ToTokens) -> bool { - let tokens = tokens(ty); - if tokens.trim_start_matches("-> ").starts_with("Result <") { - return true; - } - // Detect `io::Result<...>`, `anyhow::Result<...>`, etc... - // i.e: Result aliases/shorthands which are unfortunately "opaque" at macro-time - match tokens.find(":: Result <") { - Some(idx) => !tokens.split_at(idx).0.contains('<'), - None => false, - } -} - -fn is_string(ty: impl ToTokens) -> Option<bool> { - let toks = tokens(ty); - if toks == "String" { - return Some(false); - } - if toks == "& str" { - return Some(true); - } - None -} - -fn is_option_string(ty: impl ToTokens) -> bool { - tokens(ty) == "Option < String >" -} - -fn is_cow_str(ty: impl ToTokens) -> bool { - tokens(&ty).starts_with("Cow <") && tokens(&ty).ends_with("str >") -} - -enum SliceType { - U8, - U8Mut, - U32Mut, - F64Mut, -} - -fn is_ref_slice(ty: impl ToTokens) -> Option<SliceType> { - if is_u8_slice(&ty) { - return Some(SliceType::U8); - } - if is_u8_slice_mut(&ty) { - return Some(SliceType::U8Mut); - } - if is_u32_slice_mut(&ty) { - return Some(SliceType::U32Mut); - } - if is_f64_slice_mut(&ty) { - return Some(SliceType::F64Mut); - } - None -} - -fn is_u8_slice(ty: impl ToTokens) -> bool { - tokens(ty) == "& [u8]" -} - -fn is_u8_slice_mut(ty: impl ToTokens) -> bool { - tokens(ty) == "& mut [u8]" -} - -fn is_u32_slice_mut(ty: impl ToTokens) -> bool { - tokens(ty) == "& mut [u32]" -} - -fn is_f64_slice_mut(ty: impl ToTokens) -> bool { - tokens(ty) == "& mut [f64]" -} - -fn is_ptr_u8(ty: impl ToTokens) -> bool { - tokens(ty) == "* const u8" -} - -fn is_ptr_cvoid(ty: impl ToTokens) -> bool { - tokens(&ty) == "* const c_void" || tokens(&ty) == "* mut c_void" -} - -fn is_ptr_cvoid_rv(ty: impl ToTokens) -> bool { - tokens(&ty).contains("Result < * const c_void") - || tokens(&ty).contains("Result < * mut c_void") -} - -fn is_optional_fast_callback_option(ty: impl ToTokens) -> bool { - tokens(&ty).contains("Option < & mut FastApiCallbackOptions") -} - -fn is_optional_wasm_memory(ty: impl ToTokens) -> bool { - tokens(&ty).contains("Option < & mut [u8]") -} - -/// Detects if the type can be set using `rv.set_uint32` fast path -fn is_u32_rv(ty: impl ToTokens) -> bool { - ["u32", "u8", "u16"].iter().any(|&s| tokens(&ty) == s) || is_resource_id(&ty) -} - -/// Detects if the type is of the format Result<u32/u8/u16, Err> -fn is_u32_rv_result(ty: impl ToTokens) -> bool { - is_result(&ty) - && (tokens(&ty).contains("Result < u32") - || tokens(&ty).contains("Result < u8") - || tokens(&ty).contains("Result < u16") - || is_resource_id(&ty)) -} - -/// Detects if a type is of the form Result<(), Err> -fn is_unit_result(ty: impl ToTokens) -> bool { - is_result(&ty) && tokens(&ty).contains("Result < ()") -} - -fn is_resource_id(arg: impl ToTokens) -> bool { - let re = lazy_regex::regex!(r#": (?:deno_core :: )?ResourceId$"#); - re.is_match(&tokens(arg)) -} - -fn is_mut_ref_opstate(arg: impl ToTokens) -> bool { - let re = lazy_regex::regex!(r#": & mut (?:deno_core :: )?OpState$"#); - re.is_match(&tokens(arg)) -} - -fn is_rc_refcell_opstate(arg: &syn::FnArg) -> bool { - let re = - lazy_regex::regex!(r#": Rc < RefCell < (?:deno_core :: )?OpState > >$"#); - re.is_match(&tokens(arg)) -} - -fn is_handle_scope(arg: &syn::FnArg) -> bool { - let re = lazy_regex::regex!( - r#": & mut (?:deno_core :: )?v8 :: HandleScope(?: < '\w+ >)?$"# - ); - re.is_match(&tokens(arg)) -} - -fn is_future(ty: impl ToTokens) -> bool { - tokens(&ty).contains("impl Future < Output =") -} - -fn tokens(x: impl ToTokens) -> String { - x.to_token_stream().to_string() -} - -fn exclude_lifetime_params( - generic_params: &Punctuated<GenericParam, Comma>, -) -> Punctuated<GenericParam, Comma> { - generic_params - .iter() - .filter(|t| !tokens(t).starts_with('\'')) - .cloned() - .collect::<Punctuated<GenericParam, Comma>>() -} - -fn exclude_non_lifetime_params( - generic_params: &Punctuated<GenericParam, Comma>, -) -> Punctuated<GenericParam, Comma> { - generic_params - .iter() - .filter(|t| tokens(t).starts_with('\'')) - .cloned() - .collect::<Punctuated<GenericParam, Comma>>() -} - -#[cfg(test)] -mod tests { - use crate::Attributes; - use crate::Op; - use pretty_assertions::assert_eq; - use std::path::PathBuf; - - #[testing_macros::fixture("optimizer_tests/**/*.rs")] - fn test_codegen(input: PathBuf) { - let update_expected = std::env::var("UPDATE_EXPECTED").is_ok(); - - let source = - std::fs::read_to_string(&input).expect("Failed to read test file"); - - let mut attrs = Attributes::default(); - if source.contains("// @test-attr:fast") { - attrs.must_be_fast = true; - } - if source.contains("// @test-attr:wasm") { - attrs.is_wasm = true; - attrs.must_be_fast = true; - } - - let item = syn::parse_str(&source).expect("Failed to parse test file"); - let op = Op::new(item, attrs); - - let expected = std::fs::read_to_string(input.with_extension("out")) - .expect("Failed to read expected output file"); - - // Print the raw tokens in case we fail to parse - let actual = op.gen(); - println!("-----Raw tokens-----\n{}----------\n", actual); - - // Validate syntax tree. - let tree = syn::parse2(actual).unwrap(); - let actual = prettyplease::unparse(&tree); - if update_expected { - std::fs::write(input.with_extension("out"), actual) - .expect("Failed to write expected file"); - } else { - assert_eq!(actual, expected); - } - } -} diff --git a/ops/op2/dispatch_fast.rs b/ops/op2/dispatch_fast.rs deleted file mode 100644 index f9d74416a..000000000 --- a/ops/op2/dispatch_fast.rs +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use super::generator_state::GeneratorState; -use super::signature::Arg; -use super::signature::NumericArg; -use super::signature::ParsedSignature; -use super::signature::RetVal; -use super::signature::Special; -use super::V8MappingError; -use proc_macro2::Ident; -use proc_macro2::TokenStream; -use quote::format_ident; -use quote::quote; -use std::iter::zip; - -#[allow(unused)] -#[derive(Debug, Default, PartialEq, Clone)] -pub(crate) enum V8FastCallType { - #[default] - Void, - Bool, - U32, - I32, - U64, - I64, - F32, - F64, - Pointer, - V8Value, - Uint8Array, - Uint32Array, - Float64Array, - SeqOneByteString, - CallbackOptions, -} - -impl V8FastCallType { - /// Quote fast value type. - fn quote_rust_type(&self, deno_core: &TokenStream) -> TokenStream { - match self { - V8FastCallType::Void => quote!(()), - V8FastCallType::Bool => quote!(bool), - V8FastCallType::U32 => quote!(u32), - V8FastCallType::I32 => quote!(i32), - V8FastCallType::U64 => quote!(u64), - V8FastCallType::I64 => quote!(i64), - V8FastCallType::F32 => quote!(f32), - V8FastCallType::F64 => quote!(f64), - V8FastCallType::Pointer => quote!(*mut ::std::ffi::c_void), - V8FastCallType::V8Value => { - quote!(#deno_core::v8::Local<#deno_core::v8::Value>) - } - V8FastCallType::CallbackOptions => { - quote!(*mut #deno_core::v8::fast_api::FastApiCallbackOptions) - } - V8FastCallType::SeqOneByteString => { - quote!(*mut #deno_core::v8::fast_api::FastApiOneByteString) - } - V8FastCallType::Uint8Array - | V8FastCallType::Uint32Array - | V8FastCallType::Float64Array => unreachable!(), - } - } - - /// Quote fast value type's variant. - fn quote_ctype(&self) -> TokenStream { - match &self { - V8FastCallType::Void => quote!(CType::Void), - V8FastCallType::Bool => quote!(CType::Bool), - V8FastCallType::U32 => quote!(CType::Uint32), - V8FastCallType::I32 => quote!(CType::Int32), - V8FastCallType::U64 => quote!(CType::Uint64), - V8FastCallType::I64 => quote!(CType::Int64), - V8FastCallType::F32 => quote!(CType::Float32), - V8FastCallType::F64 => quote!(CType::Float64), - V8FastCallType::Pointer => quote!(CType::Pointer), - V8FastCallType::V8Value => quote!(CType::V8Value), - V8FastCallType::CallbackOptions => quote!(CType::CallbackOptions), - V8FastCallType::Uint8Array => unreachable!(), - V8FastCallType::Uint32Array => unreachable!(), - V8FastCallType::Float64Array => unreachable!(), - V8FastCallType::SeqOneByteString => quote!(CType::SeqOneByteString), - } - } - - /// Quote fast value type's variant. - fn quote_type(&self) -> TokenStream { - match &self { - V8FastCallType::Void => quote!(Type::Void), - V8FastCallType::Bool => quote!(Type::Bool), - V8FastCallType::U32 => quote!(Type::Uint32), - V8FastCallType::I32 => quote!(Type::Int32), - V8FastCallType::U64 => quote!(Type::Uint64), - V8FastCallType::I64 => quote!(Type::Int64), - V8FastCallType::F32 => quote!(Type::Float32), - V8FastCallType::F64 => quote!(Type::Float64), - V8FastCallType::Pointer => quote!(Type::Pointer), - V8FastCallType::V8Value => quote!(Type::V8Value), - V8FastCallType::CallbackOptions => quote!(Type::CallbackOptions), - V8FastCallType::Uint8Array => quote!(Type::TypedArray(CType::Uint8)), - V8FastCallType::Uint32Array => quote!(Type::TypedArray(CType::Uint32)), - V8FastCallType::Float64Array => quote!(Type::TypedArray(CType::Float64)), - V8FastCallType::SeqOneByteString => quote!(Type::SeqOneByteString), - } - } -} - -pub fn generate_dispatch_fast( - generator_state: &mut GeneratorState, - signature: &ParsedSignature, -) -> Result<Option<(TokenStream, TokenStream)>, V8MappingError> { - let mut inputs = vec![]; - for arg in &signature.args { - let Some(fv) = map_arg_to_v8_fastcall_type(arg)? else { - return Ok(None); - }; - inputs.push(fv); - } - let mut names = inputs - .iter() - .enumerate() - .map(|(i, _)| format_ident!("arg{i}")) - .collect::<Vec<_>>(); - - let ret_val = match &signature.ret_val { - RetVal::Infallible(arg) => arg, - RetVal::Result(arg) => arg, - }; - - let output = match map_retval_to_v8_fastcall_type(ret_val)? { - None => return Ok(None), - Some(rv) => rv, - }; - - let GeneratorState { - fast_function, - deno_core, - result, - opctx, - fast_api_callback_options, - needs_fast_api_callback_options, - needs_fast_opctx, - .. - } = generator_state; - - let handle_error = match signature.ret_val { - RetVal::Infallible(_) => quote!(), - RetVal::Result(_) => { - *needs_fast_api_callback_options = true; - *needs_fast_opctx = true; - inputs.push(V8FastCallType::CallbackOptions); - quote! { - let #result = match #result { - Ok(#result) => #result, - Err(err) => { - // FASTCALL FALLBACK: This is where we set the errors for the slow-call error pickup path. There - // is no code running between this and the other FASTCALL FALLBACK comment, except some V8 code - // required to perform the fallback process. This is why the below call is safe. - - // The reason we need to do this is because V8 does not allow exceptions to be thrown from the - // fast call. Instead, you are required to set the fallback flag, which indicates to V8 that it - // should re-call the slow version of the function. Technically the slow call should perform the - // same operation and then throw the same error (because it should be idempotent), but in our - // case we stash the error and pick it up on the slow path before doing any work. - - // TODO(mmastrac): We should allow an #[op] flag to re-perform slow calls without the error path when - // the method is performance sensitive. - - // SAFETY: We guarantee that OpCtx has no mutable references once ops are live and being called, - // allowing us to perform this one little bit of mutable magic. - unsafe { #opctx.unsafely_set_last_error_for_ops_only(err); } - #fast_api_callback_options.fallback = true; - return ::std::default::Default::default(); - } - }; - } - } - }; - - let input_types = inputs.iter().map(|fv| fv.quote_type()).collect::<Vec<_>>(); - let output_type = output.quote_ctype(); - - let fast_definition = quote! { - use #deno_core::v8::fast_api::Type; - use #deno_core::v8::fast_api::CType; - #deno_core::v8::fast_api::FastFunction::new( - &[ Type::V8Value, #( #input_types ),* ], - #output_type, - Self::#fast_function as *const ::std::ffi::c_void - ) - }; - - let output_type = output.quote_rust_type(deno_core); - let mut types = inputs - .iter() - .map(|rv| rv.quote_rust_type(deno_core)) - .collect::<Vec<_>>(); - - let call_idents = names.clone(); - let call_args = zip(names.iter(), signature.args.iter()) - .map(|(name, arg)| map_v8_fastcall_arg_to_arg(deno_core, name, arg)) - .collect::<Vec<_>>(); - - let with_fast_api_callback_options = if *needs_fast_api_callback_options { - types.push(V8FastCallType::CallbackOptions.quote_rust_type(deno_core)); - names.push(fast_api_callback_options.clone()); - quote! { - let #fast_api_callback_options = unsafe { &mut *#fast_api_callback_options }; - } - } else { - quote!() - }; - let with_opctx = if *needs_fast_opctx { - quote!( - let #opctx = unsafe { - &*(#deno_core::v8::Local::<v8::External>::cast(unsafe { #fast_api_callback_options.data.data }).value() - as *const #deno_core::_ops::OpCtx) - }; - ) - } else { - quote!() - }; - - let fast_fn = quote!( - fn #fast_function( - _: #deno_core::v8::Local<#deno_core::v8::Object>, - #( #names: #types, )* - ) -> #output_type { - #with_fast_api_callback_options - #with_opctx - #(#call_args)* - let #result = Self::call(#(#call_idents),*); - #handle_error - #result - } - ); - - Ok(Some((fast_definition, fast_fn))) -} - -fn map_v8_fastcall_arg_to_arg( - deno_core: &TokenStream, - arg_ident: &Ident, - arg: &Arg, -) -> TokenStream { - let arg_temp = format_ident!("{}_temp", arg_ident); - match arg { - Arg::Special(Special::RefStr) => { - quote! { - let mut #arg_temp: [::std::mem::MaybeUninit<u8>; 1024] = [::std::mem::MaybeUninit::uninit(); 1024]; - let #arg_ident = &#deno_core::_ops::to_str_ptr(unsafe { &mut *#arg_ident }, &mut #arg_temp); - } - } - Arg::Special(Special::String) => { - quote!(let #arg_ident = #deno_core::_ops::to_string_ptr(unsafe { &mut *#arg_ident });) - } - Arg::Special(Special::CowStr) => { - quote! { - let mut #arg_temp: [::std::mem::MaybeUninit<u8>; 1024] = [::std::mem::MaybeUninit::uninit(); 1024]; - let #arg_ident = #deno_core::_ops::to_str_ptr(unsafe { &mut *#arg_ident }, &mut #arg_temp); - } - } - _ => quote!(let #arg_ident = #arg_ident as _;), - } -} - -fn map_arg_to_v8_fastcall_type( - arg: &Arg, -) -> Result<Option<V8FastCallType>, V8MappingError> { - let rv = match arg { - Arg::OptionNumeric(_) | Arg::SerdeV8(_) => return Ok(None), - Arg::Numeric(NumericArg::bool) => V8FastCallType::Bool, - Arg::Numeric(NumericArg::u32) - | Arg::Numeric(NumericArg::u16) - | Arg::Numeric(NumericArg::u8) => V8FastCallType::U32, - Arg::Numeric(NumericArg::i32) - | Arg::Numeric(NumericArg::i16) - | Arg::Numeric(NumericArg::i8) - | Arg::Numeric(NumericArg::__SMI__) => V8FastCallType::I32, - Arg::Numeric(NumericArg::u64) | Arg::Numeric(NumericArg::usize) => { - V8FastCallType::U64 - } - Arg::Numeric(NumericArg::i64) | Arg::Numeric(NumericArg::isize) => { - V8FastCallType::I64 - } - // Ref strings that are one byte internally may be passed as a SeqOneByteString, - // which gives us a FastApiOneByteString. - Arg::Special(Special::RefStr) => V8FastCallType::SeqOneByteString, - // Owned strings can be fast, but we'll have to copy them. - Arg::Special(Special::String) => V8FastCallType::SeqOneByteString, - // Cow strings can be fast, but may require copying - Arg::Special(Special::CowStr) => V8FastCallType::SeqOneByteString, - _ => return Err(V8MappingError::NoMapping("a fast argument", arg.clone())), - }; - Ok(Some(rv)) -} - -fn map_retval_to_v8_fastcall_type( - arg: &Arg, -) -> Result<Option<V8FastCallType>, V8MappingError> { - let rv = match arg { - Arg::OptionNumeric(_) | Arg::SerdeV8(_) => return Ok(None), - Arg::Void => V8FastCallType::Void, - Arg::Numeric(NumericArg::bool) => V8FastCallType::Bool, - Arg::Numeric(NumericArg::u32) - | Arg::Numeric(NumericArg::u16) - | Arg::Numeric(NumericArg::u8) => V8FastCallType::U32, - Arg::Numeric(NumericArg::i32) - | Arg::Numeric(NumericArg::i16) - | Arg::Numeric(NumericArg::i8) => V8FastCallType::I32, - Arg::Numeric(NumericArg::u64) | Arg::Numeric(NumericArg::usize) => { - V8FastCallType::U64 - } - Arg::Numeric(NumericArg::i64) | Arg::Numeric(NumericArg::isize) => { - V8FastCallType::I64 - } - // We don't return special return types - Arg::Option(_) => return Ok(None), - Arg::Special(_) => return Ok(None), - _ => { - return Err(V8MappingError::NoMapping( - "a fast return value", - arg.clone(), - )) - } - }; - Ok(Some(rv)) -} diff --git a/ops/op2/dispatch_slow.rs b/ops/op2/dispatch_slow.rs deleted file mode 100644 index 2ec67cc76..000000000 --- a/ops/op2/dispatch_slow.rs +++ /dev/null @@ -1,401 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use super::generator_state::GeneratorState; -use super::signature::Arg; -use super::signature::NumericArg; -use super::signature::ParsedSignature; -use super::signature::RetVal; -use super::signature::Special; -use super::MacroConfig; -use super::V8MappingError; -use proc_macro2::TokenStream; -use quote::format_ident; -use quote::quote; - -pub(crate) fn generate_dispatch_slow( - config: &MacroConfig, - generator_state: &mut GeneratorState, - signature: &ParsedSignature, -) -> Result<TokenStream, V8MappingError> { - let mut output = TokenStream::new(); - - // Fast ops require the slow op to check op_ctx for the last error - if config.fast && matches!(signature.ret_val, RetVal::Result(_)) { - generator_state.needs_opctx = true; - let throw_exception = throw_exception(generator_state)?; - // If the fast op returned an error, we must throw it rather than doing work. - output.extend(quote!{ - // FASTCALL FALLBACK: This is where we pick up the errors for the slow-call error pickup - // path. There is no code running between this and the other FASTCALL FALLBACK comment, - // except some V8 code required to perform the fallback process. This is why the below call is safe. - - // SAFETY: We guarantee that OpCtx has no mutable references once ops are live and being called, - // allowing us to perform this one little bit of mutable magic. - if let Some(err) = unsafe { opctx.unsafely_take_last_error_for_ops_only() } { - #throw_exception - } - }); - } - - for (index, arg) in signature.args.iter().enumerate() { - output.extend(extract_arg(generator_state, index)?); - output.extend(from_arg(generator_state, index, arg)?); - } - output.extend(call(generator_state)?); - output.extend(return_value(generator_state, &signature.ret_val)?); - - let with_scope = if generator_state.needs_scope { - with_scope(generator_state) - } else { - quote!() - }; - - let with_opctx = if generator_state.needs_opctx { - with_opctx(generator_state) - } else { - quote!() - }; - - let with_retval = if generator_state.needs_retval { - with_retval(generator_state) - } else { - quote!() - }; - - let with_args = if generator_state.needs_args { - with_fn_args(generator_state) - } else { - quote!() - }; - - let GeneratorState { - deno_core, - info, - slow_function, - .. - } = &generator_state; - - Ok(quote! { - extern "C" fn #slow_function(#info: *const #deno_core::v8::FunctionCallbackInfo) { - #with_scope - #with_retval - #with_args - #with_opctx - - #output - }}) -} - -fn with_scope(generator_state: &mut GeneratorState) -> TokenStream { - let GeneratorState { - deno_core, - scope, - info, - .. - } = &generator_state; - - quote!(let #scope = &mut unsafe { #deno_core::v8::CallbackScope::new(&*#info) };) -} - -fn with_retval(generator_state: &mut GeneratorState) -> TokenStream { - let GeneratorState { - deno_core, - retval, - info, - .. - } = &generator_state; - - quote!(let mut #retval = #deno_core::v8::ReturnValue::from_function_callback_info(unsafe { &*#info });) -} - -fn with_fn_args(generator_state: &mut GeneratorState) -> TokenStream { - let GeneratorState { - deno_core, - fn_args, - info, - .. - } = &generator_state; - - quote!(let #fn_args = #deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { &*#info });) -} - -fn with_opctx(generator_state: &mut GeneratorState) -> TokenStream { - let GeneratorState { - deno_core, - opctx, - fn_args, - needs_args, - .. - } = generator_state; - - *needs_args = true; - quote!(let #opctx = unsafe { - &*(#deno_core::v8::Local::<#deno_core::v8::External>::cast(#fn_args.data()).value() - as *const #deno_core::_ops::OpCtx) - };) -} - -pub fn extract_arg( - generator_state: &mut GeneratorState, - index: usize, -) -> Result<TokenStream, V8MappingError> { - let GeneratorState { fn_args, .. } = &generator_state; - let arg_ident = generator_state.args.get(index); - - Ok(quote!( - let #arg_ident = #fn_args.get(#index as i32); - )) -} - -pub fn from_arg( - mut generator_state: &mut GeneratorState, - index: usize, - arg: &Arg, -) -> Result<TokenStream, V8MappingError> { - let GeneratorState { - deno_core, - args, - scope, - needs_scope, - .. - } = &mut generator_state; - let arg_ident = args.get_mut(index).expect("Argument at index was missing"); - let arg_temp = format_ident!("{}_temp", arg_ident); - let res = match arg { - Arg::Numeric(NumericArg::bool) => quote! { - let #arg_ident = #arg_ident.is_true(); - }, - Arg::Numeric(NumericArg::u8) - | Arg::Numeric(NumericArg::u16) - | Arg::Numeric(NumericArg::u32) => { - quote! { - let #arg_ident = #deno_core::_ops::to_u32(&#arg_ident) as _; - } - } - Arg::Numeric(NumericArg::i8) - | Arg::Numeric(NumericArg::i16) - | Arg::Numeric(NumericArg::i32) - | Arg::Numeric(NumericArg::__SMI__) => { - quote! { - let #arg_ident = #deno_core::_ops::to_i32(&#arg_ident) as _; - } - } - Arg::Numeric(NumericArg::u64) | Arg::Numeric(NumericArg::usize) => { - quote! { - let #arg_ident = #deno_core::_ops::to_u64(&#arg_ident) as _; - } - } - Arg::Numeric(NumericArg::i64) | Arg::Numeric(NumericArg::isize) => { - quote! { - let #arg_ident = #deno_core::_ops::to_i64(&#arg_ident) as _; - } - } - Arg::OptionNumeric(numeric) => { - // Ends the borrow of generator_state - let arg_ident = arg_ident.clone(); - let some = from_arg(generator_state, index, &Arg::Numeric(*numeric))?; - quote! { - let #arg_ident = if #arg_ident.is_null_or_undefined() { - None - } else { - #some - Some(#arg_ident) - }; - } - } - Arg::Option(Special::String) => { - *needs_scope = true; - quote! { - let #arg_ident = #arg_ident.to_rust_string_lossy(#scope); - } - } - Arg::Special(Special::String) => { - *needs_scope = true; - quote! { - let #arg_ident = #arg_ident.to_rust_string_lossy(#scope); - } - } - Arg::Special(Special::RefStr) => { - *needs_scope = true; - quote! { - // Trade 1024 bytes of stack space for potentially non-allocating strings - let mut #arg_temp: [::std::mem::MaybeUninit<u8>; 1024] = [::std::mem::MaybeUninit::uninit(); 1024]; - let #arg_ident = &#deno_core::_ops::to_str(#scope, &#arg_ident, &mut #arg_temp); - } - } - Arg::Special(Special::CowStr) => { - *needs_scope = true; - quote! { - // Trade 1024 bytes of stack space for potentially non-allocating strings - let mut #arg_temp: [::std::mem::MaybeUninit<u8>; 1024] = [::std::mem::MaybeUninit::uninit(); 1024]; - let #arg_ident = #deno_core::_ops::to_str(#scope, &#arg_ident, &mut #arg_temp); - } - } - _ => return Err(V8MappingError::NoMapping("a slow argument", arg.clone())), - }; - Ok(res) -} - -pub fn call( - generator_state: &mut GeneratorState, -) -> Result<TokenStream, V8MappingError> { - let GeneratorState { result, .. } = &generator_state; - - let mut tokens = TokenStream::new(); - for arg in &generator_state.args { - tokens.extend(quote!( #arg , )); - } - Ok(quote! { - let #result = Self::call( #tokens ); - }) -} - -pub fn return_value( - generator_state: &mut GeneratorState, - ret_type: &RetVal, -) -> Result<TokenStream, V8MappingError> { - match ret_type { - RetVal::Infallible(ret_type) => { - return_value_infallible(generator_state, ret_type) - } - RetVal::Result(ret_type) => return_value_result(generator_state, ret_type), - } -} - -pub fn return_value_infallible( - generator_state: &mut GeneratorState, - ret_type: &Arg, -) -> Result<TokenStream, V8MappingError> { - let GeneratorState { - deno_core, - scope, - result, - retval, - needs_retval, - needs_scope, - .. - } = generator_state; - - let res = match ret_type { - Arg::Void => { - quote! {/* void */} - } - Arg::Numeric(NumericArg::u8) - | Arg::Numeric(NumericArg::u16) - | Arg::Numeric(NumericArg::u32) => { - *needs_retval = true; - quote!(#retval.set_uint32(#result as u32);) - } - Arg::Numeric(NumericArg::i8) - | Arg::Numeric(NumericArg::i16) - | Arg::Numeric(NumericArg::i32) => { - *needs_retval = true; - quote!(#retval.set_int32(#result as i32);) - } - Arg::Special(Special::String) => { - *needs_retval = true; - *needs_scope = true; - quote! { - if #result.is_empty() { - #retval.set_empty_string(); - } else { - // This should not fail in normal cases - // TODO(mmastrac): This has extra allocations that we need to get rid of, especially if the string - // is ASCII. We could make an "external Rust String" string in V8 from these and re-use the allocation. - let temp = #deno_core::v8::String::new(#scope, &#result).unwrap(); - #retval.set(temp.into()); - } - } - } - Arg::Option(Special::String) => { - *needs_retval = true; - *needs_scope = true; - // End the generator_state borrow - let (result, retval) = (result.clone(), retval.clone()); - let some = return_value_infallible( - generator_state, - &Arg::Special(Special::String), - )?; - quote! { - if let Some(#result) = #result { - #some - } else { - #retval.set_null(); - } - } - } - _ => { - return Err(V8MappingError::NoMapping( - "a slow return value", - ret_type.clone(), - )) - } - }; - - Ok(res) -} - -fn return_value_result( - generator_state: &mut GeneratorState, - ret_type: &Arg, -) -> Result<TokenStream, V8MappingError> { - let infallible = return_value_infallible(generator_state, ret_type)?; - let exception = throw_exception(generator_state)?; - - let GeneratorState { result, .. } = &generator_state; - - let tokens = quote!( - match #result { - Ok(#result) => { - #infallible - } - Err(err) => { - #exception - } - }; - ); - Ok(tokens) -} - -/// Generates code to throw an exception, adding required additional dependencies as needed. -fn throw_exception( - generator_state: &mut GeneratorState, -) -> Result<TokenStream, V8MappingError> { - let maybe_scope = if generator_state.needs_scope { - quote!() - } else { - with_scope(generator_state) - }; - - let maybe_opctx = if generator_state.needs_opctx { - quote!() - } else { - with_opctx(generator_state) - }; - - let maybe_args = if generator_state.needs_args { - quote!() - } else { - with_fn_args(generator_state) - }; - - let GeneratorState { - deno_core, - scope, - opctx, - .. - } = &generator_state; - - Ok(quote! { - #maybe_scope - #maybe_args - #maybe_opctx - let opstate = ::std::cell::RefCell::borrow(&*#opctx.state); - let exception = #deno_core::error::to_v8_error( - #scope, - opstate.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - return; - }) -} diff --git a/ops/op2/generator_state.rs b/ops/op2/generator_state.rs deleted file mode 100644 index e437ea47c..000000000 --- a/ops/op2/generator_state.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use proc_macro2::Ident; -use proc_macro2::TokenStream; - -pub struct GeneratorState { - /// The path to the `deno_core` crate (either `deno_core` or `crate`, the latter used if the op is `(core)`). - pub deno_core: TokenStream, - - /// Identifiers for each of the arguments of the original function - pub args: Vec<Ident>, - /// The new identifier for the original function's contents. - pub call: Ident, - /// The result of the `call` function - pub result: Ident, - - /// The `v8::CallbackScope` used if necessary for the function. - pub scope: Ident, - /// The `v8::FunctionCallbackInfo` used to pass args into the slow function. - pub info: Ident, - /// The `v8::FunctionCallbackArguments` used to pass args into the slow function. - pub fn_args: Ident, - /// The `OpCtx` used for various information required for some ops. - pub opctx: Ident, - /// The `FastApiCallbackOptions` used in fast calls for fallback returns. - pub fast_api_callback_options: Ident, - /// The `v8::ReturnValue` used in the slow function - pub retval: Ident, - /// The "slow" function (ie: the one that isn't a fastcall) - pub slow_function: Ident, - /// The "fast" function (ie: a fastcall) - pub fast_function: Ident, - - pub needs_args: bool, - pub needs_retval: bool, - pub needs_scope: bool, - pub needs_opstate: bool, - pub needs_opctx: bool, - pub needs_fast_opctx: bool, - pub needs_fast_api_callback_options: bool, -} diff --git a/ops/op2/mod.rs b/ops/op2/mod.rs deleted file mode 100644 index 7f652fe1b..000000000 --- a/ops/op2/mod.rs +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use deno_proc_macro_rules::rules; -use proc_macro2::Ident; -use proc_macro2::Span; -use proc_macro2::TokenStream; -use quote::format_ident; -use quote::quote; -use quote::ToTokens; -use std::iter::zip; -use syn2::parse2; -use syn2::parse_str; -use syn2::FnArg; -use syn2::ItemFn; -use syn2::Path; -use thiserror::Error; - -use self::dispatch_fast::generate_dispatch_fast; -use self::dispatch_slow::generate_dispatch_slow; -use self::generator_state::GeneratorState; -use self::signature::parse_signature; -use self::signature::Arg; -use self::signature::SignatureError; - -pub mod dispatch_fast; -pub mod dispatch_slow; -pub mod generator_state; -pub mod signature; - -#[derive(Debug, Error)] -pub enum Op2Error { - #[error("Failed to match a pattern for '{0}': (input was '{1}')")] - PatternMatchFailed(&'static str, String), - #[error("Invalid attribute: '{0}'")] - InvalidAttribute(String), - #[error("Failed to parse syntax tree")] - ParseError(#[from] syn2::Error), - #[error("Failed to map a parsed signature to a V8 call")] - V8MappingError(#[from] V8MappingError), - #[error("Failed to parse signature")] - SignatureError(#[from] SignatureError), - #[error("This op is fast-compatible and should be marked as (fast)")] - ShouldBeFast, - #[error("This op is not fast-compatible and should not be marked as (fast)")] - ShouldNotBeFast, -} - -#[derive(Debug, Error)] -pub enum V8MappingError { - #[error("Unable to map {1:?} to {0}")] - NoMapping(&'static str, Arg), -} - -#[derive(Default)] -pub(crate) struct MacroConfig { - pub core: bool, - pub fast: bool, -} - -impl MacroConfig { - pub fn from_flags(flags: Vec<Ident>) -> Result<Self, Op2Error> { - let mut config: MacroConfig = Self::default(); - for flag in flags { - if flag == "core" { - config.core = true; - } else if flag == "fast" { - config.fast = true; - } else { - return Err(Op2Error::InvalidAttribute(flag.to_string())); - } - } - Ok(config) - } - - pub fn from_tokens(tokens: TokenStream) -> Result<Self, Op2Error> { - let attr_string = tokens.to_string(); - let config = std::panic::catch_unwind(|| { - rules!(tokens => { - () => { - Ok(MacroConfig::default()) - } - ($($flags:ident),+) => { - Self::from_flags(flags) - } - }) - }) - .map_err(|_| Op2Error::PatternMatchFailed("attribute", attr_string))??; - Ok(config) - } -} - -pub fn op2( - attr: TokenStream, - item: TokenStream, -) -> Result<TokenStream, Op2Error> { - let func = parse2::<ItemFn>(item)?; - let config = MacroConfig::from_tokens(attr)?; - generate_op2(config, func) -} - -fn generate_op2( - config: MacroConfig, - func: ItemFn, -) -> Result<TokenStream, Op2Error> { - // Create a copy of the original function, named "call" - let call = Ident::new("call", Span::call_site()); - let mut op_fn = func.clone(); - op_fn.attrs.clear(); - op_fn.sig.generics.params.clear(); - op_fn.sig.ident = call.clone(); - - // Clear inert attributes - // TODO(mmastrac): This should limit itself to clearing ours only - for arg in op_fn.sig.inputs.iter_mut() { - match arg { - FnArg::Receiver(slf) => slf.attrs.clear(), - FnArg::Typed(ty) => ty.attrs.clear(), - } - } - - let signature = parse_signature(func.attrs, func.sig.clone())?; - let processed_args = - zip(signature.args.iter(), &func.sig.inputs).collect::<Vec<_>>(); - - let mut args = vec![]; - let mut needs_args = false; - for (index, _) in processed_args.iter().enumerate() { - let input = format_ident!("arg{index}"); - args.push(input); - needs_args = true; - } - - let retval = Ident::new("rv", Span::call_site()); - let result = Ident::new("result", Span::call_site()); - let fn_args = Ident::new("args", Span::call_site()); - let scope = Ident::new("scope", Span::call_site()); - let info = Ident::new("info", Span::call_site()); - let opctx = Ident::new("opctx", Span::call_site()); - let slow_function = Ident::new("v8_fn_ptr", Span::call_site()); - let fast_function = Ident::new("v8_fn_ptr_fast", Span::call_site()); - let fast_api_callback_options = - Ident::new("fast_api_callback_options", Span::call_site()); - - let deno_core = if config.core { - syn2::parse_str::<Path>("crate") - } else { - syn2::parse_str::<Path>("deno_core") - } - .expect("Parsing crate should not fail") - .into_token_stream(); - - let mut generator_state = GeneratorState { - args, - fn_args, - call, - scope, - info, - opctx, - fast_api_callback_options, - deno_core, - result, - retval, - needs_args, - slow_function, - fast_function, - needs_retval: false, - needs_scope: false, - needs_opctx: false, - needs_opstate: false, - needs_fast_opctx: false, - needs_fast_api_callback_options: false, - }; - - let name = func.sig.ident; - - let slow_fn = - generate_dispatch_slow(&config, &mut generator_state, &signature)?; - let (fast_definition, fast_fn) = - match generate_dispatch_fast(&mut generator_state, &signature)? { - Some((fast_definition, fast_fn)) => { - if !config.fast { - return Err(Op2Error::ShouldBeFast); - } - (quote!(Some({#fast_definition})), fast_fn) - } - None => { - if config.fast { - return Err(Op2Error::ShouldNotBeFast); - } - (quote!(None), quote!()) - } - }; - - let GeneratorState { - deno_core, - slow_function, - .. - } = &generator_state; - - let arg_count: usize = generator_state.args.len(); - let vis = func.vis; - let generic = signature - .generic_bounds - .keys() - .map(|s| format_ident!("{s}")) - .collect::<Vec<_>>(); - let bound = signature - .generic_bounds - .values() - .map(|p| parse_str::<Path>(p).expect("Failed to reparse path")) - .collect::<Vec<_>>(); - - Ok(quote! { - #[allow(non_camel_case_types)] - #vis struct #name <#(#generic),*> { - // We need to mark these type parameters as used, so we use a PhantomData - _unconstructable: ::std::marker::PhantomData<(#(#generic),*)> - } - - impl <#(#generic : #bound),*> #deno_core::_ops::Op for #name <#(#generic),*> { - const NAME: &'static str = stringify!(#name); - const DECL: #deno_core::_ops::OpDecl = #deno_core::_ops::OpDecl { - name: stringify!(#name), - v8_fn_ptr: Self::#slow_function as _, - enabled: true, - fast_fn: #fast_definition, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: #arg_count as u8, - }; - } - - impl <#(#generic : #bound),*> #name <#(#generic),*> { - pub const fn name() -> &'static str { - stringify!(#name) - } - - pub const fn decl() -> #deno_core::_ops::OpDecl { - #deno_core::_ops::OpDecl { - name: stringify!(#name), - v8_fn_ptr: Self::#slow_function as _, - enabled: true, - fast_fn: #fast_definition, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: #arg_count as u8, - } - } - - #fast_fn - #slow_fn - - #[inline(always)] - #op_fn - } - }) -} - -#[cfg(test)] -mod tests { - use super::*; - use pretty_assertions::assert_eq; - use std::path::PathBuf; - use syn2::parse_str; - use syn2::File; - use syn2::Item; - - #[testing_macros::fixture("op2/test_cases/**/*.rs")] - fn test_signature_parser(input: PathBuf) { - let update_expected = std::env::var("UPDATE_EXPECTED").is_ok(); - - let source = - std::fs::read_to_string(&input).expect("Failed to read test file"); - let file = parse_str::<File>(&source).expect("Failed to parse Rust file"); - let mut expected_out = vec![]; - for item in file.items { - if let Item::Fn(mut func) = item { - let mut config = None; - func.attrs.retain(|attr| { - let tokens = attr.into_token_stream(); - let attr_string = attr.clone().into_token_stream().to_string(); - println!("{}", attr_string); - use syn2 as syn; - if let Some(new_config) = rules!(tokens => { - (#[op2]) => { - Some(MacroConfig::default()) - } - (#[op2( $($x:ident),* )]) => { - Some(MacroConfig::from_flags(x).expect("Failed to parse attribute")) - } - (#[$_attr:meta]) => { - None - } - }) { - config = Some(new_config); - false - } else { - true - } - }); - let tokens = - generate_op2(config.unwrap(), func).expect("Failed to generate op"); - println!("======== Raw tokens ========:\n{}", tokens.clone()); - let tree = syn::parse2(tokens).unwrap(); - let actual = prettyplease::unparse(&tree); - println!("======== Generated ========:\n{}", actual); - expected_out.push(actual); - } - } - - let expected_out = expected_out.join("\n"); - - if update_expected { - std::fs::write(input.with_extension("out"), expected_out) - .expect("Failed to write expectation file"); - } else { - let expected = std::fs::read_to_string(input.with_extension("out")) - .expect("Failed to read expectation file"); - assert_eq!( - expected, expected_out, - "Failed to match expectation. Use UPDATE_EXPECTED=1." - ); - } - } -} diff --git a/ops/op2/signature.rs b/ops/op2/signature.rs deleted file mode 100644 index 5d472fcf3..000000000 --- a/ops/op2/signature.rs +++ /dev/null @@ -1,741 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use deno_proc_macro_rules::rules; -use proc_macro2::Ident; -use proc_macro2::Span; -use quote::quote; -use quote::ToTokens; -use std::collections::BTreeMap; -use strum::IntoEnumIterator; -use strum::IntoStaticStr; -use strum_macros::EnumIter; -use strum_macros::EnumString; -use syn2::Attribute; -use syn2::FnArg; -use syn2::GenericParam; -use syn2::Generics; -use syn2::Pat; -use syn2::ReturnType; -use syn2::Signature; -use syn2::Type; -use syn2::TypePath; -use thiserror::Error; - -#[allow(non_camel_case_types)] -#[derive( - Copy, Clone, Debug, Eq, PartialEq, IntoStaticStr, EnumString, EnumIter, -)] -pub enum NumericArg { - /// A placeholder argument for arguments annotated with #[smi]. - __SMI__, - /// A placeholder argument for void data. - __VOID__, - bool, - i8, - u8, - i16, - u16, - i32, - u32, - i64, - u64, - f32, - f64, - isize, - usize, -} - -impl ToTokens for NumericArg { - fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { - let ident = Ident::new(self.into(), Span::call_site()); - tokens.extend(quote! { #ident }) - } -} - -#[derive( - Copy, Clone, Debug, Eq, PartialEq, IntoStaticStr, EnumString, EnumIter, -)] -pub enum V8Arg { - External, - Object, - Array, - ArrayBuffer, - ArrayBufferView, - DataView, - TypedArray, - BigInt64Array, - BigUint64Array, - Float32Array, - Float64Array, - Int16Array, - Int32Array, - Int8Array, - Uint16Array, - Uint32Array, - Uint8Array, - Uint8ClampedArray, - BigIntObject, - BooleanObject, - Date, - Function, - Map, - NumberObject, - Promise, - PromiseResolver, - Proxy, - RegExp, - Set, - SharedArrayBuffer, - StringObject, - SymbolObject, - WasmMemoryObject, - WasmModuleObject, - Primitive, - BigInt, - Boolean, - Name, - String, - Symbol, - Number, - Integer, - Int32, - Uint32, -} - -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum Special { - HandleScope, - OpState, - String, - CowStr, - RefStr, - FastApiCallbackOptions, -} - -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum RefType { - Ref, - Mut, -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum Arg { - Void, - Special(Special), - Ref(RefType, Special), - RcRefCell(Special), - Option(Special), - OptionNumeric(NumericArg), - Slice(RefType, NumericArg), - Ptr(RefType, NumericArg), - V8Local(V8Arg), - Numeric(NumericArg), - SerdeV8(String), -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum RetVal { - Infallible(Arg), - Result(Arg), -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ParsedSignature { - // The parsed arguments - pub args: Vec<Arg>, - // The argument names - pub names: Vec<String>, - // The parsed return value - pub ret_val: RetVal, - // One and only one lifetime allowed - pub lifetime: Option<String>, - // Generic bounds: each generic must have one and only simple trait bound - pub generic_bounds: BTreeMap<String, String>, -} - -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -enum AttributeModifier { - /// #[serde], for serde_v8 types. - Serde, - /// #[smi], for small integers - Smi, - /// #[string], for strings. - String, -} - -#[derive(Error, Debug)] -pub enum SignatureError { - #[error("Invalid argument: '{0}'")] - ArgError(String, #[source] ArgError), - #[error("Invalid return type")] - RetError(#[from] ArgError), - #[error("Only one lifetime is permitted")] - TooManyLifetimes, - #[error("Generic '{0}' must have one and only bound (either <T> and 'where T: Trait', or <T: Trait>)")] - GenericBoundCardinality(String), - #[error("Where clause predicate '{0}' (eg: where T: Trait) must appear in generics list (eg: <T>)")] - WherePredicateMustAppearInGenerics(String), - #[error("All generics must appear only once in the generics parameter list or where clause")] - DuplicateGeneric(String), - #[error("Generic lifetime '{0}' may not have bounds (eg: <'a: 'b>)")] - LifetimesMayNotHaveBounds(String), - #[error("Invalid generic: '{0}' Only simple generics bounds are allowed (eg: T: Trait)")] - InvalidGeneric(String), - #[error("Invalid predicate: '{0}' Only simple where predicates are allowed (eg: T: Trait)")] - InvalidWherePredicate(String), -} - -#[derive(Error, Debug)] -pub enum ArgError { - #[error("Invalid self argument")] - InvalidSelf, - #[error("Invalid argument type: {0}")] - InvalidType(String), - #[error( - "Invalid argument type path (should this be #[smi] or #[serde]?): {0}" - )] - InvalidTypePath(String), - #[error("Too many attributes")] - TooManyAttributes, - #[error("Invalid #[serde] type: {0}")] - InvalidSerdeType(String), - #[error("Cannot use #[serde] for type: {0}")] - InvalidSerdeAttributeType(String), - #[error("Invalid v8 type: {0}")] - InvalidV8Type(String), - #[error("Internal error: {0}")] - InternalError(String), - #[error("Missing a #[string] attribute")] - MissingStringAttribute, -} - -#[derive(Copy, Clone, Default)] -struct Attributes { - primary: Option<AttributeModifier>, -} - -fn stringify_token(tokens: impl ToTokens) -> String { - tokens - .into_token_stream() - .into_iter() - .map(|s| s.to_string()) - .collect::<Vec<_>>() - .join("") -} - -pub fn parse_signature( - attributes: Vec<Attribute>, - signature: Signature, -) -> Result<ParsedSignature, SignatureError> { - let mut args = vec![]; - let mut names = vec![]; - for input in signature.inputs { - let name = match &input { - FnArg::Receiver(_) => "self".to_owned(), - FnArg::Typed(ty) => match &*ty.pat { - Pat::Ident(ident) => ident.ident.to_string(), - _ => "(complex)".to_owned(), - }, - }; - names.push(name.clone()); - args.push( - parse_arg(input).map_err(|err| SignatureError::ArgError(name, err))?, - ); - } - let ret_val = - parse_return(parse_attributes(&attributes)?, &signature.output)?; - let lifetime = parse_lifetime(&signature.generics)?; - let generic_bounds = parse_generics(&signature.generics)?; - Ok(ParsedSignature { - args, - names, - ret_val, - lifetime, - generic_bounds, - }) -} - -/// Extract one lifetime from the [`syn2::Generics`], ensuring that the lifetime is valid -/// and has no bounds. -fn parse_lifetime( - generics: &Generics, -) -> Result<Option<String>, SignatureError> { - let mut res = None; - for param in &generics.params { - if let GenericParam::Lifetime(lt) = param { - if !lt.bounds.is_empty() { - return Err(SignatureError::LifetimesMayNotHaveBounds( - lt.lifetime.to_string(), - )); - } - if res.is_some() { - return Err(SignatureError::TooManyLifetimes); - } - res = Some(lt.lifetime.ident.to_string()); - } - } - Ok(res) -} - -/// Parse and validate generics. We require one and only one trait bound for each generic -/// parameter. Tries to sanity check and return reasonable errors for possible signature errors. -fn parse_generics( - generics: &Generics, -) -> Result<BTreeMap<String, String>, SignatureError> { - let mut where_clauses = BTreeMap::new(); - - // First, extract the where clause so we can detect duplicated predicates - if let Some(where_clause) = &generics.where_clause { - for predicate in &where_clause.predicates { - let predicate = predicate.to_token_stream(); - let (generic_name, bound) = std::panic::catch_unwind(|| { - use syn2 as syn; - rules!(predicate => { - ($t:ident : $bound:path) => (t.to_string(), stringify_token(bound)), - }) - }) - .map_err(|_| { - SignatureError::InvalidWherePredicate(predicate.to_string()) - })?; - if where_clauses.insert(generic_name.clone(), bound).is_some() { - return Err(SignatureError::DuplicateGeneric(generic_name)); - } - } - } - - let mut res = BTreeMap::new(); - for param in &generics.params { - if let GenericParam::Type(ty) = param { - let ty = ty.to_token_stream(); - let (name, bound) = std::panic::catch_unwind(|| { - use syn2 as syn; - rules!(ty => { - ($t:ident : $bound:path) => (t.to_string(), Some(stringify_token(bound))), - ($t:ident) => (t.to_string(), None), - }) - }).map_err(|_| SignatureError::InvalidGeneric(ty.to_string()))?; - let bound = match bound { - Some(bound) => { - if where_clauses.contains_key(&name) { - return Err(SignatureError::GenericBoundCardinality(name)); - } - bound - } - None => { - let Some(bound) = where_clauses.remove(&name) else { - return Err(SignatureError::GenericBoundCardinality(name)); - }; - bound - } - }; - if res.contains_key(&name) { - return Err(SignatureError::DuplicateGeneric(name)); - } - res.insert(name, bound); - } - } - if !where_clauses.is_empty() { - return Err(SignatureError::WherePredicateMustAppearInGenerics( - where_clauses.into_keys().next().unwrap(), - )); - } - - Ok(res) -} - -fn parse_attributes(attributes: &[Attribute]) -> Result<Attributes, ArgError> { - let attrs = attributes - .iter() - .filter_map(parse_attribute) - .collect::<Vec<_>>(); - - if attrs.is_empty() { - return Ok(Attributes::default()); - } - if attrs.len() > 1 { - return Err(ArgError::TooManyAttributes); - } - Ok(Attributes { - primary: Some(*attrs.get(0).unwrap()), - }) -} - -fn parse_attribute(attr: &Attribute) -> Option<AttributeModifier> { - let tokens = attr.into_token_stream(); - use syn2 as syn; - std::panic::catch_unwind(|| { - rules!(tokens => { - (#[serde]) => Some(AttributeModifier::Serde), - (#[smi]) => Some(AttributeModifier::Smi), - (#[string]) => Some(AttributeModifier::String), - (#[$_attr:meta]) => None, - }) - }) - .expect("Failed to parse an attribute") -} - -fn parse_return( - attrs: Attributes, - rt: &ReturnType, -) -> Result<RetVal, ArgError> { - match rt { - ReturnType::Default => Ok(RetVal::Infallible(Arg::Void)), - ReturnType::Type(_, ty) => { - let s = stringify_token(ty); - let tokens = ty.into_token_stream(); - use syn2 as syn; - - std::panic::catch_unwind(|| { - rules!(tokens => { - // x::y::Result<Value>, like io::Result and other specialty result types - ($($_package:ident ::)* Result < $ty:ty >) => { - Ok(RetVal::Result(parse_type(attrs, &ty)?)) - } - // x::y::Result<Value, Error> - ($($_package:ident ::)* Result < $ty:ty, $_error:ty >) => { - Ok(RetVal::Result(parse_type(attrs, &ty)?)) - } - ($ty:ty) => { - Ok(RetVal::Infallible(parse_type(attrs, &ty)?)) - } - }) - }) - .map_err(|e| { - ArgError::InternalError(format!( - "parse_return({}) {}", - s, - e.downcast::<&str>().unwrap_or_default() - )) - })? - } - } -} - -fn parse_type_path(attrs: Attributes, tp: &TypePath) -> Result<Arg, ArgError> { - if tp.path.segments.len() == 1 { - let segment = tp.path.segments.first().unwrap().ident.to_string(); - for numeric in NumericArg::iter() { - if Into::<&'static str>::into(numeric) == segment.as_str() { - return Ok(Arg::Numeric(numeric)); - } - } - } - - use syn2 as syn; - - let tokens = tp.clone().into_token_stream(); - std::panic::catch_unwind(|| { - rules!(tokens => { - ( $( std :: str :: )? String ) => { - if attrs.primary == Some(AttributeModifier::String) { - Ok(Arg::Special(Special::String)) - } else { - Err(ArgError::MissingStringAttribute) - } - } - ( $( std :: str :: )? str ) => { - // We should not hit this path with a #[string] argument - Err(ArgError::MissingStringAttribute) - } - ( $( std :: borrow :: )? Cow < str > ) => { - if attrs.primary == Some(AttributeModifier::String) { - Ok(Arg::Special(Special::CowStr)) - } else { - Err(ArgError::MissingStringAttribute) - } - } - ( $( std :: ffi :: )? c_void ) => Ok(Arg::Numeric(NumericArg::__VOID__)), - ( OpState ) => Ok(Arg::Special(Special::OpState)), - ( v8 :: HandleScope ) => Ok(Arg::Special(Special::HandleScope)), - ( v8 :: FastApiCallbackOptions ) => Ok(Arg::Special(Special::FastApiCallbackOptions)), - ( v8 :: Local < $( $_scope:lifetime , )? v8 :: $v8:ident >) => Ok(Arg::V8Local(parse_v8_type(&v8)?)), - ( Rc < RefCell < $ty:ty > > ) => Ok(Arg::RcRefCell(parse_type_special(attrs, &ty)?)), - ( Option < $ty:ty > ) => { - match parse_type(attrs, &ty)? { - Arg::Special(special) => Ok(Arg::Option(special)), - Arg::Numeric(numeric) => Ok(Arg::OptionNumeric(numeric)), - _ => Err(ArgError::InvalidType(stringify_token(ty))) - } - } - ( $any:ty ) => Err(ArgError::InvalidTypePath(stringify_token(any))), - }) - }).map_err(|e| ArgError::InternalError(format!("parse_type_path {e:?}")))? -} - -fn parse_v8_type(v8: &Ident) -> Result<V8Arg, ArgError> { - let v8 = v8.to_string(); - V8Arg::try_from(v8.as_str()).map_err(|_| ArgError::InvalidV8Type(v8)) -} - -fn parse_type_special( - attrs: Attributes, - ty: &Type, -) -> Result<Special, ArgError> { - match parse_type(attrs, ty)? { - Arg::Special(special) => Ok(special), - _ => Err(ArgError::InvalidType(stringify_token(ty))), - } -} - -fn parse_type(attrs: Attributes, ty: &Type) -> Result<Arg, ArgError> { - if let Some(primary) = attrs.primary { - match primary { - AttributeModifier::Serde => match ty { - Type::Path(of) => { - // If this type will parse without #[serde], it is illegal to use this type with #[serde] - if parse_type_path(Attributes::default(), of).is_ok() { - return Err(ArgError::InvalidSerdeAttributeType(stringify_token( - ty, - ))); - } - return Ok(Arg::SerdeV8(stringify_token(of.path.clone()))); - } - _ => return Err(ArgError::InvalidSerdeType(stringify_token(ty))), - }, - AttributeModifier::String => match ty { - Type::Path(of) => { - return parse_type_path(attrs, of); - } - Type::Reference(of) => { - let mut_type = if of.mutability.is_some() { - RefType::Mut - } else { - RefType::Ref - }; - let tokens = of.elem.clone().into_token_stream(); - use syn2 as syn; - return rules!(tokens => { - (str) => Ok(Arg::Special(Special::RefStr)), - ($_ty:ty) => Ok(Arg::Ref(mut_type, parse_type_special(attrs, &of.elem)?)), - }); - } - _ => return Err(ArgError::InvalidSerdeType(stringify_token(ty))), - }, - AttributeModifier::Smi => { - return Ok(Arg::Numeric(NumericArg::__SMI__)); - } - } - }; - match ty { - Type::Tuple(of) => { - if of.elems.is_empty() { - Ok(Arg::Void) - } else { - Err(ArgError::InvalidType(stringify_token(ty))) - } - } - Type::Reference(of) => { - let mut_type = if of.mutability.is_some() { - RefType::Mut - } else { - RefType::Ref - }; - match &*of.elem { - Type::Slice(of) => match parse_type(attrs, &of.elem)? { - Arg::Numeric(numeric) => Ok(Arg::Slice(mut_type, numeric)), - _ => Err(ArgError::InvalidType(stringify_token(ty))), - }, - Type::Path(of) => match parse_type_path(attrs, of)? { - Arg::Special(special) => Ok(Arg::Ref(mut_type, special)), - _ => Err(ArgError::InvalidType(stringify_token(ty))), - }, - _ => Err(ArgError::InvalidType(stringify_token(ty))), - } - } - Type::Ptr(of) => { - let mut_type = if of.mutability.is_some() { - RefType::Mut - } else { - RefType::Ref - }; - match &*of.elem { - Type::Path(of) => match parse_type_path(attrs, of)? { - Arg::Numeric(numeric) => Ok(Arg::Ptr(mut_type, numeric)), - _ => Err(ArgError::InvalidType(stringify_token(ty))), - }, - _ => Err(ArgError::InvalidType(stringify_token(ty))), - } - } - Type::Path(of) => parse_type_path(attrs, of), - _ => Err(ArgError::InvalidType(stringify_token(ty))), - } -} - -fn parse_arg(arg: FnArg) -> Result<Arg, ArgError> { - let FnArg::Typed(typed) = arg else { - return Err(ArgError::InvalidSelf); - }; - parse_type(parse_attributes(&typed.attrs)?, &typed.ty) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::op2::signature::parse_signature; - use syn2::parse_str; - use syn2::ItemFn; - - // We can't test pattern args :/ - // https://github.com/rust-lang/rfcs/issues/2688 - macro_rules! test { - ( - // Function attributes - $(# [ $fn_attr:ident ])? - // fn name < 'scope, GENERIC1, GENERIC2, ... > - fn $name:ident $( < $scope:lifetime $( , $generic:ident)* >)? - ( - // Argument attribute, argument - $( $(# [ $attr:ident ])? $ident:ident : $ty:ty ),* - ) - // Return value - $(-> $(# [ $ret_attr:ident ])? $ret:ty)? - // Where clause - $( where $($trait:ident : $bounds:path),* )? - ; - // Expected return value - $( < $( $lifetime_res:lifetime )? $(, $generic_res:ident : $bounds_res:path )* >)? ( $( $arg_res:expr ),* ) -> $ret_res:expr ) => { - #[test] - fn $name() { - test( - stringify!($( #[$fn_attr] )? fn op $( < $scope $( , $generic)* >)? ( $( $( #[$attr] )? $ident : $ty ),* ) $(-> $( #[$ret_attr] )? $ret)? $( where $($trait : $bounds),* )? {}), - stringify!($( < $( $lifetime_res )? $(, $generic_res : $bounds_res)* > )?), - stringify!($($arg_res),*), - stringify!($ret_res) - ); - } - }; - } - - fn test( - op: &str, - generics_expected: &str, - args_expected: &str, - return_expected: &str, - ) { - // Parse the provided macro input as an ItemFn - let item_fn = parse_str::<ItemFn>(op) - .unwrap_or_else(|_| panic!("Failed to parse {op} as a ItemFn")); - - let attrs = item_fn.attrs; - let sig = parse_signature(attrs, item_fn.sig).unwrap_or_else(|err| { - panic!("Failed to successfully parse signature from {op} ({err:?})") - }); - println!("Raw parsed signatures = {sig:?}"); - - let mut generics_res = vec![]; - if let Some(lifetime) = sig.lifetime { - generics_res.push(format!("'{lifetime}")); - } - for (name, bounds) in sig.generic_bounds { - generics_res.push(format!("{name} : {bounds}")); - } - if !generics_res.is_empty() { - assert_eq!( - generics_expected, - format!("< {} >", generics_res.join(", ")) - ); - } - assert_eq!( - args_expected, - format!("{:?}", sig.args).trim_matches(|c| c == '[' || c == ']') - ); - assert_eq!(return_expected, format!("{:?}", sig.ret_val)); - } - - macro_rules! expect_fail { - ($name:ident, $error:expr, $f:item) => { - #[test] - pub fn $name() { - expect_fail(stringify!($f), stringify!($error)); - } - }; - } - - fn expect_fail(op: &str, error: &str) { - // Parse the provided macro input as an ItemFn - let item_fn = parse_str::<ItemFn>(op) - .unwrap_or_else(|_| panic!("Failed to parse {op} as a ItemFn")); - let attrs = item_fn.attrs; - let err = parse_signature(attrs, item_fn.sig) - .expect_err("Expected function to fail to parse"); - assert_eq!(format!("{err:?}"), error.to_owned()); - } - - test!( - fn op_state_and_number(opstate: &mut OpState, a: u32) -> (); - (Ref(Mut, OpState), Numeric(u32)) -> Infallible(Void) - ); - test!( - fn op_slices(r#in: &[u8], out: &mut [u8]); - (Slice(Ref, u8), Slice(Mut, u8)) -> Infallible(Void) - ); - test!( - #[serde] fn op_serde(#[serde] input: package::SerdeInputType) -> Result<package::SerdeReturnType, Error>; - (SerdeV8("package::SerdeInputType")) -> Result(SerdeV8("package::SerdeReturnType")) - ); - test!( - fn op_local(input: v8::Local<v8::String>) -> Result<v8::Local<v8::String>, Error>; - (V8Local(String)) -> Result(V8Local(String)) - ); - test!( - fn op_resource(#[smi] rid: ResourceId, buffer: &[u8]); - (Numeric(__SMI__), Slice(Ref, u8)) -> Infallible(Void) - ); - test!( - fn op_option_numeric_result(state: &mut OpState) -> Result<Option<u32>, AnyError>; - (Ref(Mut, OpState)) -> Result(OptionNumeric(u32)) - ); - test!( - fn op_ffi_read_f64(state: &mut OpState, ptr: * mut c_void, offset: isize) -> Result <f64, AnyError>; - (Ref(Mut, OpState), Ptr(Mut, __VOID__), Numeric(isize)) -> Result(Numeric(f64)) - ); - test!( - fn op_print(#[string] msg: &str, is_err: bool) -> Result<(), Error>; - (Special(RefStr), Numeric(bool)) -> Result(Void) - ); - test!( - fn op_scope<'s>(#[string] msg: &'s str); - <'s> (Special(RefStr)) -> Infallible(Void) - ); - test!( - fn op_scope_and_generics<'s, AB, BC>(#[string] msg: &'s str) where AB: some::Trait, BC: OtherTrait; - <'s, AB: some::Trait, BC: OtherTrait> (Special(RefStr)) -> Infallible(Void) - ); - - expect_fail!(op_with_two_lifetimes, TooManyLifetimes, fn f<'a, 'b>() {}); - expect_fail!( - op_with_lifetime_bounds, - LifetimesMayNotHaveBounds("'a"), - fn f<'a: 'b, 'b>() {} - ); - expect_fail!( - op_with_missing_bounds, - GenericBoundCardinality("B"), - fn f<'a, B>() {} - ); - expect_fail!( - op_with_duplicate_bounds, - GenericBoundCardinality("B"), - fn f<'a, B: Trait>() - where - B: Trait, - { - } - ); - expect_fail!( - op_with_extra_bounds, - WherePredicateMustAppearInGenerics("C"), - fn f<'a, B>() - where - B: Trait, - C: Trait, - { - } - ); - - #[test] - fn test_parse_result() { - let rt = parse_str::<ReturnType>("-> Result < (), Error >") - .expect("Failed to parse"); - println!("{:?}", parse_return(Attributes::default(), &rt)); - } -} diff --git a/ops/op2/test_cases/sync/add.out b/ops/op2/test_cases/sync/add.out deleted file mode 100644 index a73f032aa..000000000 --- a/ops/op2/test_cases/sync/add.out +++ /dev/null @@ -1,78 +0,0 @@ -#[allow(non_camel_case_types)] -struct op_add { - _unconstructable: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_add { - const NAME: &'static str = stringify!(op_add); - const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl { - name: stringify!(op_add), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::Uint32, Type::Uint32], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - }; -} -impl op_add { - pub const fn name() -> &'static str { - stringify!(op_add) - } - pub const fn decl() -> deno_core::_ops::OpDecl { - deno_core::_ops::OpDecl { - name: stringify!(op_add), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::Uint32, Type::Uint32], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - fn v8_fn_ptr_fast( - _: deno_core::v8::Local<deno_core::v8::Object>, - arg0: u32, - arg1: u32, - ) -> u32 { - let arg0 = arg0 as _; - let arg1 = arg1 as _; - let result = Self::call(arg0, arg1); - result - } - extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let mut rv = deno_core::v8::ReturnValue::from_function_callback_info(unsafe { - &*info - }); - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let arg0 = args.get(0usize as i32); - let arg0 = deno_core::_ops::to_u32(&arg0) as _; - let arg1 = args.get(1usize as i32); - let arg1 = deno_core::_ops::to_u32(&arg1) as _; - let result = Self::call(arg0, arg1); - rv.set_uint32(result as u32); - } - #[inline(always)] - fn call(a: u32, b: u32) -> u32 { - a + b - } -} diff --git a/ops/op2/test_cases/sync/add.rs b/ops/op2/test_cases/sync/add.rs deleted file mode 100644 index 74dbb1893..000000000 --- a/ops/op2/test_cases/sync/add.rs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -#[op2(fast)] -fn op_add(a: u32, b: u32) -> u32 { - a + b -} diff --git a/ops/op2/test_cases/sync/add_options.out b/ops/op2/test_cases/sync/add_options.out deleted file mode 100644 index 9fada187f..000000000 --- a/ops/op2/test_cases/sync/add_options.out +++ /dev/null @@ -1,57 +0,0 @@ -#[allow(non_camel_case_types)] -pub struct op_test_add_option { - _unconstructable: ::std::marker::PhantomData<()>, -} -impl crate::_ops::Op for op_test_add_option { - const NAME: &'static str = stringify!(op_test_add_option); - const DECL: crate::_ops::OpDecl = crate::_ops::OpDecl { - name: stringify!(op_test_add_option), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - }; -} -impl op_test_add_option { - pub const fn name() -> &'static str { - stringify!(op_test_add_option) - } - pub const fn decl() -> crate::_ops::OpDecl { - crate::_ops::OpDecl { - name: stringify!(op_test_add_option), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - extern "C" fn v8_fn_ptr(info: *const crate::v8::FunctionCallbackInfo) { - let mut rv = crate::v8::ReturnValue::from_function_callback_info(unsafe { - &*info - }); - let args = crate::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let arg0 = args.get(0usize as i32); - let arg0 = crate::_ops::to_u32(&arg0) as _; - let arg1 = args.get(1usize as i32); - let arg1 = if arg1.is_null_or_undefined() { - None - } else { - let arg1 = crate::_ops::to_u32(&arg1) as _; - Some(arg1) - }; - let result = Self::call(arg0, arg1); - rv.set_uint32(result as u32); - } - #[inline(always)] - pub fn call(a: u32, b: Option<u32>) -> u32 { - a + b.unwrap_or(100) - } -} diff --git a/ops/op2/test_cases/sync/add_options.rs b/ops/op2/test_cases/sync/add_options.rs deleted file mode 100644 index a5f2c8f4a..000000000 --- a/ops/op2/test_cases/sync/add_options.rs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -#[op2(core)] -pub fn op_test_add_option(a: u32, b: Option<u32>) -> u32 { - a + b.unwrap_or(100) -} diff --git a/ops/op2/test_cases/sync/doc_comment.out b/ops/op2/test_cases/sync/doc_comment.out deleted file mode 100644 index d7e8005d9..000000000 --- a/ops/op2/test_cases/sync/doc_comment.out +++ /dev/null @@ -1,59 +0,0 @@ -#[allow(non_camel_case_types)] -pub struct op_has_doc_comment { - _unconstructable: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_has_doc_comment { - const NAME: &'static str = stringify!(op_has_doc_comment); - const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl { - name: stringify!(op_has_doc_comment), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value], - CType::Void, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - }; -} -impl op_has_doc_comment { - pub const fn name() -> &'static str { - stringify!(op_has_doc_comment) - } - pub const fn decl() -> deno_core::_ops::OpDecl { - deno_core::_ops::OpDecl { - name: stringify!(op_has_doc_comment), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value], - CType::Void, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - } - } - fn v8_fn_ptr_fast(_: deno_core::v8::Local<deno_core::v8::Object>) -> () { - let result = Self::call(); - result - } - extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let result = Self::call(); - } - #[inline(always)] - pub fn call() -> () {} -} diff --git a/ops/op2/test_cases/sync/doc_comment.rs b/ops/op2/test_cases/sync/doc_comment.rs deleted file mode 100644 index b729a64bd..000000000 --- a/ops/op2/test_cases/sync/doc_comment.rs +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -/// This is a doc comment. -#[op2(fast)] -pub fn op_has_doc_comment() -> () {} diff --git a/ops/op2/test_cases/sync/generics.out b/ops/op2/test_cases/sync/generics.out deleted file mode 100644 index 26e3af9b7..000000000 --- a/ops/op2/test_cases/sync/generics.out +++ /dev/null @@ -1,59 +0,0 @@ -#[allow(non_camel_case_types)] -pub struct op_generics<T> { - _unconstructable: ::std::marker::PhantomData<(T)>, -} -impl<T: Trait> deno_core::_ops::Op for op_generics<T> { - const NAME: &'static str = stringify!(op_generics); - const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl { - name: stringify!(op_generics), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value], - CType::Void, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - }; -} -impl<T: Trait> op_generics<T> { - pub const fn name() -> &'static str { - stringify!(op_generics) - } - pub const fn decl() -> deno_core::_ops::OpDecl { - deno_core::_ops::OpDecl { - name: stringify!(op_generics), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value], - CType::Void, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - } - } - fn v8_fn_ptr_fast(_: deno_core::v8::Local<deno_core::v8::Object>) -> () { - let result = Self::call(); - result - } - extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let result = Self::call(); - } - #[inline(always)] - pub fn call() {} -} diff --git a/ops/op2/test_cases/sync/generics.rs b/ops/op2/test_cases/sync/generics.rs deleted file mode 100644 index b412a7f93..000000000 --- a/ops/op2/test_cases/sync/generics.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -#[op2(fast)] -pub fn op_generics<T: Trait>() {} diff --git a/ops/op2/test_cases/sync/result_primitive.out b/ops/op2/test_cases/sync/result_primitive.out deleted file mode 100644 index 4f296a893..000000000 --- a/ops/op2/test_cases/sync/result_primitive.out +++ /dev/null @@ -1,122 +0,0 @@ -#[allow(non_camel_case_types)] -pub struct op_u32_with_result { - _unconstructable: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_u32_with_result { - const NAME: &'static str = stringify!(op_u32_with_result); - const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl { - name: stringify!(op_u32_with_result), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::CallbackOptions], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - }; -} -impl op_u32_with_result { - pub const fn name() -> &'static str { - stringify!(op_u32_with_result) - } - pub const fn decl() -> deno_core::_ops::OpDecl { - deno_core::_ops::OpDecl { - name: stringify!(op_u32_with_result), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::CallbackOptions], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - } - } - fn v8_fn_ptr_fast( - _: deno_core::v8::Local<deno_core::v8::Object>, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> u32 { - let fast_api_callback_options = unsafe { &mut *fast_api_callback_options }; - let opctx = unsafe { - &*(deno_core::v8::Local::< - v8::External, - >::cast(unsafe { fast_api_callback_options.data.data }) - .value() as *const deno_core::_ops::OpCtx) - }; - let result = Self::call(); - let result = match result { - Ok(result) => result, - Err(err) => { - unsafe { - opctx.unsafely_set_last_error_for_ops_only(err); - } - fast_api_callback_options.fallback = true; - return ::std::default::Default::default(); - } - }; - result - } - extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let mut rv = deno_core::v8::ReturnValue::from_function_callback_info(unsafe { - &*info - }); - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let opctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - if let Some(err) = unsafe { opctx.unsafely_take_last_error_for_ops_only() } { - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(&*info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let opstate = ::std::cell::RefCell::borrow(&*opctx.state); - let exception = deno_core::error::to_v8_error( - scope, - opstate.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - return; - } - let result = Self::call(); - match result { - Ok(result) => { - rv.set_uint32(result as u32); - } - Err(err) => { - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(&*info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let opstate = ::std::cell::RefCell::borrow(&*opctx.state); - let exception = deno_core::error::to_v8_error( - scope, - opstate.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - return; - } - }; - } - #[inline(always)] - pub fn call() -> Result<u32, AnyError> {} -} diff --git a/ops/op2/test_cases/sync/result_primitive.rs b/ops/op2/test_cases/sync/result_primitive.rs deleted file mode 100644 index df89c2432..000000000 --- a/ops/op2/test_cases/sync/result_primitive.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -#[op2(fast)] -pub fn op_u32_with_result() -> Result<u32, AnyError> {} diff --git a/ops/op2/test_cases/sync/result_void.out b/ops/op2/test_cases/sync/result_void.out deleted file mode 100644 index 74aa84a8d..000000000 --- a/ops/op2/test_cases/sync/result_void.out +++ /dev/null @@ -1,117 +0,0 @@ -#[allow(non_camel_case_types)] -pub struct op_void_with_result { - _unconstructable: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_void_with_result { - const NAME: &'static str = stringify!(op_void_with_result); - const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl { - name: stringify!(op_void_with_result), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::CallbackOptions], - CType::Void, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - }; -} -impl op_void_with_result { - pub const fn name() -> &'static str { - stringify!(op_void_with_result) - } - pub const fn decl() -> deno_core::_ops::OpDecl { - deno_core::_ops::OpDecl { - name: stringify!(op_void_with_result), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::CallbackOptions], - CType::Void, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - } - } - fn v8_fn_ptr_fast( - _: deno_core::v8::Local<deno_core::v8::Object>, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - let fast_api_callback_options = unsafe { &mut *fast_api_callback_options }; - let opctx = unsafe { - &*(deno_core::v8::Local::< - v8::External, - >::cast(unsafe { fast_api_callback_options.data.data }) - .value() as *const deno_core::_ops::OpCtx) - }; - let result = Self::call(); - let result = match result { - Ok(result) => result, - Err(err) => { - unsafe { - opctx.unsafely_set_last_error_for_ops_only(err); - } - fast_api_callback_options.fallback = true; - return ::std::default::Default::default(); - } - }; - result - } - extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let opctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - if let Some(err) = unsafe { opctx.unsafely_take_last_error_for_ops_only() } { - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(&*info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let opstate = ::std::cell::RefCell::borrow(&*opctx.state); - let exception = deno_core::error::to_v8_error( - scope, - opstate.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - return; - } - let result = Self::call(); - match result { - Ok(result) => {} - Err(err) => { - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(&*info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let opstate = ::std::cell::RefCell::borrow(&*opctx.state); - let exception = deno_core::error::to_v8_error( - scope, - opstate.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - return; - } - }; - } - #[inline(always)] - pub fn call() -> Result<(), AnyError> {} -} diff --git a/ops/op2/test_cases/sync/result_void.rs b/ops/op2/test_cases/sync/result_void.rs deleted file mode 100644 index ef3aa7b32..000000000 --- a/ops/op2/test_cases/sync/result_void.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -#[op2(fast)] -pub fn op_void_with_result() -> Result<(), AnyError> {} diff --git a/ops/op2/test_cases/sync/smi.out b/ops/op2/test_cases/sync/smi.out deleted file mode 100644 index 24b81ae47..000000000 --- a/ops/op2/test_cases/sync/smi.out +++ /dev/null @@ -1,76 +0,0 @@ -#[allow(non_camel_case_types)] -struct op_add { - _unconstructable: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_add { - const NAME: &'static str = stringify!(op_add); - const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl { - name: stringify!(op_add), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::Int32, Type::Uint32], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - }; -} -impl op_add { - pub const fn name() -> &'static str { - stringify!(op_add) - } - pub const fn decl() -> deno_core::_ops::OpDecl { - deno_core::_ops::OpDecl { - name: stringify!(op_add), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::Int32, Type::Uint32], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - fn v8_fn_ptr_fast( - _: deno_core::v8::Local<deno_core::v8::Object>, - arg0: i32, - arg1: u32, - ) -> u32 { - let arg0 = arg0 as _; - let arg1 = arg1 as _; - let result = Self::call(arg0, arg1); - result - } - extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let mut rv = deno_core::v8::ReturnValue::from_function_callback_info(unsafe { - &*info - }); - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let arg0 = args.get(0usize as i32); - let arg0 = deno_core::_ops::to_i32(&arg0) as _; - let arg1 = args.get(1usize as i32); - let arg1 = deno_core::_ops::to_u32(&arg1) as _; - let result = Self::call(arg0, arg1); - rv.set_uint32(result as u32); - } - #[inline(always)] - fn call(id: ResourceId, extra: u16) -> u32 {} -} diff --git a/ops/op2/test_cases/sync/smi.rs b/ops/op2/test_cases/sync/smi.rs deleted file mode 100644 index a5a441845..000000000 --- a/ops/op2/test_cases/sync/smi.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -#[op2(fast)] -fn op_add(#[smi] id: ResourceId, extra: u16) -> u32 {} diff --git a/ops/op2/test_cases/sync/string_cow.out b/ops/op2/test_cases/sync/string_cow.out deleted file mode 100644 index 7d388e598..000000000 --- a/ops/op2/test_cases/sync/string_cow.out +++ /dev/null @@ -1,75 +0,0 @@ -#[allow(non_camel_case_types)] -struct op_string_cow { - _unconstructable: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_string_cow { - const NAME: &'static str = stringify!(op_string_cow); - const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl { - name: stringify!(op_string_cow), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::SeqOneByteString], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - }; -} -impl op_string_cow { - pub const fn name() -> &'static str { - stringify!(op_string_cow) - } - pub const fn decl() -> deno_core::_ops::OpDecl { - deno_core::_ops::OpDecl { - name: stringify!(op_string_cow), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::SeqOneByteString], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - fn v8_fn_ptr_fast( - _: deno_core::v8::Local<deno_core::v8::Object>, - arg0: *mut deno_core::v8::fast_api::FastApiOneByteString, - ) -> u32 { - let mut arg0_temp: [::std::mem::MaybeUninit<u8>; 1024] = [::std::mem::MaybeUninit::uninit(); 1024]; - let arg0 = deno_core::_ops::to_str_ptr(unsafe { &mut *arg0 }, &mut arg0_temp); - let result = Self::call(arg0); - result - } - extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(&*info) }; - let mut rv = deno_core::v8::ReturnValue::from_function_callback_info(unsafe { - &*info - }); - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let arg0 = args.get(0usize as i32); - let mut arg0_temp: [::std::mem::MaybeUninit<u8>; 1024] = [::std::mem::MaybeUninit::uninit(); 1024]; - let arg0 = deno_core::_ops::to_str(scope, &arg0, &mut arg0_temp); - let result = Self::call(arg0); - rv.set_uint32(result as u32); - } - #[inline(always)] - fn call(s: Cow<str>) -> u32 {} -} diff --git a/ops/op2/test_cases/sync/string_cow.rs b/ops/op2/test_cases/sync/string_cow.rs deleted file mode 100644 index ed4dfca82..000000000 --- a/ops/op2/test_cases/sync/string_cow.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -#[op2(fast)] -fn op_string_cow(#[string] s: Cow<str>) -> u32 {} diff --git a/ops/op2/test_cases/sync/string_option_return.out b/ops/op2/test_cases/sync/string_option_return.out deleted file mode 100644 index 6143ac217..000000000 --- a/ops/op2/test_cases/sync/string_option_return.out +++ /dev/null @@ -1,53 +0,0 @@ -#[allow(non_camel_case_types)] -pub struct op_string_return { - _unconstructable: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_string_return { - const NAME: &'static str = stringify!(op_string_return); - const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl { - name: stringify!(op_string_return), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - }; -} -impl op_string_return { - pub const fn name() -> &'static str { - stringify!(op_string_return) - } - pub const fn decl() -> deno_core::_ops::OpDecl { - deno_core::_ops::OpDecl { - name: stringify!(op_string_return), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - } - } - extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(&*info) }; - let mut rv = deno_core::v8::ReturnValue::from_function_callback_info(unsafe { - &*info - }); - let result = Self::call(); - if let Some(result) = result { - if result.is_empty() { - rv.set_empty_string(); - } else { - let temp = deno_core::v8::String::new(scope, &result).unwrap(); - rv.set(temp.into()); - } - } else { - rv.set_null(); - } - } - #[inline(always)] - pub fn call() -> Option<String> {} -} diff --git a/ops/op2/test_cases/sync/string_option_return.rs b/ops/op2/test_cases/sync/string_option_return.rs deleted file mode 100644 index 932836d2f..000000000 --- a/ops/op2/test_cases/sync/string_option_return.rs +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -#[op2] -#[string] -pub fn op_string_return() -> Option<String> {} diff --git a/ops/op2/test_cases/sync/string_owned.out b/ops/op2/test_cases/sync/string_owned.out deleted file mode 100644 index 7418a311c..000000000 --- a/ops/op2/test_cases/sync/string_owned.out +++ /dev/null @@ -1,73 +0,0 @@ -#[allow(non_camel_case_types)] -struct op_string_owned { - _unconstructable: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_string_owned { - const NAME: &'static str = stringify!(op_string_owned); - const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl { - name: stringify!(op_string_owned), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::SeqOneByteString], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - }; -} -impl op_string_owned { - pub const fn name() -> &'static str { - stringify!(op_string_owned) - } - pub const fn decl() -> deno_core::_ops::OpDecl { - deno_core::_ops::OpDecl { - name: stringify!(op_string_owned), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::SeqOneByteString], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - fn v8_fn_ptr_fast( - _: deno_core::v8::Local<deno_core::v8::Object>, - arg0: *mut deno_core::v8::fast_api::FastApiOneByteString, - ) -> u32 { - let arg0 = deno_core::_ops::to_string_ptr(unsafe { &mut *arg0 }); - let result = Self::call(arg0); - result - } - extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(&*info) }; - let mut rv = deno_core::v8::ReturnValue::from_function_callback_info(unsafe { - &*info - }); - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let arg0 = args.get(0usize as i32); - let arg0 = arg0.to_rust_string_lossy(scope); - let result = Self::call(arg0); - rv.set_uint32(result as u32); - } - #[inline(always)] - fn call(s: String) -> u32 {} -} diff --git a/ops/op2/test_cases/sync/string_owned.rs b/ops/op2/test_cases/sync/string_owned.rs deleted file mode 100644 index b81d7ece9..000000000 --- a/ops/op2/test_cases/sync/string_owned.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -#[op2(fast)] -fn op_string_owned(#[string] s: String) -> u32 {} diff --git a/ops/op2/test_cases/sync/string_ref.out b/ops/op2/test_cases/sync/string_ref.out deleted file mode 100644 index 1b853fccc..000000000 --- a/ops/op2/test_cases/sync/string_ref.out +++ /dev/null @@ -1,75 +0,0 @@ -#[allow(non_camel_case_types)] -struct op_string_owned { - _unconstructable: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_string_owned { - const NAME: &'static str = stringify!(op_string_owned); - const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl { - name: stringify!(op_string_owned), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::SeqOneByteString], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - }; -} -impl op_string_owned { - pub const fn name() -> &'static str { - stringify!(op_string_owned) - } - pub const fn decl() -> deno_core::_ops::OpDecl { - deno_core::_ops::OpDecl { - name: stringify!(op_string_owned), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: Some({ - use deno_core::v8::fast_api::Type; - use deno_core::v8::fast_api::CType; - deno_core::v8::fast_api::FastFunction::new( - &[Type::V8Value, Type::SeqOneByteString], - CType::Uint32, - Self::v8_fn_ptr_fast as *const ::std::ffi::c_void, - ) - }), - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - fn v8_fn_ptr_fast( - _: deno_core::v8::Local<deno_core::v8::Object>, - arg0: *mut deno_core::v8::fast_api::FastApiOneByteString, - ) -> u32 { - let mut arg0_temp: [::std::mem::MaybeUninit<u8>; 1024] = [::std::mem::MaybeUninit::uninit(); 1024]; - let arg0 = &deno_core::_ops::to_str_ptr(unsafe { &mut *arg0 }, &mut arg0_temp); - let result = Self::call(arg0); - result - } - extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(&*info) }; - let mut rv = deno_core::v8::ReturnValue::from_function_callback_info(unsafe { - &*info - }); - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info(unsafe { - &*info - }); - let arg0 = args.get(0usize as i32); - let mut arg0_temp: [::std::mem::MaybeUninit<u8>; 1024] = [::std::mem::MaybeUninit::uninit(); 1024]; - let arg0 = &deno_core::_ops::to_str(scope, &arg0, &mut arg0_temp); - let result = Self::call(arg0); - rv.set_uint32(result as u32); - } - #[inline(always)] - fn call(s: &str) -> u32 {} -} diff --git a/ops/op2/test_cases/sync/string_ref.rs b/ops/op2/test_cases/sync/string_ref.rs deleted file mode 100644 index a7efa9f0c..000000000 --- a/ops/op2/test_cases/sync/string_ref.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -#[op2(fast)] -fn op_string_owned(#[string] s: &str) -> u32 {} diff --git a/ops/op2/test_cases/sync/string_return.out b/ops/op2/test_cases/sync/string_return.out deleted file mode 100644 index 5e68b9314..000000000 --- a/ops/op2/test_cases/sync/string_return.out +++ /dev/null @@ -1,49 +0,0 @@ -#[allow(non_camel_case_types)] -pub struct op_string_return { - _unconstructable: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_string_return { - const NAME: &'static str = stringify!(op_string_return); - const DECL: deno_core::_ops::OpDecl = deno_core::_ops::OpDecl { - name: stringify!(op_string_return), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - }; -} -impl op_string_return { - pub const fn name() -> &'static str { - stringify!(op_string_return) - } - pub const fn decl() -> deno_core::_ops::OpDecl { - deno_core::_ops::OpDecl { - name: stringify!(op_string_return), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - } - } - extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(&*info) }; - let mut rv = deno_core::v8::ReturnValue::from_function_callback_info(unsafe { - &*info - }); - let result = Self::call(); - if result.is_empty() { - rv.set_empty_string(); - } else { - let temp = deno_core::v8::String::new(scope, &result).unwrap(); - rv.set(temp.into()); - } - } - #[inline(always)] - pub fn call() -> String {} -} diff --git a/ops/op2/test_cases/sync/string_return.rs b/ops/op2/test_cases/sync/string_return.rs deleted file mode 100644 index 667b68a14..000000000 --- a/ops/op2/test_cases/sync/string_return.rs +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -#[op2] -#[string] -pub fn op_string_return() -> String {} diff --git a/ops/optimizer.rs b/ops/optimizer.rs deleted file mode 100644 index 28911162f..000000000 --- a/ops/optimizer.rs +++ /dev/null @@ -1,1004 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -//! Optimizer for #[op] - -use std::collections::BTreeMap; -use std::fmt::Debug; -use std::fmt::Formatter; - -use pmutil::q; -use pmutil::Quote; -use proc_macro2::TokenStream; - -use syn::parse_quote; -use syn::punctuated::Punctuated; -use syn::token::Colon2; -use syn::AngleBracketedGenericArguments; -use syn::FnArg; -use syn::GenericArgument; -use syn::PatType; -use syn::Path; -use syn::PathArguments; -use syn::PathSegment; -use syn::ReturnType; -use syn::Signature; -use syn::Type; -use syn::TypePath; -use syn::TypePtr; -use syn::TypeReference; -use syn::TypeSlice; -use syn::TypeTuple; - -use crate::Op; - -#[derive(Debug)] -pub(crate) enum BailoutReason { - // Recoverable errors - MustBeSingleSegment, - FastUnsupportedParamType, -} - -#[derive(Debug, PartialEq)] -enum StringType { - Cow, - Ref, - Owned, -} - -#[derive(Debug, PartialEq)] -enum TransformKind { - // serde_v8::Value - V8Value, - SliceU32(bool), - SliceU8(bool), - SliceF64(bool), - SeqOneByteString(StringType), - PtrU8, - PtrVoid, - WasmMemory, -} - -impl Transform { - fn serde_v8_value(index: usize) -> Self { - Transform { - kind: TransformKind::V8Value, - index, - } - } - - fn slice_u32(index: usize, is_mut: bool) -> Self { - Transform { - kind: TransformKind::SliceU32(is_mut), - index, - } - } - - fn slice_u8(index: usize, is_mut: bool) -> Self { - Transform { - kind: TransformKind::SliceU8(is_mut), - index, - } - } - - fn slice_f64(index: usize, is_mut: bool) -> Self { - Transform { - kind: TransformKind::SliceF64(is_mut), - index, - } - } - - fn seq_one_byte_string(index: usize, is_ref: StringType) -> Self { - Transform { - kind: TransformKind::SeqOneByteString(is_ref), - index, - } - } - - fn wasm_memory(index: usize) -> Self { - Transform { - kind: TransformKind::WasmMemory, - index, - } - } - - fn u8_ptr(index: usize) -> Self { - Transform { - kind: TransformKind::PtrU8, - index, - } - } - - fn void_ptr(index: usize) -> Self { - Transform { - kind: TransformKind::PtrVoid, - index, - } - } -} - -#[derive(Debug, PartialEq)] -pub(crate) struct Transform { - kind: TransformKind, - index: usize, -} - -impl Transform { - pub(crate) fn apply_for_fast_call( - &self, - core: &TokenStream, - input: &mut FnArg, - ) -> Quote { - let (ty, ident) = match input { - FnArg::Typed(PatType { - ref mut ty, - ref pat, - .. - }) => { - let ident = match &**pat { - syn::Pat::Ident(ident) => &ident.ident, - _ => unreachable!("error not recovered"), - }; - (ty, ident) - } - _ => unreachable!("error not recovered"), - }; - - match &self.kind { - // serde_v8::Value - TransformKind::V8Value => { - *ty = parse_quote! { #core::v8::Local<#core::v8::Value> }; - - q!(Vars { var: &ident }, { - let var = serde_v8::Value { v8_value: var }; - }) - } - // &[u32] - TransformKind::SliceU32(_) => { - *ty = - parse_quote! { *const #core::v8::fast_api::FastApiTypedArray<u32> }; - - q!(Vars { var: &ident }, { - // V8 guarantees that ArrayBuffers are always 4-byte aligned - // (seems to be always 8-byte aligned on 64-bit machines) - // but Deno FFI makes it possible to create ArrayBuffers at any - // alignment. Thus this check is needed. - let var = match unsafe { &*var }.get_storage_if_aligned() { - Some(v) => v, - None => { - unsafe { &mut *fast_api_callback_options }.fallback = true; - return Default::default(); - } - }; - }) - } - // &[u8] - TransformKind::SliceU8(_) => { - *ty = - parse_quote! { *const #core::v8::fast_api::FastApiTypedArray<u8> }; - - q!(Vars { var: &ident }, { - // SAFETY: U8 slice is always byte-aligned. - let var = - unsafe { (&*var).get_storage_if_aligned().unwrap_unchecked() }; - }) - } - TransformKind::SliceF64(_) => { - *ty = - parse_quote! { *const #core::v8::fast_api::FastApiTypedArray<f64> }; - - q!(Vars { var: &ident }, { - let var = match unsafe { &*var }.get_storage_if_aligned() { - Some(v) => v, - None => { - unsafe { &mut *fast_api_callback_options }.fallback = true; - return Default::default(); - } - }; - }) - } - // &str - TransformKind::SeqOneByteString(str_ty) => { - *ty = parse_quote! { *const #core::v8::fast_api::FastApiOneByteString }; - match str_ty { - StringType::Ref => q!(Vars { var: &ident }, { - let var = match ::std::str::from_utf8(unsafe { &*var }.as_bytes()) { - Ok(v) => v, - Err(_) => { - unsafe { &mut *fast_api_callback_options }.fallback = true; - return Default::default(); - } - }; - }), - StringType::Cow => q!(Vars { var: &ident }, { - let var = ::std::borrow::Cow::Borrowed( - match ::std::str::from_utf8(unsafe { &*var }.as_bytes()) { - Ok(v) => v, - Err(_) => { - unsafe { &mut *fast_api_callback_options }.fallback = true; - return Default::default(); - } - }, - ); - }), - StringType::Owned => q!(Vars { var: &ident }, { - let var = match ::std::str::from_utf8(unsafe { &*var }.as_bytes()) { - Ok(v) => v.to_owned(), - Err(_) => { - unsafe { &mut *fast_api_callback_options }.fallback = true; - return Default::default(); - } - }; - }), - } - } - TransformKind::WasmMemory => { - // Note: `ty` is correctly set to __opts by the fast call tier. - // U8 slice is always byte-aligned. - q!(Vars { var: &ident, core }, { - let var = unsafe { - &*(__opts.wasm_memory - as *const core::v8::fast_api::FastApiTypedArray<u8>) - } - .get_storage_if_aligned(); - }) - } - // *const u8 - TransformKind::PtrU8 => { - *ty = - parse_quote! { *const #core::v8::fast_api::FastApiTypedArray<u8> }; - - q!(Vars { var: &ident }, { - // SAFETY: U8 slice is always byte-aligned. - let var = - unsafe { (&*var).get_storage_if_aligned().unwrap_unchecked() } - .as_ptr(); - }) - } - TransformKind::PtrVoid => { - *ty = parse_quote! { *mut ::std::ffi::c_void }; - - q!(Vars {}, {}) - } - } - } -} - -fn get_fast_scalar(s: &str) -> Option<FastValue> { - match s { - "bool" => Some(FastValue::Bool), - "u32" => Some(FastValue::U32), - "i32" => Some(FastValue::I32), - "u64" | "usize" => Some(FastValue::U64), - "i64" | "isize" => Some(FastValue::I64), - "f32" => Some(FastValue::F32), - "f64" => Some(FastValue::F64), - "* const c_void" | "* mut c_void" => Some(FastValue::Pointer), - "ResourceId" => Some(FastValue::U32), - _ => None, - } -} - -fn can_return_fast(v: &FastValue) -> bool { - !matches!( - v, - FastValue::U64 - | FastValue::I64 - | FastValue::Uint8Array - | FastValue::Uint32Array - ) -} - -#[derive(Debug, PartialEq, Clone)] -pub(crate) enum FastValue { - Void, - Bool, - U32, - I32, - U64, - I64, - F32, - F64, - Pointer, - V8Value, - Uint8Array, - Uint32Array, - Float64Array, - SeqOneByteString, -} - -impl FastValue { - pub fn default_value(&self) -> Quote { - match self { - FastValue::Pointer => q!({ ::std::ptr::null_mut() }), - FastValue::Void => q!({}), - _ => q!({ Default::default() }), - } - } -} - -impl Default for FastValue { - fn default() -> Self { - Self::Void - } -} - -#[derive(Default, PartialEq)] -pub(crate) struct Optimizer { - pub(crate) returns_result: bool, - - pub(crate) has_ref_opstate: bool, - - pub(crate) has_rc_opstate: bool, - - // Do we need an explicit FastApiCallbackOptions argument? - pub(crate) has_fast_callback_option: bool, - // Do we depend on FastApiCallbackOptions? - pub(crate) needs_fast_callback_option: bool, - - pub(crate) has_wasm_memory: bool, - - pub(crate) fast_result: Option<FastValue>, - pub(crate) fast_parameters: Vec<FastValue>, - - pub(crate) transforms: BTreeMap<usize, Transform>, - pub(crate) fast_compatible: bool, - - pub(crate) is_async: bool, -} - -impl Debug for Optimizer { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - writeln!(f, "=== Optimizer Dump ===")?; - writeln!(f, "returns_result: {}", self.returns_result)?; - writeln!(f, "has_ref_opstate: {}", self.has_ref_opstate)?; - writeln!(f, "has_rc_opstate: {}", self.has_rc_opstate)?; - writeln!( - f, - "has_fast_callback_option: {}", - self.has_fast_callback_option - )?; - writeln!( - f, - "needs_fast_callback_option: {}", - self.needs_fast_callback_option - )?; - writeln!(f, "fast_result: {:?}", self.fast_result)?; - writeln!(f, "fast_parameters: {:?}", self.fast_parameters)?; - writeln!(f, "transforms: {:?}", self.transforms)?; - writeln!(f, "is_async: {}", self.is_async)?; - writeln!(f, "fast_compatible: {}", self.fast_compatible)?; - Ok(()) - } -} - -impl Optimizer { - pub(crate) fn new() -> Self { - Default::default() - } - - pub(crate) const fn has_opstate_in_parameters(&self) -> bool { - self.has_ref_opstate || self.has_rc_opstate - } - - pub(crate) const fn needs_opstate(&self) -> bool { - self.has_ref_opstate || self.has_rc_opstate || self.returns_result - } - - pub(crate) fn analyze(&mut self, op: &mut Op) -> Result<(), BailoutReason> { - // Fast async ops are opt-in as they have a lazy polling behavior. - if op.is_async && !op.attrs.must_be_fast { - self.fast_compatible = false; - return Ok(()); - } - - if op.attrs.is_v8 { - self.fast_compatible = false; - return Ok(()); - } - - self.is_async = op.is_async; - self.fast_compatible = true; - // Just assume for now. We will validate later. - self.has_wasm_memory = op.attrs.is_wasm; - - let sig = &op.item.sig; - - // Analyze return type - match &sig { - Signature { - output: ReturnType::Default, - .. - } => self.fast_result = Some(FastValue::default()), - Signature { - output: ReturnType::Type(_, ty), - .. - } if !self.is_async => self.analyze_return_type(ty)?, - - // No need to error on the return type for async ops, its OK if - // it's not a fast value. - Signature { - output: ReturnType::Type(_, ty), - .. - } => { - let _ = self.analyze_return_type(ty); - // Recover. - self.fast_result = None; - self.fast_compatible = true; - } - }; - - // The receiver, which we don't actually care about. - self.fast_parameters.push(FastValue::V8Value); - - if self.is_async { - // The promise ID. - self.fast_parameters.push(FastValue::I32); - } - - // Analyze parameters - for (index, param) in sig.inputs.iter().enumerate() { - self.analyze_param_type(index, param)?; - } - - // TODO(@littledivy): https://github.com/denoland/deno/issues/17159 - if self.returns_result - && self.fast_parameters.contains(&FastValue::SeqOneByteString) - { - self.fast_compatible = false; - } - - Ok(()) - } - - fn analyze_return_type(&mut self, ty: &Type) -> Result<(), BailoutReason> { - match ty { - Type::Tuple(TypeTuple { elems, .. }) if elems.is_empty() => { - self.fast_result = Some(FastValue::Void); - } - Type::Path(TypePath { - path: Path { segments, .. }, - .. - }) => { - let segment = single_segment(segments)?; - - match segment { - // Result<T, E> - PathSegment { - ident, arguments, .. - } if ident == "Result" => { - self.returns_result = true; - - if let PathArguments::AngleBracketed( - AngleBracketedGenericArguments { args, .. }, - ) = arguments - { - match args.first() { - Some(GenericArgument::Type(Type::Path(TypePath { - path: Path { segments, .. }, - .. - }))) => { - let PathSegment { ident, .. } = single_segment(segments)?; - // Is `T` a scalar FastValue? - if let Some(val) = get_fast_scalar(ident.to_string().as_str()) - { - if can_return_fast(&val) { - self.fast_result = Some(val); - return Ok(()); - } - } - - self.fast_compatible = false; - return Err(BailoutReason::FastUnsupportedParamType); - } - Some(GenericArgument::Type(Type::Tuple(TypeTuple { - elems, - .. - }))) - if elems.is_empty() => - { - self.fast_result = Some(FastValue::Void); - } - Some(GenericArgument::Type(Type::Ptr(TypePtr { - mutability: Some(_), - elem, - .. - }))) => { - match &**elem { - Type::Path(TypePath { - path: Path { segments, .. }, - .. - }) => { - // Is `T` a c_void? - let segment = single_segment(segments)?; - match segment { - PathSegment { ident, .. } if ident == "c_void" => { - self.fast_result = Some(FastValue::Pointer); - return Ok(()); - } - _ => { - return Err(BailoutReason::FastUnsupportedParamType) - } - } - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - } - // Is `T` a scalar FastValue? - PathSegment { ident, .. } => { - if let Some(val) = get_fast_scalar(ident.to_string().as_str()) { - self.fast_result = Some(val); - return Ok(()); - } - - self.fast_compatible = false; - return Err(BailoutReason::FastUnsupportedParamType); - } - }; - } - Type::Ptr(TypePtr { - mutability: Some(_), - elem, - .. - }) => { - match &**elem { - Type::Path(TypePath { - path: Path { segments, .. }, - .. - }) => { - // Is `T` a c_void? - let segment = single_segment(segments)?; - match segment { - PathSegment { ident, .. } if ident == "c_void" => { - self.fast_result = Some(FastValue::Pointer); - return Ok(()); - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - }; - - Ok(()) - } - - fn analyze_param_type( - &mut self, - index: usize, - arg: &FnArg, - ) -> Result<(), BailoutReason> { - match arg { - FnArg::Typed(typed) => match &*typed.ty { - Type::Path(TypePath { - path: Path { segments, .. }, - .. - }) if segments.len() == 2 => { - match double_segment(segments)? { - // -> serde_v8::Value - [PathSegment { ident: first, .. }, PathSegment { ident: last, .. }] - if first == "serde_v8" && last == "Value" => - { - self.fast_parameters.push(FastValue::V8Value); - assert!(self - .transforms - .insert(index, Transform::serde_v8_value(index)) - .is_none()); - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - Type::Path(TypePath { - path: Path { segments, .. }, - .. - }) => { - let segment = single_segment(segments)?; - - match segment { - // -> Option<T> - PathSegment { - ident, arguments, .. - } if ident == "Option" => { - if let PathArguments::AngleBracketed( - AngleBracketedGenericArguments { args, .. }, - ) = arguments - { - // -> Option<&mut T> - if let Some(GenericArgument::Type(Type::Reference( - TypeReference { elem, .. }, - ))) = args.last() - { - if self.has_wasm_memory { - // -> Option<&mut [u8]> - if let Type::Slice(TypeSlice { elem, .. }) = &**elem { - if let Type::Path(TypePath { - path: Path { segments, .. }, - .. - }) = &**elem - { - let segment = single_segment(segments)?; - - match segment { - // Is `T` a u8? - PathSegment { ident, .. } if ident == "u8" => { - assert!(self - .transforms - .insert(index, Transform::wasm_memory(index)) - .is_none()); - } - _ => { - return Err(BailoutReason::FastUnsupportedParamType) - } - } - } - } - } else if let Type::Path(TypePath { - path: Path { segments, .. }, - .. - }) = &**elem - { - let segment = single_segment(segments)?; - match segment { - // Is `T` a FastApiCallbackOptions? - PathSegment { ident, .. } - if ident == "FastApiCallbackOptions" => - { - self.has_fast_callback_option = true; - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } else { - return Err(BailoutReason::FastUnsupportedParamType); - } - } else { - return Err(BailoutReason::FastUnsupportedParamType); - } - } - } - // -> Rc<T> - PathSegment { - ident, arguments, .. - } if ident == "Rc" => { - if let PathArguments::AngleBracketed( - AngleBracketedGenericArguments { args, .. }, - ) = arguments - { - match args.last() { - Some(GenericArgument::Type(Type::Path(TypePath { - path: Path { segments, .. }, - .. - }))) => { - let segment = single_segment(segments)?; - match segment { - // -> Rc<RefCell<T>> - PathSegment { - ident, arguments, .. - } if ident == "RefCell" => { - if let PathArguments::AngleBracketed( - AngleBracketedGenericArguments { args, .. }, - ) = arguments - { - match args.last() { - // -> Rc<RefCell<OpState>> - Some(GenericArgument::Type(Type::Path( - TypePath { - path: Path { segments, .. }, - .. - }, - ))) => { - let segment = single_segment(segments)?; - match segment { - PathSegment { ident, .. } - if ident == "OpState" => - { - self.has_rc_opstate = true; - } - _ => { - return Err( - BailoutReason::FastUnsupportedParamType, - ) - } - } - } - _ => { - return Err( - BailoutReason::FastUnsupportedParamType, - ) - } - } - } - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - } - // Cow<'_, str> - PathSegment { - ident, arguments, .. - } if ident == "Cow" => { - if let PathArguments::AngleBracketed( - AngleBracketedGenericArguments { args, .. }, - ) = arguments - { - assert_eq!(args.len(), 2); - - let ty = &args[1]; - match ty { - GenericArgument::Type(Type::Path(TypePath { - path: Path { segments, .. }, - .. - })) => { - let segment = single_segment(segments)?; - match segment { - PathSegment { ident, .. } if ident == "str" => { - self.needs_fast_callback_option = true; - self.fast_parameters.push(FastValue::SeqOneByteString); - assert!(self - .transforms - .insert( - index, - Transform::seq_one_byte_string( - index, - StringType::Cow - ) - ) - .is_none()); - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - } - // Is `T` a fast scalar? - PathSegment { ident, .. } => { - if let Some(val) = get_fast_scalar(ident.to_string().as_str()) { - self.fast_parameters.push(val); - } else if ident == "String" { - self.needs_fast_callback_option = true; - // Is `T` an owned String? - self.fast_parameters.push(FastValue::SeqOneByteString); - assert!(self - .transforms - .insert( - index, - Transform::seq_one_byte_string(index, StringType::Owned) - ) - .is_none()); - } else { - return Err(BailoutReason::FastUnsupportedParamType); - } - } - }; - } - // &mut T - Type::Reference(TypeReference { - elem, mutability, .. - }) => match &**elem { - Type::Path(TypePath { - path: Path { segments, .. }, - .. - }) => { - let segment = single_segment(segments)?; - match segment { - // Is `T` a OpState? - PathSegment { ident, .. } - if ident == "OpState" && !self.is_async => - { - self.has_ref_opstate = true; - } - // Is `T` a str? - PathSegment { ident, .. } if ident == "str" => { - self.needs_fast_callback_option = true; - self.fast_parameters.push(FastValue::SeqOneByteString); - assert!(self - .transforms - .insert( - index, - Transform::seq_one_byte_string(index, StringType::Ref) - ) - .is_none()); - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - // &mut [T] - Type::Slice(TypeSlice { elem, .. }) => match &**elem { - Type::Path(TypePath { - path: Path { segments, .. }, - .. - }) => { - let segment = single_segment(segments)?; - let is_mut_ref = mutability.is_some(); - match segment { - // Is `T` a u8? - PathSegment { ident, .. } if ident == "u8" => { - self.fast_parameters.push(FastValue::Uint8Array); - assert!(self - .transforms - .insert(index, Transform::slice_u8(index, is_mut_ref)) - .is_none()); - } - // Is `T` a u32? - PathSegment { ident, .. } if ident == "u32" => { - self.needs_fast_callback_option = true; - self.fast_parameters.push(FastValue::Uint32Array); - assert!(self - .transforms - .insert(index, Transform::slice_u32(index, is_mut_ref)) - .is_none()); - } - // Is `T` a f64? - PathSegment { ident, .. } if ident == "f64" => { - self.needs_fast_callback_option = true; - self.fast_parameters.push(FastValue::Float64Array); - assert!(self - .transforms - .insert(index, Transform::slice_f64(index, is_mut_ref)) - .is_none()); - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - }, - _ => return Err(BailoutReason::FastUnsupportedParamType), - }, - // *const T - Type::Ptr(TypePtr { - elem, - const_token: Some(_), - .. - }) => match &**elem { - Type::Path(TypePath { - path: Path { segments, .. }, - .. - }) => { - let segment = single_segment(segments)?; - match segment { - // Is `T` a u8? - PathSegment { ident, .. } if ident == "u8" => { - self.fast_parameters.push(FastValue::Uint8Array); - assert!(self - .transforms - .insert(index, Transform::u8_ptr(index)) - .is_none()); - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - }, - // *const T - Type::Ptr(TypePtr { - elem, - mutability: Some(_), - .. - }) => match &**elem { - Type::Path(TypePath { - path: Path { segments, .. }, - .. - }) => { - let segment = single_segment(segments)?; - match segment { - // Is `T` a c_void? - PathSegment { ident, .. } if ident == "c_void" => { - self.fast_parameters.push(FastValue::Pointer); - assert!(self - .transforms - .insert(index, Transform::void_ptr(index)) - .is_none()); - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - } - } - _ => return Err(BailoutReason::FastUnsupportedParamType), - }, - _ => return Err(BailoutReason::FastUnsupportedParamType), - }, - _ => return Err(BailoutReason::FastUnsupportedParamType), - }; - Ok(()) - } -} - -fn single_segment( - segments: &Punctuated<PathSegment, Colon2>, -) -> Result<&PathSegment, BailoutReason> { - if segments.len() != 1 { - return Err(BailoutReason::MustBeSingleSegment); - } - - match segments.last() { - Some(segment) => Ok(segment), - None => Err(BailoutReason::MustBeSingleSegment), - } -} - -fn double_segment( - segments: &Punctuated<PathSegment, Colon2>, -) -> Result<[&PathSegment; 2], BailoutReason> { - match (segments.first(), segments.last()) { - (Some(first), Some(last)) => Ok([first, last]), - // Caller ensures that there are only two segments. - _ => unreachable!(), - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::Attributes; - use crate::Op; - use pretty_assertions::assert_eq; - use std::path::PathBuf; - use syn::parse_quote; - - #[test] - fn test_single_segment() { - let segments = parse_quote!(foo); - assert!(single_segment(&segments).is_ok()); - - let segments = parse_quote!(foo::bar); - assert!(single_segment(&segments).is_err()); - } - - #[test] - fn test_double_segment() { - let segments = parse_quote!(foo::bar); - assert!(double_segment(&segments).is_ok()); - assert_eq!(double_segment(&segments).unwrap()[0].ident, "foo"); - assert_eq!(double_segment(&segments).unwrap()[1].ident, "bar"); - } - - #[testing_macros::fixture("optimizer_tests/**/*.rs")] - fn test_analyzer(input: PathBuf) { - let update_expected = std::env::var("UPDATE_EXPECTED").is_ok(); - - let source = - std::fs::read_to_string(&input).expect("Failed to read test file"); - let expected = std::fs::read_to_string(input.with_extension("expected")) - .expect("Failed to read expected file"); - - let mut attrs = Attributes::default(); - if source.contains("// @test-attr:wasm") { - attrs.must_be_fast = true; - attrs.is_wasm = true; - } - if source.contains("// @test-attr:fast") { - attrs.must_be_fast = true; - } - - let item = syn::parse_str(&source).expect("Failed to parse test file"); - let mut op = Op::new(item, attrs); - let mut optimizer = Optimizer::new(); - if let Err(e) = optimizer.analyze(&mut op) { - let e_str = format!("{e:?}"); - if update_expected { - std::fs::write(input.with_extension("expected"), e_str) - .expect("Failed to write expected file"); - } else { - assert_eq!(e_str, expected); - } - return; - } - - if update_expected { - std::fs::write( - input.with_extension("expected"), - format!("{optimizer:#?}"), - ) - .expect("Failed to write expected file"); - } else { - assert_eq!(format!("{optimizer:#?}"), expected); - } - } -} diff --git a/ops/optimizer_tests/async_nop.expected b/ops/optimizer_tests/async_nop.expected deleted file mode 100644 index 42a1180bd..000000000 --- a/ops/optimizer_tests/async_nop.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(Void) -fast_parameters: [V8Value, I32] -transforms: {} -is_async: true -fast_compatible: true diff --git a/ops/optimizer_tests/async_nop.out b/ops/optimizer_tests/async_nop.out deleted file mode 100644 index 85c55f2f4..000000000 --- a/ops/optimizer_tests/async_nop.out +++ /dev/null @@ -1,137 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_void_async::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_void_async { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_void_async { - const NAME: &'static str = stringify!(op_void_async); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Int32, CallbackOptions], - CType::Void, - Self::op_void_async_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: true, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_void_async { - pub const fn name() -> &'static str { - stringify!(op_void_async) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Int32, CallbackOptions], - CType::Void, - Self::op_void_async_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: true, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - async fn call<'scope>() {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - use deno_core::futures::FutureExt; - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let promise_id = args.get(0); - let promise_id = deno_core::v8::Local::< - deno_core::v8::Integer, - >::try_from(promise_id) - .map(|l| l.value() as deno_core::PromiseId) - .map_err(deno_core::anyhow::Error::from); - let promise_id: deno_core::PromiseId = match promise_id { - Ok(promise_id) => promise_id, - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!("invalid promise id: {}", err), - ); - return; - } - }; - let fut = deno_core::_ops::map_async_op2(ctx, Self::call()); - let maybe_response = deno_core::_ops::queue_async_op( - ctx, - scope, - false, - promise_id, - fut, - ); - if let Some(response) = maybe_response { - rv.set(response); - } - } -} -impl op_void_async { - #[allow(clippy::too_many_arguments)] - fn op_void_async_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - __promise_id: i32, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let op_state = __ctx.state.clone(); - let result = Self::call(); - let result = _ops::queue_fast_async_op( - __ctx, - __promise_id, - async move { Ok(result.await) }, - ); - result - } -} diff --git a/ops/optimizer_tests/async_nop.rs b/ops/optimizer_tests/async_nop.rs deleted file mode 100644 index 95a1522f1..000000000 --- a/ops/optimizer_tests/async_nop.rs +++ /dev/null @@ -1,3 +0,0 @@ -async fn op_void_async() { - // @test-attr:fast -} diff --git a/ops/optimizer_tests/async_result.expected b/ops/optimizer_tests/async_result.expected deleted file mode 100644 index 87d46977d..000000000 --- a/ops/optimizer_tests/async_result.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: true -has_ref_opstate: false -has_rc_opstate: true -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: None -fast_parameters: [V8Value, I32, U32] -transforms: {} -is_async: true -fast_compatible: true diff --git a/ops/optimizer_tests/async_result.out b/ops/optimizer_tests/async_result.out deleted file mode 100644 index 91117e4a1..000000000 --- a/ops/optimizer_tests/async_result.out +++ /dev/null @@ -1,150 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_async_result::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_async_result { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_async_result { - const NAME: &'static str = stringify!(op_async_result); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Int32, Uint32, CallbackOptions], - CType::Void, - Self::op_async_result_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: true, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_async_result { - pub const fn name() -> &'static str { - stringify!(op_async_result) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Int32, Uint32, CallbackOptions], - CType::Void, - Self::op_async_result_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: true, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - async fn call<'scope>( - state: Rc<RefCell<OpState>>, - rid: ResourceId, - ) -> Result<u32, Error> {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - use deno_core::futures::FutureExt; - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let promise_id = args.get(0); - let promise_id = deno_core::v8::Local::< - deno_core::v8::Integer, - >::try_from(promise_id) - .map(|l| l.value() as deno_core::PromiseId) - .map_err(deno_core::anyhow::Error::from); - let promise_id: deno_core::PromiseId = match promise_id { - Ok(promise_id) => promise_id, - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!("invalid promise id: {}", err), - ); - return; - } - }; - let arg_0 = args.get(1usize as i32); - let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 1usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let fut = deno_core::_ops::map_async_op1( - ctx, - Self::call(ctx.state.clone(), arg_0), - ); - let maybe_response = deno_core::_ops::queue_async_op( - ctx, - scope, - false, - promise_id, - fut, - ); - if let Some(response) = maybe_response { - rv.set(response); - } - } -} -impl op_async_result { - #[allow(clippy::too_many_arguments)] - fn op_async_result_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - __promise_id: i32, - rid: ResourceId, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let state = __ctx.state.clone(); - let result = Self::call(state, rid); - let result = _ops::queue_fast_async_op(__ctx, __promise_id, result); - } -} diff --git a/ops/optimizer_tests/async_result.rs b/ops/optimizer_tests/async_result.rs deleted file mode 100644 index 54ac20d3c..000000000 --- a/ops/optimizer_tests/async_result.rs +++ /dev/null @@ -1,6 +0,0 @@ -async fn op_async_result( - state: Rc<RefCell<OpState>>, - rid: ResourceId, -) -> Result<u32, Error> { - // @test-attr:fast -} diff --git a/ops/optimizer_tests/callback_options.expected b/ops/optimizer_tests/callback_options.expected deleted file mode 100644 index 245fdfd55..000000000 --- a/ops/optimizer_tests/callback_options.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: true -needs_fast_callback_option: false -fast_result: Some(Void) -fast_parameters: [V8Value] -transforms: {} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/callback_options.out b/ops/optimizer_tests/callback_options.out deleted file mode 100644 index a868d6393..000000000 --- a/ops/optimizer_tests/callback_options.out +++ /dev/null @@ -1,106 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_fallback::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_fallback { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_fallback { - const NAME: &'static str = stringify!(op_fallback); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, CallbackOptions], - CType::Void, - Self::op_fallback_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_fallback { - pub const fn name() -> &'static str { - stringify!(op_fallback) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, CallbackOptions], - CType::Void, - Self::op_fallback_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(options: Option<&mut FastApiCallbackOptions>) { - if let Some(options) = options { - options.fallback = true; - } - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = None; - let result = Self::call(arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - } -} -impl op_fallback { - #[allow(clippy::too_many_arguments)] - fn op_fallback_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let result = Self::call(options); - result - } -} diff --git a/ops/optimizer_tests/callback_options.rs b/ops/optimizer_tests/callback_options.rs deleted file mode 100644 index c210171d2..000000000 --- a/ops/optimizer_tests/callback_options.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn op_fallback(options: Option<&mut FastApiCallbackOptions>) { - if let Some(options) = options { - options.fallback = true; - } -} diff --git a/ops/optimizer_tests/cow_str.expected b/ops/optimizer_tests/cow_str.expected deleted file mode 100644 index 9db8cfaf3..000000000 --- a/ops/optimizer_tests/cow_str.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: true -fast_result: Some(Void) -fast_parameters: [V8Value, SeqOneByteString] -transforms: {0: Transform { kind: SeqOneByteString(Cow), index: 0 }} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/cow_str.out b/ops/optimizer_tests/cow_str.out deleted file mode 100644 index 15c92f346..000000000 --- a/ops/optimizer_tests/cow_str.out +++ /dev/null @@ -1,121 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_cow_str::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_cow_str { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_cow_str { - const NAME: &'static str = stringify!(op_cow_str); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, SeqOneByteString, CallbackOptions], - CType::Void, - Self::op_cow_str_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_cow_str { - pub const fn name() -> &'static str { - stringify!(op_cow_str) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, SeqOneByteString, CallbackOptions], - CType::Void, - Self::op_cow_str_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(c: Cow<'_, str>) {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = match deno_core::v8::Local::< - deno_core::v8::String, - >::try_from(args.get(0usize as i32)) { - Ok(v8_string) => { - ::std::borrow::Cow::Owned(deno_core::serde_v8::to_utf8(v8_string, scope)) - } - Err(_) => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected string at position {}", 0usize), - ); - } - }; - let result = Self::call(arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - } -} -impl op_cow_str { - #[allow(clippy::too_many_arguments)] - fn op_cow_str_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - c: *const deno_core::v8::fast_api::FastApiOneByteString, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let c = ::std::borrow::Cow::Borrowed( - match ::std::str::from_utf8(unsafe { &*c }.as_bytes()) { - Ok(v) => v, - Err(_) => { - unsafe { &mut *fast_api_callback_options }.fallback = true; - return Default::default(); - } - }, - ); - let result = Self::call(c); - result - } -} diff --git a/ops/optimizer_tests/cow_str.rs b/ops/optimizer_tests/cow_str.rs deleted file mode 100644 index b7214bdc7..000000000 --- a/ops/optimizer_tests/cow_str.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn op_cow_str(c: Cow<'_, str>) { - // ... -} diff --git a/ops/optimizer_tests/f64_slice.expected b/ops/optimizer_tests/f64_slice.expected deleted file mode 100644 index 32182b004..000000000 --- a/ops/optimizer_tests/f64_slice.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: true -fast_result: Some(Void) -fast_parameters: [V8Value, Float64Array] -transforms: {0: Transform { kind: SliceF64(true), index: 0 }} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/f64_slice.out b/ops/optimizer_tests/f64_slice.out deleted file mode 100644 index 183677731..000000000 --- a/ops/optimizer_tests/f64_slice.out +++ /dev/null @@ -1,137 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_f64_buf::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_f64_buf { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_f64_buf { - const NAME: &'static str = stringify!(op_f64_buf); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, TypedArray(CType::Float64), CallbackOptions], - CType::Void, - Self::op_f64_buf_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_f64_buf { - pub const fn name() -> &'static str { - stringify!(op_f64_buf) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, TypedArray(CType::Float64), CallbackOptions], - CType::Void, - Self::op_f64_buf_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(buffer: &mut [f64]) {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = if let Ok(view) - = deno_core::v8::Local::< - deno_core::v8::Float64Array, - >::try_from(args.get(0usize as i32)) { - let (offset, len) = (view.byte_offset(), view.byte_length()); - let buffer = match view.buffer(scope) { - Some(v) => v, - None => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected Float64Array at position {}", 0usize), - ); - } - }; - if let Some(data) = buffer.data() { - let store = data.cast::<u8>().as_ptr(); - unsafe { - ::std::slice::from_raw_parts_mut( - store.add(offset) as *mut f64, - len / 8, - ) - } - } else { - &mut [] - } - } else { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected Float64Array at position {}", 0usize), - ); - }; - let result = Self::call(arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - } -} -impl op_f64_buf { - #[allow(clippy::too_many_arguments)] - fn op_f64_buf_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - buffer: *const deno_core::v8::fast_api::FastApiTypedArray<f64>, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let buffer = match unsafe { &*buffer }.get_storage_if_aligned() { - Some(v) => v, - None => { - unsafe { &mut *fast_api_callback_options }.fallback = true; - return Default::default(); - } - }; - let result = Self::call(buffer); - result - } -} diff --git a/ops/optimizer_tests/f64_slice.rs b/ops/optimizer_tests/f64_slice.rs deleted file mode 100644 index fa2778531..000000000 --- a/ops/optimizer_tests/f64_slice.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn op_f64_buf(buffer: &mut [f64]) { - // @test-attr:fast -} diff --git a/ops/optimizer_tests/incompatible_1.expected b/ops/optimizer_tests/incompatible_1.expected deleted file mode 100644 index 250ff1022..000000000 --- a/ops/optimizer_tests/incompatible_1.expected +++ /dev/null @@ -1 +0,0 @@ -FastUnsupportedParamType
\ No newline at end of file diff --git a/ops/optimizer_tests/incompatible_1.out b/ops/optimizer_tests/incompatible_1.out deleted file mode 100644 index d51a1eda8..000000000 --- a/ops/optimizer_tests/incompatible_1.out +++ /dev/null @@ -1,93 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_sync_serialize_object_with_numbers_as_keys::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_sync_serialize_object_with_numbers_as_keys { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_sync_serialize_object_with_numbers_as_keys { - const NAME: &'static str = stringify!(op_sync_serialize_object_with_numbers_as_keys); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_sync_serialize_object_with_numbers_as_keys { - pub const fn name() -> &'static str { - stringify!(op_sync_serialize_object_with_numbers_as_keys) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(value: serde_json::Value) -> Result<(), Error> { - assert_eq!( - value.to_string(), r#"{"lines":{"100":{"unit":"m"},"200":{"unit":"cm"}}}"# - ); - Ok(()) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = args.get(0usize as i32); - let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 0usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let result = Self::call(arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => {} - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} diff --git a/ops/optimizer_tests/incompatible_1.rs b/ops/optimizer_tests/incompatible_1.rs deleted file mode 100644 index 326189aa1..000000000 --- a/ops/optimizer_tests/incompatible_1.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn op_sync_serialize_object_with_numbers_as_keys( - value: serde_json::Value, -) -> Result<(), Error> { - assert_eq!( - value.to_string(), - r#"{"lines":{"100":{"unit":"m"},"200":{"unit":"cm"}}}"# - ); - Ok(()) -} diff --git a/ops/optimizer_tests/issue16934.expected b/ops/optimizer_tests/issue16934.expected deleted file mode 100644 index 6b75ff5bf..000000000 --- a/ops/optimizer_tests/issue16934.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: None -fast_parameters: [] -transforms: {} -is_async: false -fast_compatible: false diff --git a/ops/optimizer_tests/issue16934.out b/ops/optimizer_tests/issue16934.out deleted file mode 100644 index 0f85b1157..000000000 --- a/ops/optimizer_tests/issue16934.out +++ /dev/null @@ -1,115 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `send_stdin::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct send_stdin { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for send_stdin { - const NAME: &'static str = stringify!(send_stdin); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: true, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl send_stdin { - pub const fn name() -> &'static str { - stringify!(send_stdin) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: true, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - async fn call<'scope>( - state: &mut OpState, - cmd: String, - ) -> Result<(), anyhow::Error> { - let instance = state.borrow::<MinecraftInstance>().clone(); - instance.send_command(&cmd, CausedBy::Unknown).await?; - Ok(()) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - use deno_core::futures::FutureExt; - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let promise_id = args.get(0); - let promise_id = deno_core::v8::Local::< - deno_core::v8::Integer, - >::try_from(promise_id) - .map(|l| l.value() as deno_core::PromiseId) - .map_err(deno_core::anyhow::Error::from); - let promise_id: deno_core::PromiseId = match promise_id { - Ok(promise_id) => promise_id, - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!("invalid promise id: {}", err), - ); - return; - } - }; - let arg_0 = match deno_core::v8::Local::< - deno_core::v8::String, - >::try_from(args.get(1usize as i32)) { - Ok(v8_string) => deno_core::serde_v8::to_utf8(v8_string, scope), - Err(_) => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected string at position {}", 1usize), - ); - } - }; - let fut = deno_core::_ops::map_async_op1( - ctx, - Self::call( - compile_error!("mutable opstate is not supported in async ops"), - arg_0, - ), - ); - let maybe_response = deno_core::_ops::queue_async_op( - ctx, - scope, - false, - promise_id, - fut, - ); - if let Some(response) = maybe_response { - rv.set(response); - } - } -} diff --git a/ops/optimizer_tests/issue16934.rs b/ops/optimizer_tests/issue16934.rs deleted file mode 100644 index 1e77f1281..000000000 --- a/ops/optimizer_tests/issue16934.rs +++ /dev/null @@ -1,11 +0,0 @@ -async fn send_stdin( - state: &mut OpState, - cmd: String, -) -> Result<(), anyhow::Error> { - // https://github.com/denoland/deno/issues/16934 - // - // OpState borrowed across await point is not allowed, as it will likely panic at runtime. - let instance = state.borrow::<MinecraftInstance>().clone(); - instance.send_command(&cmd, CausedBy::Unknown).await?; - Ok(()) -} diff --git a/ops/optimizer_tests/issue16934_fast.expected b/ops/optimizer_tests/issue16934_fast.expected deleted file mode 100644 index 250ff1022..000000000 --- a/ops/optimizer_tests/issue16934_fast.expected +++ /dev/null @@ -1 +0,0 @@ -FastUnsupportedParamType
\ No newline at end of file diff --git a/ops/optimizer_tests/issue16934_fast.out b/ops/optimizer_tests/issue16934_fast.out deleted file mode 100644 index 2bbbc02bb..000000000 --- a/ops/optimizer_tests/issue16934_fast.out +++ /dev/null @@ -1,110 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `send_stdin::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct send_stdin { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for send_stdin { - const NAME: &'static str = stringify!(send_stdin); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: true, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl send_stdin { - pub const fn name() -> &'static str { - stringify!(send_stdin) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: true, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - async fn call<'scope>(state: &mut OpState, v: i32) -> Result<(), anyhow::Error> { - Ok(()) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - use deno_core::futures::FutureExt; - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let promise_id = args.get(0); - let promise_id = deno_core::v8::Local::< - deno_core::v8::Integer, - >::try_from(promise_id) - .map(|l| l.value() as deno_core::PromiseId) - .map_err(deno_core::anyhow::Error::from); - let promise_id: deno_core::PromiseId = match promise_id { - Ok(promise_id) => promise_id, - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!("invalid promise id: {}", err), - ); - return; - } - }; - let arg_0 = args.get(1usize as i32); - let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 1usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let fut = deno_core::_ops::map_async_op1( - ctx, - Self::call( - compile_error!("mutable opstate is not supported in async ops"), - arg_0, - ), - ); - let maybe_response = deno_core::_ops::queue_async_op( - ctx, - scope, - false, - promise_id, - fut, - ); - if let Some(response) = maybe_response { - rv.set(response); - } - } -} diff --git a/ops/optimizer_tests/issue16934_fast.rs b/ops/optimizer_tests/issue16934_fast.rs deleted file mode 100644 index 8d3488e9d..000000000 --- a/ops/optimizer_tests/issue16934_fast.rs +++ /dev/null @@ -1,8 +0,0 @@ -async fn send_stdin(state: &mut OpState, v: i32) -> Result<(), anyhow::Error> { - // @test-attr:fast - // - // https://github.com/denoland/deno/issues/16934 - // - // OpState borrowed across await point is not allowed, as it will likely panic at runtime. - Ok(()) -} diff --git a/ops/optimizer_tests/op_blob_revoke_object_url.expected b/ops/optimizer_tests/op_blob_revoke_object_url.expected deleted file mode 100644 index a412eceb8..000000000 --- a/ops/optimizer_tests/op_blob_revoke_object_url.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: true -has_ref_opstate: true -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: true -fast_result: Some(Void) -fast_parameters: [V8Value, SeqOneByteString] -transforms: {1: Transform { kind: SeqOneByteString(Owned), index: 1 }} -is_async: false -fast_compatible: false diff --git a/ops/optimizer_tests/op_blob_revoke_object_url.out b/ops/optimizer_tests/op_blob_revoke_object_url.out deleted file mode 100644 index 85c6460e9..000000000 --- a/ops/optimizer_tests/op_blob_revoke_object_url.out +++ /dev/null @@ -1,93 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_blob_revoke_object_url::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_blob_revoke_object_url { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_blob_revoke_object_url { - const NAME: &'static str = stringify!(op_blob_revoke_object_url); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_blob_revoke_object_url { - pub const fn name() -> &'static str { - stringify!(op_blob_revoke_object_url) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - pub fn call<'scope>(state: &mut OpState, url: String) -> Result<(), AnyError> { - let url = Url::parse(&url)?; - let blob_store = state.borrow::<Arc<BlobStore>>(); - blob_store.remove_object_url(&url); - Ok(()) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = match deno_core::v8::Local::< - deno_core::v8::String, - >::try_from(args.get(0usize as i32)) { - Ok(v8_string) => deno_core::serde_v8::to_utf8(v8_string, scope), - Err(_) => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected string at position {}", 0usize), - ); - } - }; - let result = Self::call(&mut std::cell::RefCell::borrow_mut(&ctx.state), arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => {} - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} diff --git a/ops/optimizer_tests/op_blob_revoke_object_url.rs b/ops/optimizer_tests/op_blob_revoke_object_url.rs deleted file mode 100644 index 9e82d7b37..000000000 --- a/ops/optimizer_tests/op_blob_revoke_object_url.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub fn op_blob_revoke_object_url( - state: &mut OpState, - url: String, -) -> Result<(), AnyError> { - // TODO(@littledivy): fast compatible https://github.com/denoland/deno/issues/17159 - let url = Url::parse(&url)?; - let blob_store = state.borrow::<Arc<BlobStore>>(); - blob_store.remove_object_url(&url); - Ok(()) -} diff --git a/ops/optimizer_tests/op_ffi_ptr_value.expected b/ops/optimizer_tests/op_ffi_ptr_value.expected deleted file mode 100644 index 00a28591c..000000000 --- a/ops/optimizer_tests/op_ffi_ptr_value.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: true -fast_result: Some(Void) -fast_parameters: [V8Value, Pointer, Uint32Array] -transforms: {0: Transform { kind: PtrVoid, index: 0 }, 1: Transform { kind: SliceU32(true), index: 1 }} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/op_ffi_ptr_value.out b/ops/optimizer_tests/op_ffi_ptr_value.out deleted file mode 100644 index 8fcce53c6..000000000 --- a/ops/optimizer_tests/op_ffi_ptr_value.out +++ /dev/null @@ -1,152 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_ffi_ptr_value::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_ffi_ptr_value { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_ffi_ptr_value { - const NAME: &'static str = stringify!(op_ffi_ptr_value); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Pointer, TypedArray(CType::Uint32), CallbackOptions], - CType::Void, - Self::op_ffi_ptr_value_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_ffi_ptr_value { - pub const fn name() -> &'static str { - stringify!(op_ffi_ptr_value) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Pointer, TypedArray(CType::Uint32), CallbackOptions], - CType::Void, - Self::op_ffi_ptr_value_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - pub fn call<'scope>(ptr: *mut c_void, out: &mut [u32]) {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = { - let value = args.get(0usize as i32); - if value.is_null() { - std::ptr::null_mut() - } else if let Ok(b) - = deno_core::v8::Local::<deno_core::v8::External>::try_from(value) { - b.value() - } else { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected External at position {}", 0usize), - ); - } - }; - let arg_1 = if let Ok(view) - = deno_core::v8::Local::< - deno_core::v8::Uint32Array, - >::try_from(args.get(1usize as i32)) { - let (offset, len) = (view.byte_offset(), view.byte_length()); - let buffer = match view.buffer(scope) { - Some(v) => v, - None => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected Uint32Array at position {}", 1usize), - ); - } - }; - if let Some(data) = buffer.data() { - let store = data.cast::<u8>().as_ptr(); - unsafe { - ::std::slice::from_raw_parts_mut( - store.add(offset) as *mut u32, - len / 4, - ) - } - } else { - &mut [] - } - } else { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected Uint32Array at position {}", 1usize), - ); - }; - let result = Self::call(arg_0, arg_1); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - } -} -impl op_ffi_ptr_value { - #[allow(clippy::too_many_arguments)] - fn op_ffi_ptr_value_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - ptr: *mut ::std::ffi::c_void, - out: *const deno_core::v8::fast_api::FastApiTypedArray<u32>, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let out = match unsafe { &*out }.get_storage_if_aligned() { - Some(v) => v, - None => { - unsafe { &mut *fast_api_callback_options }.fallback = true; - return Default::default(); - } - }; - let result = Self::call(ptr, out); - result - } -} diff --git a/ops/optimizer_tests/op_ffi_ptr_value.rs b/ops/optimizer_tests/op_ffi_ptr_value.rs deleted file mode 100644 index 4c3364507..000000000 --- a/ops/optimizer_tests/op_ffi_ptr_value.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn op_ffi_ptr_value(ptr: *mut c_void, out: &mut [u32]) { - // ... -} diff --git a/ops/optimizer_tests/op_print.expected b/ops/optimizer_tests/op_print.expected deleted file mode 100644 index 6095c138e..000000000 --- a/ops/optimizer_tests/op_print.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: true -has_ref_opstate: true -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: true -fast_result: Some(Void) -fast_parameters: [V8Value, SeqOneByteString, Bool] -transforms: {1: Transform { kind: SeqOneByteString(Ref), index: 1 }} -is_async: false -fast_compatible: false diff --git a/ops/optimizer_tests/op_print.out b/ops/optimizer_tests/op_print.out deleted file mode 100644 index 5023a6b03..000000000 --- a/ops/optimizer_tests/op_print.out +++ /dev/null @@ -1,108 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_print::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_print { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_print { - const NAME: &'static str = stringify!(op_print); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_print { - pub const fn name() -> &'static str { - stringify!(op_print) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>( - state: &mut OpState, - msg: &str, - is_err: bool, - ) -> Result<(), AnyError> {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = match deno_core::v8::Local::< - deno_core::v8::String, - >::try_from(args.get(0usize as i32)) { - Ok(v8_string) => deno_core::serde_v8::to_utf8(v8_string, scope), - Err(_) => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected string at position {}", 0usize), - ); - } - }; - let arg_0 = arg_0.as_ref(); - let arg_1 = args.get(1usize as i32); - let arg_1 = match deno_core::serde_v8::from_v8(scope, arg_1) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 1usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let result = Self::call( - &mut std::cell::RefCell::borrow_mut(&ctx.state), - arg_0, - arg_1, - ); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => {} - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} diff --git a/ops/optimizer_tests/op_print.rs b/ops/optimizer_tests/op_print.rs deleted file mode 100644 index 776ee8418..000000000 --- a/ops/optimizer_tests/op_print.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn op_print( - state: &mut OpState, - msg: &str, - is_err: bool, -) -> Result<(), AnyError> { - // TODO(@littledivy): fast compatible https://github.com/denoland/deno/issues/17159 -} diff --git a/ops/optimizer_tests/op_state.expected b/ops/optimizer_tests/op_state.expected deleted file mode 100644 index 241ea7693..000000000 --- a/ops/optimizer_tests/op_state.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: true -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(Void) -fast_parameters: [V8Value, I32] -transforms: {} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/op_state.out b/ops/optimizer_tests/op_state.out deleted file mode 100644 index 1b6d86b06..000000000 --- a/ops/optimizer_tests/op_state.out +++ /dev/null @@ -1,120 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_set_exit_code::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_set_exit_code { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_set_exit_code { - const NAME: &'static str = stringify!(op_set_exit_code); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Int32, CallbackOptions], - CType::Void, - Self::op_set_exit_code_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_set_exit_code { - pub const fn name() -> &'static str { - stringify!(op_set_exit_code) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Int32, CallbackOptions], - CType::Void, - Self::op_set_exit_code_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(state: &mut OpState, code: i32) { - state.borrow_mut::<ExitCode>().set(code); - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = args.get(0usize as i32); - let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 0usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let result = Self::call(&mut std::cell::RefCell::borrow_mut(&ctx.state), arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - } -} -impl op_set_exit_code { - #[allow(clippy::too_many_arguments)] - fn op_set_exit_code_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - code: i32, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state); - let result = Self::call(state, code); - result - } -} diff --git a/ops/optimizer_tests/op_state.rs b/ops/optimizer_tests/op_state.rs deleted file mode 100644 index 04e9a886d..000000000 --- a/ops/optimizer_tests/op_state.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn op_set_exit_code(state: &mut OpState, code: i32) { - state.borrow_mut::<ExitCode>().set(code); -} diff --git a/ops/optimizer_tests/op_state_basic1.expected b/ops/optimizer_tests/op_state_basic1.expected deleted file mode 100644 index e325dd2f7..000000000 --- a/ops/optimizer_tests/op_state_basic1.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: true -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(U32) -fast_parameters: [V8Value, U32, U32] -transforms: {} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/op_state_basic1.out b/ops/optimizer_tests/op_state_basic1.out deleted file mode 100644 index 284232a3a..000000000 --- a/ops/optimizer_tests/op_state_basic1.out +++ /dev/null @@ -1,148 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `foo::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct foo { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for foo { - const NAME: &'static str = stringify!(foo); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Uint32, Uint32, CallbackOptions], - CType::Uint32, - Self::foo_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl foo { - pub const fn name() -> &'static str { - stringify!(foo) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Uint32, Uint32, CallbackOptions], - CType::Uint32, - Self::foo_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(state: &mut OpState, a: u32, b: u32) -> u32 { - a + b - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = args.get(0usize as i32); - let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 0usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let arg_1 = args.get(1usize as i32); - let arg_1 = match deno_core::serde_v8::from_v8(scope, arg_1) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 1usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let result = Self::call( - &mut std::cell::RefCell::borrow_mut(&ctx.state), - arg_0, - arg_1, - ); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match deno_core::serde_v8::to_v8(scope, result) { - Ok(ret) => rv.set(ret), - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!( - "Error serializing return: {}", - deno_core::anyhow::Error::from(err) - ), - ) - } - }; - } -} -impl foo { - #[allow(clippy::too_many_arguments)] - fn foo_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - a: u32, - b: u32, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> u32 { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state); - let result = Self::call(state, a, b); - result - } -} diff --git a/ops/optimizer_tests/op_state_basic1.rs b/ops/optimizer_tests/op_state_basic1.rs deleted file mode 100644 index 9c89b41ce..000000000 --- a/ops/optimizer_tests/op_state_basic1.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn foo(state: &mut OpState, a: u32, b: u32) -> u32 { - a + b -} diff --git a/ops/optimizer_tests/op_state_generics.expected b/ops/optimizer_tests/op_state_generics.expected deleted file mode 100644 index c29258d75..000000000 --- a/ops/optimizer_tests/op_state_generics.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: true -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(Void) -fast_parameters: [V8Value] -transforms: {} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/op_state_generics.out b/ops/optimizer_tests/op_state_generics.out deleted file mode 100644 index a3e476d9e..000000000 --- a/ops/optimizer_tests/op_state_generics.out +++ /dev/null @@ -1,115 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_foo::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_foo<SP> { - _phantom_data: ::std::marker::PhantomData<(SP)>, -} -impl<SP> deno_core::_ops::Op for op_foo<SP> -where - SP: SomePermission + 'static, -{ - const NAME: &'static str = stringify!(op_foo); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, CallbackOptions], - CType::Void, - Self::op_foo_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl<SP> op_foo<SP> -where - SP: SomePermission + 'static, -{ - pub const fn name() -> &'static str { - stringify!(op_foo) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, CallbackOptions], - CType::Void, - Self::op_foo_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - pub fn call<'scope>(state: &mut OpState) {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let result = Self::call(&mut std::cell::RefCell::borrow_mut(&ctx.state)); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - } -} -impl<SP> op_foo<SP> -where - SP: SomePermission + 'static, -{ - #[allow(clippy::too_many_arguments)] - fn op_foo_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state); - let result = Self::call(state); - result - } -} diff --git a/ops/optimizer_tests/op_state_generics.rs b/ops/optimizer_tests/op_state_generics.rs deleted file mode 100644 index 7fa498981..000000000 --- a/ops/optimizer_tests/op_state_generics.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub fn op_foo<SP>(state: &mut OpState) -where - SP: SomePermission + 'static, -{ -} diff --git a/ops/optimizer_tests/op_state_result.expected b/ops/optimizer_tests/op_state_result.expected deleted file mode 100644 index 15ac033f3..000000000 --- a/ops/optimizer_tests/op_state_result.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: true -has_ref_opstate: true -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(U32) -fast_parameters: [V8Value, U32, U32] -transforms: {} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/op_state_result.out b/ops/optimizer_tests/op_state_result.out deleted file mode 100644 index 67793d93a..000000000 --- a/ops/optimizer_tests/op_state_result.out +++ /dev/null @@ -1,168 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `foo::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct foo { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for foo { - const NAME: &'static str = stringify!(foo); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Uint32, Uint32, CallbackOptions], - CType::Uint32, - Self::foo_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl foo { - pub const fn name() -> &'static str { - stringify!(foo) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Uint32, Uint32, CallbackOptions], - CType::Uint32, - Self::foo_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(state: &mut OpState, a: u32, b: u32) -> Result<u32, AnyError> { - Ok(a + b) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - { - let op_state = &mut std::cell::RefCell::borrow_mut(&ctx.state); - if let Some(err) = op_state.last_fast_op_error.take() { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - return; - } - } - let arg_0 = args.get(0usize as i32); - let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 0usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let arg_1 = args.get(1usize as i32); - let arg_1 = match deno_core::serde_v8::from_v8(scope, arg_1) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 1usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let result = Self::call( - &mut std::cell::RefCell::borrow_mut(&ctx.state), - arg_0, - arg_1, - ); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => { - rv.set_uint32(result as u32); - } - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} -impl foo { - #[allow(clippy::too_many_arguments)] - fn foo_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - a: u32, - b: u32, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> u32 { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state); - let result = Self::call(state, a, b); - match result { - Ok(result) => result, - Err(err) => { - state.last_fast_op_error.replace(err); - __opts.fallback = true; - Default::default() - } - } - } -} diff --git a/ops/optimizer_tests/op_state_result.rs b/ops/optimizer_tests/op_state_result.rs deleted file mode 100644 index 331005c08..000000000 --- a/ops/optimizer_tests/op_state_result.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn foo(state: &mut OpState, a: u32, b: u32) -> Result<u32, AnyError> { - Ok(a + b) -} diff --git a/ops/optimizer_tests/op_state_warning.expected b/ops/optimizer_tests/op_state_warning.expected deleted file mode 100644 index 7b33ad1ef..000000000 --- a/ops/optimizer_tests/op_state_warning.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: true -has_ref_opstate: true -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(U32) -fast_parameters: [V8Value] -transforms: {} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/op_state_warning.out b/ops/optimizer_tests/op_state_warning.out deleted file mode 100644 index 51947f90a..000000000 --- a/ops/optimizer_tests/op_state_warning.out +++ /dev/null @@ -1,157 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_listen::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_listen { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_listen { - const NAME: &'static str = stringify!(op_listen); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, CallbackOptions], - CType::Uint32, - Self::op_listen_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_listen { - pub const fn name() -> &'static str { - stringify!(op_listen) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, CallbackOptions], - CType::Uint32, - Self::op_listen_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(state: &mut OpState) -> Result<ResourceId, Error> { - log::debug!("listen"); - let addr = "127.0.0.1:4570".parse::<SocketAddr>().unwrap(); - let std_listener = std::net::TcpListener::bind(&addr)?; - std_listener.set_nonblocking(true)?; - let listener = TcpListener::try_from(std_listener)?; - let rid = state.resource_table.add(listener); - Ok(rid) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - { - let op_state = &mut std::cell::RefCell::borrow_mut(&ctx.state); - if let Some(err) = op_state.last_fast_op_error.take() { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - return; - } - } - let result = Self::call(&mut std::cell::RefCell::borrow_mut(&ctx.state)); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => { - match deno_core::serde_v8::to_v8(scope, result) { - Ok(ret) => rv.set(ret), - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!( - "Error serializing return: {}", - deno_core::anyhow::Error::from(err) - ), - ) - } - }; - } - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} -impl op_listen { - #[allow(clippy::too_many_arguments)] - fn op_listen_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> u32 { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state); - let result = Self::call(state); - match result { - Ok(result) => result, - Err(err) => { - state.last_fast_op_error.replace(err); - __opts.fallback = true; - Default::default() - } - } - } -} diff --git a/ops/optimizer_tests/op_state_warning.rs b/ops/optimizer_tests/op_state_warning.rs deleted file mode 100644 index a725e6f7e..000000000 --- a/ops/optimizer_tests/op_state_warning.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn op_listen(state: &mut OpState) -> Result<ResourceId, Error> { - log::debug!("listen"); - let addr = "127.0.0.1:4570".parse::<SocketAddr>().unwrap(); - let std_listener = std::net::TcpListener::bind(&addr)?; - std_listener.set_nonblocking(true)?; - let listener = TcpListener::try_from(std_listener)?; - let rid = state.resource_table.add(listener); - Ok(rid) -} diff --git a/ops/optimizer_tests/op_state_with_transforms.expected b/ops/optimizer_tests/op_state_with_transforms.expected deleted file mode 100644 index f5f236b7d..000000000 --- a/ops/optimizer_tests/op_state_with_transforms.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: true -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(Void) -fast_parameters: [V8Value, Uint8Array] -transforms: {1: Transform { kind: SliceU8(true), index: 1 }} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/op_state_with_transforms.out b/ops/optimizer_tests/op_state_with_transforms.out deleted file mode 100644 index 09303e269..000000000 --- a/ops/optimizer_tests/op_state_with_transforms.out +++ /dev/null @@ -1,162 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_now::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_now<TP> { - _phantom_data: ::std::marker::PhantomData<(TP)>, -} -impl<TP> deno_core::_ops::Op for op_now<TP> -where - TP: TimersPermission + 'static, -{ - const NAME: &'static str = stringify!(op_now); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, TypedArray(CType::Uint8), CallbackOptions], - CType::Void, - Self::op_now_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl<TP> op_now<TP> -where - TP: TimersPermission + 'static, -{ - pub const fn name() -> &'static str { - stringify!(op_now) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, TypedArray(CType::Uint8), CallbackOptions], - CType::Void, - Self::op_now_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - pub fn call<'scope>(state: &mut OpState, buf: &mut [u8]) {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = { - let value = args.get(0usize as i32); - match deno_core::v8::Local::<deno_core::v8::ArrayBuffer>::try_from(value) { - Ok(b) => { - let byte_length = b.byte_length(); - if let Some(data) = b.data() { - let store = data.cast::<u8>().as_ptr(); - unsafe { ::std::slice::from_raw_parts_mut(store, byte_length) } - } else { - &mut [] - } - } - Err(_) => { - if let Ok(view) - = deno_core::v8::Local::< - deno_core::v8::ArrayBufferView, - >::try_from(value) { - let len = view.byte_length(); - let offset = view.byte_offset(); - let buffer = match view.buffer(scope) { - Some(v) => v, - None => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected ArrayBufferView at position {}", 0usize), - ); - } - }; - if let Some(data) = buffer.data() { - let store = data.cast::<u8>().as_ptr(); - unsafe { - ::std::slice::from_raw_parts_mut(store.add(offset), len) - } - } else { - &mut [] - } - } else { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected ArrayBufferView at position {}", 0usize), - ); - } - } - } - }; - let result = Self::call(&mut std::cell::RefCell::borrow_mut(&ctx.state), arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - } -} -impl<TP> op_now<TP> -where - TP: TimersPermission + 'static, -{ - #[allow(clippy::too_many_arguments)] - fn op_now_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - buf: *const deno_core::v8::fast_api::FastApiTypedArray<u8>, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state); - let buf = unsafe { (&*buf).get_storage_if_aligned().unwrap_unchecked() }; - let result = Self::call(state, buf); - result - } -} diff --git a/ops/optimizer_tests/op_state_with_transforms.rs b/ops/optimizer_tests/op_state_with_transforms.rs deleted file mode 100644 index 4e7e616f3..000000000 --- a/ops/optimizer_tests/op_state_with_transforms.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub fn op_now<TP>(state: &mut OpState, buf: &mut [u8]) -where - TP: TimersPermission + 'static, -{ -} diff --git a/ops/optimizer_tests/opstate_with_arity.expected b/ops/optimizer_tests/opstate_with_arity.expected deleted file mode 100644 index b38455d0d..000000000 --- a/ops/optimizer_tests/opstate_with_arity.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: true -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(U32) -fast_parameters: [V8Value, U32, U32, U32, U32] -transforms: {} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/opstate_with_arity.out b/ops/optimizer_tests/opstate_with_arity.out deleted file mode 100644 index d7e85328a..000000000 --- a/ops/optimizer_tests/opstate_with_arity.out +++ /dev/null @@ -1,188 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_add_4::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_add_4 { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_add_4 { - const NAME: &'static str = stringify!(op_add_4); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Uint32, Uint32, Uint32, Uint32, CallbackOptions], - CType::Uint32, - Self::op_add_4_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_add_4 { - pub const fn name() -> &'static str { - stringify!(op_add_4) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Uint32, Uint32, Uint32, Uint32, CallbackOptions], - CType::Uint32, - Self::op_add_4_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 4usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(x1: u32, x2: u32, x3: u32, x4: u32) -> Result<u32, anyhow::Error> { - Ok(x1 + x2 + x3 + x4) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - { - let op_state = &mut std::cell::RefCell::borrow_mut(&ctx.state); - if let Some(err) = op_state.last_fast_op_error.take() { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - return; - } - } - let arg_0 = args.get(0usize as i32); - let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 0usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let arg_1 = args.get(1usize as i32); - let arg_1 = match deno_core::serde_v8::from_v8(scope, arg_1) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 1usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let arg_2 = args.get(2usize as i32); - let arg_2 = match deno_core::serde_v8::from_v8(scope, arg_2) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 2usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let arg_3 = args.get(3usize as i32); - let arg_3 = match deno_core::serde_v8::from_v8(scope, arg_3) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 3usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let result = Self::call(arg_0, arg_1, arg_2, arg_3); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => { - rv.set_uint32(result as u32); - } - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} -impl op_add_4 { - #[allow(clippy::too_many_arguments)] - fn op_add_4_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - x1: u32, - x2: u32, - x3: u32, - x4: u32, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> u32 { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let op_state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state); - let result = Self::call(x1, x2, x3, x4); - match result { - Ok(result) => result, - Err(err) => { - op_state.last_fast_op_error.replace(err); - __opts.fallback = true; - Default::default() - } - } - } -} diff --git a/ops/optimizer_tests/opstate_with_arity.rs b/ops/optimizer_tests/opstate_with_arity.rs deleted file mode 100644 index 7212ca975..000000000 --- a/ops/optimizer_tests/opstate_with_arity.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn op_add_4(x1: u32, x2: u32, x3: u32, x4: u32) -> Result<u32, anyhow::Error> { - Ok(x1 + x2 + x3 + x4) -} diff --git a/ops/optimizer_tests/option_arg.expected b/ops/optimizer_tests/option_arg.expected deleted file mode 100644 index 250ff1022..000000000 --- a/ops/optimizer_tests/option_arg.expected +++ /dev/null @@ -1 +0,0 @@ -FastUnsupportedParamType
\ No newline at end of file diff --git a/ops/optimizer_tests/option_arg.out b/ops/optimizer_tests/option_arg.out deleted file mode 100644 index 5880ec88e..000000000 --- a/ops/optimizer_tests/option_arg.out +++ /dev/null @@ -1,91 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_try_close::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_try_close { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_try_close { - const NAME: &'static str = stringify!(op_try_close); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_try_close { - pub const fn name() -> &'static str { - stringify!(op_try_close) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - pub fn call<'scope>( - state: &mut OpState, - rid: Option<ResourceId>, - ) -> Result<(), Error> {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = args.get(0usize as i32); - let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 0usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let result = Self::call(&mut std::cell::RefCell::borrow_mut(&ctx.state), arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => {} - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} diff --git a/ops/optimizer_tests/option_arg.rs b/ops/optimizer_tests/option_arg.rs deleted file mode 100644 index 47a02974d..000000000 --- a/ops/optimizer_tests/option_arg.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub fn op_try_close( - state: &mut OpState, - rid: Option<ResourceId>, -) -> Result<(), Error> { - // ... -} diff --git a/ops/optimizer_tests/owned_string.expected b/ops/optimizer_tests/owned_string.expected deleted file mode 100644 index 4c47a0525..000000000 --- a/ops/optimizer_tests/owned_string.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: true -fast_result: Some(U32) -fast_parameters: [V8Value, SeqOneByteString] -transforms: {0: Transform { kind: SeqOneByteString(Owned), index: 0 }} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/owned_string.out b/ops/optimizer_tests/owned_string.out deleted file mode 100644 index 58c7f72ae..000000000 --- a/ops/optimizer_tests/owned_string.out +++ /dev/null @@ -1,131 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_string_length::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_string_length { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_string_length { - const NAME: &'static str = stringify!(op_string_length); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, SeqOneByteString, CallbackOptions], - CType::Uint32, - Self::op_string_length_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_string_length { - pub const fn name() -> &'static str { - stringify!(op_string_length) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, SeqOneByteString, CallbackOptions], - CType::Uint32, - Self::op_string_length_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(string: String) -> u32 { - string.len() as u32 - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = match deno_core::v8::Local::< - deno_core::v8::String, - >::try_from(args.get(0usize as i32)) { - Ok(v8_string) => deno_core::serde_v8::to_utf8(v8_string, scope), - Err(_) => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected string at position {}", 0usize), - ); - } - }; - let result = Self::call(arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match deno_core::serde_v8::to_v8(scope, result) { - Ok(ret) => rv.set(ret), - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!( - "Error serializing return: {}", - deno_core::anyhow::Error::from(err) - ), - ) - } - }; - } -} -impl op_string_length { - #[allow(clippy::too_many_arguments)] - fn op_string_length_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - string: *const deno_core::v8::fast_api::FastApiOneByteString, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> u32 { - use deno_core::v8; - use deno_core::_ops; - let string = match ::std::str::from_utf8(unsafe { &*string }.as_bytes()) { - Ok(v) => v.to_owned(), - Err(_) => { - unsafe { &mut *fast_api_callback_options }.fallback = true; - return Default::default(); - } - }; - let result = Self::call(string); - result - } -} diff --git a/ops/optimizer_tests/owned_string.rs b/ops/optimizer_tests/owned_string.rs deleted file mode 100644 index 102cf00fb..000000000 --- a/ops/optimizer_tests/owned_string.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn op_string_length(string: String) -> u32 { - string.len() as u32 -} diff --git a/ops/optimizer_tests/param_mut_binding_warning.expected b/ops/optimizer_tests/param_mut_binding_warning.expected deleted file mode 100644 index 250ff1022..000000000 --- a/ops/optimizer_tests/param_mut_binding_warning.expected +++ /dev/null @@ -1 +0,0 @@ -FastUnsupportedParamType
\ No newline at end of file diff --git a/ops/optimizer_tests/param_mut_binding_warning.out b/ops/optimizer_tests/param_mut_binding_warning.out deleted file mode 100644 index 43a33d6e3..000000000 --- a/ops/optimizer_tests/param_mut_binding_warning.out +++ /dev/null @@ -1,111 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_read_sync::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_read_sync { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_read_sync { - const NAME: &'static str = stringify!(op_read_sync); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_read_sync { - pub const fn name() -> &'static str { - stringify!(op_read_sync) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>( - state: &mut OpState, - rid: ResourceId, - mut buf: ZeroCopyBuf, - ) -> Result<u32, AnyError> { - Ok(23) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = args.get(0usize as i32); - let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 0usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let arg_1 = args.get(1usize as i32); - let arg_1 = match deno_core::serde_v8::from_v8(scope, arg_1) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 1usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let result = Self::call( - &mut std::cell::RefCell::borrow_mut(&ctx.state), - arg_0, - arg_1, - ); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => { - rv.set_uint32(result as u32); - } - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} diff --git a/ops/optimizer_tests/param_mut_binding_warning.rs b/ops/optimizer_tests/param_mut_binding_warning.rs deleted file mode 100644 index c47122728..000000000 --- a/ops/optimizer_tests/param_mut_binding_warning.rs +++ /dev/null @@ -1,11 +0,0 @@ -fn op_read_sync( - state: &mut OpState, - rid: ResourceId, - mut buf: ZeroCopyBuf, -) -> Result<u32, AnyError> { - // Should not warn about unused `mut buf` binding. - // - // This was caused due to incorrect codegen by fast_call.rs - // on an incompatible op function. - Ok(23) -} diff --git a/ops/optimizer_tests/raw_ptr.expected b/ops/optimizer_tests/raw_ptr.expected deleted file mode 100644 index badd6e3f4..000000000 --- a/ops/optimizer_tests/raw_ptr.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: true -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: true -fast_result: Some(Void) -fast_parameters: [V8Value, Uint8Array, Uint32Array] -transforms: {1: Transform { kind: PtrU8, index: 1 }, 2: Transform { kind: SliceU32(true), index: 2 }} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/raw_ptr.out b/ops/optimizer_tests/raw_ptr.out deleted file mode 100644 index 18d2aaa4a..000000000 --- a/ops/optimizer_tests/raw_ptr.out +++ /dev/null @@ -1,211 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_ffi_ptr_of::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_ffi_ptr_of<FP> { - _phantom_data: ::std::marker::PhantomData<(FP)>, -} -impl<FP> deno_core::_ops::Op for op_ffi_ptr_of<FP> -where - FP: FfiPermissions + 'static, -{ - const NAME: &'static str = stringify!(op_ffi_ptr_of); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[ - V8Value, - TypedArray(CType::Uint8), - TypedArray(CType::Uint32), - CallbackOptions, - ], - CType::Void, - Self::op_ffi_ptr_of_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl<FP> op_ffi_ptr_of<FP> -where - FP: FfiPermissions + 'static, -{ - pub const fn name() -> &'static str { - stringify!(op_ffi_ptr_of) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[ - V8Value, - TypedArray(CType::Uint8), - TypedArray(CType::Uint32), - CallbackOptions, - ], - CType::Void, - Self::op_ffi_ptr_of_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(state: &mut OpState, buf: *const u8, out: &mut [u32]) {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = { - let value = args.get(0usize as i32); - match deno_core::v8::Local::<deno_core::v8::ArrayBuffer>::try_from(value) { - Ok(b) => { - if let Some(data) = b.data() { - data.cast::<u8>().as_ptr() - } else { - std::ptr::null::<u8>() - } - } - Err(_) => { - if let Ok(view) - = deno_core::v8::Local::< - deno_core::v8::ArrayBufferView, - >::try_from(value) { - let offset = view.byte_offset(); - let buffer = match view.buffer(scope) { - Some(v) => v, - None => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected ArrayBufferView at position {}", 0usize), - ); - } - }; - let store = if let Some(data) = buffer.data() { - data.cast::<u8>().as_ptr() - } else { - std::ptr::null_mut::<u8>() - }; - unsafe { store.add(offset) } - } else { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected ArrayBufferView at position {}", 0usize), - ); - } - } - } - }; - let arg_1 = if let Ok(view) - = deno_core::v8::Local::< - deno_core::v8::Uint32Array, - >::try_from(args.get(1usize as i32)) { - let (offset, len) = (view.byte_offset(), view.byte_length()); - let buffer = match view.buffer(scope) { - Some(v) => v, - None => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected Uint32Array at position {}", 1usize), - ); - } - }; - if let Some(data) = buffer.data() { - let store = data.cast::<u8>().as_ptr(); - unsafe { - ::std::slice::from_raw_parts_mut( - store.add(offset) as *mut u32, - len / 4, - ) - } - } else { - &mut [] - } - } else { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected Uint32Array at position {}", 1usize), - ); - }; - let result = Self::call( - &mut std::cell::RefCell::borrow_mut(&ctx.state), - arg_0, - arg_1, - ); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - } -} -impl<FP> op_ffi_ptr_of<FP> -where - FP: FfiPermissions + 'static, -{ - #[allow(clippy::too_many_arguments)] - fn op_ffi_ptr_of_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - buf: *const deno_core::v8::fast_api::FastApiTypedArray<u8>, - out: *const deno_core::v8::fast_api::FastApiTypedArray<u32>, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state); - let buf = unsafe { (&*buf).get_storage_if_aligned().unwrap_unchecked() } - .as_ptr(); - let out = match unsafe { &*out }.get_storage_if_aligned() { - Some(v) => v, - None => { - unsafe { &mut *fast_api_callback_options }.fallback = true; - return Default::default(); - } - }; - let result = Self::call(state, buf, out); - result - } -} diff --git a/ops/optimizer_tests/raw_ptr.rs b/ops/optimizer_tests/raw_ptr.rs deleted file mode 100644 index 249b3b35b..000000000 --- a/ops/optimizer_tests/raw_ptr.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn op_ffi_ptr_of<FP>(state: &mut OpState, buf: *const u8, out: &mut [u32]) -where - FP: FfiPermissions + 'static, -{ - // .. -} diff --git a/ops/optimizer_tests/serde_v8_value.expected b/ops/optimizer_tests/serde_v8_value.expected deleted file mode 100644 index 411fbec0b..000000000 --- a/ops/optimizer_tests/serde_v8_value.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(Bool) -fast_parameters: [V8Value, V8Value] -transforms: {0: Transform { kind: V8Value, index: 0 }} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/serde_v8_value.out b/ops/optimizer_tests/serde_v8_value.out deleted file mode 100644 index 20cc97584..000000000 --- a/ops/optimizer_tests/serde_v8_value.out +++ /dev/null @@ -1,124 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_is_proxy::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_is_proxy { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_is_proxy { - const NAME: &'static str = stringify!(op_is_proxy); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, V8Value], - CType::Bool, - Self::op_is_proxy_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_is_proxy { - pub const fn name() -> &'static str { - stringify!(op_is_proxy) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, V8Value], - CType::Bool, - Self::op_is_proxy_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(value: serde_v8::Value) -> bool { - value.v8_value.is_proxy() - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = args.get(0usize as i32); - let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 0usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let result = Self::call(arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match deno_core::serde_v8::to_v8(scope, result) { - Ok(ret) => rv.set(ret), - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!( - "Error serializing return: {}", - deno_core::anyhow::Error::from(err) - ), - ) - } - }; - } -} -impl op_is_proxy { - #[allow(clippy::too_many_arguments)] - fn op_is_proxy_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - value: deno_core::v8::Local<deno_core::v8::Value>, - ) -> bool { - use deno_core::v8; - use deno_core::_ops; - let value = serde_v8::Value { v8_value: value }; - let result = Self::call(value); - result - } -} diff --git a/ops/optimizer_tests/serde_v8_value.rs b/ops/optimizer_tests/serde_v8_value.rs deleted file mode 100644 index c986930d9..000000000 --- a/ops/optimizer_tests/serde_v8_value.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn op_is_proxy(value: serde_v8::Value) -> bool { - value.v8_value.is_proxy() -} diff --git a/ops/optimizer_tests/strings.expected b/ops/optimizer_tests/strings.expected deleted file mode 100644 index 4a6bb1556..000000000 --- a/ops/optimizer_tests/strings.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: true -fast_result: Some(U32) -fast_parameters: [V8Value, SeqOneByteString] -transforms: {0: Transform { kind: SeqOneByteString(Ref), index: 0 }} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/strings.out b/ops/optimizer_tests/strings.out deleted file mode 100644 index c59214f6a..000000000 --- a/ops/optimizer_tests/strings.out +++ /dev/null @@ -1,132 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_string_length::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_string_length { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_string_length { - const NAME: &'static str = stringify!(op_string_length); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, SeqOneByteString, CallbackOptions], - CType::Uint32, - Self::op_string_length_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_string_length { - pub const fn name() -> &'static str { - stringify!(op_string_length) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, SeqOneByteString, CallbackOptions], - CType::Uint32, - Self::op_string_length_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(string: &str) -> u32 { - string.len() as u32 - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = match deno_core::v8::Local::< - deno_core::v8::String, - >::try_from(args.get(0usize as i32)) { - Ok(v8_string) => deno_core::serde_v8::to_utf8(v8_string, scope), - Err(_) => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected string at position {}", 0usize), - ); - } - }; - let arg_0 = arg_0.as_ref(); - let result = Self::call(arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match deno_core::serde_v8::to_v8(scope, result) { - Ok(ret) => rv.set(ret), - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!( - "Error serializing return: {}", - deno_core::anyhow::Error::from(err) - ), - ) - } - }; - } -} -impl op_string_length { - #[allow(clippy::too_many_arguments)] - fn op_string_length_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - string: *const deno_core::v8::fast_api::FastApiOneByteString, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> u32 { - use deno_core::v8; - use deno_core::_ops; - let string = match ::std::str::from_utf8(unsafe { &*string }.as_bytes()) { - Ok(v) => v, - Err(_) => { - unsafe { &mut *fast_api_callback_options }.fallback = true; - return Default::default(); - } - }; - let result = Self::call(string); - result - } -} diff --git a/ops/optimizer_tests/strings.rs b/ops/optimizer_tests/strings.rs deleted file mode 100644 index 860f1e8ec..000000000 --- a/ops/optimizer_tests/strings.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn op_string_length(string: &str) -> u32 { - string.len() as u32 -} diff --git a/ops/optimizer_tests/strings_result.expected b/ops/optimizer_tests/strings_result.expected deleted file mode 100644 index 3866751fd..000000000 --- a/ops/optimizer_tests/strings_result.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: true -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: true -fast_result: Some(U32) -fast_parameters: [V8Value, SeqOneByteString] -transforms: {0: Transform { kind: SeqOneByteString(Ref), index: 0 }} -is_async: false -fast_compatible: false diff --git a/ops/optimizer_tests/strings_result.out b/ops/optimizer_tests/strings_result.out deleted file mode 100644 index 45ca1fac7..000000000 --- a/ops/optimizer_tests/strings_result.out +++ /dev/null @@ -1,93 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_string_length::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_string_length { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_string_length { - const NAME: &'static str = stringify!(op_string_length); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_string_length { - pub const fn name() -> &'static str { - stringify!(op_string_length) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(string: &str) -> Result<u32, AnyError> { - Ok(string.len() as u32) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = match deno_core::v8::Local::< - deno_core::v8::String, - >::try_from(args.get(0usize as i32)) { - Ok(v8_string) => deno_core::serde_v8::to_utf8(v8_string, scope), - Err(_) => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected string at position {}", 0usize), - ); - } - }; - let arg_0 = arg_0.as_ref(); - let result = Self::call(arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => { - rv.set_uint32(result as u32); - } - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} diff --git a/ops/optimizer_tests/strings_result.rs b/ops/optimizer_tests/strings_result.rs deleted file mode 100644 index f89efaab1..000000000 --- a/ops/optimizer_tests/strings_result.rs +++ /dev/null @@ -1,4 +0,0 @@ -// https://github.com/denoland/deno/issues/16979 -fn op_string_length(string: &str) -> Result<u32, AnyError> { - Ok(string.len() as u32) -} diff --git a/ops/optimizer_tests/u64_result.expected b/ops/optimizer_tests/u64_result.expected deleted file mode 100644 index 250ff1022..000000000 --- a/ops/optimizer_tests/u64_result.expected +++ /dev/null @@ -1 +0,0 @@ -FastUnsupportedParamType
\ No newline at end of file diff --git a/ops/optimizer_tests/u64_result.out b/ops/optimizer_tests/u64_result.out deleted file mode 100644 index 5a4df68b1..000000000 --- a/ops/optimizer_tests/u64_result.out +++ /dev/null @@ -1,94 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_bench_now::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_bench_now { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_bench_now { - const NAME: &'static str = stringify!(op_bench_now); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_bench_now { - pub const fn name() -> &'static str { - stringify!(op_bench_now) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: None, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(state: &mut OpState) -> Result<u64, AnyError> { - let ns = state.borrow::<time::Instant>().elapsed().as_nanos(); - let ns_u64 = u64::try_from(ns)?; - Ok(ns_u64) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let result = Self::call(&mut std::cell::RefCell::borrow_mut(&ctx.state)); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => { - match deno_core::serde_v8::to_v8(scope, result) { - Ok(ret) => rv.set(ret), - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!( - "Error serializing return: {}", - deno_core::anyhow::Error::from(err) - ), - ) - } - }; - } - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} diff --git a/ops/optimizer_tests/u64_result.rs b/ops/optimizer_tests/u64_result.rs deleted file mode 100644 index 1cc783db8..000000000 --- a/ops/optimizer_tests/u64_result.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn op_bench_now(state: &mut OpState) -> Result<u64, AnyError> { - let ns = state.borrow::<time::Instant>().elapsed().as_nanos(); - let ns_u64 = u64::try_from(ns)?; - Ok(ns_u64) -} diff --git a/ops/optimizer_tests/uint8array.expected b/ops/optimizer_tests/uint8array.expected deleted file mode 100644 index 49554a2e8..000000000 --- a/ops/optimizer_tests/uint8array.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(Bool) -fast_parameters: [V8Value, Uint8Array, Uint8Array] -transforms: {0: Transform { kind: SliceU8(false), index: 0 }, 1: Transform { kind: SliceU8(true), index: 1 }} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/uint8array.out b/ops/optimizer_tests/uint8array.out deleted file mode 100644 index 335bf42f6..000000000 --- a/ops/optimizer_tests/uint8array.out +++ /dev/null @@ -1,205 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_import_spki_x25519::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_import_spki_x25519 { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_import_spki_x25519 { - const NAME: &'static str = stringify!(op_import_spki_x25519); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, TypedArray(CType::Uint8), TypedArray(CType::Uint8)], - CType::Bool, - Self::op_import_spki_x25519_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_import_spki_x25519 { - pub const fn name() -> &'static str { - stringify!(op_import_spki_x25519) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, TypedArray(CType::Uint8), TypedArray(CType::Uint8)], - CType::Bool, - Self::op_import_spki_x25519_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - pub fn call<'scope>(key_data: &[u8], out: &mut [u8]) -> bool {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = { - let value = args.get(0usize as i32); - match deno_core::v8::Local::<deno_core::v8::ArrayBuffer>::try_from(value) { - Ok(b) => { - let byte_length = b.byte_length(); - if let Some(data) = b.data() { - let store = data.cast::<u8>().as_ptr(); - unsafe { ::std::slice::from_raw_parts_mut(store, byte_length) } - } else { - &mut [] - } - } - Err(_) => { - if let Ok(view) - = deno_core::v8::Local::< - deno_core::v8::ArrayBufferView, - >::try_from(value) { - let len = view.byte_length(); - let offset = view.byte_offset(); - let buffer = match view.buffer(scope) { - Some(v) => v, - None => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected ArrayBufferView at position {}", 0usize), - ); - } - }; - if let Some(data) = buffer.data() { - let store = data.cast::<u8>().as_ptr(); - unsafe { - ::std::slice::from_raw_parts_mut(store.add(offset), len) - } - } else { - &mut [] - } - } else { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected ArrayBufferView at position {}", 0usize), - ); - } - } - } - }; - let arg_1 = { - let value = args.get(1usize as i32); - match deno_core::v8::Local::<deno_core::v8::ArrayBuffer>::try_from(value) { - Ok(b) => { - let byte_length = b.byte_length(); - if let Some(data) = b.data() { - let store = data.cast::<u8>().as_ptr(); - unsafe { ::std::slice::from_raw_parts_mut(store, byte_length) } - } else { - &mut [] - } - } - Err(_) => { - if let Ok(view) - = deno_core::v8::Local::< - deno_core::v8::ArrayBufferView, - >::try_from(value) { - let len = view.byte_length(); - let offset = view.byte_offset(); - let buffer = match view.buffer(scope) { - Some(v) => v, - None => { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected ArrayBufferView at position {}", 1usize), - ); - } - }; - if let Some(data) = buffer.data() { - let store = data.cast::<u8>().as_ptr(); - unsafe { - ::std::slice::from_raw_parts_mut(store.add(offset), len) - } - } else { - &mut [] - } - } else { - return deno_core::_ops::throw_type_error( - scope, - format!("Expected ArrayBufferView at position {}", 1usize), - ); - } - } - } - }; - let result = Self::call(arg_0, arg_1); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match deno_core::serde_v8::to_v8(scope, result) { - Ok(ret) => rv.set(ret), - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!( - "Error serializing return: {}", - deno_core::anyhow::Error::from(err) - ), - ) - } - }; - } -} -impl op_import_spki_x25519 { - #[allow(clippy::too_many_arguments)] - fn op_import_spki_x25519_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - key_data: *const deno_core::v8::fast_api::FastApiTypedArray<u8>, - out: *const deno_core::v8::fast_api::FastApiTypedArray<u8>, - ) -> bool { - use deno_core::v8; - use deno_core::_ops; - let key_data = unsafe { - (&*key_data).get_storage_if_aligned().unwrap_unchecked() - }; - let out = unsafe { (&*out).get_storage_if_aligned().unwrap_unchecked() }; - let result = Self::call(key_data, out); - result - } -} diff --git a/ops/optimizer_tests/uint8array.rs b/ops/optimizer_tests/uint8array.rs deleted file mode 100644 index f4507b21f..000000000 --- a/ops/optimizer_tests/uint8array.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn op_import_spki_x25519(key_data: &[u8], out: &mut [u8]) -> bool { - // ... -} diff --git a/ops/optimizer_tests/unit_result.expected b/ops/optimizer_tests/unit_result.expected deleted file mode 100644 index 693a771e9..000000000 --- a/ops/optimizer_tests/unit_result.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: true -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(Void) -fast_parameters: [V8Value] -transforms: {} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/unit_result.out b/ops/optimizer_tests/unit_result.out deleted file mode 100644 index 894297255..000000000 --- a/ops/optimizer_tests/unit_result.out +++ /dev/null @@ -1,137 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_unit_result::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_unit_result { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_unit_result { - const NAME: &'static str = stringify!(op_unit_result); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, CallbackOptions], - CType::Void, - Self::op_unit_result_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_unit_result { - pub const fn name() -> &'static str { - stringify!(op_unit_result) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, CallbackOptions], - CType::Void, - Self::op_unit_result_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>() -> Result<(), AnyError> { - Ok(()) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - { - let op_state = &mut std::cell::RefCell::borrow_mut(&ctx.state); - if let Some(err) = op_state.last_fast_op_error.take() { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - return; - } - } - let result = Self::call(); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => {} - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} -impl op_unit_result { - #[allow(clippy::too_many_arguments)] - fn op_unit_result_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let op_state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state); - let result = Self::call(); - match result { - Ok(result) => result, - Err(err) => { - op_state.last_fast_op_error.replace(err); - __opts.fallback = true; - } - } - } -} diff --git a/ops/optimizer_tests/unit_result.rs b/ops/optimizer_tests/unit_result.rs deleted file mode 100644 index 207896929..000000000 --- a/ops/optimizer_tests/unit_result.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn op_unit_result() -> Result<(), AnyError> { - Ok(()) -} diff --git a/ops/optimizer_tests/unit_result2.expected b/ops/optimizer_tests/unit_result2.expected deleted file mode 100644 index d799a77b2..000000000 --- a/ops/optimizer_tests/unit_result2.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: true -has_ref_opstate: true -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(Void) -fast_parameters: [V8Value, U32, Bool] -transforms: {} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/unit_result2.out b/ops/optimizer_tests/unit_result2.out deleted file mode 100644 index d091b91cd..000000000 --- a/ops/optimizer_tests/unit_result2.out +++ /dev/null @@ -1,172 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_set_nodelay::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_set_nodelay { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_set_nodelay { - const NAME: &'static str = stringify!(op_set_nodelay); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Uint32, Bool, CallbackOptions], - CType::Void, - Self::op_set_nodelay_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_set_nodelay { - pub const fn name() -> &'static str { - stringify!(op_set_nodelay) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, Uint32, Bool, CallbackOptions], - CType::Void, - Self::op_set_nodelay_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 2usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - pub fn call<'scope>( - state: &mut OpState, - rid: ResourceId, - nodelay: bool, - ) -> Result<(), AnyError> { - let resource: Rc<TcpStreamResource> = state - .resource_table - .get::<TcpStreamResource>(rid)?; - resource.set_nodelay(nodelay) - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - { - let op_state = &mut std::cell::RefCell::borrow_mut(&ctx.state); - if let Some(err) = op_state.last_fast_op_error.take() { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - return; - } - } - let arg_0 = args.get(0usize as i32); - let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 0usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let arg_1 = args.get(1usize as i32); - let arg_1 = match deno_core::serde_v8::from_v8(scope, arg_1) { - Ok(v) => v, - Err(err) => { - let msg = format!( - "Error parsing args at position {}: {}", 1usize, - deno_core::anyhow::Error::from(err) - ); - return deno_core::_ops::throw_type_error(scope, msg); - } - }; - let result = Self::call( - &mut std::cell::RefCell::borrow_mut(&ctx.state), - arg_0, - arg_1, - ); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match result { - Ok(result) => {} - Err(err) => { - let exception = deno_core::error::to_v8_error( - scope, - op_state.get_error_class_fn, - &err, - ); - scope.throw_exception(exception); - } - }; - } -} -impl op_set_nodelay { - #[allow(clippy::too_many_arguments)] - fn op_set_nodelay_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - rid: ResourceId, - nodelay: bool, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let __ctx = unsafe { - &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value() - as *const _ops::OpCtx) - }; - let state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state); - let result = Self::call(state, rid, nodelay); - match result { - Ok(result) => result, - Err(err) => { - state.last_fast_op_error.replace(err); - __opts.fallback = true; - } - } - } -} diff --git a/ops/optimizer_tests/unit_result2.rs b/ops/optimizer_tests/unit_result2.rs deleted file mode 100644 index 83b73e194..000000000 --- a/ops/optimizer_tests/unit_result2.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub fn op_set_nodelay( - state: &mut OpState, - rid: ResourceId, - nodelay: bool, -) -> Result<(), AnyError> { - let resource: Rc<TcpStreamResource> = - state.resource_table.get::<TcpStreamResource>(rid)?; - resource.set_nodelay(nodelay) -} diff --git a/ops/optimizer_tests/unit_ret.expected b/ops/optimizer_tests/unit_ret.expected deleted file mode 100644 index 5d414e1e3..000000000 --- a/ops/optimizer_tests/unit_ret.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(Void) -fast_parameters: [V8Value] -transforms: {} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/unit_ret.out b/ops/optimizer_tests/unit_ret.out deleted file mode 100644 index 1a721c407..000000000 --- a/ops/optimizer_tests/unit_ret.out +++ /dev/null @@ -1,109 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_unit::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_unit { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_unit { - const NAME: &'static str = stringify!(op_unit); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value], - CType::Void, - Self::op_unit_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_unit { - pub const fn name() -> &'static str { - stringify!(op_unit) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value], - CType::Void, - Self::op_unit_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>() -> () { - () - } - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let result = Self::call(); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - match deno_core::serde_v8::to_v8(scope, result) { - Ok(ret) => rv.set(ret), - Err(err) => { - deno_core::_ops::throw_type_error( - scope, - format!( - "Error serializing return: {}", - deno_core::anyhow::Error::from(err) - ), - ) - } - }; - } -} -impl op_unit { - #[allow(clippy::too_many_arguments)] - fn op_unit_fast_fn(_: deno_core::v8::Local<deno_core::v8::Object>) -> () { - use deno_core::v8; - use deno_core::_ops; - let result = Self::call(); - result - } -} diff --git a/ops/optimizer_tests/unit_ret.rs b/ops/optimizer_tests/unit_ret.rs deleted file mode 100644 index 4cf3651db..000000000 --- a/ops/optimizer_tests/unit_ret.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn op_unit() -> () { - () -} diff --git a/ops/optimizer_tests/wasm_op.expected b/ops/optimizer_tests/wasm_op.expected deleted file mode 100644 index 8d3719cf7..000000000 --- a/ops/optimizer_tests/wasm_op.expected +++ /dev/null @@ -1,11 +0,0 @@ -=== Optimizer Dump === -returns_result: false -has_ref_opstate: false -has_rc_opstate: false -has_fast_callback_option: false -needs_fast_callback_option: false -fast_result: Some(Void) -fast_parameters: [V8Value] -transforms: {0: Transform { kind: WasmMemory, index: 0 }} -is_async: false -fast_compatible: true diff --git a/ops/optimizer_tests/wasm_op.out b/ops/optimizer_tests/wasm_op.out deleted file mode 100644 index 023506fc2..000000000 --- a/ops/optimizer_tests/wasm_op.out +++ /dev/null @@ -1,107 +0,0 @@ -#[allow(non_camel_case_types)] -///Auto-generated by `deno_ops`, i.e: `#[op]` -/// -///Use `op_wasm::decl()` to get an op-declaration -///you can include in a `deno_core::Extension`. -pub struct op_wasm { - _phantom_data: ::std::marker::PhantomData<()>, -} -impl deno_core::_ops::Op for op_wasm { - const NAME: &'static str = stringify!(op_wasm); - const DECL: deno_core::OpDecl = deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, CallbackOptions], - CType::Void, - Self::op_wasm_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 0, - }; -} -#[doc(hidden)] -impl op_wasm { - pub const fn name() -> &'static str { - stringify!(op_wasm) - } - #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub extern "C" fn v8_fn_ptr(info: *const deno_core::v8::FunctionCallbackInfo) { - let info = unsafe { &*info }; - let scope = &mut unsafe { deno_core::v8::CallbackScope::new(info) }; - let args = deno_core::v8::FunctionCallbackArguments::from_function_callback_info( - info, - ); - let rv = deno_core::v8::ReturnValue::from_function_callback_info(info); - Self::v8_func(scope, args, rv); - } - pub const fn decl() -> deno_core::OpDecl { - deno_core::OpDecl { - name: Self::name(), - v8_fn_ptr: Self::v8_fn_ptr as _, - enabled: true, - fast_fn: { - use deno_core::v8::fast_api::CType; - use deno_core::v8::fast_api::Type::*; - Some( - deno_core::v8::fast_api::FastFunction::new( - &[V8Value, CallbackOptions], - CType::Void, - Self::op_wasm_fast_fn as *const ::std::ffi::c_void, - ), - ) - }, - is_async: false, - is_unstable: false, - is_v8: false, - arg_count: 1usize as u8, - } - } - #[inline] - #[allow(clippy::too_many_arguments)] - #[allow(clippy::extra_unused_lifetimes)] - fn call<'scope>(memory: Option<&mut [u8]>) {} - pub fn v8_func<'scope>( - scope: &mut deno_core::v8::HandleScope<'scope>, - args: deno_core::v8::FunctionCallbackArguments, - mut rv: deno_core::v8::ReturnValue, - ) { - let ctx = unsafe { - &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value() - as *const deno_core::_ops::OpCtx) - }; - let arg_0 = None; - let result = Self::call(arg_0); - let op_state = ::std::cell::RefCell::borrow(&*ctx.state); - op_state.tracker.track_sync(ctx.id); - } -} -impl op_wasm { - #[allow(clippy::too_many_arguments)] - fn op_wasm_fast_fn( - _: deno_core::v8::Local<deno_core::v8::Object>, - fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions, - ) -> () { - use deno_core::v8; - use deno_core::_ops; - let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe { - &mut *fast_api_callback_options - }; - let memory = unsafe { - &*(__opts.wasm_memory - as *const deno_core::v8::fast_api::FastApiTypedArray<u8>) - } - .get_storage_if_aligned(); - let result = Self::call(memory); - result - } -} diff --git a/ops/optimizer_tests/wasm_op.rs b/ops/optimizer_tests/wasm_op.rs deleted file mode 100644 index b18f32fd1..000000000 --- a/ops/optimizer_tests/wasm_op.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn op_wasm(memory: Option<&mut [u8]>) { - // @test-attr:wasm -} diff --git a/ops/tests/compile_fail/mem_slices.rs b/ops/tests/compile_fail/mem_slices.rs deleted file mode 100644 index da74ac577..000000000 --- a/ops/tests/compile_fail/mem_slices.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -use deno_ops::op; - -#[op] -fn sync_test(slice: &mut [u32]) { - // -} - -#[op] -async fn async_test(slice: &[u8]) { - // Memory slices are not allowed in async ops. -} - -#[op] -fn async_test2(slice: &mut [u8]) -> impl Future<Output = ()> { - // Memory slices are not allowed in async ops, even when not implemented as an - // async function. - async {} -} - -fn main() { - // pass -} diff --git a/ops/tests/compile_fail/mem_slices.stderr b/ops/tests/compile_fail/mem_slices.stderr deleted file mode 100644 index c45acfcf9..000000000 --- a/ops/tests/compile_fail/mem_slices.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: custom attribute panicked - --> tests/compile_fail/mem_slices.rs:10:1 - | -10 | #[op] - | ^^^^^ - | - = help: message: Memory slices are not allowed in async ops - -error: custom attribute panicked - --> tests/compile_fail/mem_slices.rs:15:1 - | -15 | #[op] - | ^^^^^ - | - = help: message: Memory slices are not allowed in async ops |