Skip to content

Commit b4aeecb

Browse files
authored
feat: add support for nogc types via BasicEnv (#1514)
* src: introduce `NogcEnv`; support for nogc finalizers
1 parent a0619ff commit b4aeecb

15 files changed

+1045
-300
lines changed

doc/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ The following is the documentation for node-addon-api.
3737
- [Full Class Hierarchy](hierarchy.md)
3838
- [Addon Structure](addon.md)
3939
- Data Types:
40+
- [BasicEnv](basic_env.md)
4041
- [Env](env.md)
4142
- [CallbackInfo](callbackinfo.md)
4243
- [Reference](reference.md)
@@ -70,6 +71,7 @@ The following is the documentation for node-addon-api.
7071
- [Object Lifetime Management](object_lifetime_management.md)
7172
- [HandleScope](handle_scope.md)
7273
- [EscapableHandleScope](escapable_handle_scope.md)
74+
- [Finalization](finalization.md)
7375
- [Memory Management](memory_management.md)
7476
- [Async Operations](async_operations.md)
7577
- [AsyncWorker](async_worker.md)

doc/array_buffer.md

+15-15
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ Wraps the provided external data into a new `Napi::ArrayBuffer` instance.
3131
The `Napi::ArrayBuffer` instance does not assume ownership for the data and
3232
expects it to be valid for the lifetime of the instance. Since the
3333
`Napi::ArrayBuffer` is subject to garbage collection this overload is only
34-
suitable for data which is static and never needs to be freed.
35-
This factory method will not provide the caller with an opportunity to free the
36-
data when the `Napi::ArrayBuffer` gets garbage-collected. If you need to free
37-
the data retained by the `Napi::ArrayBuffer` object please use other
38-
variants of the `Napi::ArrayBuffer::New` factory method that accept
39-
`Napi::Finalizer`, which is a function that will be invoked when the
40-
`Napi::ArrayBuffer` object has been destroyed.
34+
suitable for data which is static and never needs to be freed. This factory
35+
method will not provide the caller with an opportunity to free the data when the
36+
`Napi::ArrayBuffer` gets garbage-collected. If you need to free the data
37+
retained by the `Napi::ArrayBuffer` object please use other variants of the
38+
`Napi::ArrayBuffer::New` factory method that accept `Napi::Finalizer`, which is
39+
a function that will be invoked when the `Napi::ArrayBuffer` object has been
40+
destroyed. See [Finalization][] for more details.
4141
4242
```cpp
4343
static Napi::ArrayBuffer Napi::ArrayBuffer::New(napi_env env, void* externalData, size_t byteLength);
@@ -72,9 +72,9 @@ static Napi::ArrayBuffer Napi::ArrayBuffer::New(napi_env env,
7272
- `[in] env`: The environment in which to create the `Napi::ArrayBuffer` instance.
7373
- `[in] externalData`: The pointer to the external data to wrap.
7474
- `[in] byteLength`: The length of the `externalData`, in bytes.
75-
- `[in] finalizeCallback`: A function to be called when the `Napi::ArrayBuffer` is
76-
destroyed. It must implement `operator()`, accept an Napi::Env, a `void*` (which is the
77-
`externalData` pointer), and return `void`.
75+
- `[in] finalizeCallback`: A function called when the engine destroys the
76+
`Napi::ArrayBuffer` object, implementing `operator()(Napi::BasicEnv, void*)`.
77+
See [Finalization][] for more details.
7878
7979
Returns a new `Napi::ArrayBuffer` instance.
8080
@@ -102,11 +102,10 @@ static Napi::ArrayBuffer Napi::ArrayBuffer::New(napi_env env,
102102
- `[in] env`: The environment in which to create the `Napi::ArrayBuffer` instance.
103103
- `[in] externalData`: The pointer to the external data to wrap.
104104
- `[in] byteLength`: The length of the `externalData`, in bytes.
105-
- `[in] finalizeCallback`: The function to be called when the `Napi::ArrayBuffer` is
106-
destroyed. It must implement `operator()`, accept an Napi::Env, a `void*` (which is the
107-
`externalData` pointer) and `Hint*`, and return `void`.
108-
- `[in] finalizeHint`: The hint to be passed as the second parameter of the
109-
finalize callback.
105+
- `[in] finalizeCallback`: A function called when the engine destroys the
106+
`Napi::ArrayBuffer` object, implementing `operator()(Napi::BasicEnv, void*,
107+
Hint*)`. See [Finalization][] for more details.
108+
- `[in] finalizeHint`: The hint value passed to the `finalizeCallback` function.
110109

111110
Returns a new `Napi::ArrayBuffer` instance.
112111

@@ -163,3 +162,4 @@ Returns `true` if this `ArrayBuffer` has been detached.
163162

164163
[`Napi::Object`]: ./object.md
165164
[External Buffer]: ./external_buffer.md
165+
[Finalization]: ./finalization.md

doc/basic_env.md

+200
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
# BasicEnv
2+
3+
The data structure containing the environment in which the request is being run.
4+
5+
The `Napi::BasicEnv` object is usually created and passed by the Node.js runtime
6+
or node-addon-api infrastructure.
7+
8+
The `Napi::BasicEnv` object represents an environment that has a limited subset
9+
of APIs when compared to `Napi::Env` and can be used in basic finalizers. See
10+
[Finalization][] for more details.
11+
12+
## Methods
13+
14+
### Constructor
15+
16+
```cpp
17+
Napi::BasicEnv::BasicEnv(node_api_nogc_env env);
18+
```
19+
20+
- `[in] env`: The `node_api_nogc_env` environment from which to construct the
21+
`Napi::BasicEnv` object.
22+
23+
### node_api_nogc_env
24+
25+
```cpp
26+
operator node_api_nogc_env() const;
27+
```
28+
29+
Returns the `node_api_nogc_env` opaque data structure representing the
30+
environment.
31+
32+
### GetInstanceData
33+
```cpp
34+
template <typename T> T* GetInstanceData() const;
35+
```
36+
37+
Returns the instance data that was previously associated with the environment,
38+
or `nullptr` if none was associated.
39+
40+
### SetInstanceData
41+
42+
43+
```cpp
44+
template <typename T> using Finalizer = void (*)(Env, T*);
45+
template <typename T, Finalizer<T> fini = Env::DefaultFini<T>>
46+
void SetInstanceData(T* data) const;
47+
```
48+
49+
- `[template] fini`: A function to call when the instance data is to be deleted.
50+
Accepts a function of the form `void CleanupData(Napi::Env env, T* data)`. If
51+
not given, the default finalizer will be used, which simply uses the `delete`
52+
operator to destroy `T*` when the add-on instance is unloaded.
53+
- `[in] data`: A pointer to data that will be associated with the instance of
54+
the add-on for the duration of its lifecycle.
55+
56+
Associates a data item stored at `T* data` with the current instance of the
57+
add-on. The item will be passed to the function `fini` which gets called when an
58+
instance of the add-on is unloaded.
59+
60+
### SetInstanceData
61+
62+
```cpp
63+
template <typename DataType, typename HintType>
64+
using FinalizerWithHint = void (*)(Env, DataType*, HintType*);
65+
template <typename DataType,
66+
typename HintType,
67+
FinalizerWithHint<DataType, HintType> fini =
68+
Env::DefaultFiniWithHint<DataType, HintType>>
69+
void SetInstanceData(DataType* data, HintType* hint) const;
70+
```
71+
72+
- `[template] fini`: A function to call when the instance data is to be deleted.
73+
Accepts a function of the form `void CleanupData(Napi::Env env, DataType* data,
74+
HintType* hint)`. If not given, the default finalizer will be used, which simply
75+
uses the `delete` operator to destroy `T*` when the add-on instance is unloaded.
76+
- `[in] data`: A pointer to data that will be associated with the instance of
77+
the add-on for the duration of its lifecycle.
78+
- `[in] hint`: A pointer to data that will be associated with the instance of
79+
the add-on for the duration of its lifecycle and will be passed as a hint to
80+
`fini` when the add-on instance is unloaded.
81+
82+
Associates a data item stored at `T* data` with the current instance of the
83+
add-on. The item will be passed to the function `fini` which gets called when an
84+
instance of the add-on is unloaded. This overload accepts an additional hint to
85+
be passed to `fini`.
86+
87+
### GetModuleFileName
88+
89+
```cpp
90+
const char* Napi::Env::GetModuleFileName() const;
91+
```
92+
93+
Returns a URL containing the absolute path of the location from which the add-on
94+
was loaded. For a file on the local file system it will start with `file://`.
95+
The string is null-terminated and owned by env and must thus not be modified or
96+
freed. It is only valid while the add-on is loaded.
97+
98+
### AddCleanupHook
99+
100+
```cpp
101+
template <typename Hook>
102+
CleanupHook<Hook> AddCleanupHook(Hook hook);
103+
```
104+
105+
- `[in] hook`: A function to call when the environment exits. Accepts a function
106+
of the form `void ()`.
107+
108+
Registers `hook` as a function to be run once the current Node.js environment
109+
exits. Unlike the underlying C-based Node-API, providing the same `hook`
110+
multiple times **is** allowed. The hooks will be called in reverse order, i.e.
111+
the most recently added one will be called first.
112+
113+
Returns an `Env::CleanupHook` object, which can be used to remove the hook via
114+
its `Remove()` method.
115+
116+
### PostFinalizer
117+
118+
```cpp
119+
template <typename FinalizerType>
120+
inline void PostFinalizer(FinalizerType finalizeCallback) const;
121+
```
122+
123+
- `[in] finalizeCallback`: The function to queue for execution outside of the GC
124+
finalization, implementing `operator()(Napi::Env)`. See [Finalization][] for
125+
more details.
126+
127+
### PostFinalizer
128+
129+
```cpp
130+
template <typename FinalizerType, typename T>
131+
inline void PostFinalizer(FinalizerType finalizeCallback, T* data) const;
132+
```
133+
134+
- `[in] finalizeCallback`: The function to queue for execution outside of the GC
135+
finalization, implementing `operator()(Napi::Env, T*)`. See [Finalization][]
136+
for more details.
137+
- `[in] data`: The data to associate with the object.
138+
139+
### PostFinalizer
140+
141+
```cpp
142+
template <typename FinalizerType, typename T, typename Hint>
143+
inline void PostFinalizer(FinalizerType finalizeCallback,
144+
T* data,
145+
Hint* finalizeHint) const;
146+
```
147+
148+
- `[in] finalizeCallback`: The function to queue for execution outside of the GC
149+
finalization, implementing `operator()(Napi::Env, T*, Hint*)`. See
150+
[Finalization][] for more details.
151+
- `[in] data`: The data to associate with the object.
152+
- `[in] finalizeHint`: The hint value passed to the `finalizeCallback` function.
153+
154+
### AddCleanupHook
155+
156+
```cpp
157+
template <typename Hook, typename Arg>
158+
CleanupHook<Hook, Arg> AddCleanupHook(Hook hook, Arg* arg);
159+
```
160+
161+
- `[in] hook`: A function to call when the environment exits. Accepts a function
162+
of the form `void (Arg* arg)`.
163+
- `[in] arg`: A pointer to data that will be passed as the argument to `hook`.
164+
165+
Registers `hook` as a function to be run with the `arg` parameter once the
166+
current Node.js environment exits. Unlike the underlying C-based Node-API,
167+
providing the same `hook` and `arg` pair multiple times **is** allowed. The
168+
hooks will be called in reverse order, i.e. the most recently added one will be
169+
called first.
170+
171+
Returns an `Env::CleanupHook` object, which can be used to remove the hook via
172+
its `Remove()` method.
173+
174+
# Env::CleanupHook
175+
176+
The `Env::CleanupHook` object allows removal of the hook added via
177+
`Env::AddCleanupHook()`
178+
179+
## Methods
180+
181+
### IsEmpty
182+
183+
```cpp
184+
bool IsEmpty();
185+
```
186+
187+
Returns `true` if the cleanup hook was **not** successfully registered.
188+
189+
### Remove
190+
191+
```cpp
192+
bool Remove(Env env);
193+
```
194+
195+
Unregisters the hook from running once the current Node.js environment exits.
196+
197+
Returns `true` if the hook was successfully removed from the Node.js
198+
environment.
199+
200+
[Finalization]: ./finalization.md

doc/buffer.md

+24-26
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,15 @@ Returns a new `Napi::Buffer` object.
2727
2828
Wraps the provided external data into a new `Napi::Buffer` object.
2929
30-
The `Napi::Buffer` object does not assume ownership for the data and expects it to be
31-
valid for the lifetime of the object. Since the `Napi::Buffer` is subject to garbage
32-
collection this overload is only suitable for data which is static and never
33-
needs to be freed.
34-
This factory method will not provide the caller with an opportunity to free the
35-
data when the `Napi::Buffer` gets garbage-collected. If you need to free the
36-
data retained by the `Napi::Buffer` object please use other variants of the
37-
`Napi::Buffer::New` factory method that accept `Napi::Finalizer`, which is a
38-
function that will be invoked when the `Napi::Buffer` object has been
39-
destroyed.
30+
The `Napi::Buffer` object does not assume ownership for the data and expects it
31+
to be valid for the lifetime of the object. Since the `Napi::Buffer` is subject
32+
to garbage collection this overload is only suitable for data which is static
33+
and never needs to be freed. This factory method will not provide the caller
34+
with an opportunity to free the data when the `Napi::Buffer` gets
35+
garbage-collected. If you need to free the data retained by the `Napi::Buffer`
36+
object please use other variants of the `Napi::Buffer::New` factory method that
37+
accept `Finalizer`, which is a function that will be invoked when the
38+
`Napi::Buffer` object has been destroyed. See [Finalization][] for more details.
4039
4140
```cpp
4241
static Napi::Buffer<T> Napi::Buffer::New(napi_env env, T* data, size_t length);
@@ -70,9 +69,9 @@ static Napi::Buffer<T> Napi::Buffer::New(napi_env env,
7069
- `[in] env`: The environment in which to create the `Napi::Buffer` object.
7170
- `[in] data`: The pointer to the external data to expose.
7271
- `[in] length`: The number of `T` elements in the external data.
73-
- `[in] finalizeCallback`: The function to be called when the `Napi::Buffer` is
74-
destroyed. It must implement `operator()`, accept an Napi::Env, a `T*` (which is the
75-
external data pointer), and return `void`.
72+
- `[in] finalizeCallback`: The function called when the engine destroys the
73+
`Napi::Buffer` object, implementing `operator()(Napi::BasicEnv, T*)`. See
74+
[Finalization][] for more details.
7675
7776
Returns a new `Napi::Buffer` object.
7877
@@ -99,11 +98,10 @@ static Napi::Buffer<T> Napi::Buffer::New(napi_env env,
9998
- `[in] env`: The environment in which to create the `Napi::Buffer` object.
10099
- `[in] data`: The pointer to the external data to expose.
101100
- `[in] length`: The number of `T` elements in the external data.
102-
- `[in] finalizeCallback`: The function to be called when the `Napi::Buffer` is
103-
destroyed. It must implement `operator()`, accept an Napi::Env, a `T*` (which is the
104-
external data pointer) and `Hint*`, and return `void`.
105-
- `[in] finalizeHint`: The hint to be passed as the second parameter of the
106-
finalize callback.
101+
- `[in] finalizeCallback`: The function called when the engine destroys the
102+
`Napi::Buffer` object, implementing `operator()(Napi::BasicEnv, T*, Hint*)`.
103+
See [Finalization][] for more details.
104+
- `[in] finalizeHint`: The hint value passed to the `finalizeCallback` function.
107105

108106
Returns a new `Napi::Buffer` object.
109107

@@ -157,9 +155,9 @@ static Napi::Buffer<T> Napi::Buffer::NewOrCopy(napi_env env,
157155
- `[in] env`: The environment in which to create the `Napi::Buffer` object.
158156
- `[in] data`: The pointer to the external data to expose.
159157
- `[in] length`: The number of `T` elements in the external data.
160-
- `[in] finalizeCallback`: The function to be called when the `Napi::Buffer` is
161-
destroyed. It must implement `operator()`, accept an Napi::Env, a `T*` (which is the
162-
external data pointer), and return `void`.
158+
- `[in] finalizeCallback`: The function called when the engine destroys the
159+
`Napi::Buffer` object, implementing `operator()(Napi::BasicEnv, T*)`. See
160+
[Finalization][] for more details.
163161

164162
Returns a new `Napi::Buffer` object.
165163

@@ -186,11 +184,10 @@ static Napi::Buffer<T> Napi::Buffer::NewOrCopy(napi_env env,
186184
- `[in] env`: The environment in which to create the `Napi::Buffer` object.
187185
- `[in] data`: The pointer to the external data to expose.
188186
- `[in] length`: The number of `T` elements in the external data.
189-
- `[in] finalizeCallback`: The function to be called when the `Napi::Buffer` is
190-
destroyed. It must implement `operator()`, accept an Napi::Env, a `T*` (which is the
191-
external data pointer) and `Hint*`, and return `void`.
192-
- `[in] finalizeHint`: The hint to be passed as the second parameter of the
193-
finalize callback.
187+
- `[in] finalizeCallback`: The function called when the engine destroys the
188+
`Napi::Buffer` object, implementing `operator()(Napi::BasicEnv, T*, Hint*)`.
189+
See [Finalization][] for more details.
190+
- `[in] finalizeHint`: The hint value passed to the `finalizeCallback` function.
194191
195192
Returns a new `Napi::Buffer` object.
196193
@@ -245,3 +242,4 @@ Returns the number of `T` elements in the external data.
245242

246243
[`Napi::Uint8Array`]: ./typed_array_of.md
247244
[External Buffer]: ./external_buffer.md
245+
[Finalization]: ./finalization.md

0 commit comments

Comments
 (0)