koffi 2.4.2 → 2.5.0-beta.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/build/2.5.0-beta.2/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_darwin_x64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_ia32/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_x64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/{2.4.2 → 2.5.0-beta.2}/koffi_openbsd_x64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_win32_arm64/koffi.node +0 -0
- package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.node +0 -0
- package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_x64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_win32_x64/koffi.pdb +0 -0
- package/doc/callbacks.md +1 -1
- package/doc/conf.py +1 -1
- package/doc/functions.md +1 -1
- package/doc/index.rst +1 -0
- package/doc/parameters.md +1 -1
- package/doc/pointers.md +1 -1
- package/doc/unions.md +187 -0
- package/package.json +1 -1
- package/src/core/libcc/libcc.cc +58 -54
- package/src/core/libcc/libcc.hh +33 -19
- package/src/koffi/src/abi_x86.cc +31 -4
- package/src/koffi/src/call.cc +42 -22
- package/src/koffi/src/ffi.cc +259 -311
- package/src/koffi/src/ffi.hh +3 -1
- package/src/koffi/src/util.cc +20 -13
- package/src/koffi/src/util.hh +5 -2
- package/vendor/node-addon-api/CHANGELOG.md +31 -0
- package/vendor/node-addon-api/README.md +3 -2
- package/vendor/node-addon-api/doc/async_worker.md +1 -0
- package/vendor/node-addon-api/doc/creating_a_release.md +21 -0
- package/vendor/node-addon-api/doc/value.md +7 -0
- package/vendor/node-addon-api/napi-inl.h +23 -7
- package/vendor/node-addon-api/package.json +9 -1
- package/vendor/node-addon-api/test/async_progress_queue_worker.cc +155 -0
- package/vendor/node-addon-api/test/async_progress_queue_worker.js +134 -0
- package/vendor/node-addon-api/test/async_progress_worker.cc +155 -0
- package/vendor/node-addon-api/test/async_progress_worker.js +134 -0
- package/vendor/node-addon-api/test/common/index.js +45 -0
- package/vendor/node-addon-api/test/objectwrap.js +9 -0
- package/build/2.4.2/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.4.2/koffi_darwin_x64/koffi.node +0 -0
- package/build/2.4.2/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/2.4.2/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/2.4.2/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.4.2/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.4.2/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.4.2/koffi_linux_ia32/koffi.node +0 -0
- package/build/2.4.2/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/2.4.2/koffi_linux_x64/koffi.node +0 -0
- package/build/2.4.2/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/2.4.2/koffi_win32_arm64/koffi.node +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_arm64/koffi.exp +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_arm64/koffi.lib +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.exp +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.lib +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_x64/koffi.exp +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_x64/koffi.lib +0 -0
package/src/koffi/src/ffi.hh
CHANGED
|
@@ -198,7 +198,7 @@ struct ParameterInfo {
|
|
|
198
198
|
int8_t vec_bytes; // ARM64
|
|
199
199
|
#elif defined(__i386__) || defined(_M_IX86)
|
|
200
200
|
bool trivial; // Only matters for return value
|
|
201
|
-
|
|
201
|
+
int8_t fast;
|
|
202
202
|
#elif __riscv_xlen == 64
|
|
203
203
|
bool use_memory;
|
|
204
204
|
int8_t gpr_count;
|
|
@@ -273,6 +273,8 @@ struct InstanceData {
|
|
|
273
273
|
const TypeInfo *char_type;
|
|
274
274
|
const TypeInfo *char16_type;
|
|
275
275
|
|
|
276
|
+
Napi::Symbol active_symbol;
|
|
277
|
+
|
|
276
278
|
std::mutex memories_mutex;
|
|
277
279
|
LocalArray<InstanceMemory *, 9> memories;
|
|
278
280
|
int temporaries = 0;
|
package/src/koffi/src/util.cc
CHANGED
|
@@ -58,14 +58,19 @@ Napi::Function MagicUnion::InitClass(Napi::Env env, const TypeInfo *type)
|
|
|
58
58
|
MagicUnion::MagicUnion(const Napi::CallbackInfo &info)
|
|
59
59
|
: Napi::ObjectWrap<MagicUnion>(info), type((const TypeInfo *)info.Data())
|
|
60
60
|
{
|
|
61
|
+
Napi::Env env = info.Env();
|
|
62
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
63
|
+
|
|
64
|
+
active_symbol = instance->active_symbol;
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
void MagicUnion::SetRaw(const uint8_t *ptr)
|
|
64
68
|
{
|
|
65
|
-
raw
|
|
69
|
+
raw.RemoveFrom(0);
|
|
70
|
+
raw.Append(MakeSpan(ptr, type->size));
|
|
66
71
|
|
|
72
|
+
Value().Set(active_symbol, Env().Undefined());
|
|
67
73
|
active_idx = -1;
|
|
68
|
-
Value().Set("__active", Env().Undefined());
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
Napi::Value MagicUnion::Getter(const Napi::CallbackInfo &info)
|
|
@@ -76,18 +81,18 @@ Napi::Value MagicUnion::Getter(const Napi::CallbackInfo &info)
|
|
|
76
81
|
Napi::Value value;
|
|
77
82
|
|
|
78
83
|
if (idx == active_idx) {
|
|
79
|
-
value = Value().Get(
|
|
84
|
+
value = Value().Get(active_symbol);
|
|
80
85
|
} else {
|
|
81
86
|
Napi::Env env = info.Env();
|
|
82
87
|
|
|
83
|
-
if (RG_UNLIKELY(!raw)) {
|
|
88
|
+
if (RG_UNLIKELY(!raw.len)) {
|
|
84
89
|
ThrowError<Napi::Error>(env, "Cannont convert %1 union value", active_idx < 0 ? "empty" : "assigned");
|
|
85
90
|
return env.Null();
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
value = Decode(env, raw, member.type);
|
|
93
|
+
value = Decode(env, raw.ptr, member.type);
|
|
89
94
|
|
|
90
|
-
Value().Set(
|
|
95
|
+
Value().Set(active_symbol, value);
|
|
91
96
|
active_idx = idx;
|
|
92
97
|
}
|
|
93
98
|
|
|
@@ -99,10 +104,10 @@ void MagicUnion::Setter(const Napi::CallbackInfo &info, const Napi::Value &value
|
|
|
99
104
|
{
|
|
100
105
|
Size idx = (Size)info.Data();
|
|
101
106
|
|
|
102
|
-
Value().Set(
|
|
107
|
+
Value().Set(active_symbol, value);
|
|
103
108
|
active_idx = idx;
|
|
104
109
|
|
|
105
|
-
raw
|
|
110
|
+
raw.Clear();
|
|
106
111
|
}
|
|
107
112
|
|
|
108
113
|
const TypeInfo *ResolveType(Napi::Value value, int *out_directions)
|
|
@@ -272,10 +277,11 @@ const TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *ref, int
|
|
|
272
277
|
char name_buf[256];
|
|
273
278
|
Fmt(name_buf, "%1%2*", ref->name, EndsWith(ref->name, "*") ? "" : " ");
|
|
274
279
|
|
|
275
|
-
|
|
280
|
+
bool inserted;
|
|
281
|
+
auto bucket = instance->types_map.TrySetDefault(name_buf, &inserted);
|
|
276
282
|
|
|
277
|
-
if (
|
|
278
|
-
type = instance->types.AppendDefault();
|
|
283
|
+
if (inserted) {
|
|
284
|
+
TypeInfo *type = instance->types.AppendDefault();
|
|
279
285
|
|
|
280
286
|
type->name = DuplicateString(name_buf, &instance->str_alloc).ptr;
|
|
281
287
|
|
|
@@ -291,10 +297,11 @@ const TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *ref, int
|
|
|
291
297
|
type->ref.proto = ref->ref.proto;
|
|
292
298
|
}
|
|
293
299
|
|
|
294
|
-
|
|
300
|
+
bucket->key = type->name;
|
|
301
|
+
bucket->value = type;
|
|
295
302
|
}
|
|
296
303
|
|
|
297
|
-
ref =
|
|
304
|
+
ref = bucket->value;
|
|
298
305
|
}
|
|
299
306
|
|
|
300
307
|
return ref;
|
package/src/koffi/src/util.hh
CHANGED
|
@@ -38,18 +38,21 @@ extern const int MagicUnionMarker;
|
|
|
38
38
|
class MagicUnion: public Napi::ObjectWrap<MagicUnion> {
|
|
39
39
|
const TypeInfo *type;
|
|
40
40
|
|
|
41
|
+
napi_value active_symbol;
|
|
41
42
|
Size active_idx = -1;
|
|
42
|
-
|
|
43
|
+
|
|
44
|
+
HeapArray<uint8_t> raw;
|
|
43
45
|
|
|
44
46
|
public:
|
|
45
47
|
static Napi::Function InitClass(Napi::Env env, const TypeInfo *type);
|
|
46
48
|
|
|
47
49
|
MagicUnion(const Napi::CallbackInfo &info);
|
|
48
50
|
|
|
51
|
+
const TypeInfo *GetType() { return type; }
|
|
49
52
|
const RecordMember *GetMember() const { return (active_idx >= 0) ? &type->members[active_idx] : nullptr; }
|
|
50
53
|
|
|
51
54
|
void SetRaw(const uint8_t *ptr);
|
|
52
|
-
const uint8_t *GetRaw() const { return raw; }
|
|
55
|
+
const uint8_t *GetRaw() const { return raw.ptr; }
|
|
53
56
|
|
|
54
57
|
private:
|
|
55
58
|
Napi::Value Getter(const Napi::CallbackInfo &info);
|
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# node-addon-api Changelog
|
|
2
2
|
|
|
3
|
+
## 2023-06-13 Version 7.0.0, @KevinEady
|
|
4
|
+
|
|
5
|
+
### Notable changes
|
|
6
|
+
|
|
7
|
+
#### API
|
|
8
|
+
|
|
9
|
+
- Drop support for Node.js v14.x and v19.x.
|
|
10
|
+
- Ensure native receiver exists when calling instance methods and properties.
|
|
11
|
+
- Fix issue when creating `Napi::Error` instances that wrap primitives values.
|
|
12
|
+
|
|
13
|
+
#### TEST
|
|
14
|
+
|
|
15
|
+
- Added tests for `Napi::AsyncProgressQueueWorker<T>` class.
|
|
16
|
+
- Added tests for `Napi::AsyncProgressWorker<T>` class.
|
|
17
|
+
|
|
18
|
+
### Documentation
|
|
19
|
+
|
|
20
|
+
- Added documentation for `Napi::Value::IsBigInt()`.
|
|
21
|
+
|
|
22
|
+
### Commits
|
|
23
|
+
|
|
24
|
+
* \[[`de5c899400`](https://github.com/nodejs/node-addon-api/commit/de5c899400)] - **doc,chore**: drop support for Node.js v14, v19 (Kevin Eady) [#1324](https://github.com/nodejs/node-addon-api/pull/1324)
|
|
25
|
+
* \[[`3083b7f148`](https://github.com/nodejs/node-addon-api/commit/3083b7f148)] - \[StepSecurity] Apply security best practices (StepSecurity Bot) [#1308](https://github.com/nodejs/node-addon-api/pull/1308)
|
|
26
|
+
* \[[`a198e24a15`](https://github.com/nodejs/node-addon-api/commit/a198e24a15)] - \[Test] Add tests for async progress queue worker (Jack) [#1316](https://github.com/nodejs/node-addon-api/pull/1316)
|
|
27
|
+
* \[[`665f4aa845`](https://github.com/nodejs/node-addon-api/commit/665f4aa845)] - **doc**: add missing Value::IsBigInt (Kevin Eady) [#1319](https://github.com/nodejs/node-addon-api/pull/1319)
|
|
28
|
+
* \[[`358b2d3b4f`](https://github.com/nodejs/node-addon-api/commit/358b2d3b4f)] - **doc**: complete code curly braces in async\_worker.md (wanlu) [#1317](https://github.com/nodejs/node-addon-api/pull/1317)
|
|
29
|
+
* \[[`858942ce31`](https://github.com/nodejs/node-addon-api/commit/858942ce31)] - **src**: avoid calling into C++ with a null this (Caleb Hearon) [#1313](https://github.com/nodejs/node-addon-api/pull/1313)
|
|
30
|
+
* \[[`64f6515331`](https://github.com/nodejs/node-addon-api/commit/64f6515331)] - **src**: handle failure during error wrap of primitive (Gabriel Schulhof) [#1310](https://github.com/nodejs/node-addon-api/pull/1310)
|
|
31
|
+
* \[[`dfad6b45fe`](https://github.com/nodejs/node-addon-api/commit/dfad6b45fe)] - \[test] Add test coverage for AsyncProgressWorker (Jack) [#1307](https://github.com/nodejs/node-addon-api/pull/1307)
|
|
32
|
+
* \[[`0e34f22839`](https://github.com/nodejs/node-addon-api/commit/0e34f22839)] - **release**: v6.1.0. (Nicola Del Gobbo)
|
|
33
|
+
|
|
3
34
|
## 2023-04-20 Version 6.1.0, @NickNaso
|
|
4
35
|
|
|
5
36
|
### Notable changes
|
|
@@ -70,7 +70,7 @@ and node-addon-api.
|
|
|
70
70
|
- **[Contributors](#contributors)**
|
|
71
71
|
- **[License](#license)**
|
|
72
72
|
|
|
73
|
-
## **Current version:
|
|
73
|
+
## **Current version: 7.0.0**
|
|
74
74
|
|
|
75
75
|
(See [CHANGELOG.md](CHANGELOG.md) for complete Changelog)
|
|
76
76
|
|
|
@@ -83,7 +83,7 @@ This allows addons built with it to run with Node.js versions which support the
|
|
|
83
83
|
**However** the node-addon-api support model is to support only the active LTS Node.js versions. This means that
|
|
84
84
|
every year there will be a new major which drops support for the Node.js LTS version which has gone out of service.
|
|
85
85
|
|
|
86
|
-
The oldest Node.js version supported by the current version of node-addon-api is Node.js
|
|
86
|
+
The oldest Node.js version supported by the current version of node-addon-api is Node.js 16.x.
|
|
87
87
|
|
|
88
88
|
## Setup
|
|
89
89
|
- [Installation and usage](doc/setup.md)
|
|
@@ -275,6 +275,7 @@ available:
|
|
|
275
275
|

|
|
276
276
|

|
|
277
277
|

|
|
278
|
+

|
|
278
279
|

|
|
279
280
|
|
|
280
281
|
## **Contributing**
|
|
@@ -60,3 +60,24 @@ and that the correct version is installed.
|
|
|
60
60
|
and close the issue.
|
|
61
61
|
|
|
62
62
|
* Tweet that the release has been created.
|
|
63
|
+
|
|
64
|
+
## Optional Steps
|
|
65
|
+
|
|
66
|
+
Depending on circumstances for the release, additional steps may be required to
|
|
67
|
+
support the release process.
|
|
68
|
+
|
|
69
|
+
### Major Releases to Drop Support Node.js Versions
|
|
70
|
+
|
|
71
|
+
`node-addon-api` provides support for Node.js versions following the same
|
|
72
|
+
[release schedule](https://nodejs.dev/en/about/releases/): once a Node.js
|
|
73
|
+
version leaves maintenance mode, the next major version of `node-addon-api`
|
|
74
|
+
published will drop support for that version. These are the steps to follow to
|
|
75
|
+
drop support for a Node.js version:
|
|
76
|
+
|
|
77
|
+
* Update minimum version supported in documentation ([README.md](../README.md))
|
|
78
|
+
|
|
79
|
+
* Remove from GitHub actions ([ci.yml](../.github/workflows/ci.yml) and
|
|
80
|
+
[ci-win.yml](../.github/workflows/ci-win.yml))
|
|
81
|
+
|
|
82
|
+
* Remove from Jenkins CI ([node-test-node-addon-api-LTS versions
|
|
83
|
+
[Jenkins]](https://ci.nodejs.org/view/x%20-%20Abi%20stable%20module%20API/job/node-test-node-addon-api-LTS%20versions/))
|
|
@@ -141,6 +141,13 @@ bool Napi::Value::IsArrayBuffer() const;
|
|
|
141
141
|
Returns `true` if the underlying value is a JavaScript `Napi::ArrayBuffer` or
|
|
142
142
|
`false` otherwise.
|
|
143
143
|
|
|
144
|
+
```cpp
|
|
145
|
+
bool Napi::Value::IsBigInt() const;
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Returns `true` if the underlying value is a JavaScript `Napi::BigInt` or `false`
|
|
149
|
+
otherwise.
|
|
150
|
+
|
|
144
151
|
### IsBoolean
|
|
145
152
|
|
|
146
153
|
```cpp
|
|
@@ -165,7 +165,7 @@ napi_value TemplatedInstanceCallback(napi_env env,
|
|
|
165
165
|
return details::WrapCallback([&] {
|
|
166
166
|
CallbackInfo cbInfo(env, info);
|
|
167
167
|
T* instance = T::Unwrap(cbInfo.This().As<Object>());
|
|
168
|
-
return (instance->*UnwrapCallback)(cbInfo);
|
|
168
|
+
return instance ? (instance->*UnwrapCallback)(cbInfo) : Napi::Value();
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
171
|
|
|
@@ -175,7 +175,7 @@ napi_value TemplatedInstanceVoidCallback(napi_env env, napi_callback_info info)
|
|
|
175
175
|
return details::WrapCallback([&] {
|
|
176
176
|
CallbackInfo cbInfo(env, info);
|
|
177
177
|
T* instance = T::Unwrap(cbInfo.This().As<Object>());
|
|
178
|
-
(instance->*UnwrapCallback)(cbInfo);
|
|
178
|
+
if (instance) (instance->*UnwrapCallback)(cbInfo);
|
|
179
179
|
return nullptr;
|
|
180
180
|
});
|
|
181
181
|
}
|
|
@@ -2937,6 +2937,22 @@ inline Error::Error(napi_env env, napi_value value)
|
|
|
2937
2937
|
nullptr};
|
|
2938
2938
|
|
|
2939
2939
|
status = napi_define_properties(env, wrappedErrorObj, 1, &wrapObjFlag);
|
|
2940
|
+
#ifdef NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS
|
|
2941
|
+
if (status == napi_pending_exception) {
|
|
2942
|
+
// Test if the pending exception was reported because the environment is
|
|
2943
|
+
// shutting down. We assume that a status of napi_pending_exception
|
|
2944
|
+
// coupled with the absence of an actual pending exception means that
|
|
2945
|
+
// the environment is shutting down. If so, we replace the
|
|
2946
|
+
// napi_pending_exception status with napi_ok.
|
|
2947
|
+
bool is_exception_pending = false;
|
|
2948
|
+
status = napi_is_exception_pending(env, &is_exception_pending);
|
|
2949
|
+
if (status == napi_ok && !is_exception_pending) {
|
|
2950
|
+
status = napi_ok;
|
|
2951
|
+
} else {
|
|
2952
|
+
status = napi_pending_exception;
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
#endif // NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS
|
|
2940
2956
|
NAPI_FATAL_IF_FAILED(status, "Error::Error", "napi_define_properties");
|
|
2941
2957
|
|
|
2942
2958
|
// Create a reference on the newly wrapped object
|
|
@@ -4340,7 +4356,7 @@ inline napi_value InstanceWrap<T>::InstanceVoidMethodCallbackWrapper(
|
|
|
4340
4356
|
callbackInfo.SetData(callbackData->data);
|
|
4341
4357
|
T* instance = T::Unwrap(callbackInfo.This().As<Object>());
|
|
4342
4358
|
auto cb = callbackData->callback;
|
|
4343
|
-
(instance->*cb)(callbackInfo);
|
|
4359
|
+
if (instance) (instance->*cb)(callbackInfo);
|
|
4344
4360
|
return nullptr;
|
|
4345
4361
|
});
|
|
4346
4362
|
}
|
|
@@ -4355,7 +4371,7 @@ inline napi_value InstanceWrap<T>::InstanceMethodCallbackWrapper(
|
|
|
4355
4371
|
callbackInfo.SetData(callbackData->data);
|
|
4356
4372
|
T* instance = T::Unwrap(callbackInfo.This().As<Object>());
|
|
4357
4373
|
auto cb = callbackData->callback;
|
|
4358
|
-
return (instance->*cb)(callbackInfo);
|
|
4374
|
+
return instance ? (instance->*cb)(callbackInfo) : Napi::Value();
|
|
4359
4375
|
});
|
|
4360
4376
|
}
|
|
4361
4377
|
|
|
@@ -4369,7 +4385,7 @@ inline napi_value InstanceWrap<T>::InstanceGetterCallbackWrapper(
|
|
|
4369
4385
|
callbackInfo.SetData(callbackData->data);
|
|
4370
4386
|
T* instance = T::Unwrap(callbackInfo.This().As<Object>());
|
|
4371
4387
|
auto cb = callbackData->getterCallback;
|
|
4372
|
-
return (instance->*cb)(callbackInfo);
|
|
4388
|
+
return instance ? (instance->*cb)(callbackInfo) : Napi::Value();
|
|
4373
4389
|
});
|
|
4374
4390
|
}
|
|
4375
4391
|
|
|
@@ -4383,7 +4399,7 @@ inline napi_value InstanceWrap<T>::InstanceSetterCallbackWrapper(
|
|
|
4383
4399
|
callbackInfo.SetData(callbackData->data);
|
|
4384
4400
|
T* instance = T::Unwrap(callbackInfo.This().As<Object>());
|
|
4385
4401
|
auto cb = callbackData->setterCallback;
|
|
4386
|
-
(instance->*cb)(callbackInfo, callbackInfo[0]);
|
|
4402
|
+
if (instance) (instance->*cb)(callbackInfo, callbackInfo[0]);
|
|
4387
4403
|
return nullptr;
|
|
4388
4404
|
});
|
|
4389
4405
|
}
|
|
@@ -4395,7 +4411,7 @@ inline napi_value InstanceWrap<T>::WrappedMethod(
|
|
|
4395
4411
|
return details::WrapCallback([&] {
|
|
4396
4412
|
const CallbackInfo cbInfo(env, info);
|
|
4397
4413
|
T* instance = T::Unwrap(cbInfo.This().As<Object>());
|
|
4398
|
-
(instance->*method)(cbInfo, cbInfo[0]);
|
|
4414
|
+
if (instance) (instance->*method)(cbInfo, cbInfo[0]);
|
|
4399
4415
|
return nullptr;
|
|
4400
4416
|
});
|
|
4401
4417
|
}
|
|
@@ -399,6 +399,14 @@
|
|
|
399
399
|
{
|
|
400
400
|
"name": "Feng Yu",
|
|
401
401
|
"url": "https://github.com/F3n67u"
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
"name": "wanlu wang",
|
|
405
|
+
"url": "https://github.com/wanlu"
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
"name": "Caleb Hearon",
|
|
409
|
+
"url": "https://github.com/chearon"
|
|
402
410
|
}
|
|
403
411
|
],
|
|
404
412
|
"description": "Node.js API (Node-API)",
|
|
@@ -459,6 +467,6 @@
|
|
|
459
467
|
"lint:fix": "node tools/clang-format --fix && node tools/eslint-format --fix"
|
|
460
468
|
},
|
|
461
469
|
"pre-commit": "lint",
|
|
462
|
-
"version": "
|
|
470
|
+
"version": "7.0.0",
|
|
463
471
|
"support": true
|
|
464
472
|
}
|
|
@@ -15,6 +15,158 @@ struct ProgressData {
|
|
|
15
15
|
int32_t progress;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
class TestWorkerWithNoCb : public AsyncProgressQueueWorker<ProgressData> {
|
|
19
|
+
public:
|
|
20
|
+
static void DoWork(const CallbackInfo& info) {
|
|
21
|
+
switch (info.Length()) {
|
|
22
|
+
case 1: {
|
|
23
|
+
Function cb = info[0].As<Function>();
|
|
24
|
+
TestWorkerWithNoCb* worker = new TestWorkerWithNoCb(info.Env(), cb);
|
|
25
|
+
worker->Queue();
|
|
26
|
+
} break;
|
|
27
|
+
|
|
28
|
+
case 2: {
|
|
29
|
+
std::string resName = info[0].As<String>();
|
|
30
|
+
Function cb = info[1].As<Function>();
|
|
31
|
+
TestWorkerWithNoCb* worker =
|
|
32
|
+
new TestWorkerWithNoCb(info.Env(), resName.c_str(), cb);
|
|
33
|
+
worker->Queue();
|
|
34
|
+
} break;
|
|
35
|
+
|
|
36
|
+
case 3: {
|
|
37
|
+
std::string resName = info[0].As<String>();
|
|
38
|
+
Object resObject = info[1].As<Object>();
|
|
39
|
+
Function cb = info[2].As<Function>();
|
|
40
|
+
TestWorkerWithNoCb* worker =
|
|
41
|
+
new TestWorkerWithNoCb(info.Env(), resName.c_str(), resObject, cb);
|
|
42
|
+
worker->Queue();
|
|
43
|
+
} break;
|
|
44
|
+
|
|
45
|
+
default:
|
|
46
|
+
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
protected:
|
|
52
|
+
void Execute(const ExecutionProgress& progress) override {
|
|
53
|
+
ProgressData data{1};
|
|
54
|
+
progress.Send(&data, 1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
void OnProgress(const ProgressData*, size_t /* count */) override {
|
|
58
|
+
_cb.Call({});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private:
|
|
62
|
+
TestWorkerWithNoCb(Napi::Env env, Function cb)
|
|
63
|
+
: AsyncProgressQueueWorker(env) {
|
|
64
|
+
_cb.Reset(cb, 1);
|
|
65
|
+
}
|
|
66
|
+
TestWorkerWithNoCb(Napi::Env env, const char* resourceName, Function cb)
|
|
67
|
+
: AsyncProgressQueueWorker(env, resourceName) {
|
|
68
|
+
_cb.Reset(cb, 1);
|
|
69
|
+
}
|
|
70
|
+
TestWorkerWithNoCb(Napi::Env env,
|
|
71
|
+
const char* resourceName,
|
|
72
|
+
const Object& resourceObject,
|
|
73
|
+
Function cb)
|
|
74
|
+
: AsyncProgressQueueWorker(env, resourceName, resourceObject) {
|
|
75
|
+
_cb.Reset(cb, 1);
|
|
76
|
+
}
|
|
77
|
+
FunctionReference _cb;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
class TestWorkerWithRecv : public AsyncProgressQueueWorker<ProgressData> {
|
|
81
|
+
public:
|
|
82
|
+
static void DoWork(const CallbackInfo& info) {
|
|
83
|
+
switch (info.Length()) {
|
|
84
|
+
case 2: {
|
|
85
|
+
Object recv = info[0].As<Object>();
|
|
86
|
+
Function cb = info[1].As<Function>();
|
|
87
|
+
TestWorkerWithRecv* worker = new TestWorkerWithRecv(recv, cb);
|
|
88
|
+
worker->Queue();
|
|
89
|
+
} break;
|
|
90
|
+
|
|
91
|
+
case 3: {
|
|
92
|
+
Object recv = info[0].As<Object>();
|
|
93
|
+
Function cb = info[1].As<Function>();
|
|
94
|
+
std::string resName = info[2].As<String>();
|
|
95
|
+
TestWorkerWithRecv* worker =
|
|
96
|
+
new TestWorkerWithRecv(recv, cb, resName.c_str());
|
|
97
|
+
worker->Queue();
|
|
98
|
+
} break;
|
|
99
|
+
|
|
100
|
+
case 4: {
|
|
101
|
+
Object recv = info[0].As<Object>();
|
|
102
|
+
Function cb = info[1].As<Function>();
|
|
103
|
+
std::string resName = info[2].As<String>();
|
|
104
|
+
Object resObject = info[3].As<Object>();
|
|
105
|
+
TestWorkerWithRecv* worker =
|
|
106
|
+
new TestWorkerWithRecv(recv, cb, resName.c_str(), resObject);
|
|
107
|
+
worker->Queue();
|
|
108
|
+
} break;
|
|
109
|
+
|
|
110
|
+
default:
|
|
111
|
+
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
protected:
|
|
117
|
+
void Execute(const ExecutionProgress&) override {}
|
|
118
|
+
|
|
119
|
+
void OnProgress(const ProgressData*, size_t /* count */) override {}
|
|
120
|
+
|
|
121
|
+
private:
|
|
122
|
+
TestWorkerWithRecv(const Object& recv, const Function& cb)
|
|
123
|
+
: AsyncProgressQueueWorker(recv, cb) {}
|
|
124
|
+
TestWorkerWithRecv(const Object& recv,
|
|
125
|
+
const Function& cb,
|
|
126
|
+
const char* resourceName)
|
|
127
|
+
: AsyncProgressQueueWorker(recv, cb, resourceName) {}
|
|
128
|
+
TestWorkerWithRecv(const Object& recv,
|
|
129
|
+
const Function& cb,
|
|
130
|
+
const char* resourceName,
|
|
131
|
+
const Object& resourceObject)
|
|
132
|
+
: AsyncProgressQueueWorker(recv, cb, resourceName, resourceObject) {}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
class TestWorkerWithCb : public AsyncProgressQueueWorker<ProgressData> {
|
|
136
|
+
public:
|
|
137
|
+
static void DoWork(const CallbackInfo& info) {
|
|
138
|
+
switch (info.Length()) {
|
|
139
|
+
case 1: {
|
|
140
|
+
Function cb = info[0].As<Function>();
|
|
141
|
+
TestWorkerWithCb* worker = new TestWorkerWithCb(cb);
|
|
142
|
+
worker->Queue();
|
|
143
|
+
} break;
|
|
144
|
+
|
|
145
|
+
case 2: {
|
|
146
|
+
Function cb = info[0].As<Function>();
|
|
147
|
+
std::string asyncResName = info[1].As<String>();
|
|
148
|
+
TestWorkerWithCb* worker =
|
|
149
|
+
new TestWorkerWithCb(cb, asyncResName.c_str());
|
|
150
|
+
worker->Queue();
|
|
151
|
+
} break;
|
|
152
|
+
|
|
153
|
+
default:
|
|
154
|
+
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
protected:
|
|
160
|
+
void Execute(const ExecutionProgress&) override {}
|
|
161
|
+
|
|
162
|
+
void OnProgress(const ProgressData*, size_t /* count */) override {}
|
|
163
|
+
|
|
164
|
+
private:
|
|
165
|
+
TestWorkerWithCb(Function cb) : AsyncProgressQueueWorker(cb) {}
|
|
166
|
+
TestWorkerWithCb(Function cb, const char* res_name)
|
|
167
|
+
: AsyncProgressQueueWorker(cb, res_name) {}
|
|
168
|
+
};
|
|
169
|
+
|
|
18
170
|
class TestWorker : public AsyncProgressQueueWorker<ProgressData> {
|
|
19
171
|
public:
|
|
20
172
|
static Napi::Value CreateWork(const CallbackInfo& info) {
|
|
@@ -87,6 +239,9 @@ Object InitAsyncProgressQueueWorker(Env env) {
|
|
|
87
239
|
Object exports = Object::New(env);
|
|
88
240
|
exports["createWork"] = Function::New(env, TestWorker::CreateWork);
|
|
89
241
|
exports["queueWork"] = Function::New(env, TestWorker::QueueWork);
|
|
242
|
+
exports["runWorkerNoCb"] = Function::New(env, TestWorkerWithNoCb::DoWork);
|
|
243
|
+
exports["runWorkerWithRecv"] = Function::New(env, TestWorkerWithRecv::DoWork);
|
|
244
|
+
exports["runWorkerWithCb"] = Function::New(env, TestWorkerWithCb::DoWork);
|
|
90
245
|
return exports;
|
|
91
246
|
}
|
|
92
247
|
|
|
@@ -4,10 +4,144 @@ const common = require('./common');
|
|
|
4
4
|
const assert = require('assert');
|
|
5
5
|
|
|
6
6
|
module.exports = common.runTest(test);
|
|
7
|
+
const nodeVersion = process.versions.node.split('.')[0];
|
|
8
|
+
|
|
9
|
+
let asyncHooks;
|
|
10
|
+
function checkAsyncHooks () {
|
|
11
|
+
if (nodeVersion >= 8) {
|
|
12
|
+
if (asyncHooks === undefined) {
|
|
13
|
+
asyncHooks = require('async_hooks');
|
|
14
|
+
}
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
7
19
|
|
|
8
20
|
async function test ({ asyncprogressqueueworker }) {
|
|
9
21
|
await success(asyncprogressqueueworker);
|
|
10
22
|
await fail(asyncprogressqueueworker);
|
|
23
|
+
|
|
24
|
+
await asyncProgressWorkerCallbackOverloads(asyncprogressqueueworker.runWorkerWithCb);
|
|
25
|
+
await asyncProgressWorkerRecvOverloads(asyncprogressqueueworker.runWorkerWithRecv);
|
|
26
|
+
await asyncProgressWorkerNoCbOverloads(asyncprogressqueueworker.runWorkerNoCb);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function asyncProgressWorkerCallbackOverloads (bindingFunction) {
|
|
30
|
+
bindingFunction(common.mustCall());
|
|
31
|
+
if (!checkAsyncHooks()) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const hooks = common.installAysncHooks('cbResources');
|
|
36
|
+
|
|
37
|
+
const triggerAsyncId = asyncHooks.executionAsyncId();
|
|
38
|
+
await new Promise((resolve, reject) => {
|
|
39
|
+
bindingFunction(common.mustCall(), 'cbResources');
|
|
40
|
+
hooks.then(actual => {
|
|
41
|
+
assert.deepStrictEqual(actual, [
|
|
42
|
+
{
|
|
43
|
+
eventName: 'init',
|
|
44
|
+
type: 'cbResources',
|
|
45
|
+
triggerAsyncId: triggerAsyncId,
|
|
46
|
+
resource: {}
|
|
47
|
+
},
|
|
48
|
+
{ eventName: 'before' },
|
|
49
|
+
{ eventName: 'after' },
|
|
50
|
+
{ eventName: 'destroy' }
|
|
51
|
+
]);
|
|
52
|
+
resolve();
|
|
53
|
+
}).catch((err) => reject(err));
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function asyncProgressWorkerRecvOverloads (bindingFunction) {
|
|
58
|
+
const recvObject = {
|
|
59
|
+
a: 4
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
function cb () {
|
|
63
|
+
assert.strictEqual(this.a, recvObject.a);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
bindingFunction(recvObject, common.mustCall(cb));
|
|
67
|
+
if (!checkAsyncHooks()) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const asyncResources = [
|
|
71
|
+
{ resName: 'cbRecvResources', resObject: {} },
|
|
72
|
+
{ resName: 'cbRecvResourcesObject', resObject: { foo: 'bar' } }
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
for (const asyncResource of asyncResources) {
|
|
76
|
+
const asyncResName = asyncResource.resName;
|
|
77
|
+
const asyncResObject = asyncResource.resObject;
|
|
78
|
+
|
|
79
|
+
const hooks = common.installAysncHooks(asyncResource.resName);
|
|
80
|
+
const triggerAsyncId = asyncHooks.executionAsyncId();
|
|
81
|
+
await new Promise((resolve, reject) => {
|
|
82
|
+
if (Object.keys(asyncResObject).length === 0) {
|
|
83
|
+
bindingFunction(recvObject, common.mustCall(cb), asyncResName);
|
|
84
|
+
} else {
|
|
85
|
+
bindingFunction(recvObject, common.mustCall(cb), asyncResName, asyncResObject);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
hooks.then(actual => {
|
|
89
|
+
assert.deepStrictEqual(actual, [
|
|
90
|
+
{
|
|
91
|
+
eventName: 'init',
|
|
92
|
+
type: asyncResName,
|
|
93
|
+
triggerAsyncId: triggerAsyncId,
|
|
94
|
+
resource: asyncResObject
|
|
95
|
+
},
|
|
96
|
+
{ eventName: 'before' },
|
|
97
|
+
{ eventName: 'after' },
|
|
98
|
+
{ eventName: 'destroy' }
|
|
99
|
+
]);
|
|
100
|
+
resolve();
|
|
101
|
+
}).catch((err) => reject(err));
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function asyncProgressWorkerNoCbOverloads (bindingFunction) {
|
|
107
|
+
bindingFunction(common.mustCall());
|
|
108
|
+
if (!checkAsyncHooks()) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const asyncResources = [
|
|
112
|
+
{ resName: 'noCbResources', resObject: {} },
|
|
113
|
+
{ resName: 'noCbResourcesObject', resObject: { foo: 'bar' } }
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
for (const asyncResource of asyncResources) {
|
|
117
|
+
const asyncResName = asyncResource.resName;
|
|
118
|
+
const asyncResObject = asyncResource.resObject;
|
|
119
|
+
|
|
120
|
+
const hooks = common.installAysncHooks(asyncResource.resName);
|
|
121
|
+
const triggerAsyncId = asyncHooks.executionAsyncId();
|
|
122
|
+
await new Promise((resolve, reject) => {
|
|
123
|
+
if (Object.keys(asyncResObject).length === 0) {
|
|
124
|
+
bindingFunction(asyncResName, common.mustCall(() => {}));
|
|
125
|
+
} else {
|
|
126
|
+
bindingFunction(asyncResName, asyncResObject, common.mustCall(() => {}));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
hooks.then(actual => {
|
|
130
|
+
assert.deepStrictEqual(actual, [
|
|
131
|
+
{
|
|
132
|
+
eventName: 'init',
|
|
133
|
+
type: asyncResName,
|
|
134
|
+
triggerAsyncId: triggerAsyncId,
|
|
135
|
+
resource: asyncResObject
|
|
136
|
+
},
|
|
137
|
+
{ eventName: 'before' },
|
|
138
|
+
{ eventName: 'after' },
|
|
139
|
+
{ eventName: 'destroy' }
|
|
140
|
+
]);
|
|
141
|
+
resolve();
|
|
142
|
+
}).catch((err) => reject(err));
|
|
143
|
+
});
|
|
144
|
+
}
|
|
11
145
|
}
|
|
12
146
|
|
|
13
147
|
function success (binding) {
|