diff options
Diffstat (limited to 'ops/lib.rs')
-rw-r--r-- | ops/lib.rs | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/ops/lib.rs b/ops/lib.rs index 0b0689356..7d291d1da 100644 --- a/ops/lib.rs +++ b/ops/lib.rs @@ -304,6 +304,7 @@ fn codegen_fast_impl( args, ret, use_recv, + v8_values, }) = fast_info { let inputs = &f @@ -311,17 +312,42 @@ fn codegen_fast_impl( .inputs .iter() .skip(if use_recv { 1 } else { 0 }) + .enumerate() + .map(|(idx, arg)| { + if v8_values.contains(&idx) { + let ident = match arg { + FnArg::Receiver(_) => unreachable!(), + FnArg::Typed(t) => match &*t.pat { + syn::Pat::Ident(i) => format_ident!("{}", i.ident), + _ => unreachable!(), + }, + }; + return quote! { #ident: #core::v8::Local < #core::v8::Value > }; + } + quote!(#arg) + }) .collect::<Vec<_>>(); let input_idents = f .sig .inputs .iter() - .map(|a| match a { - FnArg::Receiver(_) => unreachable!(), - FnArg::Typed(t) => match &*t.pat { - syn::Pat::Ident(i) => format_ident!("{}", i.ident), - _ => unreachable!(), - }, + .enumerate() + .map(|(idx, a)| { + let ident = match a { + FnArg::Receiver(_) => unreachable!(), + FnArg::Typed(t) => match &*t.pat { + syn::Pat::Ident(i) => format_ident!("{}", i.ident), + _ => unreachable!(), + }, + }; + if v8_values.contains(&idx) { + return quote! { + #core::serde_v8::Value { + v8_value: #ident, + } + }; + } + quote! { #ident } }) .collect::<Vec<_>>(); let generics = &f.sig.generics; @@ -453,6 +479,7 @@ struct FastApiSyn { args: TokenStream2, ret: TokenStream2, use_recv: bool, + v8_values: Vec<usize>, } fn can_be_fast_api(core: &TokenStream2, f: &syn::ItemFn) -> Option<FastApiSyn> { @@ -466,6 +493,7 @@ fn can_be_fast_api(core: &TokenStream2, f: &syn::ItemFn) -> Option<FastApiSyn> { }; let mut use_recv = false; + let mut v8_values = Vec::new(); let mut args = vec![quote! { #core::v8::fast_api::Type::V8Value }]; for (pos, input) in inputs.iter().enumerate() { if pos == 0 && is_mut_ref_opstate(input) { @@ -478,16 +506,21 @@ fn can_be_fast_api(core: &TokenStream2, f: &syn::ItemFn) -> Option<FastApiSyn> { _ => unreachable!(), }; - match is_fast_scalar(core, ty, false) { - None => match is_fast_arg_sequence(core, ty) { + if let Some(arg) = is_fast_v8_value(core, ty) { + args.push(arg); + v8_values.push(pos); + } else { + match is_fast_scalar(core, ty, false) { + None => match is_fast_arg_sequence(core, ty) { + Some(arg) => { + args.push(arg); + } + // early return, this function cannot be a fast call. + None => return None, + }, Some(arg) => { args.push(arg); } - // early return, this function cannot be a fast call. - None => return None, - }, - Some(arg) => { - args.push(arg); } } } @@ -501,6 +534,7 @@ fn can_be_fast_api(core: &TokenStream2, f: &syn::ItemFn) -> Option<FastApiSyn> { args: args.parse().unwrap(), ret, use_recv, + v8_values, }) } @@ -523,6 +557,16 @@ fn is_fast_arg_sequence( None } +fn is_fast_v8_value( + core: &TokenStream2, + arg: impl ToTokens, +) -> Option<TokenStream2> { + if tokens(&arg).contains("serde_v8 :: Value") { + return Some(quote! { #core::v8::fast_api::Type::V8Value }); + } + None +} + fn is_local_array(arg: impl ToTokens) -> bool { static RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"^v8::Local<v8::Array>$").unwrap()); @@ -558,6 +602,7 @@ fn is_fast_scalar( "i32" => Some(quote! { #core::v8::fast_api::#cty::Int32 }), "f32" => Some(quote! { #core::v8::fast_api::#cty::Float32 }), "f64" => Some(quote! { #core::v8::fast_api::#cty::Float64 }), + "bool" => Some(quote! { #core::v8::fast_api::#cty::Bool }), _ => None, } } |