diff options
author | Stephen Belanger <admin@stephenbelanger.com> | 2020-06-06 22:06:06 +0300 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2020-06-19 18:37:25 +0300 |
commit | 59e6230a30954f78836048b581d8db61582242ef (patch) | |
tree | 861f4260ba22fb1807380cf39d2a8ea14f9b15ac /src/api | |
parent | 2c4864762d2b97a55ef15fe44b7691d67de51766 (diff) |
async_hooks: callback trampoline for MakeCallback
PR-URL: https://github.com/nodejs/node/pull/33801
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Vladimir de Turckheim <vlad2t@hotmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Andrey Pechkurov <apechkurov@gmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Diffstat (limited to 'src/api')
-rw-r--r-- | src/api/callback.cc | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/src/api/callback.cc b/src/api/callback.cc index a03a2587b4c..7daddcd977e 100644 --- a/src/api/callback.cc +++ b/src/api/callback.cc @@ -158,20 +158,46 @@ MaybeLocal<Value> InternalMakeCallback(Environment* env, CHECK(!argv[i].IsEmpty()); #endif - InternalCallbackScope scope(env, resource, asyncContext); + Local<Function> hook_cb = env->async_hooks_callback_trampoline(); + int flags = InternalCallbackScope::kNoFlags; + int hook_count = 0; + if (!hook_cb.IsEmpty()) { + flags = InternalCallbackScope::kSkipAsyncHooks; + AsyncHooks* async_hooks = env->async_hooks(); + hook_count = async_hooks->fields()[AsyncHooks::kBefore] + + async_hooks->fields()[AsyncHooks::kAfter]; + } + + InternalCallbackScope scope(env, resource, asyncContext, flags); if (scope.Failed()) { return MaybeLocal<Value>(); } Local<Function> domain_cb = env->domain_callback(); MaybeLocal<Value> ret; - if (asyncContext.async_id != 0 || domain_cb.IsEmpty()) { - ret = callback->Call(env->context(), recv, argc, argv); - } else { - std::vector<Local<Value>> args(1 + argc); + + if (asyncContext.async_id != 0 && hook_count != 0) { + MaybeStackBuffer<Local<Value>, 16> args(3 + argc); + args[0] = v8::Number::New(env->isolate(), asyncContext.async_id); + args[1] = callback; + if (domain_cb.IsEmpty()) { + args[2] = Undefined(env->isolate()); + } else { + args[2] = domain_cb; + } + for (int i = 0; i < argc; i++) { + args[i + 3] = argv[i]; + } + ret = hook_cb->Call(env->context(), recv, args.length(), &args[0]); + } else if (asyncContext.async_id == 0 && !domain_cb.IsEmpty()) { + MaybeStackBuffer<Local<Value>, 16> 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]); + for (int i = 0; i < argc; i++) { + args[i + 1] = argv[i]; + } + ret = domain_cb->Call(env->context(), recv, args.length(), &args[0]); + } else { + ret = callback->Call(env->context(), recv, argc, argv); } if (ret.IsEmpty()) { |