mirror of
https://github.com/denoland/deno.git
synced 2025-08-03 18:38:33 +00:00
This commit is contained in:
parent
02187966c1
commit
115cc1e6ae
10 changed files with 112 additions and 265 deletions
120
ops/lib.rs
120
ops/lib.rs
|
@ -118,7 +118,7 @@ pub fn op(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||
let (has_fallible_fast_call, fast_impl, fast_field) =
|
||||
codegen_fast_impl(&core, &func, name, is_async, must_be_fast);
|
||||
|
||||
let (v8_body, argc) = if is_async {
|
||||
let v8_body = if is_async {
|
||||
codegen_v8_async(&core, &func, margs, asyncness, deferred)
|
||||
} else {
|
||||
codegen_v8_sync(&core, &func, margs, has_fallible_fast_call)
|
||||
|
@ -154,7 +154,6 @@ pub fn op(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||
is_async: #is_async,
|
||||
is_unstable: #is_unstable,
|
||||
is_v8: #is_v8,
|
||||
argc: #argc,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,7 +181,7 @@ fn codegen_v8_async(
|
|||
margs: MacroArgs,
|
||||
asyncness: bool,
|
||||
deferred: bool,
|
||||
) -> (TokenStream2, usize) {
|
||||
) -> TokenStream2 {
|
||||
let MacroArgs { is_v8, .. } = margs;
|
||||
let special_args = f
|
||||
.sig
|
||||
|
@ -195,7 +194,7 @@ fn codegen_v8_async(
|
|||
let rust_i0 = special_args.len();
|
||||
let args_head = special_args.into_iter().collect::<TokenStream2>();
|
||||
|
||||
let (arg_decls, args_tail, argc) = codegen_args(core, f, rust_i0, 1);
|
||||
let (arg_decls, args_tail) = codegen_args(core, f, rust_i0, 1);
|
||||
let type_params = exclude_lifetime_params(&f.sig.generics.params);
|
||||
|
||||
let (pre_result, mut result_fut) = match asyncness {
|
||||
|
@ -226,47 +225,44 @@ fn codegen_v8_async(
|
|||
false => quote! { let result = Ok(result); },
|
||||
};
|
||||
|
||||
(
|
||||
quote! {
|
||||
use #core::futures::FutureExt;
|
||||
// SAFETY: #core guarantees args.data() is a v8 External pointing to an OpCtx for the isolates lifetime
|
||||
let ctx = unsafe {
|
||||
&*(#core::v8::Local::<#core::v8::External>::cast(args.data()).value()
|
||||
as *const #core::_ops::OpCtx)
|
||||
};
|
||||
let op_id = ctx.id;
|
||||
quote! {
|
||||
use #core::futures::FutureExt;
|
||||
// SAFETY: #core guarantees args.data() is a v8 External pointing to an OpCtx for the isolates lifetime
|
||||
let ctx = unsafe {
|
||||
&*(#core::v8::Local::<#core::v8::External>::cast(args.data()).value()
|
||||
as *const #core::_ops::OpCtx)
|
||||
};
|
||||
let op_id = ctx.id;
|
||||
|
||||
let promise_id = args.get(0);
|
||||
let promise_id = #core::v8::Local::<#core::v8::Integer>::try_from(promise_id)
|
||||
.map(|l| l.value() as #core::PromiseId)
|
||||
.map_err(#core::anyhow::Error::from);
|
||||
// Fail if promise id invalid (not an int)
|
||||
let promise_id: #core::PromiseId = match promise_id {
|
||||
Ok(promise_id) => promise_id,
|
||||
Err(err) => {
|
||||
#core::_ops::throw_type_error(scope, format!("invalid promise id: {}", err));
|
||||
return;
|
||||
}
|
||||
};
|
||||
let promise_id = args.get(0);
|
||||
let promise_id = #core::v8::Local::<#core::v8::Integer>::try_from(promise_id)
|
||||
.map(|l| l.value() as #core::PromiseId)
|
||||
.map_err(#core::anyhow::Error::from);
|
||||
// Fail if promise id invalid (not an int)
|
||||
let promise_id: #core::PromiseId = match promise_id {
|
||||
Ok(promise_id) => promise_id,
|
||||
Err(err) => {
|
||||
#core::_ops::throw_type_error(scope, format!("invalid promise id: {}", err));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
#arg_decls
|
||||
#arg_decls
|
||||
|
||||
// Track async call & get copy of get_error_class_fn
|
||||
let get_class = {
|
||||
let state = ::std::cell::RefCell::borrow(&ctx.state);
|
||||
state.tracker.track_async(op_id);
|
||||
state.get_error_class_fn
|
||||
};
|
||||
// Track async call & get copy of get_error_class_fn
|
||||
let get_class = {
|
||||
let state = ::std::cell::RefCell::borrow(&ctx.state);
|
||||
state.tracker.track_async(op_id);
|
||||
state.get_error_class_fn
|
||||
};
|
||||
|
||||
#pre_result
|
||||
#core::_ops::queue_async_op(ctx, scope, #deferred, async move {
|
||||
let result = #result_fut
|
||||
#result_wrapper
|
||||
(promise_id, op_id, #core::_ops::to_op_result(get_class, result))
|
||||
});
|
||||
},
|
||||
argc,
|
||||
)
|
||||
#pre_result
|
||||
#core::_ops::queue_async_op(ctx, scope, #deferred, async move {
|
||||
let result = #result_fut
|
||||
#result_wrapper
|
||||
(promise_id, op_id, #core::_ops::to_op_result(get_class, result))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn scope_arg(arg: &FnArg) -> Option<TokenStream2> {
|
||||
|
@ -520,7 +516,7 @@ fn codegen_v8_sync(
|
|||
f: &syn::ItemFn,
|
||||
margs: MacroArgs,
|
||||
has_fallible_fast_call: bool,
|
||||
) -> (TokenStream2, usize) {
|
||||
) -> TokenStream2 {
|
||||
let MacroArgs { is_v8, .. } = margs;
|
||||
let special_args = f
|
||||
.sig
|
||||
|
@ -532,7 +528,7 @@ fn codegen_v8_sync(
|
|||
.collect::<Vec<_>>();
|
||||
let rust_i0 = special_args.len();
|
||||
let args_head = special_args.into_iter().collect::<TokenStream2>();
|
||||
let (arg_decls, args_tail, argc) = codegen_args(core, f, rust_i0, 0);
|
||||
let (arg_decls, args_tail) = codegen_args(core, f, rust_i0, 0);
|
||||
let ret = codegen_sync_ret(core, &f.sig.output);
|
||||
let type_params = exclude_lifetime_params(&f.sig.generics.params);
|
||||
|
||||
|
@ -551,27 +547,24 @@ fn codegen_v8_sync(
|
|||
quote! {}
|
||||
};
|
||||
|
||||
(
|
||||
quote! {
|
||||
// SAFETY: #core guarantees args.data() is a v8 External pointing to an OpCtx for the isolates lifetime
|
||||
let ctx = unsafe {
|
||||
&*(#core::v8::Local::<#core::v8::External>::cast(args.data()).value()
|
||||
as *const #core::_ops::OpCtx)
|
||||
};
|
||||
quote! {
|
||||
// SAFETY: #core guarantees args.data() is a v8 External pointing to an OpCtx for the isolates lifetime
|
||||
let ctx = unsafe {
|
||||
&*(#core::v8::Local::<#core::v8::External>::cast(args.data()).value()
|
||||
as *const #core::_ops::OpCtx)
|
||||
};
|
||||
|
||||
#fast_error_handler
|
||||
#arg_decls
|
||||
#fast_error_handler
|
||||
#arg_decls
|
||||
|
||||
let result = Self::call::<#type_params>(#args_head #args_tail);
|
||||
let result = Self::call::<#type_params>(#args_head #args_tail);
|
||||
|
||||
// use RefCell::borrow instead of state.borrow to avoid clash with std::borrow::Borrow
|
||||
let op_state = ::std::cell::RefCell::borrow(&*ctx.state);
|
||||
op_state.tracker.track_sync(ctx.id);
|
||||
// use RefCell::borrow instead of state.borrow to avoid clash with std::borrow::Borrow
|
||||
let op_state = ::std::cell::RefCell::borrow(&*ctx.state);
|
||||
op_state.tracker.track_sync(ctx.id);
|
||||
|
||||
#ret
|
||||
},
|
||||
argc,
|
||||
)
|
||||
#ret
|
||||
}
|
||||
}
|
||||
|
||||
struct FastApiSyn {
|
||||
|
@ -810,15 +803,12 @@ fn is_fast_scalar(
|
|||
}
|
||||
}
|
||||
|
||||
/// (full declarations, idents, v8 argument count)
|
||||
type ArgumentDecl = (TokenStream2, TokenStream2, usize);
|
||||
|
||||
fn codegen_args(
|
||||
core: &TokenStream2,
|
||||
f: &syn::ItemFn,
|
||||
rust_i0: usize, // Index of first generic arg in rust
|
||||
v8_i0: usize, // Index of first generic arg in v8/js
|
||||
) -> ArgumentDecl {
|
||||
) -> (TokenStream2, TokenStream2) {
|
||||
let inputs = &f.sig.inputs.iter().skip(rust_i0).enumerate();
|
||||
let ident_seq: TokenStream2 = inputs
|
||||
.clone()
|
||||
|
@ -833,7 +823,7 @@ fn codegen_args(
|
|||
codegen_arg(core, arg, format!("arg_{i}").as_ref(), v8_i0 + i)
|
||||
})
|
||||
.collect();
|
||||
(decls, ident_seq, inputs.len())
|
||||
(decls, ident_seq)
|
||||
}
|
||||
|
||||
fn codegen_arg(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue