diff options
Diffstat (limited to 'ops/op2/dispatch_fast.rs')
-rw-r--r-- | ops/op2/dispatch_fast.rs | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/ops/op2/dispatch_fast.rs b/ops/op2/dispatch_fast.rs index 5262196f4..f9d74416a 100644 --- a/ops/op2/dispatch_fast.rs +++ b/ops/op2/dispatch_fast.rs @@ -4,10 +4,13 @@ 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)] @@ -49,10 +52,12 @@ impl V8FastCallType { 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 - | V8FastCallType::SeqOneByteString => unreachable!(), + | V8FastCallType::Float64Array => unreachable!(), } } @@ -190,7 +195,10 @@ pub fn generate_dispatch_fast( .map(|rv| rv.quote_rust_type(deno_core)) .collect::<Vec<_>>(); - let call_args = names.clone(); + 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)); @@ -219,7 +227,8 @@ pub fn generate_dispatch_fast( ) -> #output_type { #with_fast_api_callback_options #with_opctx - let #result = Self::call(#(#call_args as _),*); + #(#call_args)* + let #result = Self::call(#(#call_idents),*); #handle_error #result } @@ -228,6 +237,32 @@ pub fn generate_dispatch_fast( 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> { @@ -247,6 +282,13 @@ fn map_arg_to_v8_fastcall_type( 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)) @@ -271,6 +313,8 @@ fn map_retval_to_v8_fastcall_type( 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( |