node-addon-api 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +1 -1
- package/napi-inl.h +58 -13
- package/napi.h +2 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# node-addon-api Changelog
|
|
2
2
|
|
|
3
|
+
## 2020-07-01 Version 2.0.2, @NickNaso
|
|
4
|
+
|
|
5
|
+
### Notable changes:
|
|
6
|
+
|
|
7
|
+
#### API
|
|
8
|
+
|
|
9
|
+
- `Napi::ObjectWrap`: avoid double-free on old Node.js.
|
|
10
|
+
- `Napi::ObjectWrap`: remove wrap only on failure.
|
|
11
|
+
- `Napi::ObjectWrap`: gracefully handle constructor exceptions
|
|
12
|
+
- `Napi::ObjectWrap`: call `napi_remove_wrap()` in destructor.
|
|
13
|
+
|
|
14
|
+
#### TEST
|
|
15
|
+
|
|
16
|
+
- Updated `Napi::BigInt` test for recent change in core.
|
|
17
|
+
|
|
18
|
+
### Commmits
|
|
19
|
+
|
|
20
|
+
* [[`5abf60257d`](https://github.com/nodejs/node-addon-api/commit/5abf60257d)] - Merge pull request #723 from gabrielschulhof/backport-4e885069-pr-475 (Nicola Del Gobbo)
|
|
21
|
+
* [[`470f130666`](https://github.com/nodejs/node-addon-api/commit/470f130666)] - **objectwrap**: avoid double-free on old Node.js (Gabriel Schulhof)
|
|
22
|
+
* [[`81e2eac7ba`](https://github.com/nodejs/node-addon-api/commit/81e2eac7ba)] - **test**: update BigInt test for recent change in core (Michael Dawson) [#649](https://github.com/nodejs/node-addon-api/pull/649)
|
|
23
|
+
* [[`204f07252c`](https://github.com/nodejs/node-addon-api/commit/204f07252c)] - **objectwrap**: remove wrap only on failure (Gabriel Schulhof)
|
|
24
|
+
* [[`a552a384dd`](https://github.com/nodejs/node-addon-api/commit/a552a384dd)] - **src**: call `napi\_remove\_wrap()` in `ObjectWrap` dtor (Anna Henningsen) [#475](https://github.com/nodejs/node-addon-api/pull/475)
|
|
25
|
+
* [[`1a51067438`](https://github.com/nodejs/node-addon-api/commit/1a51067438)] - **objectwrap**: gracefully handle constructor exceptions (Gabriel Schulhof)
|
|
26
|
+
|
|
3
27
|
## 2020-06-02 Version 2.0.1, @NickNaso
|
|
4
28
|
|
|
5
29
|
### Notable changes:
|
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ to ideas specified in the **ECMA262 Language Specification**.
|
|
|
46
46
|
- **[Contributors](#contributors)**
|
|
47
47
|
- **[License](#license)**
|
|
48
48
|
|
|
49
|
-
## **Current version: 2.0.
|
|
49
|
+
## **Current version: 2.0.2**
|
|
50
50
|
|
|
51
51
|
(See [CHANGELOG.md](CHANGELOG.md) for complete Changelog)
|
|
52
52
|
|
package/napi-inl.h
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// Note: Do not include this file directly! Include "napi.h" instead.
|
|
11
11
|
|
|
12
12
|
#include <algorithm>
|
|
13
|
+
#include <atomic>
|
|
13
14
|
#include <cstring>
|
|
14
15
|
#include <mutex>
|
|
15
16
|
#include <type_traits>
|
|
@@ -19,6 +20,8 @@ namespace Napi {
|
|
|
19
20
|
// Helpers to handle functions exposed from C++.
|
|
20
21
|
namespace details {
|
|
21
22
|
|
|
23
|
+
extern std::atomic_bool needs_objectwrap_destructor_fix;
|
|
24
|
+
|
|
22
25
|
// Attach a data item to an object and delete it when the object gets
|
|
23
26
|
// garbage-collected.
|
|
24
27
|
// TODO: Replace this code with `napi_add_finalizer()` whenever it becomes
|
|
@@ -251,11 +254,16 @@ struct AccessorCallbackData {
|
|
|
251
254
|
// Module registration
|
|
252
255
|
////////////////////////////////////////////////////////////////////////////////
|
|
253
256
|
|
|
254
|
-
#define NODE_API_MODULE(modname, regfunc)
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
257
|
+
#define NODE_API_MODULE(modname, regfunc) \
|
|
258
|
+
namespace Napi { \
|
|
259
|
+
namespace details { \
|
|
260
|
+
std::atomic_bool needs_objectwrap_destructor_fix(false); \
|
|
261
|
+
} \
|
|
262
|
+
} \
|
|
263
|
+
napi_value __napi_ ## regfunc(napi_env env, \
|
|
264
|
+
napi_value exports) { \
|
|
265
|
+
return Napi::RegisterModule(env, exports, regfunc); \
|
|
266
|
+
} \
|
|
259
267
|
NAPI_MODULE(modname, __napi_ ## regfunc)
|
|
260
268
|
|
|
261
269
|
// Adapt the NAPI_MODULE registration function:
|
|
@@ -264,6 +272,12 @@ struct AccessorCallbackData {
|
|
|
264
272
|
inline napi_value RegisterModule(napi_env env,
|
|
265
273
|
napi_value exports,
|
|
266
274
|
ModuleRegisterCallback registerCallback) {
|
|
275
|
+
const napi_node_version* nver = Napi::VersionManagement::GetNodeVersion(env);
|
|
276
|
+
Napi::details::needs_objectwrap_destructor_fix =
|
|
277
|
+
(nver->major < 10 ||
|
|
278
|
+
(nver->major == 10 && nver->minor < 15) ||
|
|
279
|
+
(nver->major == 10 && nver->minor == 15 && nver->patch < 3));
|
|
280
|
+
|
|
267
281
|
return details::WrapCallback([&] {
|
|
268
282
|
return napi_value(registerCallback(Napi::Env(env),
|
|
269
283
|
Napi::Object(env, exports)));
|
|
@@ -2968,16 +2982,36 @@ inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
|
|
|
2968
2982
|
napi_value wrapper = callbackInfo.This();
|
|
2969
2983
|
napi_status status;
|
|
2970
2984
|
napi_ref ref;
|
|
2971
|
-
|
|
2972
|
-
status = napi_wrap(env, wrapper, instance, FinalizeCallback, nullptr, &ref);
|
|
2985
|
+
status = napi_wrap(env, wrapper, this, FinalizeCallback, nullptr, &ref);
|
|
2973
2986
|
NAPI_THROW_IF_FAILED_VOID(env, status);
|
|
2974
2987
|
|
|
2975
|
-
Reference<Object>* instanceRef =
|
|
2988
|
+
Reference<Object>* instanceRef = this;
|
|
2976
2989
|
*instanceRef = Reference<Object>(env, ref);
|
|
2977
2990
|
}
|
|
2978
2991
|
|
|
2979
|
-
template<typename T>
|
|
2980
|
-
inline ObjectWrap<T>::~ObjectWrap() {
|
|
2992
|
+
template <typename T>
|
|
2993
|
+
inline ObjectWrap<T>::~ObjectWrap() {
|
|
2994
|
+
// If the JS object still exists at this point, remove the finalizer added
|
|
2995
|
+
// through `napi_wrap()`.
|
|
2996
|
+
if (!IsEmpty()) {
|
|
2997
|
+
Object object = Value();
|
|
2998
|
+
// It is not valid to call `napi_remove_wrap()` with an empty `object`.
|
|
2999
|
+
// This happens e.g. during garbage collection.
|
|
3000
|
+
if (!object.IsEmpty() && _construction_failed) {
|
|
3001
|
+
napi_remove_wrap(Env(), object, nullptr);
|
|
3002
|
+
|
|
3003
|
+
if (Napi::details::needs_objectwrap_destructor_fix) {
|
|
3004
|
+
// If construction failed we delete the reference via
|
|
3005
|
+
// `napi_remove_wrap()`, not via `napi_delete_reference()` in the
|
|
3006
|
+
// `Reference<Object>` destructor. This will prevent the
|
|
3007
|
+
// `Reference<Object>` destructor from doing a double delete of this
|
|
3008
|
+
// reference.
|
|
3009
|
+
_ref = nullptr;
|
|
3010
|
+
_env = nullptr;
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
2981
3015
|
|
|
2982
3016
|
template<typename T>
|
|
2983
3017
|
inline T* ObjectWrap<T>::Unwrap(Object wrapper) {
|
|
@@ -3369,10 +3403,21 @@ inline napi_value ObjectWrap<T>::ConstructorCallbackWrapper(
|
|
|
3369
3403
|
return nullptr;
|
|
3370
3404
|
}
|
|
3371
3405
|
|
|
3372
|
-
T* instance;
|
|
3373
3406
|
napi_value wrapper = details::WrapCallback([&] {
|
|
3374
3407
|
CallbackInfo callbackInfo(env, info);
|
|
3375
|
-
instance = new T(callbackInfo);
|
|
3408
|
+
T* instance = new T(callbackInfo);
|
|
3409
|
+
#ifdef NAPI_CPP_EXCEPTIONS
|
|
3410
|
+
instance->_construction_failed = false;
|
|
3411
|
+
#else
|
|
3412
|
+
if (callbackInfo.Env().IsExceptionPending()) {
|
|
3413
|
+
// We need to clear the exception so that removing the wrap might work.
|
|
3414
|
+
Error e = callbackInfo.Env().GetAndClearPendingException();
|
|
3415
|
+
delete instance;
|
|
3416
|
+
e.ThrowAsJavaScriptException();
|
|
3417
|
+
} else {
|
|
3418
|
+
instance->_construction_failed = false;
|
|
3419
|
+
}
|
|
3420
|
+
# endif // NAPI_CPP_EXCEPTIONS
|
|
3376
3421
|
return callbackInfo.This();
|
|
3377
3422
|
});
|
|
3378
3423
|
|
|
@@ -3497,7 +3542,7 @@ inline napi_value ObjectWrap<T>::InstanceSetterCallbackWrapper(
|
|
|
3497
3542
|
|
|
3498
3543
|
template <typename T>
|
|
3499
3544
|
inline void ObjectWrap<T>::FinalizeCallback(napi_env env, void* data, void* /*hint*/) {
|
|
3500
|
-
T
|
|
3545
|
+
ObjectWrap<T>* instance = static_cast<ObjectWrap<T>*>(data);
|
|
3501
3546
|
instance->Finalize(Napi::Env(env));
|
|
3502
3547
|
delete instance;
|
|
3503
3548
|
}
|
package/napi.h
CHANGED
|
@@ -1735,6 +1735,8 @@ namespace Napi {
|
|
|
1735
1735
|
StaticAccessorCallbackData;
|
|
1736
1736
|
typedef AccessorCallbackData<InstanceGetterCallback, InstanceSetterCallback>
|
|
1737
1737
|
InstanceAccessorCallbackData;
|
|
1738
|
+
|
|
1739
|
+
bool _construction_failed = true;
|
|
1738
1740
|
};
|
|
1739
1741
|
|
|
1740
1742
|
class HandleScope {
|
package/package.json
CHANGED