summaryrefslogtreecommitdiff
path: root/ops/fast_call.rs
diff options
context:
space:
mode:
authorMatt Mastracci <matthew@mastracci.com>2023-06-29 10:23:14 -0600
committerGitHub <noreply@github.com>2023-06-29 10:23:14 -0600
commitfbb69329343c9985c26181e6297e6556c46d381d (patch)
treeee428c94727bdfdf9040a4944bd66981b4cd07fb /ops/fast_call.rs
parent98df69fd4cbe3687e2ff3519fbd6bff4e5f3101f (diff)
refactor(ops): op2 support for generics (#19636)
Implementation of generics for `#[op2]`, along with some refactoring to improve the ergonomics of ops with generics parameters: - The ops have generics on the struct rather than the associated methods, which allows us to trait-ify ops (impossible when they are on the methods) - The decl() method can become a trait-associated const field which unlocks future optimizations Callers of ops need to switch from: `op_net_connect_tcp::call::<TestPermission>(conn_state, ip_addr)` to `op_net_connect_tcp::<TestPermission>::call(conn_state, ip_addr)`.
Diffstat (limited to 'ops/fast_call.rs')
-rw-r--r--ops/fast_call.rs79
1 files changed, 30 insertions, 49 deletions
diff --git a/ops/fast_call.rs b/ops/fast_call.rs
index ebbb1927b..63cff4c62 100644
--- a/ops/fast_call.rs
+++ b/ops/fast_call.rs
@@ -10,7 +10,6 @@ use quote::quote;
use syn::parse_quote;
use syn::punctuated::Punctuated;
use syn::token::Comma;
-use syn::GenericParam;
use syn::Generics;
use syn::Ident;
use syn::ItemFn;
@@ -68,14 +67,6 @@ pub(crate) fn generate(
let generics = &item_fn.sig.generics;
let (impl_generics, _, where_clause) = generics.split_for_impl();
- // struct op_foo_fast <T, U> { ... }
- let struct_generics = exclude_lifetime_params(&generics.params);
- // op_foo_fast_fn :: <T>
- let caller_generics: Quote = match struct_generics {
- Some(ref params) => q!(Vars { params }, { ::params }),
- None => q!({}),
- };
-
// This goes in the FastFunction impl block.
// let mut segments = Punctuated::new();
// {
@@ -280,16 +271,18 @@ pub(crate) fn generate(
// r.into()
// }
let fast_fn = q!(
- Vars { core, pre_transforms, op_name_fast: &fast_fn_ident, op_name: &ident, fast_fn_inputs, generics, call_generics: &caller_generics, where_clause, idents, transforms, output_transforms, output: &output },
+ 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 },
{
- #[allow(clippy::too_many_arguments)]
- fn op_name_fast generics (_: core::v8::Local<core::v8::Object>, fast_fn_inputs) -> output where_clause {
- use core::v8;
- use core::_ops;
- pre_transforms
- transforms
- let result = op_name::call call_generics (idents);
- output_transforms
+ 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
+ }
}
}
);
@@ -300,17 +293,25 @@ pub(crate) fn generate(
// 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, generics: caller_generics, inputs: input_variants, output: output_variant },
- {{
- use core::v8::fast_api::Type::*;
- use core::v8::fast_api::CType;
- Some(core::v8::fast_api::FastFunction::new(
- &[ inputs ],
- CType :: output,
- fast_fn_ident generics as *const ::std::ffi::c_void
- ))
- }}
- ).dump();
+ 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();
@@ -360,23 +361,3 @@ fn q_fast_ty_variant(v: &FastValue) -> Quote {
FastValue::SeqOneByteString => q!({ SeqOneByteString }),
}
}
-
-fn exclude_lifetime_params(
- generic_params: &Punctuated<GenericParam, Comma>,
-) -> Option<Generics> {
- let params = generic_params
- .iter()
- .filter(|t| !matches!(t, GenericParam::Lifetime(_)))
- .cloned()
- .collect::<Punctuated<GenericParam, Comma>>();
- if params.is_empty() {
- // <()>
- return None;
- }
- Some(Generics {
- lt_token: Some(Default::default()),
- params,
- gt_token: Some(Default::default()),
- where_clause: None,
- })
-}