diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2023-03-05 13:30:22 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-05 13:30:22 +0530 |
commit | 0910be4d64272be6774b8b3d44852737e8c53ad4 (patch) | |
tree | ef8dcbf2e5cf0c8940512923dec016dd2a30c762 /ops/attrs.rs | |
parent | 888ceac7fdc6e9b96d860f183dd2f31df3f3d601 (diff) |
feat(ops): relational ops (#18023)
Join two independent ops into one. A fast impl of one + a slow callback
of another. Here's an example showing optimized paths for latin-1 via
fast call and the next-best fallback using V8 apis.
```rust
#[op(v8)]
fn op_encoding_encode_into_fallback(
scope: &mut v8::HandleScope,
input: serde_v8::Value,
// ...
#[op(fast, slow = op_encoding_encode_into_fallback)]
fn op_encoding_encode_into(
input: Cow<'_, str>,
// ...
```
Benchmark results of the fallback path:
```
time target/release/deno run -A --unstable ./cli/tests/testdata/benches/text_encoder_into_perf.js
________________________________________________________
Executed in 70.90 millis fish external
usr time 57.76 millis 0.23 millis 57.53 millis
sys time 17.02 millis 1.28 millis 15.74 millis
target/release/deno_main run -A --unstable ./cli/tests/testdata/benches/text_encoder_into_perf.js
________________________________________________________
Executed in 154.00 millis fish external
usr time 67.14 millis 0.26 millis 66.88 millis
sys time 38.82 millis 1.47 millis 37.35 millis
```
Diffstat (limited to 'ops/attrs.rs')
-rw-r--r-- | ops/attrs.rs | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/ops/attrs.rs b/ops/attrs.rs index a76cfddf6..d0182fc69 100644 --- a/ops/attrs.rs +++ b/ops/attrs.rs @@ -1,44 +1,54 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use syn::parse::Parse; use syn::parse::ParseStream; -use syn::punctuated::Punctuated; use syn::Error; use syn::Ident; use syn::Result; use syn::Token; -#[derive(Copy, Clone, Debug, Default)] +#[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 vars = Punctuated::<Ident, Token![,]>::parse_terminated(input)?; - - let vars: Vec<_> = vars.iter().map(Ident::to_string).collect(); - let vars: Vec<_> = vars.iter().map(String::as_str).collect(); - for var in vars.iter() { - if !["unstable", "v8", "fast", "deferred", "wasm"].contains(var) { - return Err(Error::new( - input.span(), - "invalid attribute, expected one of: unstable, v8, fast, deferred, wasm", - )); - } + 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![,]>(); } - let is_wasm = vars.contains(&"wasm"); + self_.must_be_fast = self_.is_wasm || fast; - Ok(Self { - is_unstable: vars.contains(&"unstable"), - is_v8: vars.contains(&"v8"), - deferred: vars.contains(&"deferred"), - must_be_fast: is_wasm || vars.contains(&"fast"), - is_wasm, - }) + Ok(self_) } } |