node-addon-api 2.0.2 → 3.1.0
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/.clang-format +111 -0
- package/.github/workflows/ci.yml +55 -0
- package/.github/workflows/linter.yml +24 -0
- package/.github/workflows/stale.yml +18 -0
- package/.travis.yml +1 -5
- package/CHANGELOG.md +237 -23
- package/README.md +101 -31
- package/appveyor.yml +3 -14
- package/benchmark/README.md +47 -0
- package/benchmark/binding.gyp +25 -0
- package/benchmark/function_args.cc +217 -0
- package/benchmark/function_args.js +60 -0
- package/benchmark/index.js +34 -0
- package/benchmark/property_descriptor.cc +91 -0
- package/benchmark/property_descriptor.js +37 -0
- package/common.gypi +21 -0
- package/doc/addon.md +157 -0
- package/doc/array.md +81 -0
- package/doc/array_buffer.md +20 -0
- package/doc/async_context.md +1 -1
- package/doc/async_worker.md +34 -5
- package/doc/{async_progress_worker.md → async_worker_variants.md} +236 -23
- package/doc/bigint.md +7 -2
- package/doc/boolean.md +5 -1
- package/doc/buffer.md +4 -0
- package/doc/checker-tool.md +1 -1
- package/doc/class_property_descriptor.md +3 -3
- package/doc/creating_a_release.md +6 -6
- package/doc/dataview.md +4 -0
- package/doc/date.md +2 -2
- package/doc/env.md +69 -0
- package/doc/error.md +5 -0
- package/doc/escapable_handle_scope.md +1 -1
- package/doc/external.md +4 -0
- package/doc/function.md +111 -3
- package/doc/function_reference.md +1 -1
- package/doc/handle_scope.md +1 -1
- package/doc/hierarchy.md +91 -0
- package/doc/instance_wrap.md +408 -0
- package/doc/name.md +29 -0
- package/doc/number.md +1 -1
- package/doc/object.md +44 -1
- package/doc/object_lifetime_management.md +2 -2
- package/doc/object_reference.md +1 -1
- package/doc/object_wrap.md +220 -216
- package/doc/prebuild_tools.md +2 -2
- package/doc/promises.md +5 -0
- package/doc/property_descriptor.md +67 -12
- package/doc/setup.md +1 -2
- package/doc/string.md +5 -1
- package/doc/symbol.md +5 -1
- package/doc/threadsafe.md +121 -0
- package/doc/threadsafe_function.md +16 -46
- package/doc/typed_array.md +4 -0
- package/doc/typed_array_of.md +4 -0
- package/doc/typed_threadsafe_function.md +307 -0
- package/doc/value.md +166 -104
- package/doc/version_management.md +2 -2
- package/except.gypi +16 -0
- package/index.js +7 -41
- package/napi-inl.h +1685 -464
- package/napi.h +606 -141
- package/node_api.gyp +9 -0
- package/noexcept.gypi +16 -0
- package/{src/nothing.c → nothing.c} +0 -0
- package/package-support.json +21 -0
- package/package.json +106 -2
- package/tools/README.md +12 -6
- package/tools/clang-format.js +47 -0
- package/tools/conversion.js +4 -8
- package/doc/Doxyfile +0 -2450
- package/doc/basic_types.md +0 -423
- package/doc/working_with_javascript_values.md +0 -14
- package/external-napi/node_api.h +0 -7
- package/src/node_api.cc +0 -3655
- package/src/node_api.gyp +0 -21
- package/src/node_api.h +0 -588
- package/src/node_api_types.h +0 -115
- package/src/node_internals.cc +0 -142
- package/src/node_internals.h +0 -157
- package/src/util-inl.h +0 -38
- package/src/util.h +0 -7
package/README.md
CHANGED
|
@@ -4,6 +4,14 @@ the use of the C based [N-API](https://nodejs.org/dist/latest/docs/api/n-api.htm
|
|
|
4
4
|
provided by Node.js when using C++. It provides a C++ object model
|
|
5
5
|
and exception handling semantics with low overhead.
|
|
6
6
|
|
|
7
|
+
There are three options for implementing addons: N-API, nan, or direct
|
|
8
|
+
use of internal V8, libuv and Node.js libraries. Unless there is a need for
|
|
9
|
+
direct access to functionality which is not exposed by N-API as outlined
|
|
10
|
+
in [C/C++ addons](https://nodejs.org/dist/latest/docs/api/addons.html)
|
|
11
|
+
in Node.js core, use N-API. Refer to
|
|
12
|
+
[C/C++ addons with N-API](https://nodejs.org/dist/latest/docs/api/n-api.html)
|
|
13
|
+
for more information on N-API.
|
|
14
|
+
|
|
7
15
|
N-API is an ABI stable C interface provided by Node.js for building native
|
|
8
16
|
addons. It is independent from the underlying JavaScript runtime (e.g. V8 or ChakraCore)
|
|
9
17
|
and is maintained as part of Node.js itself. It is intended to insulate
|
|
@@ -21,7 +29,7 @@ It is important to remember that *other* Node.js interfaces such as
|
|
|
21
29
|
`libuv` (included in a project via `#include <uv.h>`) are not ABI-stable across
|
|
22
30
|
Node.js major versions. Thus, an addon must use N-API and/or `node-addon-api`
|
|
23
31
|
exclusively and build against a version of Node.js that includes an
|
|
24
|
-
implementation of N-API (meaning
|
|
32
|
+
implementation of N-API (meaning an active LTS version of Node.js) in
|
|
25
33
|
order to benefit from ABI stability across Node.js major versions. Node.js
|
|
26
34
|
provides an [ABI stability guide][] containing a detailed explanation of ABI
|
|
27
35
|
stability in general, and the N-API ABI stability guarantee in particular.
|
|
@@ -37,16 +45,21 @@ APIs exposed by node-addon-api are generally used to create and
|
|
|
37
45
|
manipulate JavaScript values. Concepts and operations generally map
|
|
38
46
|
to ideas specified in the **ECMA262 Language Specification**.
|
|
39
47
|
|
|
48
|
+
The [N-API Resource](https://nodejs.github.io/node-addon-examples/) offers an
|
|
49
|
+
excellent orientation and tips for developers just getting started with N-API
|
|
50
|
+
and node-addon-api.
|
|
51
|
+
|
|
40
52
|
- **[Setup](#setup)**
|
|
41
53
|
- **[API Documentation](#api)**
|
|
42
54
|
- **[Examples](#examples)**
|
|
43
55
|
- **[Tests](#tests)**
|
|
44
56
|
- **[More resource and info about native Addons](#resources)**
|
|
57
|
+
- **[Badges](#badges)**
|
|
45
58
|
- **[Code of Conduct](CODE_OF_CONDUCT.md)**
|
|
46
59
|
- **[Contributors](#contributors)**
|
|
47
60
|
- **[License](#license)**
|
|
48
61
|
|
|
49
|
-
## **Current version:
|
|
62
|
+
## **Current version: 3.1.0**
|
|
50
63
|
|
|
51
64
|
(See [CHANGELOG.md](CHANGELOG.md) for complete Changelog)
|
|
52
65
|
|
|
@@ -54,6 +67,13 @@ to ideas specified in the **ECMA262 Language Specification**.
|
|
|
54
67
|
|
|
55
68
|
<a name="setup"></a>
|
|
56
69
|
|
|
70
|
+
node-addon-api is based on [N-API](https://nodejs.org/api/n-api.html) and supports using different N-API versions.
|
|
71
|
+
This allows addons built with it to run with Node.js versions which support the targeted N-API version.
|
|
72
|
+
**However** the node-addon-api support model is to support only the active LTS Node.js versions. This means that
|
|
73
|
+
every year there will be a new major which drops support for the Node.js LTS version which has gone out of service.
|
|
74
|
+
|
|
75
|
+
The oldest Node.js version supported by the current version of node-addon-api is Node.js 10.x.
|
|
76
|
+
|
|
57
77
|
## Setup
|
|
58
78
|
- [Installation and usage](doc/setup.md)
|
|
59
79
|
- [node-gyp](doc/node-gyp.md)
|
|
@@ -69,31 +89,25 @@ to ideas specified in the **ECMA262 Language Specification**.
|
|
|
69
89
|
|
|
70
90
|
The following is the documentation for node-addon-api.
|
|
71
91
|
|
|
72
|
-
- [
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- [String](doc/string.md)
|
|
76
|
-
- [Name](doc/basic_types.md#name)
|
|
77
|
-
- [Number](doc/number.md)
|
|
78
|
-
- [Date](doc/date.md)
|
|
79
|
-
- [BigInt](doc/bigint.md)
|
|
80
|
-
- [Boolean](doc/boolean.md)
|
|
92
|
+
- [Full Class Hierarchy](doc/hierarchy.md)
|
|
93
|
+
- [Addon Structure](doc/addon.md)
|
|
94
|
+
- Data Types:
|
|
81
95
|
- [Env](doc/env.md)
|
|
82
|
-
- [Value](doc/value.md)
|
|
83
96
|
- [CallbackInfo](doc/callbackinfo.md)
|
|
84
97
|
- [Reference](doc/reference.md)
|
|
85
|
-
- [
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
- [Value](doc/value.md)
|
|
99
|
+
- [Name](doc/name.md)
|
|
100
|
+
- [Symbol](doc/symbol.md)
|
|
101
|
+
- [String](doc/string.md)
|
|
102
|
+
- [Number](doc/number.md)
|
|
103
|
+
- [Date](doc/date.md)
|
|
104
|
+
- [BigInt](doc/bigint.md)
|
|
105
|
+
- [Boolean](doc/boolean.md)
|
|
106
|
+
- [External](doc/external.md)
|
|
107
|
+
- [Object](doc/object.md)
|
|
108
|
+
- [Array](doc/array.md)
|
|
109
|
+
- [ObjectReference](doc/object_reference.md)
|
|
110
|
+
- [PropertyDescriptor](doc/property_descriptor.md)
|
|
97
111
|
- [Function](doc/function.md)
|
|
98
112
|
- [FunctionReference](doc/function_reference.md)
|
|
99
113
|
- [ObjectWrap](doc/object_wrap.md)
|
|
@@ -103,12 +117,21 @@ The following is the documentation for node-addon-api.
|
|
|
103
117
|
- [TypedArray](doc/typed_array.md)
|
|
104
118
|
- [TypedArrayOf](doc/typed_array_of.md)
|
|
105
119
|
- [DataView](doc/dataview.md)
|
|
120
|
+
- [Error Handling](doc/error_handling.md)
|
|
121
|
+
- [Error](doc/error.md)
|
|
122
|
+
- [TypeError](doc/type_error.md)
|
|
123
|
+
- [RangeError](doc/range_error.md)
|
|
124
|
+
- [Object Lifetime Management](doc/object_lifetime_management.md)
|
|
125
|
+
- [HandleScope](doc/handle_scope.md)
|
|
126
|
+
- [EscapableHandleScope](doc/escapable_handle_scope.md)
|
|
106
127
|
- [Memory Management](doc/memory_management.md)
|
|
107
128
|
- [Async Operations](doc/async_operations.md)
|
|
108
129
|
- [AsyncWorker](doc/async_worker.md)
|
|
109
130
|
- [AsyncContext](doc/async_context.md)
|
|
110
|
-
- [
|
|
111
|
-
- [Thread-safe Functions](doc/
|
|
131
|
+
- [AsyncWorker Variants](doc/async_worker_variants.md)
|
|
132
|
+
- [Thread-safe Functions](doc/threadsafe.md)
|
|
133
|
+
- [ThreadSafeFunction](doc/threadsafe_function.md)
|
|
134
|
+
- [TypedThreadSafeFunction](doc/typed_threadsafe_function.md)
|
|
112
135
|
- [Promises](doc/promises.md)
|
|
113
136
|
- [Version management](doc/version_management.md)
|
|
114
137
|
|
|
@@ -144,6 +167,15 @@ npm install
|
|
|
144
167
|
npm test --disable-deprecated
|
|
145
168
|
```
|
|
146
169
|
|
|
170
|
+
To run the tests targetting a specific version of N-API run
|
|
171
|
+
```
|
|
172
|
+
npm install
|
|
173
|
+
export NAPI_VERSION=X
|
|
174
|
+
npm test --NAPI_VERSION=X
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
where X is the version of N-API you want to target.
|
|
178
|
+
|
|
147
179
|
### **Debug**
|
|
148
180
|
|
|
149
181
|
To run the **node-addon-api** tests with `--debug` option:
|
|
@@ -160,26 +192,63 @@ npm run-script dev:incremental
|
|
|
160
192
|
|
|
161
193
|
Take a look and get inspired by our **[test suite](https://github.com/nodejs/node-addon-api/tree/master/test)**
|
|
162
194
|
|
|
163
|
-
|
|
195
|
+
### **Benchmarks**
|
|
164
196
|
|
|
165
|
-
|
|
197
|
+
You can run the available benchmarks using the following command:
|
|
166
198
|
|
|
167
|
-
|
|
168
|
-
|
|
199
|
+
```
|
|
200
|
+
npm run-script benchmark
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
See [benchmark/README.md](benchmark/README.md) for more details about running and adding benchmarks.
|
|
204
|
+
|
|
205
|
+
<a name="resources"></a>
|
|
169
206
|
|
|
170
207
|
### **More resource and info about native Addons**
|
|
171
208
|
- **[C++ Addons](https://nodejs.org/dist/latest/docs/api/addons.html)**
|
|
172
209
|
- **[N-API](https://nodejs.org/dist/latest/docs/api/n-api.html)**
|
|
173
210
|
- **[N-API - Next Generation Node API for Native Modules](https://youtu.be/-Oniup60Afs)**
|
|
174
211
|
|
|
212
|
+
As node-addon-api's core mission is to expose the plain C N-API as C++
|
|
213
|
+
wrappers, tools that facilitate n-api/node-addon-api providing more
|
|
214
|
+
convenient patterns on developing a Node.js add-ons with n-api/node-addon-api
|
|
215
|
+
can be published to NPM as standalone packages. It is also recommended to tag
|
|
216
|
+
such packages with `node-addon-api` to provide more visibility to the community.
|
|
217
|
+
|
|
218
|
+
Quick links to NPM searches: [keywords:node-addon-api](https://www.npmjs.com/search?q=keywords%3Anode-addon-api).
|
|
219
|
+
|
|
220
|
+
<a name="badges"></a>
|
|
221
|
+
|
|
222
|
+
### **Badges**
|
|
223
|
+
|
|
224
|
+
The use of badges is recommended to indicate the minimum version of N-API
|
|
225
|
+
required for the module. This helps to determine which Node.js major versions are
|
|
226
|
+
supported. Addon maintainers can consult the [N-API support matrix][] to determine
|
|
227
|
+
which Node.js versions provide a given N-API version. The following badges are
|
|
228
|
+
available:
|
|
229
|
+
|
|
230
|
+

|
|
231
|
+

|
|
232
|
+

|
|
233
|
+

|
|
234
|
+

|
|
235
|
+

|
|
236
|
+

|
|
237
|
+
|
|
238
|
+
## **Contributing**
|
|
239
|
+
|
|
240
|
+
We love contributions from the community to **node-addon-api**!
|
|
241
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for more details on our philosophy around extending this module.
|
|
242
|
+
|
|
175
243
|
<a name="contributors"></a>
|
|
176
244
|
|
|
177
|
-
##
|
|
245
|
+
## Team members
|
|
178
246
|
|
|
179
247
|
### Active
|
|
180
248
|
| Name | GitHub Link |
|
|
181
249
|
| ------------------- | ----------------------------------------------------- |
|
|
182
250
|
| Anna Henningsen | [addaleax](https://github.com/addaleax) |
|
|
251
|
+
| Chengzhong Wu | [legendecas](https://github.com/legendecas) |
|
|
183
252
|
| Gabriel Schulhof | [gabrielschulhof](https://github.com/gabrielschulhof) |
|
|
184
253
|
| Hitesh Kanwathirtha | [digitalinfinity](https://github.com/digitalinfinity) |
|
|
185
254
|
| Jim Schlight | [jschlight](https://github.com/jschlight) |
|
|
@@ -201,3 +270,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for more details on our philosophy around
|
|
|
201
270
|
Licensed under [MIT](./LICENSE.md)
|
|
202
271
|
|
|
203
272
|
[ABI stability guide]: https://nodejs.org/en/docs/guides/abi-stability/
|
|
273
|
+
[N-API support matrix]: https://nodejs.org/dist/latest/docs/api/n-api.html#n_api_n_api_version_matrix
|
package/appveyor.yml
CHANGED
|
@@ -1,24 +1,13 @@
|
|
|
1
1
|
environment:
|
|
2
2
|
# https://github.com/jasongin/nvs/blob/master/doc/CI.md
|
|
3
3
|
NVS_VERSION: 1.4.2
|
|
4
|
-
fast_finish: true
|
|
5
4
|
matrix:
|
|
6
|
-
- NODEJS_VERSION: node/4
|
|
7
|
-
- NODEJS_VERSION: node/6
|
|
8
|
-
- NODEJS_VERSION: node/8
|
|
9
|
-
- NODEJS_VERSION: node/9
|
|
10
5
|
- NODEJS_VERSION: node/10
|
|
11
|
-
- NODEJS_VERSION:
|
|
12
|
-
- NODEJS_VERSION:
|
|
6
|
+
- NODEJS_VERSION: node/12
|
|
7
|
+
- NODEJS_VERSION: node/14
|
|
13
8
|
- NODEJS_VERSION: nightly
|
|
14
|
-
- NODEJS_VERSION: chakracore-nightly
|
|
15
|
-
|
|
16
|
-
matrix:
|
|
17
|
-
fast_finish: true
|
|
18
|
-
allow_failures:
|
|
19
|
-
- NODEJS_VERSION: nightly
|
|
20
|
-
- NODEJS_VERSION: chakracore-nightly
|
|
21
9
|
|
|
10
|
+
os: Visual Studio 2017
|
|
22
11
|
platform:
|
|
23
12
|
- x86
|
|
24
13
|
- x64
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Benchmarks
|
|
2
|
+
|
|
3
|
+
## Running the benchmarks
|
|
4
|
+
|
|
5
|
+
From the parent directory, run
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run-script benchmark
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The above script supports the following arguments:
|
|
12
|
+
|
|
13
|
+
* `--benchmarks=...`: A semicolon-separated list of benchmark names. These names
|
|
14
|
+
will be mapped to file names in this directory by appending `.js`.
|
|
15
|
+
|
|
16
|
+
## Adding benchmarks
|
|
17
|
+
|
|
18
|
+
The steps below should be followed when adding new benchmarks.
|
|
19
|
+
|
|
20
|
+
0. Decide on a name for the benchmark. This name will be used in several places.
|
|
21
|
+
This example will use the name `new_benchmark`.
|
|
22
|
+
|
|
23
|
+
0. Create files `new_benchmark.cc` and `new_benchmark.js` in this directory.
|
|
24
|
+
|
|
25
|
+
0. Copy an existing benchmark in `binding.gyp` and change the target name prefix
|
|
26
|
+
and the source file name to `new_benchmark`. This should result in two new
|
|
27
|
+
targets which look like this:
|
|
28
|
+
|
|
29
|
+
```gyp
|
|
30
|
+
{
|
|
31
|
+
'target_name': 'new_benchmark',
|
|
32
|
+
'sources': [ 'new_benchmark.cc' ],
|
|
33
|
+
'includes': [ '../except.gypi' ],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
'target_name': 'new_benchmark_noexcept',
|
|
37
|
+
'sources': [ 'new_benchmark.cc' ],
|
|
38
|
+
'includes': [ '../noexcept.gypi' ],
|
|
39
|
+
},
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
There should always be a pair of targets: one bearing the name of the
|
|
43
|
+
benchmark and configured with C++ exceptions enabled, and one bearing the
|
|
44
|
+
same name followed by the suffix `_noexcept` and configured with C++
|
|
45
|
+
exceptions disabled. This will ensure that the benchmark can be written to
|
|
46
|
+
cover both the case where C++ exceptions are enabled and the case where they
|
|
47
|
+
are disabled.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
'target_defaults': { 'includes': ['../common.gypi'] },
|
|
3
|
+
'targets': [
|
|
4
|
+
{
|
|
5
|
+
'target_name': 'function_args',
|
|
6
|
+
'sources': [ 'function_args.cc' ],
|
|
7
|
+
'includes': [ '../except.gypi' ],
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
'target_name': 'function_args_noexcept',
|
|
11
|
+
'sources': [ 'function_args.cc' ],
|
|
12
|
+
'includes': [ '../noexcept.gypi' ],
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
'target_name': 'property_descriptor',
|
|
16
|
+
'sources': [ 'property_descriptor.cc' ],
|
|
17
|
+
'includes': [ '../except.gypi' ],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
'target_name': 'property_descriptor_noexcept',
|
|
21
|
+
'sources': [ 'property_descriptor.cc' ],
|
|
22
|
+
'includes': [ '../noexcept.gypi' ],
|
|
23
|
+
},
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
#include "napi.h"
|
|
2
|
+
|
|
3
|
+
static napi_value NoArgFunction_Core(napi_env env, napi_callback_info info) {
|
|
4
|
+
(void) env;
|
|
5
|
+
(void) info;
|
|
6
|
+
return nullptr;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static napi_value OneArgFunction_Core(napi_env env, napi_callback_info info) {
|
|
10
|
+
size_t argc = 1;
|
|
11
|
+
napi_value argv;
|
|
12
|
+
if (napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr) != napi_ok) {
|
|
13
|
+
return nullptr;
|
|
14
|
+
}
|
|
15
|
+
(void) argv;
|
|
16
|
+
return nullptr;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static napi_value TwoArgFunction_Core(napi_env env, napi_callback_info info) {
|
|
20
|
+
size_t argc = 2;
|
|
21
|
+
napi_value argv[2];
|
|
22
|
+
if (napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr) != napi_ok) {
|
|
23
|
+
return nullptr;
|
|
24
|
+
}
|
|
25
|
+
(void) argv[0];
|
|
26
|
+
(void) argv[1];
|
|
27
|
+
return nullptr;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static napi_value ThreeArgFunction_Core(napi_env env, napi_callback_info info) {
|
|
31
|
+
size_t argc = 3;
|
|
32
|
+
napi_value argv[3];
|
|
33
|
+
if (napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr) != napi_ok) {
|
|
34
|
+
return nullptr;
|
|
35
|
+
}
|
|
36
|
+
(void) argv[0];
|
|
37
|
+
(void) argv[1];
|
|
38
|
+
(void) argv[2];
|
|
39
|
+
return nullptr;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static napi_value FourArgFunction_Core(napi_env env, napi_callback_info info) {
|
|
43
|
+
size_t argc = 4;
|
|
44
|
+
napi_value argv[4];
|
|
45
|
+
if (napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr) != napi_ok) {
|
|
46
|
+
return nullptr;
|
|
47
|
+
}
|
|
48
|
+
(void) argv[0];
|
|
49
|
+
(void) argv[1];
|
|
50
|
+
(void) argv[2];
|
|
51
|
+
(void) argv[3];
|
|
52
|
+
return nullptr;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static void NoArgFunction(const Napi::CallbackInfo& info) {
|
|
56
|
+
(void) info;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static void OneArgFunction(const Napi::CallbackInfo& info) {
|
|
60
|
+
Napi::Value argv0 = info[0]; (void) argv0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static void TwoArgFunction(const Napi::CallbackInfo& info) {
|
|
64
|
+
Napi::Value argv0 = info[0]; (void) argv0;
|
|
65
|
+
Napi::Value argv1 = info[1]; (void) argv1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static void ThreeArgFunction(const Napi::CallbackInfo& info) {
|
|
69
|
+
Napi::Value argv0 = info[0]; (void) argv0;
|
|
70
|
+
Napi::Value argv1 = info[1]; (void) argv1;
|
|
71
|
+
Napi::Value argv2 = info[2]; (void) argv2;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static void FourArgFunction(const Napi::CallbackInfo& info) {
|
|
75
|
+
Napi::Value argv0 = info[0]; (void) argv0;
|
|
76
|
+
Napi::Value argv1 = info[1]; (void) argv1;
|
|
77
|
+
Napi::Value argv2 = info[2]; (void) argv2;
|
|
78
|
+
Napi::Value argv3 = info[3]; (void) argv3;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#if NAPI_VERSION > 5
|
|
82
|
+
class FunctionArgsBenchmark : public Napi::Addon<FunctionArgsBenchmark> {
|
|
83
|
+
public:
|
|
84
|
+
FunctionArgsBenchmark(Napi::Env env, Napi::Object exports) {
|
|
85
|
+
DefineAddon(exports, {
|
|
86
|
+
InstanceValue("addon", DefineProperties(Napi::Object::New(env), {
|
|
87
|
+
InstanceMethod("noArgFunction", &FunctionArgsBenchmark::NoArgFunction),
|
|
88
|
+
InstanceMethod("oneArgFunction",
|
|
89
|
+
&FunctionArgsBenchmark::OneArgFunction),
|
|
90
|
+
InstanceMethod("twoArgFunction",
|
|
91
|
+
&FunctionArgsBenchmark::TwoArgFunction),
|
|
92
|
+
InstanceMethod("threeArgFunction",
|
|
93
|
+
&FunctionArgsBenchmark::ThreeArgFunction),
|
|
94
|
+
InstanceMethod("fourArgFunction",
|
|
95
|
+
&FunctionArgsBenchmark::FourArgFunction),
|
|
96
|
+
}), napi_enumerable),
|
|
97
|
+
InstanceValue("addon_templated",
|
|
98
|
+
DefineProperties(Napi::Object::New(env), {
|
|
99
|
+
InstanceMethod<&FunctionArgsBenchmark::NoArgFunction>(
|
|
100
|
+
"noArgFunction"),
|
|
101
|
+
InstanceMethod<&FunctionArgsBenchmark::OneArgFunction>(
|
|
102
|
+
"oneArgFunction"),
|
|
103
|
+
InstanceMethod<&FunctionArgsBenchmark::TwoArgFunction>(
|
|
104
|
+
"twoArgFunction"),
|
|
105
|
+
InstanceMethod<&FunctionArgsBenchmark::ThreeArgFunction>(
|
|
106
|
+
"threeArgFunction"),
|
|
107
|
+
InstanceMethod<&FunctionArgsBenchmark::FourArgFunction>(
|
|
108
|
+
"fourArgFunction"),
|
|
109
|
+
}), napi_enumerable),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
private:
|
|
113
|
+
void NoArgFunction(const Napi::CallbackInfo& info) {
|
|
114
|
+
(void) info;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
void OneArgFunction(const Napi::CallbackInfo& info) {
|
|
118
|
+
Napi::Value argv0 = info[0]; (void) argv0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
void TwoArgFunction(const Napi::CallbackInfo& info) {
|
|
122
|
+
Napi::Value argv0 = info[0]; (void) argv0;
|
|
123
|
+
Napi::Value argv1 = info[1]; (void) argv1;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
void ThreeArgFunction(const Napi::CallbackInfo& info) {
|
|
127
|
+
Napi::Value argv0 = info[0]; (void) argv0;
|
|
128
|
+
Napi::Value argv1 = info[1]; (void) argv1;
|
|
129
|
+
Napi::Value argv2 = info[2]; (void) argv2;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
void FourArgFunction(const Napi::CallbackInfo& info) {
|
|
133
|
+
Napi::Value argv0 = info[0]; (void) argv0;
|
|
134
|
+
Napi::Value argv1 = info[1]; (void) argv1;
|
|
135
|
+
Napi::Value argv2 = info[2]; (void) argv2;
|
|
136
|
+
Napi::Value argv3 = info[3]; (void) argv3;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
#endif // NAPI_VERSION > 5
|
|
140
|
+
|
|
141
|
+
static Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
142
|
+
napi_value no_arg_function, one_arg_function, two_arg_function,
|
|
143
|
+
three_arg_function, four_arg_function;
|
|
144
|
+
napi_status status;
|
|
145
|
+
|
|
146
|
+
status = napi_create_function(env,
|
|
147
|
+
"noArgFunction",
|
|
148
|
+
NAPI_AUTO_LENGTH,
|
|
149
|
+
NoArgFunction_Core,
|
|
150
|
+
nullptr,
|
|
151
|
+
&no_arg_function);
|
|
152
|
+
NAPI_THROW_IF_FAILED(env, status, Napi::Object());
|
|
153
|
+
|
|
154
|
+
status = napi_create_function(env,
|
|
155
|
+
"oneArgFunction",
|
|
156
|
+
NAPI_AUTO_LENGTH,
|
|
157
|
+
OneArgFunction_Core,
|
|
158
|
+
nullptr,
|
|
159
|
+
&one_arg_function);
|
|
160
|
+
NAPI_THROW_IF_FAILED(env, status, Napi::Object());
|
|
161
|
+
|
|
162
|
+
status = napi_create_function(env,
|
|
163
|
+
"twoArgFunction",
|
|
164
|
+
NAPI_AUTO_LENGTH,
|
|
165
|
+
TwoArgFunction_Core,
|
|
166
|
+
nullptr,
|
|
167
|
+
&two_arg_function);
|
|
168
|
+
NAPI_THROW_IF_FAILED(env, status, Napi::Object());
|
|
169
|
+
|
|
170
|
+
status = napi_create_function(env,
|
|
171
|
+
"threeArgFunction",
|
|
172
|
+
NAPI_AUTO_LENGTH,
|
|
173
|
+
ThreeArgFunction_Core,
|
|
174
|
+
nullptr,
|
|
175
|
+
&three_arg_function);
|
|
176
|
+
NAPI_THROW_IF_FAILED(env, status, Napi::Object());
|
|
177
|
+
|
|
178
|
+
status = napi_create_function(env,
|
|
179
|
+
"fourArgFunction",
|
|
180
|
+
NAPI_AUTO_LENGTH,
|
|
181
|
+
FourArgFunction_Core,
|
|
182
|
+
nullptr,
|
|
183
|
+
&four_arg_function);
|
|
184
|
+
NAPI_THROW_IF_FAILED(env, status, Napi::Object());
|
|
185
|
+
|
|
186
|
+
Napi::Object core = Napi::Object::New(env);
|
|
187
|
+
core["noArgFunction"] = Napi::Value(env, no_arg_function);
|
|
188
|
+
core["oneArgFunction"] = Napi::Value(env, one_arg_function);
|
|
189
|
+
core["twoArgFunction"] = Napi::Value(env, two_arg_function);
|
|
190
|
+
core["threeArgFunction"] = Napi::Value(env, three_arg_function);
|
|
191
|
+
core["fourArgFunction"] = Napi::Value(env, four_arg_function);
|
|
192
|
+
exports["core"] = core;
|
|
193
|
+
|
|
194
|
+
Napi::Object cplusplus = Napi::Object::New(env);
|
|
195
|
+
cplusplus["noArgFunction"] = Napi::Function::New(env, NoArgFunction);
|
|
196
|
+
cplusplus["oneArgFunction"] = Napi::Function::New(env, OneArgFunction);
|
|
197
|
+
cplusplus["twoArgFunction"] = Napi::Function::New(env, TwoArgFunction);
|
|
198
|
+
cplusplus["threeArgFunction"] = Napi::Function::New(env, ThreeArgFunction);
|
|
199
|
+
cplusplus["fourArgFunction"] = Napi::Function::New(env, FourArgFunction);
|
|
200
|
+
exports["cplusplus"] = cplusplus;
|
|
201
|
+
|
|
202
|
+
Napi::Object templated = Napi::Object::New(env);
|
|
203
|
+
templated["noArgFunction"] = Napi::Function::New<NoArgFunction>(env);
|
|
204
|
+
templated["oneArgFunction"] = Napi::Function::New<OneArgFunction>(env);
|
|
205
|
+
templated["twoArgFunction"] = Napi::Function::New<TwoArgFunction>(env);
|
|
206
|
+
templated["threeArgFunction"] = Napi::Function::New<ThreeArgFunction>(env);
|
|
207
|
+
templated["fourArgFunction"] = Napi::Function::New<FourArgFunction>(env);
|
|
208
|
+
exports["templated"] = templated;
|
|
209
|
+
|
|
210
|
+
#if NAPI_VERSION > 5
|
|
211
|
+
FunctionArgsBenchmark::Init(env, exports);
|
|
212
|
+
#endif // NAPI_VERSION > 5
|
|
213
|
+
|
|
214
|
+
return exports;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const Benchmark = require('benchmark');
|
|
3
|
+
const addonName = path.basename(__filename, '.js');
|
|
4
|
+
|
|
5
|
+
[ addonName, addonName + '_noexcept' ]
|
|
6
|
+
.forEach((addonName) => {
|
|
7
|
+
const rootAddon = require('bindings')({
|
|
8
|
+
bindings: addonName,
|
|
9
|
+
module_root: __dirname
|
|
10
|
+
});
|
|
11
|
+
delete rootAddon.path;
|
|
12
|
+
const implems = Object.keys(rootAddon);
|
|
13
|
+
const maxNameLength =
|
|
14
|
+
implems.reduce((soFar, value) => Math.max(soFar, value.length), 0);
|
|
15
|
+
const anObject = {};
|
|
16
|
+
|
|
17
|
+
console.log(`\n${addonName}: `);
|
|
18
|
+
|
|
19
|
+
console.log('no arguments:');
|
|
20
|
+
implems.reduce((suite, implem) => {
|
|
21
|
+
const fn = rootAddon[implem].noArgFunction;
|
|
22
|
+
return suite.add(implem.padStart(maxNameLength, ' '), () => fn());
|
|
23
|
+
}, new Benchmark.Suite)
|
|
24
|
+
.on('cycle', (event) => console.log(String(event.target)))
|
|
25
|
+
.run();
|
|
26
|
+
|
|
27
|
+
console.log('one argument:');
|
|
28
|
+
implems.reduce((suite, implem) => {
|
|
29
|
+
const fn = rootAddon[implem].oneArgFunction;
|
|
30
|
+
return suite.add(implem.padStart(maxNameLength, ' '), () => fn('x'));
|
|
31
|
+
}, new Benchmark.Suite)
|
|
32
|
+
.on('cycle', (event) => console.log(String(event.target)))
|
|
33
|
+
.run();
|
|
34
|
+
|
|
35
|
+
console.log('two arguments:');
|
|
36
|
+
implems.reduce((suite, implem) => {
|
|
37
|
+
const fn = rootAddon[implem].twoArgFunction;
|
|
38
|
+
return suite.add(implem.padStart(maxNameLength, ' '), () => fn('x', 12));
|
|
39
|
+
}, new Benchmark.Suite)
|
|
40
|
+
.on('cycle', (event) => console.log(String(event.target)))
|
|
41
|
+
.run();
|
|
42
|
+
|
|
43
|
+
console.log('three arguments:');
|
|
44
|
+
implems.reduce((suite, implem) => {
|
|
45
|
+
const fn = rootAddon[implem].threeArgFunction;
|
|
46
|
+
return suite.add(implem.padStart(maxNameLength, ' '),
|
|
47
|
+
() => fn('x', 12, true));
|
|
48
|
+
}, new Benchmark.Suite)
|
|
49
|
+
.on('cycle', (event) => console.log(String(event.target)))
|
|
50
|
+
.run();
|
|
51
|
+
|
|
52
|
+
console.log('four arguments:');
|
|
53
|
+
implems.reduce((suite, implem) => {
|
|
54
|
+
const fn = rootAddon[implem].fourArgFunction;
|
|
55
|
+
return suite.add(implem.padStart(maxNameLength, ' '),
|
|
56
|
+
() => fn('x', 12, true, anObject));
|
|
57
|
+
}, new Benchmark.Suite)
|
|
58
|
+
.on('cycle', (event) => console.log(String(event.target)))
|
|
59
|
+
.run();
|
|
60
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { readdirSync } = require('fs');
|
|
4
|
+
const { spawnSync } = require('child_process');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
let benchmarks = [];
|
|
8
|
+
|
|
9
|
+
if (!!process.env.npm_config_benchmarks) {
|
|
10
|
+
benchmarks = process.env.npm_config_benchmarks
|
|
11
|
+
.split(';')
|
|
12
|
+
.map((item) => (item + '.js'));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Run each file in this directory or the list given on the command line except
|
|
16
|
+
// index.js as a Node.js process.
|
|
17
|
+
(benchmarks.length > 0 ? benchmarks : readdirSync(__dirname))
|
|
18
|
+
.filter((item) => (item !== 'index.js' && item.match(/\.js$/)))
|
|
19
|
+
.map((item) => path.join(__dirname, item))
|
|
20
|
+
.forEach((item) => {
|
|
21
|
+
const child = spawnSync(process.execPath, [
|
|
22
|
+
'--expose-gc',
|
|
23
|
+
item
|
|
24
|
+
], { stdio: 'inherit' });
|
|
25
|
+
if (child.signal) {
|
|
26
|
+
console.error(`Tests aborted with ${child.signal}`);
|
|
27
|
+
process.exitCode = 1;
|
|
28
|
+
} else {
|
|
29
|
+
process.exitCode = child.status;
|
|
30
|
+
}
|
|
31
|
+
if (child.status !== 0) {
|
|
32
|
+
process.exit(process.exitCode);
|
|
33
|
+
}
|
|
34
|
+
});
|