11cb0ef41Sopenharmony_ci#include "node.h" 21cb0ef41Sopenharmony_ci#include "async_wrap-inl.h" 31cb0ef41Sopenharmony_ci#include "env-inl.h" 41cb0ef41Sopenharmony_ci#include "v8.h" 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_cinamespace node { 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ciusing v8::Context; 91cb0ef41Sopenharmony_ciusing v8::EscapableHandleScope; 101cb0ef41Sopenharmony_ciusing v8::Function; 111cb0ef41Sopenharmony_ciusing v8::HandleScope; 121cb0ef41Sopenharmony_ciusing v8::Isolate; 131cb0ef41Sopenharmony_ciusing v8::Local; 141cb0ef41Sopenharmony_ciusing v8::MaybeLocal; 151cb0ef41Sopenharmony_ciusing v8::Object; 161cb0ef41Sopenharmony_ciusing v8::String; 171cb0ef41Sopenharmony_ciusing v8::Value; 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ciCallbackScope::CallbackScope(Isolate* isolate, 201cb0ef41Sopenharmony_ci Local<Object> object, 211cb0ef41Sopenharmony_ci async_context async_context) 221cb0ef41Sopenharmony_ci : CallbackScope(Environment::GetCurrent(isolate), object, async_context) {} 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ciCallbackScope::CallbackScope(Environment* env, 251cb0ef41Sopenharmony_ci Local<Object> object, 261cb0ef41Sopenharmony_ci async_context asyncContext) 271cb0ef41Sopenharmony_ci : private_(new InternalCallbackScope(env, 281cb0ef41Sopenharmony_ci object, 291cb0ef41Sopenharmony_ci asyncContext)), 301cb0ef41Sopenharmony_ci try_catch_(env->isolate()) { 311cb0ef41Sopenharmony_ci try_catch_.SetVerbose(true); 321cb0ef41Sopenharmony_ci} 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ciCallbackScope::~CallbackScope() { 351cb0ef41Sopenharmony_ci if (try_catch_.HasCaught()) 361cb0ef41Sopenharmony_ci private_->MarkAsFailed(); 371cb0ef41Sopenharmony_ci delete private_; 381cb0ef41Sopenharmony_ci} 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ciInternalCallbackScope::InternalCallbackScope(AsyncWrap* async_wrap, int flags) 411cb0ef41Sopenharmony_ci : InternalCallbackScope(async_wrap->env(), 421cb0ef41Sopenharmony_ci async_wrap->object(), 431cb0ef41Sopenharmony_ci { async_wrap->get_async_id(), 441cb0ef41Sopenharmony_ci async_wrap->get_trigger_async_id() }, 451cb0ef41Sopenharmony_ci flags) {} 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ciInternalCallbackScope::InternalCallbackScope(Environment* env, 481cb0ef41Sopenharmony_ci Local<Object> object, 491cb0ef41Sopenharmony_ci const async_context& asyncContext, 501cb0ef41Sopenharmony_ci int flags) 511cb0ef41Sopenharmony_ci : env_(env), 521cb0ef41Sopenharmony_ci async_context_(asyncContext), 531cb0ef41Sopenharmony_ci object_(object), 541cb0ef41Sopenharmony_ci skip_hooks_(flags & kSkipAsyncHooks), 551cb0ef41Sopenharmony_ci skip_task_queues_(flags & kSkipTaskQueues) { 561cb0ef41Sopenharmony_ci CHECK_NOT_NULL(env); 571cb0ef41Sopenharmony_ci env->PushAsyncCallbackScope(); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci if (!env->can_call_into_js()) { 601cb0ef41Sopenharmony_ci failed_ = true; 611cb0ef41Sopenharmony_ci return; 621cb0ef41Sopenharmony_ci } 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci Isolate* isolate = env->isolate(); 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci HandleScope handle_scope(isolate); 671cb0ef41Sopenharmony_ci Local<Context> current_context = isolate->GetCurrentContext(); 681cb0ef41Sopenharmony_ci // If you hit this assertion, the caller forgot to enter the right Node.js 691cb0ef41Sopenharmony_ci // Environment's v8::Context first. 701cb0ef41Sopenharmony_ci // We first check `env->context() != current_context` because the contexts 711cb0ef41Sopenharmony_ci // likely *are* the same, in which case we can skip the slightly more 721cb0ef41Sopenharmony_ci // expensive Environment::GetCurrent() call. 731cb0ef41Sopenharmony_ci if (UNLIKELY(env->context() != current_context)) { 741cb0ef41Sopenharmony_ci CHECK_EQ(Environment::GetCurrent(isolate), env); 751cb0ef41Sopenharmony_ci } 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci isolate->SetIdle(false); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci env->async_hooks()->push_async_context( 801cb0ef41Sopenharmony_ci async_context_.async_id, async_context_.trigger_async_id, object); 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci pushed_ids_ = true; 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci if (asyncContext.async_id != 0 && !skip_hooks_) { 851cb0ef41Sopenharmony_ci // No need to check a return value because the application will exit if 861cb0ef41Sopenharmony_ci // an exception occurs. 871cb0ef41Sopenharmony_ci AsyncWrap::EmitBefore(env, asyncContext.async_id); 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci} 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ciInternalCallbackScope::~InternalCallbackScope() { 921cb0ef41Sopenharmony_ci Close(); 931cb0ef41Sopenharmony_ci env_->PopAsyncCallbackScope(); 941cb0ef41Sopenharmony_ci} 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_civoid InternalCallbackScope::Close() { 971cb0ef41Sopenharmony_ci if (closed_) return; 981cb0ef41Sopenharmony_ci closed_ = true; 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci // This function must ends up with either cleanup the 1011cb0ef41Sopenharmony_ci // async id stack or pop the topmost one from it 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci auto perform_stopping_check = [&]() { 1041cb0ef41Sopenharmony_ci if (env_->is_stopping()) { 1051cb0ef41Sopenharmony_ci MarkAsFailed(); 1061cb0ef41Sopenharmony_ci env_->async_hooks()->clear_async_id_stack(); 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci }; 1091cb0ef41Sopenharmony_ci perform_stopping_check(); 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci if (env_->is_stopping()) return; 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci Isolate* isolate = env_->isolate(); 1141cb0ef41Sopenharmony_ci auto idle = OnScopeLeave([&]() { isolate->SetIdle(true); }); 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci if (!failed_ && async_context_.async_id != 0 && !skip_hooks_) { 1171cb0ef41Sopenharmony_ci AsyncWrap::EmitAfter(env_, async_context_.async_id); 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci if (pushed_ids_) 1211cb0ef41Sopenharmony_ci env_->async_hooks()->pop_async_context(async_context_.async_id); 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci if (failed_) return; 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci if (env_->async_callback_scope_depth() > 1 || skip_task_queues_) { 1261cb0ef41Sopenharmony_ci return; 1271cb0ef41Sopenharmony_ci } 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci TickInfo* tick_info = env_->tick_info(); 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci if (!env_->can_call_into_js()) return; 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci auto weakref_cleanup = OnScopeLeave([&]() { env_->RunWeakRefCleanup(); }); 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci Local<Context> context = env_->context(); 1361cb0ef41Sopenharmony_ci if (!tick_info->has_tick_scheduled()) { 1371cb0ef41Sopenharmony_ci context->GetMicrotaskQueue()->PerformCheckpoint(isolate); 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ci perform_stopping_check(); 1401cb0ef41Sopenharmony_ci } 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci // Make sure the stack unwound properly. If there are nested MakeCallback's 1431cb0ef41Sopenharmony_ci // then it should return early and not reach this code. 1441cb0ef41Sopenharmony_ci if (env_->async_hooks()->fields()[AsyncHooks::kTotals]) { 1451cb0ef41Sopenharmony_ci CHECK_EQ(env_->execution_async_id(), 0); 1461cb0ef41Sopenharmony_ci CHECK_EQ(env_->trigger_async_id(), 0); 1471cb0ef41Sopenharmony_ci } 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci if (!tick_info->has_tick_scheduled() && !tick_info->has_rejection_to_warn()) { 1501cb0ef41Sopenharmony_ci return; 1511cb0ef41Sopenharmony_ci } 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci HandleScope handle_scope(isolate); 1541cb0ef41Sopenharmony_ci Local<Object> process = env_->process_object(); 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ci if (!env_->can_call_into_js()) return; 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci Local<Function> tick_callback = env_->tick_callback_function(); 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci // The tick is triggered before JS land calls SetTickCallback 1611cb0ef41Sopenharmony_ci // to initializes the tick callback during bootstrap. 1621cb0ef41Sopenharmony_ci CHECK(!tick_callback.IsEmpty()); 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci if (tick_callback->Call(context, process, 0, nullptr).IsEmpty()) { 1651cb0ef41Sopenharmony_ci failed_ = true; 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci perform_stopping_check(); 1681cb0ef41Sopenharmony_ci} 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ciMaybeLocal<Value> InternalMakeCallback(Environment* env, 1711cb0ef41Sopenharmony_ci Local<Object> resource, 1721cb0ef41Sopenharmony_ci Local<Object> recv, 1731cb0ef41Sopenharmony_ci const Local<Function> callback, 1741cb0ef41Sopenharmony_ci int argc, 1751cb0ef41Sopenharmony_ci Local<Value> argv[], 1761cb0ef41Sopenharmony_ci async_context asyncContext) { 1771cb0ef41Sopenharmony_ci CHECK(!recv.IsEmpty()); 1781cb0ef41Sopenharmony_ci#ifdef DEBUG 1791cb0ef41Sopenharmony_ci for (int i = 0; i < argc; i++) 1801cb0ef41Sopenharmony_ci CHECK(!argv[i].IsEmpty()); 1811cb0ef41Sopenharmony_ci#endif 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci Local<Function> hook_cb = env->async_hooks_callback_trampoline(); 1841cb0ef41Sopenharmony_ci int flags = InternalCallbackScope::kNoFlags; 1851cb0ef41Sopenharmony_ci bool use_async_hooks_trampoline = false; 1861cb0ef41Sopenharmony_ci AsyncHooks* async_hooks = env->async_hooks(); 1871cb0ef41Sopenharmony_ci if (!hook_cb.IsEmpty()) { 1881cb0ef41Sopenharmony_ci // Use the callback trampoline if there are any before or after hooks, or 1891cb0ef41Sopenharmony_ci // we can expect some kind of usage of async_hooks.executionAsyncResource(). 1901cb0ef41Sopenharmony_ci flags = InternalCallbackScope::kSkipAsyncHooks; 1911cb0ef41Sopenharmony_ci use_async_hooks_trampoline = 1921cb0ef41Sopenharmony_ci async_hooks->fields()[AsyncHooks::kBefore] + 1931cb0ef41Sopenharmony_ci async_hooks->fields()[AsyncHooks::kAfter] + 1941cb0ef41Sopenharmony_ci async_hooks->fields()[AsyncHooks::kUsesExecutionAsyncResource] > 0; 1951cb0ef41Sopenharmony_ci } 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci InternalCallbackScope scope(env, resource, asyncContext, flags); 1981cb0ef41Sopenharmony_ci if (scope.Failed()) { 1991cb0ef41Sopenharmony_ci return MaybeLocal<Value>(); 2001cb0ef41Sopenharmony_ci } 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci MaybeLocal<Value> ret; 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci Local<Context> context = env->context(); 2051cb0ef41Sopenharmony_ci if (use_async_hooks_trampoline) { 2061cb0ef41Sopenharmony_ci MaybeStackBuffer<Local<Value>, 16> args(3 + argc); 2071cb0ef41Sopenharmony_ci args[0] = v8::Number::New(env->isolate(), asyncContext.async_id); 2081cb0ef41Sopenharmony_ci args[1] = resource; 2091cb0ef41Sopenharmony_ci args[2] = callback; 2101cb0ef41Sopenharmony_ci for (int i = 0; i < argc; i++) { 2111cb0ef41Sopenharmony_ci args[i + 3] = argv[i]; 2121cb0ef41Sopenharmony_ci } 2131cb0ef41Sopenharmony_ci ret = hook_cb->Call(context, recv, args.length(), &args[0]); 2141cb0ef41Sopenharmony_ci } else { 2151cb0ef41Sopenharmony_ci ret = callback->Call(context, recv, argc, argv); 2161cb0ef41Sopenharmony_ci } 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci if (ret.IsEmpty()) { 2191cb0ef41Sopenharmony_ci scope.MarkAsFailed(); 2201cb0ef41Sopenharmony_ci return MaybeLocal<Value>(); 2211cb0ef41Sopenharmony_ci } 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci scope.Close(); 2241cb0ef41Sopenharmony_ci if (scope.Failed()) { 2251cb0ef41Sopenharmony_ci return MaybeLocal<Value>(); 2261cb0ef41Sopenharmony_ci } 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci return ret; 2291cb0ef41Sopenharmony_ci} 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_ci// Public MakeCallback()s 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ciMaybeLocal<Value> MakeCallback(Isolate* isolate, 2341cb0ef41Sopenharmony_ci Local<Object> recv, 2351cb0ef41Sopenharmony_ci const char* method, 2361cb0ef41Sopenharmony_ci int argc, 2371cb0ef41Sopenharmony_ci Local<Value> argv[], 2381cb0ef41Sopenharmony_ci async_context asyncContext) { 2391cb0ef41Sopenharmony_ci Local<String> method_string = 2401cb0ef41Sopenharmony_ci String::NewFromUtf8(isolate, method).ToLocalChecked(); 2411cb0ef41Sopenharmony_ci return MakeCallback(isolate, recv, method_string, argc, argv, asyncContext); 2421cb0ef41Sopenharmony_ci} 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_ciMaybeLocal<Value> MakeCallback(Isolate* isolate, 2451cb0ef41Sopenharmony_ci Local<Object> recv, 2461cb0ef41Sopenharmony_ci Local<String> symbol, 2471cb0ef41Sopenharmony_ci int argc, 2481cb0ef41Sopenharmony_ci Local<Value> argv[], 2491cb0ef41Sopenharmony_ci async_context asyncContext) { 2501cb0ef41Sopenharmony_ci // Check can_call_into_js() first because calling Get() might do so. 2511cb0ef41Sopenharmony_ci Environment* env = 2521cb0ef41Sopenharmony_ci Environment::GetCurrent(recv->GetCreationContext().ToLocalChecked()); 2531cb0ef41Sopenharmony_ci CHECK_NOT_NULL(env); 2541cb0ef41Sopenharmony_ci if (!env->can_call_into_js()) return Local<Value>(); 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci Local<Value> callback_v; 2571cb0ef41Sopenharmony_ci if (!recv->Get(isolate->GetCurrentContext(), symbol).ToLocal(&callback_v)) 2581cb0ef41Sopenharmony_ci return Local<Value>(); 2591cb0ef41Sopenharmony_ci if (!callback_v->IsFunction()) { 2601cb0ef41Sopenharmony_ci // This used to return an empty value, but Undefined() makes more sense 2611cb0ef41Sopenharmony_ci // since no exception is pending here. 2621cb0ef41Sopenharmony_ci return Undefined(isolate); 2631cb0ef41Sopenharmony_ci } 2641cb0ef41Sopenharmony_ci Local<Function> callback = callback_v.As<Function>(); 2651cb0ef41Sopenharmony_ci return MakeCallback(isolate, recv, callback, argc, argv, asyncContext); 2661cb0ef41Sopenharmony_ci} 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ciMaybeLocal<Value> MakeCallback(Isolate* isolate, 2691cb0ef41Sopenharmony_ci Local<Object> recv, 2701cb0ef41Sopenharmony_ci Local<Function> callback, 2711cb0ef41Sopenharmony_ci int argc, 2721cb0ef41Sopenharmony_ci Local<Value> argv[], 2731cb0ef41Sopenharmony_ci async_context asyncContext) { 2741cb0ef41Sopenharmony_ci // Observe the following two subtleties: 2751cb0ef41Sopenharmony_ci // 2761cb0ef41Sopenharmony_ci // 1. The environment is retrieved from the callback function's context. 2771cb0ef41Sopenharmony_ci // 2. The context to enter is retrieved from the environment. 2781cb0ef41Sopenharmony_ci // 2791cb0ef41Sopenharmony_ci // Because of the AssignToContext() call in src/node_contextify.cc, 2801cb0ef41Sopenharmony_ci // the two contexts need not be the same. 2811cb0ef41Sopenharmony_ci Environment* env = 2821cb0ef41Sopenharmony_ci Environment::GetCurrent(callback->GetCreationContext().ToLocalChecked()); 2831cb0ef41Sopenharmony_ci CHECK_NOT_NULL(env); 2841cb0ef41Sopenharmony_ci Context::Scope context_scope(env->context()); 2851cb0ef41Sopenharmony_ci MaybeLocal<Value> ret = 2861cb0ef41Sopenharmony_ci InternalMakeCallback(env, recv, recv, callback, argc, argv, asyncContext); 2871cb0ef41Sopenharmony_ci if (ret.IsEmpty() && env->async_callback_scope_depth() == 0) { 2881cb0ef41Sopenharmony_ci // This is only for legacy compatibility and we may want to look into 2891cb0ef41Sopenharmony_ci // removing/adjusting it. 2901cb0ef41Sopenharmony_ci return Undefined(isolate); 2911cb0ef41Sopenharmony_ci } 2921cb0ef41Sopenharmony_ci return ret; 2931cb0ef41Sopenharmony_ci} 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci// Use this if you just want to safely invoke some JS callback and 2961cb0ef41Sopenharmony_ci// would like to retain the currently active async_context, if any. 2971cb0ef41Sopenharmony_ci// In case none is available, a fixed default context will be 2981cb0ef41Sopenharmony_ci// installed otherwise. 2991cb0ef41Sopenharmony_ciMaybeLocal<Value> MakeSyncCallback(Isolate* isolate, 3001cb0ef41Sopenharmony_ci Local<Object> recv, 3011cb0ef41Sopenharmony_ci Local<Function> callback, 3021cb0ef41Sopenharmony_ci int argc, 3031cb0ef41Sopenharmony_ci Local<Value> argv[]) { 3041cb0ef41Sopenharmony_ci Environment* env = 3051cb0ef41Sopenharmony_ci Environment::GetCurrent(callback->GetCreationContext().ToLocalChecked()); 3061cb0ef41Sopenharmony_ci CHECK_NOT_NULL(env); 3071cb0ef41Sopenharmony_ci if (!env->can_call_into_js()) return Local<Value>(); 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ci Local<Context> context = env->context(); 3101cb0ef41Sopenharmony_ci Context::Scope context_scope(context); 3111cb0ef41Sopenharmony_ci if (env->async_callback_scope_depth()) { 3121cb0ef41Sopenharmony_ci // There's another MakeCallback() on the stack, piggy back on it. 3131cb0ef41Sopenharmony_ci // In particular, retain the current async_context. 3141cb0ef41Sopenharmony_ci return callback->Call(context, recv, argc, argv); 3151cb0ef41Sopenharmony_ci } 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_ci // This is a toplevel invocation and the caller (intentionally) 3181cb0ef41Sopenharmony_ci // didn't provide any async_context to run in. Install a default context. 3191cb0ef41Sopenharmony_ci MaybeLocal<Value> ret = 3201cb0ef41Sopenharmony_ci InternalMakeCallback(env, env->process_object(), recv, callback, argc, argv, 3211cb0ef41Sopenharmony_ci async_context{0, 0}); 3221cb0ef41Sopenharmony_ci return ret; 3231cb0ef41Sopenharmony_ci} 3241cb0ef41Sopenharmony_ci 3251cb0ef41Sopenharmony_ci// Legacy MakeCallback()s 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ciLocal<Value> MakeCallback(Isolate* isolate, 3281cb0ef41Sopenharmony_ci Local<Object> recv, 3291cb0ef41Sopenharmony_ci const char* method, 3301cb0ef41Sopenharmony_ci int argc, 3311cb0ef41Sopenharmony_ci Local<Value>* argv) { 3321cb0ef41Sopenharmony_ci EscapableHandleScope handle_scope(isolate); 3331cb0ef41Sopenharmony_ci return handle_scope.Escape( 3341cb0ef41Sopenharmony_ci MakeCallback(isolate, recv, method, argc, argv, {0, 0}) 3351cb0ef41Sopenharmony_ci .FromMaybe(Local<Value>())); 3361cb0ef41Sopenharmony_ci} 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_ciLocal<Value> MakeCallback(Isolate* isolate, 3391cb0ef41Sopenharmony_ci Local<Object> recv, 3401cb0ef41Sopenharmony_ci Local<String> symbol, 3411cb0ef41Sopenharmony_ci int argc, 3421cb0ef41Sopenharmony_ci Local<Value>* argv) { 3431cb0ef41Sopenharmony_ci EscapableHandleScope handle_scope(isolate); 3441cb0ef41Sopenharmony_ci return handle_scope.Escape( 3451cb0ef41Sopenharmony_ci MakeCallback(isolate, recv, symbol, argc, argv, {0, 0}) 3461cb0ef41Sopenharmony_ci .FromMaybe(Local<Value>())); 3471cb0ef41Sopenharmony_ci} 3481cb0ef41Sopenharmony_ci 3491cb0ef41Sopenharmony_ciLocal<Value> MakeCallback(Isolate* isolate, 3501cb0ef41Sopenharmony_ci Local<Object> recv, 3511cb0ef41Sopenharmony_ci Local<Function> callback, 3521cb0ef41Sopenharmony_ci int argc, 3531cb0ef41Sopenharmony_ci Local<Value>* argv) { 3541cb0ef41Sopenharmony_ci EscapableHandleScope handle_scope(isolate); 3551cb0ef41Sopenharmony_ci return handle_scope.Escape( 3561cb0ef41Sopenharmony_ci MakeCallback(isolate, recv, callback, argc, argv, {0, 0}) 3571cb0ef41Sopenharmony_ci .FromMaybe(Local<Value>())); 3581cb0ef41Sopenharmony_ci} 3591cb0ef41Sopenharmony_ci 3601cb0ef41Sopenharmony_ci} // namespace node 361