diff options
Diffstat (limited to 'ops/optimizer.rs')
-rw-r--r-- | ops/optimizer.rs | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/ops/optimizer.rs b/ops/optimizer.rs index 3ca69a814..cf2c71ae4 100644 --- a/ops/optimizer.rs +++ b/ops/optimizer.rs @@ -2,13 +2,13 @@ use crate::Op; use pmutil::{q, Quote}; use proc_macro2::TokenStream; -use std::collections::HashMap; +use std::collections::BTreeMap; use std::fmt::Debug; use std::fmt::Formatter; use syn::{ parse_quote, punctuated::Punctuated, token::Colon2, AngleBracketedGenericArguments, FnArg, GenericArgument, PatType, Path, - PathArguments, PathSegment, ReturnType, Signature, Type, TypePath, + PathArguments, PathSegment, ReturnType, Signature, Type, TypePath, TypePtr, TypeReference, TypeSlice, }; @@ -25,6 +25,7 @@ enum TransformKind { V8Value, SliceU32(bool), SliceU8(bool), + PtrU8, } impl Transform { @@ -48,6 +49,13 @@ impl Transform { index, } } + + fn u8_ptr(index: usize) -> Self { + Transform { + kind: TransformKind::PtrU8, + index, + } + } } #[derive(Debug, PartialEq)] @@ -116,6 +124,21 @@ impl Transform { }; }) } + // *const u8 + TransformKind::PtrU8 => { + *ty = + parse_quote! { *const #core::v8::fast_api::FastApiTypedArray<u8> }; + + q!(Vars { var: &ident }, { + let var = match unsafe { &*var }.get_storage_if_aligned() { + Some(v) => v.as_ptr(), + None => { + unsafe { &mut *fast_api_callback_options }.fallback = true; + return Default::default(); + } + }; + }) + } } } } @@ -178,7 +201,7 @@ pub(crate) struct Optimizer { pub(crate) fast_result: Option<FastValue>, pub(crate) fast_parameters: Vec<FastValue>, - pub(crate) transforms: HashMap<usize, Transform>, + pub(crate) transforms: BTreeMap<usize, Transform>, pub(crate) fast_compatible: bool, pub(crate) is_async: bool, @@ -517,6 +540,32 @@ impl Optimizer { }, _ => return Err(BailoutReason::FastUnsupportedParamType), }, + // *const T + Type::Ptr(TypePtr { + elem, + const_token: Some(_), + .. + }) => match &**elem { + Type::Path(TypePath { + path: Path { segments, .. }, + .. + }) => { + let segment = single_segment(segments)?; + match segment { + // Is `T` a u8? + PathSegment { ident, .. } if ident == "u8" => { + self.has_fast_callback_option = true; + self.fast_parameters.push(FastValue::Uint8Array); + assert!(self + .transforms + .insert(index, Transform::u8_ptr(index)) + .is_none()); + } + _ => return Err(BailoutReason::FastUnsupportedParamType), + } + } + _ => return Err(BailoutReason::FastUnsupportedParamType), + }, _ => return Err(BailoutReason::FastUnsupportedParamType), }, _ => return Err(BailoutReason::FastUnsupportedParamType), |