diff options
author | Joyee Cheung <joyeec9h3@gmail.com> | 2019-04-20 16:35:27 +0300 |
---|---|---|
committer | Joyee Cheung <joyeec9h3@gmail.com> | 2020-07-18 06:02:58 +0300 |
commit | ef9964f4c183f062ca25337984a542895590141d (patch) | |
tree | 35d1b1b8bc3e4b65aa6572b6e0ab4c0ec022e97d /src/node_external_reference.h | |
parent | 404302fff5079b5d9faaecbb9a1b2de67f2d86cc (diff) |
src: add an ExternalReferenceRegistry class
Add an ExternalReferenceRegistry class for registering static
external references.
To register the external JS to C++ references created in a binding
(e.g. when a FunctionTemplate is created):
- Add the binding name (same as the id used for `internalBinding()`
and `NODE_MODULE_CONTEXT_AWARE_INTERNAL`) to
`EXTERNAL_REFERENCE_BINDING_LIST` in `src/node_external_reference.h`.
- In the file where the binding is implemented, create a registration
function to register the static C++ references (e.g. the C++
functions in `v8::FunctionCallback` associated with the function
templates), like this:
```c++
void RegisterExternalReferences(
ExternalReferenceRegistry* registry) {
registry->Register(cpp_func_1);
}
```
- At the end of the file where `NODE_MODULE_CONTEXT_AWARE_INTERNAL` is
also usually called, register the registration function with
```
NODE_MODULE_EXTERNAL_REFERENCE(binding_name,
RegisterExternalReferences);
```
PR-URL: https://github.com/nodejs/node/pull/32984
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Diffstat (limited to 'src/node_external_reference.h')
-rw-r--r-- | src/node_external_reference.h | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/node_external_reference.h b/src/node_external_reference.h new file mode 100644 index 00000000000..544236e3af6 --- /dev/null +++ b/src/node_external_reference.h @@ -0,0 +1,67 @@ +#ifndef SRC_NODE_EXTERNAL_REFERENCE_H_ +#define SRC_NODE_EXTERNAL_REFERENCE_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include <cinttypes> +#include <vector> +#include "v8.h" + +namespace node { + +// This class manages the external references from the V8 heap +// to the C++ addresses in Node.js. +class ExternalReferenceRegistry { + public: + ExternalReferenceRegistry(); + +#define ALLOWED_EXTERNAL_REFERENCE_TYPES(V) \ + V(v8::FunctionCallback) \ + V(v8::AccessorGetterCallback) \ + V(v8::AccessorSetterCallback) \ + V(v8::AccessorNameGetterCallback) \ + V(v8::AccessorNameSetterCallback) \ + V(v8::GenericNamedPropertyDefinerCallback) \ + V(v8::GenericNamedPropertyDeleterCallback) \ + V(v8::GenericNamedPropertyEnumeratorCallback) \ + V(v8::GenericNamedPropertyQueryCallback) \ + V(v8::GenericNamedPropertySetterCallback) + +#define V(ExternalReferenceType) \ + void Register(ExternalReferenceType addr) { RegisterT(addr); } + ALLOWED_EXTERNAL_REFERENCE_TYPES(V) +#undef V + + // This can be called only once. + const std::vector<intptr_t>& external_references(); + + bool is_empty() { return external_references_.empty(); } + + private: + template <typename T> + void RegisterT(T* address) { + external_references_.push_back(reinterpret_cast<intptr_t>(address)); + } + bool is_finalized_ = false; + std::vector<intptr_t> external_references_; +}; + +#define EXTERNAL_REFERENCE_BINDING_LIST(V) + +} // namespace node + +// Declare all the external reference registration functions here, +// and define them later with #NODE_MODULE_EXTERNAL_REFERENCE(modname, func); +#define V(modname) \ + void _register_external_reference_##modname( \ + node::ExternalReferenceRegistry* registry); +EXTERNAL_REFERENCE_BINDING_LIST(V) +#undef V + +#define NODE_MODULE_EXTERNAL_REFERENCE(modname, func) \ + void _register_external_reference_##modname( \ + node::ExternalReferenceRegistry* registry) { \ + func(registry); \ + } +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS +#endif // SRC_NODE_EXTERNAL_REFERENCE_H_ |