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