diff --git a/src/callback_scope.cc b/src/callback_scope.cc index fee7417fd37187..885134799fe019 100644 --- a/src/callback_scope.cc +++ b/src/callback_scope.cc @@ -5,11 +5,17 @@ namespace node { +using v8::Context; +using v8::EscapableHandleScope; using v8::Function; using v8::HandleScope; using v8::Isolate; using v8::Local; +using v8::MaybeLocal; +using v8::NewStringType; using v8::Object; +using v8::String; +using v8::Value; using AsyncHooks = Environment::AsyncHooks; @@ -126,4 +132,129 @@ void InternalCallbackScope::Close() { } } +MaybeLocal InternalMakeCallback(Environment* env, + Local recv, + const Local callback, + int argc, + Local argv[], + async_context asyncContext) { + CHECK(!recv.IsEmpty()); + InternalCallbackScope scope(env, recv, asyncContext); + if (scope.Failed()) { + return MaybeLocal(); + } + + Local domain_cb = env->domain_callback(); + MaybeLocal ret; + if (asyncContext.async_id != 0 || domain_cb.IsEmpty() || recv.IsEmpty()) { + ret = callback->Call(env->context(), recv, argc, argv); + } else { + std::vector> args(1 + argc); + args[0] = callback; + std::copy(&argv[0], &argv[argc], args.begin() + 1); + ret = domain_cb->Call(env->context(), recv, args.size(), &args[0]); + } + + if (ret.IsEmpty()) { + scope.MarkAsFailed(); + return MaybeLocal(); + } + + scope.Close(); + if (scope.Failed()) { + return MaybeLocal(); + } + + return ret; +} + +// Public MakeCallback()s + +MaybeLocal MakeCallback(Isolate* isolate, + Local recv, + const char* method, + int argc, + Local argv[], + async_context asyncContext) { + Local method_string = + String::NewFromUtf8(isolate, method, NewStringType::kNormal) + .ToLocalChecked(); + return MakeCallback(isolate, recv, method_string, argc, argv, asyncContext); +} + +MaybeLocal MakeCallback(Isolate* isolate, + Local recv, + Local symbol, + int argc, + Local argv[], + async_context asyncContext) { + Local callback_v = + recv->Get(isolate->GetCurrentContext(), symbol).ToLocalChecked(); + if (callback_v.IsEmpty()) return Local(); + if (!callback_v->IsFunction()) return Local(); + Local callback = callback_v.As(); + return MakeCallback(isolate, recv, callback, argc, argv, asyncContext); +} + +MaybeLocal MakeCallback(Isolate* isolate, + Local recv, + Local callback, + int argc, + Local argv[], + async_context asyncContext) { + // Observe the following two subtleties: + // + // 1. The environment is retrieved from the callback function's context. + // 2. The context to enter is retrieved from the environment. + // + // Because of the AssignToContext() call in src/node_contextify.cc, + // the two contexts need not be the same. + Environment* env = Environment::GetCurrent(callback->CreationContext()); + CHECK_NOT_NULL(env); + Context::Scope context_scope(env->context()); + MaybeLocal ret = + InternalMakeCallback(env, recv, callback, argc, argv, asyncContext); + if (ret.IsEmpty() && env->makecallback_depth() == 0) { + // This is only for legacy compatiblity and we may want to look into + // removing/adjusting it. + return Undefined(env->isolate()); + } + return ret; +} + +// Legacy MakeCallback()s + +Local MakeCallback(Isolate* isolate, + Local recv, + const char* method, + int argc, + Local* argv) { + EscapableHandleScope handle_scope(isolate); + return handle_scope.Escape( + MakeCallback(isolate, recv, method, argc, argv, {0, 0}) + .FromMaybe(Local())); +} + +Local MakeCallback(Isolate* isolate, + Local recv, + Local symbol, + int argc, + Local* argv) { + EscapableHandleScope handle_scope(isolate); + return handle_scope.Escape( + MakeCallback(isolate, recv, symbol, argc, argv, {0, 0}) + .FromMaybe(Local())); +} + +Local MakeCallback(Isolate* isolate, + Local recv, + Local callback, + int argc, + Local* argv) { + EscapableHandleScope handle_scope(isolate); + return handle_scope.Escape( + MakeCallback(isolate, recv, callback, argc, argv, {0, 0}) + .FromMaybe(Local())); +} + } // namespace node diff --git a/src/node.cc b/src/node.cc index f6a0995fe95f2c..504e3b79f98f94 100644 --- a/src/node.cc +++ b/src/node.cc @@ -109,7 +109,6 @@ using v8::Array; using v8::Boolean; using v8::Context; using v8::DEFAULT; -using v8::EscapableHandleScope; using v8::Exception; using v8::Function; using v8::FunctionCallbackInfo; @@ -560,138 +559,6 @@ void RemoveEnvironmentCleanupHook(Isolate* isolate, env->RemoveCleanupHook(fun, arg); } -MaybeLocal InternalMakeCallback(Environment* env, - Local recv, - const Local callback, - int argc, - Local argv[], - async_context asyncContext) { - CHECK(!recv.IsEmpty()); - InternalCallbackScope scope(env, recv, asyncContext); - if (scope.Failed()) { - return MaybeLocal(); - } - - Local domain_cb = env->domain_callback(); - MaybeLocal ret; - if (asyncContext.async_id != 0 || domain_cb.IsEmpty() || recv.IsEmpty()) { - ret = callback->Call(env->context(), recv, argc, argv); - } else { - std::vector> args(1 + argc); - args[0] = callback; - std::copy(&argv[0], &argv[argc], args.begin() + 1); - ret = domain_cb->Call(env->context(), recv, args.size(), &args[0]); - } - - if (ret.IsEmpty()) { - scope.MarkAsFailed(); - return MaybeLocal(); - } - - scope.Close(); - if (scope.Failed()) { - return MaybeLocal(); - } - - return ret; -} - - -// Public MakeCallback()s - - -MaybeLocal MakeCallback(Isolate* isolate, - Local recv, - const char* method, - int argc, - Local argv[], - async_context asyncContext) { - Local method_string = - String::NewFromUtf8(isolate, method, NewStringType::kNormal) - .ToLocalChecked(); - return MakeCallback(isolate, recv, method_string, argc, argv, asyncContext); -} - - -MaybeLocal MakeCallback(Isolate* isolate, - Local recv, - Local symbol, - int argc, - Local argv[], - async_context asyncContext) { - Local callback_v = recv->Get(isolate->GetCurrentContext(), - symbol).ToLocalChecked(); - if (callback_v.IsEmpty()) return Local(); - if (!callback_v->IsFunction()) return Local(); - Local callback = callback_v.As(); - return MakeCallback(isolate, recv, callback, argc, argv, asyncContext); -} - - -MaybeLocal MakeCallback(Isolate* isolate, - Local recv, - Local callback, - int argc, - Local argv[], - async_context asyncContext) { - // Observe the following two subtleties: - // - // 1. The environment is retrieved from the callback function's context. - // 2. The context to enter is retrieved from the environment. - // - // Because of the AssignToContext() call in src/node_contextify.cc, - // the two contexts need not be the same. - Environment* env = Environment::GetCurrent(callback->CreationContext()); - CHECK_NOT_NULL(env); - Context::Scope context_scope(env->context()); - MaybeLocal ret = InternalMakeCallback(env, recv, callback, - argc, argv, asyncContext); - if (ret.IsEmpty() && env->makecallback_depth() == 0) { - // This is only for legacy compatiblity and we may want to look into - // removing/adjusting it. - return Undefined(env->isolate()); - } - return ret; -} - - -// Legacy MakeCallback()s - -Local MakeCallback(Isolate* isolate, - Local recv, - const char* method, - int argc, - Local* argv) { - EscapableHandleScope handle_scope(isolate); - return handle_scope.Escape( - MakeCallback(isolate, recv, method, argc, argv, {0, 0}) - .FromMaybe(Local())); -} - - -Local MakeCallback(Isolate* isolate, - Local recv, - Local symbol, - int argc, - Local* argv) { - EscapableHandleScope handle_scope(isolate); - return handle_scope.Escape( - MakeCallback(isolate, recv, symbol, argc, argv, {0, 0}) - .FromMaybe(Local())); -} - - -Local MakeCallback(Isolate* isolate, - Local recv, - Local callback, - int argc, - Local* argv) { - EscapableHandleScope handle_scope(isolate); - return handle_scope.Escape( - MakeCallback(isolate, recv, callback, argc, argv, {0, 0}) - .FromMaybe(Local())); -} - static void WaitForInspectorDisconnect(Environment* env) { #if HAVE_INSPECTOR if (env->inspector_agent()->IsActive()) {