diff --git a/src/env.cc b/src/env.cc index b44b435d4e3..034625b3754 100644 --- a/src/env.cc +++ b/src/env.cc @@ -188,4 +188,20 @@ void Environment::AtExit(void (*cb)(void* arg), void* arg) { at_exit_functions_.push_back(AtExitCallback{cb, arg}); } +void Environment::AddPromiseHook(promise_hook_func fn, void* arg) { + promise_hooks_.push_back(PromiseHookCallback{fn, arg}); + if (promise_hooks_.size() == 1) { + isolate_->SetPromiseHook(EnvPromiseHook); + } +} + +void Environment::EnvPromiseHook(v8::PromiseHookType type, + v8::Local promise, + v8::Local parent) { + Environment* env = Environment::GetCurrent(promise->CreationContext()); + for (const PromiseHookCallback& hook : env->promise_hooks_) { + hook.cb_(type, promise, parent, hook.arg_); + } +} + } // namespace node diff --git a/src/env.h b/src/env.h index 8b158728a9a..abf5f44de05 100644 --- a/src/env.h +++ b/src/env.h @@ -35,6 +35,7 @@ #include "util.h" #include "uv.h" #include "v8.h" +#include "node.h" #include #include @@ -572,6 +573,8 @@ class Environment { static const int kContextEmbedderDataIndex = NODE_CONTEXT_EMBEDDER_DATA_INDEX; + void AddPromiseHook(promise_hook_func fn, void* arg); + private: inline void ThrowError(v8::Local (*fun)(v8::Local), const char* errmsg); @@ -620,6 +623,16 @@ class Environment { }; std::list at_exit_functions_; + struct PromiseHookCallback { + promise_hook_func cb_; + void* arg_; + }; + std::vector promise_hooks_; + + static void EnvPromiseHook(v8::PromiseHookType type, + v8::Local promise, + v8::Local parent); + #define V(PropertyName, TypeName) \ v8::Persistent PropertyName ## _; ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) diff --git a/src/node.cc b/src/node.cc index bb17a4139ae..abb570fb9eb 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1233,6 +1233,12 @@ void SetupPromises(const FunctionCallbackInfo& args) { } // anonymous namespace +void AddPromiseHook(v8::Isolate* isolate, promise_hook_func fn, void* arg) { + Environment* env = Environment::GetCurrent(isolate); + env->AddPromiseHook(fn, arg); +} + + Local MakeCallback(Environment* env, Local recv, const Local callback, diff --git a/src/node.h b/src/node.h index e0109cb14fd..7ed4521e87d 100644 --- a/src/node.h +++ b/src/node.h @@ -516,6 +516,17 @@ NODE_EXTERN void AtExit(void (*cb)(void* arg), void* arg = 0); */ NODE_EXTERN void AtExit(Environment* env, void (*cb)(void* arg), void* arg = 0); +typedef void (*promise_hook_func) (v8::PromiseHookType type, + v8::Local promise, + v8::Local parent, + void* arg); + +/* Registers an additional v8::PromiseHook wrapper. This API exists because V8 + * itself supports only a single PromiseHook. */ +NODE_EXTERN void AddPromiseHook(v8::Isolate* isolate, + promise_hook_func fn, + void* arg); + } // namespace node #endif // SRC_NODE_H_