diff options
Diffstat (limited to 'ops/op2')
-rw-r--r-- | ops/op2/dispatch_fast.rs | 52 | ||||
-rw-r--r-- | ops/op2/dispatch_slow.rs | 66 | ||||
-rw-r--r-- | ops/op2/signature.rs | 12 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/add.out | 4 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/smi.out | 4 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/string_cow.out | 75 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/string_cow.rs | 4 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/string_option_return.out | 53 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/string_option_return.rs | 5 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/string_owned.out | 73 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/string_owned.rs | 4 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/string_ref.out | 75 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/string_ref.rs | 4 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/string_return.out | 49 | ||||
-rw-r--r-- | ops/op2/test_cases/sync/string_return.rs | 5 |
15 files changed, 475 insertions, 10 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( diff --git a/ops/op2/dispatch_slow.rs b/ops/op2/dispatch_slow.rs index bf36e5d83..2ec67cc76 100644 --- a/ops/op2/dispatch_slow.rs +++ b/ops/op2/dispatch_slow.rs @@ -8,6 +8,7 @@ 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( @@ -151,10 +152,14 @@ pub fn from_arg( arg: &Arg, ) -> Result<TokenStream, V8MappingError> { let GeneratorState { - deno_core, args, .. + 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(); @@ -198,13 +203,31 @@ pub fn from_arg( } } 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(); + 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! { - let #arg_ident = #arg_ident.to_rust_string_lossy(); + // 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())), @@ -243,9 +266,12 @@ pub fn return_value_infallible( ret_type: &Arg, ) -> Result<TokenStream, V8MappingError> { let GeneratorState { + deno_core, + scope, result, retval, needs_retval, + needs_scope, .. } = generator_state; @@ -265,6 +291,38 @@ pub fn return_value_infallible( *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", diff --git a/ops/op2/signature.rs b/ops/op2/signature.rs index 15c40e007..5d472fcf3 100644 --- a/ops/op2/signature.rs +++ b/ops/op2/signature.rs @@ -106,6 +106,7 @@ pub enum Special { HandleScope, OpState, String, + CowStr, RefStr, FastApiCallbackOptions, } @@ -431,6 +432,17 @@ fn parse_type_path(attrs: Attributes, tp: &TypePath) -> Result<Arg, ArgError> { 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)), diff --git a/ops/op2/test_cases/sync/add.out b/ops/op2/test_cases/sync/add.out index c8f77ab92..a73f032aa 100644 --- a/ops/op2/test_cases/sync/add.out +++ b/ops/op2/test_cases/sync/add.out @@ -52,7 +52,9 @@ impl op_add { arg0: u32, arg1: u32, ) -> u32 { - let result = Self::call(arg0 as _, arg1 as _); + 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) { diff --git a/ops/op2/test_cases/sync/smi.out b/ops/op2/test_cases/sync/smi.out index 85db2576e..24b81ae47 100644 --- a/ops/op2/test_cases/sync/smi.out +++ b/ops/op2/test_cases/sync/smi.out @@ -52,7 +52,9 @@ impl op_add { arg0: i32, arg1: u32, ) -> u32 { - let result = Self::call(arg0 as _, arg1 as _); + 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) { diff --git a/ops/op2/test_cases/sync/string_cow.out b/ops/op2/test_cases/sync/string_cow.out new file mode 100644 index 000000000..7d388e598 --- /dev/null +++ b/ops/op2/test_cases/sync/string_cow.out @@ -0,0 +1,75 @@ +#[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 new file mode 100644 index 000000000..ed4dfca82 --- /dev/null +++ b/ops/op2/test_cases/sync/string_cow.rs @@ -0,0 +1,4 @@ +// 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 new file mode 100644 index 000000000..6143ac217 --- /dev/null +++ b/ops/op2/test_cases/sync/string_option_return.out @@ -0,0 +1,53 @@ +#[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 new file mode 100644 index 000000000..932836d2f --- /dev/null +++ b/ops/op2/test_cases/sync/string_option_return.rs @@ -0,0 +1,5 @@ +// 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 new file mode 100644 index 000000000..7418a311c --- /dev/null +++ b/ops/op2/test_cases/sync/string_owned.out @@ -0,0 +1,73 @@ +#[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 new file mode 100644 index 000000000..b81d7ece9 --- /dev/null +++ b/ops/op2/test_cases/sync/string_owned.rs @@ -0,0 +1,4 @@ +// 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 new file mode 100644 index 000000000..1b853fccc --- /dev/null +++ b/ops/op2/test_cases/sync/string_ref.out @@ -0,0 +1,75 @@ +#[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 new file mode 100644 index 000000000..a7efa9f0c --- /dev/null +++ b/ops/op2/test_cases/sync/string_ref.rs @@ -0,0 +1,4 @@ +// 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 new file mode 100644 index 000000000..5e68b9314 --- /dev/null +++ b/ops/op2/test_cases/sync/string_return.out @@ -0,0 +1,49 @@ +#[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 new file mode 100644 index 000000000..667b68a14 --- /dev/null +++ b/ops/op2/test_cases/sync/string_return.rs @@ -0,0 +1,5 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. + +#[op2] +#[string] +pub fn op_string_return() -> String {} |