summaryrefslogtreecommitdiff
path: root/ops/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ops/lib.rs')
-rw-r--r--ops/lib.rs87
1 files changed, 52 insertions, 35 deletions
diff --git a/ops/lib.rs b/ops/lib.rs
index 49ca970f2..a5e5ce51b 100644
--- a/ops/lib.rs
+++ b/ops/lib.rs
@@ -6,6 +6,7 @@ use proc_macro_crate::crate_name;
use proc_macro_crate::FoundCrate;
use quote::quote;
use quote::ToTokens;
+use syn::FnArg;
use syn::Ident;
// Identifer to the `deno_core` crate.
@@ -34,9 +35,10 @@ fn core_import() -> TokenStream2 {
}
}
-#[derive(Debug)]
+#[derive(Copy, Clone, Debug, Default)]
struct MacroArgs {
is_unstable: bool,
+ is_v8: bool,
}
impl syn::parse::Parse for MacroArgs {
@@ -47,20 +49,25 @@ impl syn::parse::Parse for MacroArgs {
)?;
let vars: Vec<_> = vars.iter().map(Ident::to_string).collect();
let vars: Vec<_> = vars.iter().map(String::as_str).collect();
- match vars[..] {
- ["unstable"] => Ok(Self { is_unstable: true }),
- [] => Ok(Self { is_unstable: false }),
- _ => Err(syn::Error::new(
- input.span(),
- "Ops expect #[op] or #[op(unstable)]",
- )),
+ for var in vars.iter() {
+ if !["unstable", "v8"].contains(var) {
+ return Err(syn::Error::new(
+ input.span(),
+ "Ops expect #[op] or #[op(unstable)]",
+ ));
+ }
}
+ Ok(Self {
+ is_unstable: vars.contains(&"unstable"),
+ is_v8: vars.contains(&"v8"),
+ })
}
}
#[proc_macro_attribute]
pub fn op(attr: TokenStream, item: TokenStream) -> TokenStream {
- let MacroArgs { is_unstable } = syn::parse_macro_input!(attr as MacroArgs);
+ let margs = syn::parse_macro_input!(attr as MacroArgs);
+ let MacroArgs { is_unstable, is_v8 } = margs;
let func = syn::parse::<syn::ItemFn>(item).expect("expected a function");
let name = &func.sig.ident;
let generics = &func.sig.generics;
@@ -78,9 +85,9 @@ pub fn op(attr: TokenStream, item: TokenStream) -> TokenStream {
let is_async = func.sig.asyncness.is_some();
let v8_body = if is_async {
- codegen_v8_async(&core, &func)
+ codegen_v8_async(&core, &func, margs)
} else {
- codegen_v8_sync(&core, &func)
+ codegen_v8_sync(&core, &func, margs)
};
let docline = format!("Use `{name}::decl()` to get an op-declaration");
@@ -111,6 +118,7 @@ pub fn op(attr: TokenStream, item: TokenStream) -> TokenStream {
enabled: true,
is_async: #is_async,
is_unstable: #is_unstable,
+ is_v8: #is_v8,
}
}
@@ -130,7 +138,11 @@ pub fn op(attr: TokenStream, item: TokenStream) -> TokenStream {
}
/// Generate the body of a v8 func for an async op
-fn codegen_v8_async(core: &TokenStream2, f: &syn::ItemFn) -> TokenStream2 {
+fn codegen_v8_async(
+ core: &TokenStream2,
+ f: &syn::ItemFn,
+ _margs: MacroArgs,
+) -> TokenStream2 {
let arg0 = f.sig.inputs.first();
let uses_opstate = arg0.map(is_rc_refcell_opstate).unwrap_or_default();
let args_head = if uses_opstate {
@@ -183,31 +195,36 @@ fn codegen_v8_async(core: &TokenStream2, f: &syn::ItemFn) -> TokenStream2 {
}
/// Generate the body of a v8 func for a sync op
-fn codegen_v8_sync(core: &TokenStream2, f: &syn::ItemFn) -> TokenStream2 {
- let args = f.sig.inputs.iter().collect::<Vec<_>>();
- let mut arg0 = args.first();
- let has_scope = match arg0 {
- Some(arg0) => is_handle_scope(arg0),
- None => false,
- };
- let rust_i0;
- let scope_arg = if has_scope {
- arg0 = args.get(1); // Next arg might be OpState.
- rust_i0 = 1;
- quote! { scope, }
- } else {
- rust_i0 = 0;
- quote! {}
- };
- let (rust_i0, args_head) = match arg0 {
- Some(arg0) if is_rc_refcell_opstate(arg0) => {
- (rust_i0 + 1, quote! { ctx.state.clone(), })
+fn codegen_v8_sync(
+ core: &TokenStream2,
+ f: &syn::ItemFn,
+ margs: MacroArgs,
+) -> TokenStream2 {
+ let MacroArgs { is_v8, .. } = margs;
+ let scope_arg = |arg: &FnArg| {
+ if is_handle_scope(arg) {
+ Some(quote! { scope, })
+ } else {
+ None
}
- Some(arg0) if is_mut_ref_opstate(arg0) => {
- (rust_i0 + 1, quote! { &mut ctx.state.borrow_mut(), })
+ };
+ let opstate_arg = |arg: &FnArg| match arg {
+ arg if is_rc_refcell_opstate(arg) => Some(quote! { ctx.state.clone(), }),
+ arg if is_mut_ref_opstate(arg) => {
+ Some(quote! { &mut ctx.state.borrow_mut(), })
}
- _ => (rust_i0, quote! {}),
+ _ => None,
};
+ let special_args = f
+ .sig
+ .inputs
+ .iter()
+ .map_while(|a| {
+ (if is_v8 { scope_arg(a) } else { None }).or_else(|| opstate_arg(a))
+ })
+ .collect::<Vec<_>>();
+ let rust_i0 = special_args.len();
+ let args_head = special_args.into_iter().collect::<TokenStream2>();
let (arg_decls, args_tail) = codegen_args(core, f, rust_i0, 0);
let ret = codegen_sync_ret(core, &f.sig.output);
@@ -222,7 +239,7 @@ fn codegen_v8_sync(core: &TokenStream2, f: &syn::ItemFn) -> TokenStream2 {
#arg_decls
- let result = Self::call::<#type_params>(#scope_arg #args_head #args_tail);
+ let result = Self::call::<#type_params>(#args_head #args_tail);
let op_state = &mut ctx.state.borrow();
op_state.tracker.track_sync(ctx.id);