/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
libs/ops/op2/dispatch_async.rs
218 строк
6 KB
Bartek Iwańczuk
feat: v8 14.9 (#34226)
20 май 2026, 15:32
Не верифицирован
20 май 2026, 15:32
3970a84
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. MIT license. use proc_macro2::TokenStream; use quote::quote; use super::V8MappingError; use super::V8SignatureMappingError; use super::config::MacroConfig; use super::dispatch_slow::generate_dispatch_slow_call; use super::dispatch_slow::return_value_infallible; use super::dispatch_slow::return_value_result; use super::dispatch_slow::return_value_v8_value; use super::dispatch_slow::throw_exception; use super::dispatch_slow::with_fn_args; use super::dispatch_slow::with_opctx; use super::dispatch_slow::with_opstate; use super::dispatch_slow::with_parts; use super::dispatch_slow::with_required_check; use super::dispatch_slow::with_retval; use super::dispatch_slow::with_scope; use super::dispatch_slow::with_self; use super::dispatch_slow::with_stack_trace; use super::generator_state::GeneratorState; use super::generator_state::gs_quote; use super::signature::ParsedSignature; use super::signature_retval::RetVal; pub(crate) fn map_async_return_type( generator_state: &mut GeneratorState, ret_val: &RetVal, ) -> Result<(TokenStream, TokenStream, TokenStream), V8MappingError> { let return_value = return_value_v8_value(generator_state, ret_val.arg())?; let fut = if generator_state.is_fake_async { Some(ret_val) } else { ret_val.get_future() }; let (mapper, return_value_immediate) = if let Some(ret_val) = fut { if let Some(res_ret_val) = ret_val.unwrap_result() { ( quote!(map_async_op_fallible), return_value_result(generator_state, res_ret_val.arg())?, ) } else { ( quote!(map_async_op_infallible), return_value_infallible(generator_state, ret_val.arg())?, ) } } else { return Err("an async return"); }; Ok((return_value, mapper, return_value_immediate)) } pub(crate) fn generate_dispatch_async( config: &MacroConfig, generator_state: &mut GeneratorState, signature: &ParsedSignature, ) -> Result<TokenStream, V8SignatureMappingError> { let mut output = TokenStream::new(); let with_self = if generator_state.needs_self { with_self(generator_state, &signature.ret_val) } else { quote!() }; // Set input_index = 1 when we don't want promise ID as the first arg. let input_index = if config.promise_id { 0 } else { 1 }; let args = generate_dispatch_slow_call(generator_state, signature, input_index)?; // Always need context and args generator_state.needs_opctx = true; generator_state.needs_args = true; // We don't have an isolate-only fast path for async yet generator_state.needs_scope |= generator_state.needs_isolate; let (return_value, mapper, return_value_immediate) = map_async_return_type(generator_state, &signature.ret_val).map_err( |s| { V8SignatureMappingError::NoRetValMapping( signature.ret_span, s, Box::new(signature.ret_val.clone()), ) }, )?; output.extend(gs_quote!(generator_state(result) => { let #result = { #args }; })); // TODO(mmastrac): we should save this unwrapped result if signature.ret_val.unwrap_result().is_some() && !generator_state.is_fake_async { let exception = throw_exception(generator_state); output.extend(gs_quote!(generator_state(result) => { let #result = match #result { Ok(#result) => #result, Err(err) => { // Handle eager error -- this will leave only a Future<R> or Future<Result<R>> #exception } }; })); } if config.async_lazy || config.async_deferred { let lazy = config.async_lazy; let deferred = config.async_deferred; output.extend(gs_quote!(generator_state(promise_id, fn_args, result, opctx, scope) => { let #promise_id = deno_core::_ops::to_i32_option(&#fn_args.get(0)).unwrap_or_default(); // Lazy and deferred results will always return None deno_core::_ops::#mapper(#opctx, #lazy, #deferred, #promise_id, #result, |#scope, #result| { #return_value }); })); } else { output.extend(gs_quote!(generator_state(promise_id, fn_args, result, opctx, scope) => { let #promise_id = deno_core::_ops::to_i32_option(&#fn_args.get(0)).unwrap_or_default(); if let Some(#result) = deno_core::_ops::#mapper(#opctx, false, false, #promise_id, #result, |#scope, #result| { #return_value }) { // Eager poll returned a value #return_value_immediate; return 0; } })); } output.extend(quote!(return 2;)); let with_opstate = if generator_state.needs_opstate | generator_state.needs_stack_trace { with_opstate(generator_state) } else { quote!() }; let with_opctx = if generator_state.needs_opctx | generator_state.needs_stack_trace { with_opctx(generator_state) } else { quote!() }; let with_retval = if generator_state.needs_retval { with_retval(generator_state) } else { quote!() }; let with_args = if generator_state.needs_args { with_fn_args(generator_state) } else { quote!() }; let with_required_check = if generator_state.needs_args && let Some(required) = config.required && required > 0 { with_required_check(generator_state, required, true) } else { quote!() }; let with_scope = if generator_state.needs_scope | generator_state.needs_stack_trace { with_scope(generator_state) } else { quote!() }; let with_stack_trace = if generator_state.needs_stack_trace { with_stack_trace(generator_state) } else { quote!() }; let with_parts_ts = if generator_state.needs_parts { with_parts(generator_state) } else { quote!() }; Ok(gs_quote!(generator_state(info, slow_function) => { fn slow_function_impl<'s>(info: *const deno_core::v8::FunctionCallbackInfo) -> usize { let info: &'s _ = unsafe { &*info }; #[cfg(debug_assertions)] let _reentrancy_check_guard = deno_core::_ops::reentrancy_check(&<Self as deno_core::_ops::Op>::DECL); #with_parts_ts #with_scope #with_retval #with_args #with_required_check #with_opctx #with_opstate #with_self #with_stack_trace #output } extern "C" fn #slow_function(#info: *const deno_core::v8::FunctionCallbackInfo) { Self::slow_function_impl(#info); } })) }