summaryrefslogtreecommitdiff
path: root/ops/op2/dispatch_fast.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ops/op2/dispatch_fast.rs')
-rw-r--r--ops/op2/dispatch_fast.rs193
1 files changed, 193 insertions, 0 deletions
diff --git a/ops/op2/dispatch_fast.rs b/ops/op2/dispatch_fast.rs
new file mode 100644
index 000000000..79b8d141b
--- /dev/null
+++ b/ops/op2/dispatch_fast.rs
@@ -0,0 +1,193 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use super::generator_state::GeneratorState;
+use super::signature::Arg;
+use super::signature::NumericArg;
+use super::signature::ParsedSignature;
+use super::signature::RetVal;
+use super::V8MappingError;
+use proc_macro2::TokenStream;
+use quote::format_ident;
+use quote::quote;
+
+#[allow(unused)]
+#[derive(Debug, Default, PartialEq, Clone)]
+pub(crate) enum FastValue {
+ #[default]
+ Void,
+ Bool,
+ U32,
+ I32,
+ U64,
+ I64,
+ F32,
+ F64,
+ Pointer,
+ V8Value,
+ Uint8Array,
+ Uint32Array,
+ Float64Array,
+ SeqOneByteString,
+}
+
+impl FastValue {
+ /// Quote fast value type.
+ fn quote_rust_type(&self) -> TokenStream {
+ match self {
+ FastValue::Void => quote!(()),
+ FastValue::Bool => quote!(bool),
+ FastValue::U32 => quote!(u32),
+ FastValue::I32 => quote!(i32),
+ FastValue::U64 => quote!(u64),
+ FastValue::I64 => quote!(i64),
+ FastValue::F32 => quote!(f32),
+ FastValue::F64 => quote!(f64),
+ FastValue::Pointer => quote!(*mut ::std::ffi::c_void),
+ FastValue::V8Value => unimplemented!("v8::Local<v8::Value>"),
+ FastValue::Uint8Array
+ | FastValue::Uint32Array
+ | FastValue::Float64Array
+ | FastValue::SeqOneByteString => unreachable!(),
+ }
+ }
+
+ /// Quote fast value type's variant.
+ fn quote_ctype(&self) -> TokenStream {
+ match &self {
+ FastValue::Void => quote!(CType::Void),
+ FastValue::Bool => quote!(CType::Bool),
+ FastValue::U32 => quote!(CType::Uint32),
+ FastValue::I32 => quote!(CType::Int32),
+ FastValue::U64 => quote!(CType::Uint64),
+ FastValue::I64 => quote!(CType::Int64),
+ FastValue::F32 => quote!(CType::Float32),
+ FastValue::F64 => quote!(CType::Float64),
+ FastValue::Pointer => quote!(CType::Pointer),
+ FastValue::V8Value => quote!(CType::V8Value),
+ FastValue::Uint8Array => unreachable!(),
+ FastValue::Uint32Array => unreachable!(),
+ FastValue::Float64Array => unreachable!(),
+ FastValue::SeqOneByteString => quote!(CType::SeqOneByteString),
+ }
+ }
+
+ /// Quote fast value type's variant.
+ fn quote_type(&self) -> TokenStream {
+ match &self {
+ FastValue::Void => quote!(Type::Void),
+ FastValue::Bool => quote!(Type::Bool),
+ FastValue::U32 => quote!(Type::Uint32),
+ FastValue::I32 => quote!(Type::Int32),
+ FastValue::U64 => quote!(Type::Uint64),
+ FastValue::I64 => quote!(Type::Int64),
+ FastValue::F32 => quote!(Type::Float32),
+ FastValue::F64 => quote!(Type::Float64),
+ FastValue::Pointer => quote!(Type::Pointer),
+ FastValue::V8Value => quote!(Type::V8Value),
+ FastValue::Uint8Array => quote!(Type::TypedArray(CType::Uint8)),
+ FastValue::Uint32Array => quote!(Type::TypedArray(CType::Uint32)),
+ FastValue::Float64Array => quote!(Type::TypedArray(CType::Float64)),
+ FastValue::SeqOneByteString => quote!(Type::SeqOneByteString),
+ }
+ }
+}
+
+pub fn generate_dispatch_fast(
+ generator_state: &mut GeneratorState,
+ signature: &ParsedSignature,
+) -> Result<Option<(TokenStream, TokenStream)>, V8MappingError> {
+ let mut inputs = vec![];
+ for arg in &signature.args {
+ let fv = match arg {
+ Arg::OptionNumeric(_) | Arg::SerdeV8(_) => return Ok(None),
+ Arg::Numeric(NumericArg::bool) => FastValue::Bool,
+ Arg::Numeric(NumericArg::u32)
+ | Arg::Numeric(NumericArg::u16)
+ | Arg::Numeric(NumericArg::u8) => FastValue::U32,
+ Arg::Numeric(NumericArg::i32)
+ | Arg::Numeric(NumericArg::i16)
+ | Arg::Numeric(NumericArg::i8)
+ | Arg::Numeric(NumericArg::__SMI__) => FastValue::I32,
+ Arg::Numeric(NumericArg::u64) | Arg::Numeric(NumericArg::usize) => {
+ FastValue::U64
+ }
+ Arg::Numeric(NumericArg::i64) | Arg::Numeric(NumericArg::isize) => {
+ FastValue::I64
+ }
+ _ => {
+ return Err(V8MappingError::NoMapping("a fast argument", arg.clone()))
+ }
+ };
+ inputs.push(fv);
+ }
+
+ let ret_val = match &signature.ret_val {
+ RetVal::Infallible(arg) => arg,
+ RetVal::Result(arg) => arg,
+ };
+
+ let output = match ret_val {
+ Arg::OptionNumeric(_) | Arg::SerdeV8(_) => return Ok(None),
+ Arg::Void => FastValue::Void,
+ Arg::Numeric(NumericArg::bool) => FastValue::Bool,
+ Arg::Numeric(NumericArg::u32)
+ | Arg::Numeric(NumericArg::u16)
+ | Arg::Numeric(NumericArg::u8) => FastValue::U32,
+ Arg::Numeric(NumericArg::i32)
+ | Arg::Numeric(NumericArg::i16)
+ | Arg::Numeric(NumericArg::i8) => FastValue::I32,
+ Arg::Numeric(NumericArg::u64) | Arg::Numeric(NumericArg::usize) => {
+ FastValue::U64
+ }
+ Arg::Numeric(NumericArg::i64) | Arg::Numeric(NumericArg::isize) => {
+ FastValue::I64
+ }
+ Arg::Special(_) => return Ok(None),
+ _ => {
+ return Err(V8MappingError::NoMapping(
+ "a fast return value",
+ ret_val.clone(),
+ ))
+ }
+ };
+
+ let GeneratorState {
+ fast_function,
+ deno_core,
+ ..
+ } = &generator_state;
+
+ let input_types = inputs.iter().map(|fv| fv.quote_type());
+ let output_type = output.quote_ctype();
+
+ let fast_definition = quote! {
+ use #deno_core::v8::fast_api::Type;
+ use #deno_core::v8::fast_api::CType;
+ #deno_core::v8::fast_api::FastFunction::new(
+ &[ #( #input_types ),* ],
+ #output_type,
+ Self::#fast_function as *const ::std::ffi::c_void
+ )
+ };
+
+ let output_type = output.quote_rust_type();
+ let names = &inputs
+ .iter()
+ .enumerate()
+ .map(|(i, _)| format_ident!("arg{i}"))
+ .collect::<Vec<_>>();
+ let types = inputs.iter().map(|rv| rv.quote_rust_type());
+
+ let fast_fn = quote!(
+ fn #fast_function(
+ _: #deno_core::v8::Local<#deno_core::v8::Object>,
+ #( #names: #types, )*
+ ) -> #output_type {
+ #(
+ let #names = #names as _;
+ )*
+ Self::call(#(#names),*)
+ }
+ );
+
+ Ok(Some((fast_definition, fast_fn)))
+}