Skip to content

Latest commit

Β 

History

History
3210 lines (2629 loc) Β· 111 KB

File metadata and controls

3210 lines (2629 loc) Β· 111 KB
Β 
1
# N-API
2
3
> Stability: 1 - Experimental
4
5
N-API (pronounced N as in the letter, followed by API)
6
is an API for building native Addons. It is independent from
7
the underlying JavaScript runtime (ex V8) and is maintained as part of
8
Node.js itself. This API will be Application Binary Interface (ABI) stable
9
across versions of Node.js. It is intended to insulate Addons from
10
changes in the underlying JavaScript engine and allow modules
11
compiled for one version to run on later versions of Node.js without
12
recompilation.
13
14
Addons are built/packaged with the same approach/tools
May 11, 2017
May 11, 2017
15
outlined in the section titled [C++ Addons](addons.html).
16
The only difference is the set of APIs that are used by the native code.
17
Instead of using the V8 or [Native Abstractions for Node.js][] APIs,
18
the functions available in the N-API are used.
19
20
APIs exposed by N-API are generally used to create and manipulate
21
JavaScript values. Concepts and operations generally map to ideas specified
22
in the ECMA262 Language Specification. The APIs have the following
23
properties:
24
- All N-API calls return a status code of type `napi_status`. This
25
status indicates whether the API call succeeded or failed.
26
- The API's return value is passed via an out parameter.
27
- All JavaScript values are abstracted behind an opaque type named
28
`napi_value`.
29
- In case of an error status code, additional information can be obtained
30
using `napi_get_last_error_info`. More information can be found in the error
31
handling section [Error Handling][].
32
33
The documentation for N-API is structured as follows:
34
35
* [Basic N-API Data Types][]
36
* [Error Handling][]
37
* [Object Lifetime Management][]
38
* [Module Registration][]
39
* [Working with JavaScript Values][]
40
* [Working with JavaScript Values - Abstract Operations][]
41
* [Working with JavaScript Properties][]
42
* [Working with JavaScript Functions][]
43
* [Object Wrap][]
Jun 29, 2017
Jun 29, 2017
44
* [Asynchronous Operations][]
45
46
The N-API is a C API that ensures ABI stability across Node.js versions
47
and different compiler levels. However, we also understand that a C++
48
API can be easier to use in many cases. To support these cases we expect
49
there to be one or more C++ wrapper modules that provide an inlineable C++
50
API. Binaries built with these wrapper modules will depend on the symbols
51
for the N-API C based functions exported by Node.js. These wrappers are not
52
part of N-API, nor will they be maintained as part of Node.js. One such
53
example is: [node-api](https://github.com/nodejs/node-api).
54
May 19, 2017
May 19, 2017
55
In order to use the N-API functions, include the file
56
[node_api.h](https://github.com/nodejs/node/blob/master/src/node_api.h)
57
which is located in the src directory in the node development tree.
58
For example:
59
```C
60
#include <node_api.h>
61
```
62
Jun 5, 2017
Jun 5, 2017
63
As the feature is experimental it must be enabled with the
64
following command line
65
[option](https://nodejs.org/dist/latest-v8.x/docs/api/cli.html#cli_napi_modules):
66
67
```bash
68
--napi-modules
69
```
70
71
## Basic N-API Data Types
72
73
N-API exposes the following fundamental datatypes as abstractions that are
74
consumed by the various APIs. These APIs should be treated as opaque,
75
introspectable only with other N-API calls.
76
77
### *napi_status*
78
Integral status code indicating the success or failure of a N-API call.
79
Currently, the following status codes are supported.
80
```C
81
typedef enum {
82
napi_ok,
83
napi_invalid_arg,
84
napi_object_expected,
85
napi_string_expected,
86
napi_name_expected,
87
napi_function_expected,
88
napi_number_expected,
89
napi_boolean_expected,
90
napi_array_expected,
91
napi_generic_failure,
92
napi_pending_exception,
93
napi_cancelled,
94
napi_status_last
95
} napi_status;
96
```
97
If additional information is required upon an API returning a failed status,
98
it can be obtained by calling `napi_get_last_error_info`.
99
100
### *napi_extended_error_info*
101
```C
102
typedef struct {
103
const char* error_message;
104
void* engine_reserved;
105
uint32_t engine_error_code;
106
napi_status error_code;
107
} napi_extended_error_info;
108
```
109
110
- `error_message`: UTF8-encoded string containing a VM-neutral description of
111
the error.
112
- `engine_reserved`: Reserved for VM-specific error details. This is currently
113
not implemented for any VM.
114
- `engine_error_code`: VM-specific error code. This is currently
115
not implemented for any VM.
116
- `error_code`: The N-API status code that originated with the last error.
117
118
See the [Error Handling][] section for additional information.
119
120
### *napi_env*
121
`napi_env` is used to represent a context that the underlying N-API
122
implementation can use to persist VM-specific state. This structure is passed
123
to native functions when they're invoked, and it must be passed back when
124
making N-API calls. Specifically, the same `napi_env` that was passed in when
125
the initial native function was called must be passed to any subsequent
126
nested N-API calls. Caching the `napi_env` for the purpose of general reuse is
127
not allowed.
128
129
### *napi_value*
130
This is an opaque pointer that is used to represent a JavaScript value.
131
132
### N-API Memory Management types
133
#### *napi_handle_scope*
134
This is an abstraction used to control and modify the lifetime of objects
135
created within a particular scope. In general, N-API values are created within
136
the context of a handle scope. When a native method is called from
137
JavaScript, a default handle scope will exist. If the user does not explicitly
138
create a new handle scope, N-API values will be created in the default handle
139
scope. For any invocations of code outside the execution of a native method
140
(for instance, during a libuv callback invocation), the module is required to
141
create a scope before invoking any functions that can result in the creation
142
of JavaScript values.
143
144
Handle scopes are created using [`napi_open_handle_scope`][] and are destroyed
145
using [`napi_close_handle_scope`][]. Closing the scope can indicate to the GC that
146
all `napi_value`s created during the lifetime of the handle scope are no longer
147
referenced from the current stack frame.
148
149
For more details, review the [Object Lifetime Management][].
150
151
#### *napi_escapable_handle_scope*
152
Escapable handle scopes are a special type of handle scope to return values
153
created within a particular handle scope to a parent scope.
154
155
#### *napi_ref*
156
This is the abstraction to use to reference a `napi_value`. This allows for
157
users to manage the lifetimes of JavaScript values, including defining their
158
minimum lifetimes explicitly.
159
160
For more details, review the [Object Lifetime Management][].
161
162
### N-API Callback types
163
#### *napi_callback_info*
Jun 13, 2017
Jun 13, 2017
164
Opaque datatype that is passed to a callback function. It can be used for
165
getting additional information about the context in which the callback was
166
invoked.
167
168
#### *napi_callback*
169
Function pointer type for user-provided native functions which are to be
170
exposed to JavaScript via N-API. Callback functions should satisfy the
171
following signature:
172
```C
Jun 13, 2017
Jun 13, 2017
173
typedef napi_value (*napi_callback)(napi_env, napi_callback_info);
174
```
175
176
#### *napi_finalize*
177
Function pointer type for add-on provided functions that allow the user to be
178
notified when externally-owned data is ready to be cleaned up because the
179
object with which it was associated with, has been garbage-collected. The user
180
must provide a function satisfying the following signature which would get
181
called upon the object's collection. Currently, `napi_finalize` can be used for
182
finding out when objects that have external data are collected.
183
184
185
#### napi_async_execute_callback
186
Function pointer used with functions that support asynchronous
187
operations. Callback functions must statisfy the following signature:
188
189
```C
190
typedef void (*napi_async_execute_callback)(napi_env env, void* data);
191
```
192
193
#### napi_async_complete_callback
194
Function pointer used with functions that support asynchronous
195
operations. Callback functions must statisfy the following signature:
196
197
```C
198
typedef void (*napi_async_complete_callback)(napi_env env,
199
napi_status status,
200
void* data);
201
```
202
203
## Error Handling
204
N-API uses both return values and Javascript exceptions for error handling.
205
The following sections explain the approach for each case.
206
207
### Return values
208
All of the N-API functions share the same error handling pattern. The
209
return type of all API functions is `napi_status`.
210
211
The return value will be `napi_ok` if the request was successful and
212
no uncaught JavaScript exception was thrown. If an error occurred AND
213
an exception was thrown, the `napi_status` value for the error
214
will be returned. If an exception was thrown, and no error occurred,
215
`napi_pending_exception` will be returned.
216
217
In cases where a return value other than `napi_ok` or
218
`napi_pending_exception` is returned, [`napi_is_exception_pending`][]
219
must be called to check if an exception is pending.
220
See the section on exceptions for more details.
221
222
The full set of possible napi_status values is defined
223
in `napi_api_types.h`.
224
225
The `napi_status` return value provides a VM-independent representation of
226
the error which occurred. In some cases it is useful to be able to get
227
more detailed information, including a string representing the error as well as
228
VM (engine)-specific information.
229
230
In order to retrieve this information [`napi_get_last_error_info`][]
231
is provided which returns a `napi_extended_error_info` structure.
232
The format of the `napi_extended_error_info` structure is as follows:
233
234
```C
235
typedef struct napi_extended_error_info {
236
const char* error_message;
237
void* engine_reserved;
238
uint32_t engine_error_code;
239
napi_status error_code;
240
};
241
```
Jun 17, 2017
Jun 17, 2017
242
- `error_message`: Textual representation of the error that occurred.
243
- `engine_reserved`: Opaque handle reserved for engine use only.
244
- `engine_error_code`: VM specific error code.
245
- `error_code`: n-api status code for the last error.
246
247
[`napi_get_last_error_info`][] returns the information for the last
248
N-API call that was made.
249
May 25, 2017
May 25, 2017
250
*Note*: Do not rely on the content or format of any of the extended
251
information as it is not subject to SemVer and may change at any time.
252
It is intended only for logging purposes.
253
254
#### napi_get_last_error_info
255
<!-- YAML
256
added: v8.0.0
257
-->
258
```C
259
NAPI_EXTERN napi_status
260
napi_get_last_error_info(napi_env env,
261
const napi_extended_error_info** result);
262
```
263
- `[in] env`: The environment that the API is invoked under.
264
- `[out] result`: The `napi_extended_error_info` structure with more
265
information about the error.
266
267
Returns `napi_ok` if the API succeeded.
268
269
This API retrieves a `napi_extended_error_info` structure with information
Jun 17, 2017
Jun 17, 2017
270
about the last error that occurred.
271
Jun 28, 2017
Jun 28, 2017
272
*Note*: The content of the `napi_extended_error_info` returned is only
273
valid up until an n-api function is called on the same `env`.
274
May 25, 2017
May 25, 2017
275
*Note*: Do not rely on the content or format of any of the extended
276
information as it is not subject to SemVer and may change at any time.
277
It is intended only for logging purposes.
278
279
280
### Exceptions
281
Any N-API function call may result in a pending JavaScript exception. This is
282
obviously the case for any function that may cause the execution of
283
JavaScript, but N-API specifies that an exception may be pending
284
on return from any of the API functions.
285
286
If the `napi_status` returned by a function is `napi_ok` then no
287
exception is pending and no additional action is required. If the
288
`napi_status` returned is anything other than `napi_ok` or
289
`napi_pending_exception`, in order to try to recover and continue
290
instead of simply returning immediately, [`napi_is_exception_pending`][]
291
must be called in order to determine if an exception is pending or not.
292
293
When an exception is pending one of two approaches can be employed.
294
295
The first appoach is to do any appropriate cleanup and then return so that
296
execution will return to JavaScript. As part of the transition back to
297
JavaScript the exception will be thrown at the point in the JavaScript
298
code where the native method was invoked. The behavior of most N-API calls
299
is unspecified while an exception is pending, and many will simply return
300
`napi_pending_exception`, so it is important to do as little as possible
301
and then return to JavaScript where the exception can be handled.
302
303
The second approach is to try to handle the exception. There will be cases
304
where the native code can catch the exception, take the appropriate action,
305
and then continue. This is only recommended in specific cases
306
where it is known that the exception can be safely handled. In these
307
cases [`napi_get_and_clear_last_exception`][] can be used to get and
308
clear the exception. On success, result will contain the handle to
309
the last JavaScript Object thrown. If it is determined, after
310
retrieving the exception, the exception cannot be handled after all
311
it can be re-thrown it with [`napi_throw`][] where error is the
312
JavaScript Error object to be thrown.
313
314
The following utility functions are also available in case native code
315
needs to throw an exception or determine if a `napi_value` is an instance
316
of a JavaScript `Error` object: [`napi_throw_error`][],
317
[`napi_throw_type_error`][], [`napi_throw_range_error`][] and
318
[`napi_is_error`][].
319
320
The following utility functions are also available in case native
321
code needs to create an Error object: [`napi_create_error`][],
322
[`napi_create_type_error`][], and [`napi_create_range_error`][].
323
where result is the napi_value that refers to the newly created
324
JavaScript Error object.
325
Jul 13, 2017
Jul 13, 2017
326
The Node.js project is adding error codes to all of the errors
327
generated internally. The goal is for applications to use these
328
error codes for all error checking. The associated error messages
329
will remain, but will only be meant to be used for logging and
330
display with the expectation that the message can change without
331
SemVer applying. In order to support this model with N-API, both
332
in internal functionality and for module specific functionality
333
(as its good practice), the `throw_` and `create_` functions
334
take an optional code parameter which is the string for the code
335
to be added to the error object. If the optional parameter is NULL
336
then no code will be associated with the error. If a code is provided,
337
the name associated with the error is also updated to be:
338
339
```
340
originalName [code]
341
```
342
343
where originalName is the original name associated with the error
344
and code is the code that was provided. For example if the code
345
is 'ERR_ERROR_1' and a TypeError is being created the name will be:
346
347
```
348
TypeError [ERR_ERROR_1]
349
```
350
351
#### napi_throw
352
<!-- YAML
353
added: v8.0.0
354
-->
355
```C
356
NODE_EXTERN napi_status napi_throw(napi_env env, napi_value error);
357
```
358
- `[in] env`: The environment that the API is invoked under.
359
- `[in] error`: The `napi_value` for the Error to be thrown.
360
361
Returns `napi_ok` if the API succeeded.
362
363
This API throws the JavaScript Error provided.
364
365
366
#### napi_throw_error
367
<!-- YAML
368
added: v8.0.0
369
-->
370
```C
Jul 13, 2017
Jul 13, 2017
371
NODE_EXTERN napi_status napi_throw_error(napi_env env,
372
const char* code,
373
const char* msg);
374
```
375
- `[in] env`: The environment that the API is invoked under.
Jul 13, 2017
Jul 13, 2017
376
- `[in] code`: Optional error code to be set on the error.
377
- `[in] msg`: C string representing the text to be associated with
378
the error.
379
380
Returns `napi_ok` if the API succeeded.
381
382
This API throws a JavaScript Error with the text provided.
383
384
#### napi_throw_type_error
385
<!-- YAML
386
added: v8.0.0
387
-->
388
```C
Jul 13, 2017
Jul 13, 2017
389
NODE_EXTERN napi_status napi_throw_type_error(napi_env env,
390
const char* code,
391
const char* msg);
392
```
393
- `[in] env`: The environment that the API is invoked under.
Jul 13, 2017
Jul 13, 2017
394
- `[in] code`: Optional error code to be set on the error.
395
- `[in] msg`: C string representing the text to be associated with
396
the error.
397
398
Returns `napi_ok` if the API succeeded.
399
400
This API throws a JavaScript TypeError with the text provided.
401
402
#### napi_throw_range_error
403
<!-- YAML
404
added: v8.0.0
405
-->
406
```C
Jul 13, 2017
Jul 13, 2017
407
NODE_EXTERN napi_status napi_throw_range_error(napi_env env,
408
const char* code,
409
const char* msg);
410
```
411
- `[in] env`: The environment that the API is invoked under.
Jul 13, 2017
Jul 13, 2017
412
- `[in] code`: Optional error code to be set on the error.
413
- `[in] msg`: C string representing the text to be associated with
414
the error.
415
416
Returns `napi_ok` if the API succeeded.
417
418
This API throws a JavaScript RangeError with the text provided.
419
420
421
#### napi_is_error
422
<!-- YAML
423
added: v8.0.0
424
-->
425
```C
426
NODE_EXTERN napi_status napi_is_error(napi_env env,
427
napi_value value,
428
bool* result);
429
```
430
- `[in] env`: The environment that the API is invoked under.
431
- `[in] msg`: The `napi_value` to be checked.
432
- `[out] result`: Boolean value that is set to true if `napi_value` represents
433
an error, false otherwise.
434
435
Returns `napi_ok` if the API succeeded.
436
437
This API queries a `napi_value` to check if it represents an error object.
438
439
440
#### napi_create_error
441
<!-- YAML
442
added: v8.0.0
443
-->
444
```C
Jun 10, 2017
Jun 10, 2017
445
NODE_EXTERN napi_status napi_create_error(napi_env env,
Jul 13, 2017
Jul 13, 2017
446
napi_value code,
Jun 16, 2017
Jun 16, 2017
447
napi_value msg,
Jun 10, 2017
Jun 10, 2017
448
napi_value* result);
449
```
450
- `[in] env`: The environment that the API is invoked under.
Jul 13, 2017
Jul 13, 2017
451
- `[in] code`: Optional `napi_value` with the string for the error code to
452
be associated with the error.
Jun 16, 2017
Jun 16, 2017
453
- `[in] msg`: napi_value that references a JavaScript String to be
454
used as the message for the Error.
455
- `[out] result`: `napi_value` representing the error created.
456
457
Returns `napi_ok` if the API succeeded.
458
459
This API returns a JavaScript Error with the text provided.
460
461
#### napi_create_type_error
462
<!-- YAML
463
added: v8.0.0
464
-->
465
```C
Jun 10, 2017
Jun 10, 2017
466
NODE_EXTERN napi_status napi_create_type_error(napi_env env,
Jul 13, 2017
Jul 13, 2017
467
napi_value code,
Jun 16, 2017
Jun 16, 2017
468
napi_value msg,
Jun 10, 2017
Jun 10, 2017
469
napi_value* result);
470
```
471
- `[in] env`: The environment that the API is invoked under.
Jul 13, 2017
Jul 13, 2017
472
- `[in] code`: Optional `napi_value` with the string for the error code to
473
be associated with the error.
Jun 16, 2017
Jun 16, 2017
474
- `[in] msg`: napi_value that references a JavaScript String to be
475
used as the message for the Error.
476
- `[out] result`: `napi_value` representing the error created.
477
478
Returns `napi_ok` if the API succeeded.
479
480
This API returns a JavaScript TypeError with the text provided.
481
482
483
#### napi_create_range_error
484
<!-- YAML
485
added: v8.0.0
486
-->
487
```C
Jun 10, 2017
Jun 10, 2017
488
NODE_EXTERN napi_status napi_create_range_error(napi_env env,
Jul 13, 2017
Jul 13, 2017
489
napi_value code,
Jun 10, 2017
Jun 10, 2017
490
const char* msg,
491
napi_value* result);
492
```
493
- `[in] env`: The environment that the API is invoked under.
Jul 13, 2017
Jul 13, 2017
494
- `[in] code`: Optional `napi_value` with the string for the error code to
495
be associated with the error.
Jun 16, 2017
Jun 16, 2017
496
- `[in] msg`: napi_value that references a JavaScript String to be
497
used as the message for the Error.
498
- `[out] result`: `napi_value` representing the error created.
499
500
Returns `napi_ok` if the API succeeded.
501
502
This API returns a JavaScript RangeError with the text provided.
503
504
505
#### napi_get_and_clear_last_exception
506
<!-- YAML
507
added: v8.0.0
508
-->
509
```C
510
NAPI_EXTERN napi_status napi_get_and_clear_last_exception(napi_env env,
511
napi_value* result);
512
```
513
514
- `[in] env`: The environment that the API is invoked under.
515
- `[out] result`: The exception if one is pending, NULL otherwise.
516
517
Returns `napi_ok` if the API succeeded.
518
519
This API returns true if an exception is pending.
520
521
#### napi_is_exception_pending
522
<!-- YAML
523
added: v8.0.0
524
-->
525
```C
526
NAPI_EXTERN napi_status napi_is_exception_pending(napi_env env, bool* result);
527
```
528
529
- `[in] env`: The environment that the API is invoked under.
530
- `[out] result`: Boolean value that is set to true if an exception is pending.
531
532
Returns `napi_ok` if the API succeeded.
533
534
This API returns true if an exception is pending.
535
Jul 13, 2017
Jul 13, 2017
536
### Fatal Errors
537
538
In the event of an unrecoverable error in a native module, a fatal error can be
539
thrown to immediately terminate the process.
540
541
#### napi_fatal_error
542
<!-- YAML
Jul 19, 2017
Jul 19, 2017
543
added: v8.2.0
Jul 13, 2017
Jul 13, 2017
544
-->
545
```C
546
NAPI_EXTERN NAPI_NO_RETURN void napi_fatal_error(const char* location, const char* message);
547
```
548
549
- `[in] location`: Optional location at which the error occurred.
550
- `[in] message`: The message associated with the error.
551
552
The function call does not return, the process will be terminated.
553
554
## Object Lifetime management
555
556
As N-API calls are made, handles to objects in the heap for the underlying
557
VM may be returned as `napi_values`. These handles must hold the
558
objects 'live' until they are no longer required by the native code,
559
otherwise the objects could be collected before the native code was
560
finished using them.
561
562
As object handles are returned they are associated with a
563
'scope'. The lifespan for the default scope is tied to the lifespan
564
of the native method call. The result is that, by default, handles
565
remain valid and the objects associated with these handles will be
566
held live for the lifespan of the native method call.
567
568
In many cases, however, it is necessary that the handles remain valid for
569
either a shorter or longer lifespan than that of the native method.
570
The sections which follow describe the N-API functions than can be used
571
to change the handle lifespan from the default.
572
573
### Making handle lifespan shorter than that of the native method
574
It is often necessary to make the lifespan of handles shorter than
575
the lifespan of a native method. For example, consider a native method
576
that has a loop which iterates through the elements in a large array:
577
578
```C
579
for (int i = 0; i < 1000000; i++) {
580
napi_value result;
581
napi_status status = napi_get_element(e object, i, &result);
582
if (status != napi_ok) {
583
break;
584
}
585
// do something with element
586
}
587
```
588
589
This would result in a large number of handles being created, consuming
590
substantial resources. In addition, even though the native code could only
591
use the most recent handle, all of the associated objects would also be
592
kept alive since they all share the same scope.
593
594
To handle this case, N-API provides the ability to establish a new 'scope' to
595
which newly created handles will be associated. Once those handles
596
are no longer required, the scope can be 'closed' and any handles associated
597
with the scope are invalidated. The methods available to open/close scopes are
598
[`napi_open_handle_scope`][] and [`napi_close_handle_scope`][].
599
600
N-API only supports a single nested hiearchy of scopes. There is only one
601
active scope at any time, and all new handles will be associated with that
602
scope while it is active. Scopes must be closed in the reverse order from
603
which they are opened. In addition, all scopes created within a native method
604
must be closed before returning from that method.
605
606
Taking the earlier example, adding calls to [`napi_open_handle_scope`][] and
607
[`napi_close_handle_scope`][] would ensure that at most a single handle
608
is valid throughout the execution of the loop:
609
610
```C
May 31, 2017
May 31, 2017
611
for (int i = 0; i < 1000000; i++) {
612
napi_handle_scope scope;
613
napi_status status = napi_open_handle_scope(env, &scope);
614
if (status != napi_ok) {
615
break;
616
}
617
napi_value result;
618
status = napi_get_element(e object, i, &result);
619
if (status != napi_ok) {
620
break;
621
}
622
// do something with element
623
status = napi_close_handle_scope(env, scope);
624
if (status != napi_ok) {
625
break;
626
}
627
}
628
```
629
630
When nesting scopes, there are cases where a handle from an
Jun 16, 2017
Jun 16, 2017
631
inner scope needs to live beyond the lifespan of that scope. N-API supports an
632
'escapable scope' in order to support this case. An escapable scope
Jun 16, 2017
Jun 16, 2017
633
allows one handle to be 'promoted' so that it 'escapes' the
634
current scope and the lifespan of the handle changes from the current
635
scope to that of the outer scope.
636
637
The methods available to open/close escapable scopes are
638
[`napi_open_escapable_handle_scope`][] and [`napi_close_escapable_handle_scope`][].
639
Jun 16, 2017
Jun 16, 2017
640
The request to promote a handle is made through [`napi_escape_handle`][] which
641
can only be called once.
642
643
#### napi_open_handle_scope
644
<!-- YAML
645
added: v8.0.0
646
-->
647
```C
648
NODE_EXTERN napi_status napi_open_handle_scope(napi_env env,
649
napi_handle_scope* result);
650
```
651
- `[in] env`: The environment that the API is invoked under.
652
- `[out] result`: `napi_value` representing the new scope.
653
654
Returns `napi_ok` if the API succeeded.
655
656
This API open a new scope.
657
658
#### napi_close_handle_scope
659
<!-- YAML
660
added: v8.0.0
661
-->
662
```C
663
NODE_EXTERN napi_status napi_close_handle_scope(napi_env env,
664
napi_handle_scope scope);
665
```
666
- `[in] env`: The environment that the API is invoked under.
667
- `[in] scope`: `napi_value` representing the scope to be closed.
668
669
Returns `napi_ok` if the API succeeded.
670
671
This API closes the scope passed in. Scopes must be closed in the
672
reverse order from which they were created.
673
674
#### napi_open_escapable_handle_scope
675
<!-- YAML
676
added: v8.0.0
677
-->
678
```C
679
NODE_EXTERN napi_status
680
napi_open_escapable_handle_scope(napi_env env,
681
napi_handle_scope* result);
682
```
683
- `[in] env`: The environment that the API is invoked under.
684
- `[out] result`: `napi_value` representing the new scope.
685
686
Returns `napi_ok` if the API succeeded.
687
Jun 16, 2017
Jun 16, 2017
688
This API open a new scope from which one object can be promoted
689
to the outer scope.
690
691
#### napi_close_escapable_handle_scope
692
<!-- YAML
693
added: v8.0.0
694
-->
695
```C
696
NODE_EXTERN napi_status
697
napi_close_escapable_handle_scope(napi_env env,
698
napi_handle_scope scope);
699
```
700
- `[in] env`: The environment that the API is invoked under.
701
- `[in] scope`: `napi_value` representing the scope to be closed.
702
703
Returns `napi_ok` if the API succeeded.
704
705
This API closes the scope passed in. Scopes must be closed in the
706
reverse order from which they were created.
707
708
#### napi_escape_handle
709
<!-- YAML
710
added: v8.0.0
711
-->
712
```C
713
NAPI_EXTERN napi_status napi_escape_handle(napi_env env,
714
napi_escapable_handle_scope scope,
715
napi_value escapee,
716
napi_value* result);
717
```
718
719
- `[in] env`: The environment that the API is invoked under.
720
- `[in] scope`: `napi_value` representing the current scope.
721
- `[in] escapee`: `napi_value` representing the JavaScript Object to be escaped.
722
- `[out] result`: `napi_value` representing the handle to the escaped
723
Object in the outer scope.
724
725
Returns `napi_ok` if the API succeeded.
726
Jun 16, 2017
Jun 16, 2017
727
This API promotes the handle to the JavaScript object so that it is valid
728
for the lifetime of the outer scope. It can only be called once per scope.
729
If it is called more than once an error will be returned.
730
731
### References to objects with a lifespan longer than that of the native method
732
In some cases an addon will need to be able to create and reference objects
733
with a lifespan longer than that of a single native method invocation. For
734
example, to create a constructor and later use that constructor
735
in a request to creates instances, it must be possible to reference
736
the constructor object across many different instance creation requests. This
737
would not be possible with a normal handle returned as a `napi_value` as
738
described in the earlier section. The lifespan of a normal handle is
739
managed by scopes and all scopes must be closed before the end of a native
740
method.
741
742
N-API provides methods to create persistent references to an object.
743
Each persistent reference has an associated count with a value of 0
744
or higher. The count determines if the reference will keep
745
the corresponding object live. References with a count of 0 do not
746
prevent the object from being collected and are often called 'weak'
747
references. Any count greater than 0 will prevent the object
748
from being collected.
749
750
References can be created with an initial reference count. The count can
751
then be modified through [`napi_reference_ref`][] and
752
[`napi_reference_unref`][]. If an object is collected while the count
753
for a reference is 0, all subsequent calls to
754
get the object associated with the reference [`napi_get_reference_value`][]
755
will return NULL for the returned `napi_value`. An attempt to call
756
[`napi_reference_ref`][] for a reference whose object has been collected
757
will result in an error.
758
759
References must be deleted once they are no longer required by the addon. When
760
a reference is deleted it will no longer prevent the corresponding object from
761
being collected. Failure to delete a persistent reference will result in
762
a 'memory leak' with both the native memory for the persistent reference and
763
the corresponding object on the heap being retained forever.
764
765
There can be multiple persistent references created which refer to the same
766
object, each of which will either keep the object live or not based on its
767
individual count.
768
769
#### napi_create_reference
770
<!-- YAML
771
added: v8.0.0
772
-->
773
```C
774
NODE_EXTERN napi_status napi_create_reference(napi_env env,
775
napi_value value,
776
int initial_refcount,
Jun 6, 2017
Jun 6, 2017
777
napi_ref* result);
778
```
779
780
- `[in] env`: The environment that the API is invoked under.
781
- `[in] value`: `napi_value` representing the Object to which we want
782
a reference to.
783
- `[in] initial_refcount`: Initial reference count for the new reference.
784
- `[out] result`: `napi_ref` pointing to the new reference.
785
786
Returns `napi_ok` if the API succeeded.
787
788
This API create a new reference with the specified reference count
789
to the Object passed in.
790
791
#### napi_delete_reference
792
<!-- YAML
793
added: v8.0.0
794
-->
795
```C
796
NODE_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref);
797
```
798
799
- `[in] env`: The environment that the API is invoked under.
800
- `[in] ref`: `napi_ref` to be deleted.
801
802
Returns `napi_ok` if the API succeeded.
803
804
This API deletes the reference passed in.
805
806
#### napi_reference_ref
807
<!-- YAML
808
added: v8.0.0
809
-->
810
```C
811
NODE_EXTERN napi_status napi_reference_ref(napi_env env,
812
napi_ref ref,
813
int* result);
814
```
815
- `[in] env`: The environment that the API is invoked under.
816
- `[in] ref`: `napi_ref` for which the reference count will be incremented.
817
- `[out] result`: The new reference count.
818
819
Returns `napi_ok` if the API succeeded.
820
821
This API increments the reference count for the reference
822
passed in and returns the resulting reference count.
823
824
825
#### napi_reference_unref
826
<!-- YAML
827
added: v8.0.0
828
-->
829
```C
830
NODE_EXTERN napi_status napi_reference_unref(napi_env env,
831
napi_ref ref,
832
int* result);
833
```
834
- `[in] env`: The environment that the API is invoked under.
835
- `[in] ref`: `napi_ref` for which the reference count will be decremented.
836
- `[out] result`: The new reference count.
837
838
Returns `napi_ok` if the API succeeded.
839
840
This API decrements the reference count for the reference
841
passed in and returns the resulting reference count.
842
843
844
#### napi_get_reference_value
845
<!-- YAML
846
added: v8.0.0
847
-->
848
```C
849
NODE_EXTERN napi_status napi_get_reference_value(napi_env env,
850
napi_ref ref,
851
napi_value* result);
852
```
853
854
the `napi_value passed` in or out of these methods is a handle to the
855
object to which the reference is related.
856
- `[in] env`: The environment that the API is invoked under.
857
- `[in] ref`: `napi_ref` for which we requesting the corresponding Object.
858
- `[out] result`: The `napi_value` for the Object referenced by the
859
`napi_ref`.
860
861
Returns `napi_ok` if the API succeeded.
862
863
If still valid, this API returns the `napi_value` representing the
864
JavaScript Object associated with the `napi_ref`. Otherise, result
865
will be NULL.
866
867
## Module registration
868
N-API modules are registered in the same manner as other modules
869
except that instead of using the `NODE_MODULE` macro the following
870
is used:
871
872
```C
873
NAPI_MODULE(addon, Init)
874
```
875
876
The next difference is the signature for the `Init` method. For a N-API
877
module it is as follows:
878
879
```C
880
void Init(napi_env env, napi_value exports, napi_value module, void* priv);
881
```
882
883
As with any other module, functions are exported by either adding them to
884
the `exports` or `module` objects passed to the `Init` method.
885
886
For example, to add the method `hello` as a function so that it can be called
887
as a method provided by the addon:
888
889
```C
890
void Init(napi_env env, napi_value exports, napi_value module, void* priv) {
891
napi_status status;
892
napi_property_descriptor desc =
893
{"hello", Method, 0, 0, 0, napi_default, 0};
894
status = napi_define_properties(env, exports, 1, &desc);
895
}
896
```
897
898
For example, to set a function to be returned by the `require()` for the addon:
899
900
```C
901
void Init(napi_env env, napi_value exports, napi_value module, void* priv) {
902
napi_status status;
903
napi_property_descriptor desc =
904
{"exports", Method, 0, 0, 0, napi_default, 0};
905
status = napi_define_properties(env, module, 1, &desc);
906
}
907
```
908
909
For example, to define a class so that new instances can be created
910
(often used with [Object Wrap][]):
911
912
```C
913
// NOTE: partial example, not all referenced code is included
914
915
napi_status status;
916
napi_property_descriptor properties[] = {
917
{ "value", nullptr, GetValue, SetValue, 0, napi_default, 0 },
918
DECLARE_NAPI_METHOD("plusOne", PlusOne),
919
DECLARE_NAPI_METHOD("multiply", Multiply),
920
};
921
922
napi_value cons;
923
status =
924
napi_define_class(env, "MyObject", New, nullptr, 3, properties, &cons);
925
if (status != napi_ok) return;
926
927
status = napi_create_reference(env, cons, 1, &constructor);
928
if (status != napi_ok) return;
929
930
status = napi_set_named_property(env, exports, "MyObject", cons);
931
if (status != napi_ok) return;
932
```
933
934
For more details on setting properties on either the `exports` or `module`
935
objects, see the section on
936
[Working with JavaScript Properties][].
937
938
For more details on building addon modules in general, refer to the existing API
939
940
## Working with JavaScript Values
941
N-API exposes a set of APIs to create all types of JavaScript values.
942
Some of these types are documented under
943
[Section 6](https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values)
944
of the [ECMAScript Language Specification][].
945
946
Fundamentally, these APIs are used to do one of the following:
947
1. Create a new JavaScript object
948
2. Convert from a primitive C type to an N-API value
949
3. Convert from N-API value to a primitive C type
950
4. Get global instances including `undefined` and `null`
951
952
N-API values are represented by the type `napi_value`.
953
Any N-API call that requires a JavaScript value takes in a `napi_value`.
954
In some cases, the API does check the type of the `napi_value` up-front.
955
However, for better performance, it's better for the caller to make sure that
956
the `napi_value` in question is of the JavaScript type expected by the API.
957
958
### Enum types
959
#### *napi_valuetype*
960
```C
961
typedef enum {
962
// ES6 types (corresponds to typeof)
963
napi_undefined,
964
napi_null,
965
napi_boolean,
966
napi_number,
967
napi_string,
968
napi_symbol,
969
napi_object,
970
napi_function,
971
napi_external,
972
} napi_valuetype;
973
```
974
975
Describes the type of a `napi_value`. This generally corresponds to the types
976
described in
977
[Section 6.1](https://tc39.github.io/ecma262/#sec-ecmascript-language-types) of
978
the ECMAScript Language Specification.
979
In addition to types in that section, `napi_valuetype` can also represent
980
Functions and Objects with external data.
981
982
#### *napi_typedarray_type*
983
```C
984
typedef enum {
985
napi_int8_array,
986
napi_uint8_array,
987
napi_uint8_clamped_array,
988
napi_int16_array,
989
napi_uint16_array,
990
napi_int32_array,
991
napi_uint32_array,
992
napi_float32_array,
993
napi_float64_array,
994
} napi_typedarray_type;
995
```
996
997
This represents the underlying binary scalar datatype of the TypedArray.
998
Elements of this enum correspond to
999
[Section 22.2](https://tc39.github.io/ecma262/#sec-typedarray-objects)
1000
of the [ECMAScript Language Specification][].