| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1aa71c2 commit 32906dd
16 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -78,7 +78,7 @@ it still gets the benefits of the ABI stability provided by the C API. | |||
| 78 | 78 | When using `node-addon-api` instead of the C APIs, start with the API [docs][] | |
| 79 | 79 | for `node-addon-api`. | |
| 80 | 80 | ||
| 81 | - The [Node-API Resource](https://nodejs.github.io/node-addon-examples/) offers | ||
| 81 | + The [Node-API Resource](https://nodejs.github.io/node-addon-examples/) offers | ||
| 82 | 82 | an excellent orientation and tips for developers just getting started with | |
| 83 | 83 | Node-API and `node-addon-api`. Additional media resources can be found on the | |
| 84 | 84 | [Node-API Media][] page. | |
@@ -175,7 +175,8 @@ developers have run into limitations in node-gyp. | |||
| 175 | 175 | [CMake.js][] is an alternative build system based on [CMake][]. | |
| 176 | 176 | ||
| 177 | 177 | CMake.js is a good choice for projects that already use CMake or for | |
| 178 | - developers affected by limitations in node-gyp. | ||
| 178 | + developers affected by limitations in node-gyp. [`build_with_cmake`][] is an | ||
| 179 | + example of a CMake-based native addon project. | ||
| 179 | 180 | ||
| 180 | 181 | ### Uploading precompiled binaries | |
| 181 | 182 | ||
@@ -237,6 +238,18 @@ Some of the Node-API surface is experimental and requires explicit opt-in: | |||
| 237 | 238 | In this case the entire API surface, including any experimental APIs, will be | |
| 238 | 239 | available to the module code. | |
| 239 | 240 | ||
| 241 | + Occasionally, experimental features are introduced that affect already-released | ||
| 242 | + and stable APIs. These features can be disabled by an opt-out: | ||
| 243 | + | ||
| 244 | + ```c | ||
| 245 | + #define NAPI_EXPERIMENTAL | ||
| 246 | + #define NODE_API_EXPERIMENTAL_<FEATURE_NAME>_OPT_OUT | ||
| 247 | + #include <node_api.h> | ||
| 248 | + ``` | ||
| 249 | + | ||
| 250 | + where `<FEATURE_NAME>` is the name of an experimental feature that affects both | ||
| 251 | + experimental and stable APIs. | ||
| 252 | + | ||
| 240 | 253 | ## Node-API version matrix | |
| 241 | 254 | ||
| 242 | 255 | Node-API versions are additive and versioned independently from Node.js. | |
@@ -398,7 +411,7 @@ napi_value create_addon(napi_env env) { | |||
| 398 | 411 | #include <node_api.h> | |
| 399 | 412 | #include "addon.h" | |
| 400 | 413 | ||
| 401 | - NAPI_MODULE_INIT() { | ||
| 414 | + NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) { | ||
| 402 | 415 | // This function body is expected to return a `napi_value`. | |
| 403 | 416 | // The variables `napi_env env` and `napi_value exports` may be used within | |
| 404 | 417 | // the body, as they are provided by the definition of `NAPI_MODULE_INIT()`. | |
@@ -443,7 +456,7 @@ napiVersion: 6 | |||
| 443 | 456 | --> | |
| 444 | 457 | ||
| 445 | 458 | ```c | |
| 446 | - napi_status napi_set_instance_data(napi_env env, | ||
| 459 | + napi_status napi_set_instance_data(node_api_nogc_env env, | ||
| 447 | 460 | void* data, | |
| 448 | 461 | napi_finalize finalize_cb, | |
| 449 | 462 | void* finalize_hint); | |
@@ -475,7 +488,7 @@ napiVersion: 6 | |||
| 475 | 488 | --> | |
| 476 | 489 | ||
| 477 | 490 | ```c | |
| 478 | - napi_status napi_get_instance_data(napi_env env, | ||
| 491 | + napi_status napi_get_instance_data(node_api_nogc_env env, | ||
| 479 | 492 | void** data); | |
| 480 | 493 | ``` | |
| 481 | 494 | ||
@@ -577,6 +590,22 @@ when an instance of a native addon is unloaded. Notification of this event is | |||
| 577 | 590 | delivered through the callbacks given to [`napi_add_env_cleanup_hook`][] and | |
| 578 | 591 | [`napi_set_instance_data`][]. | |
| 579 | 592 | ||
| 593 | + ### `node_api_nogc_env` | ||
| 594 | + | ||
| 595 | + > Stability: 1 - Experimental | ||
| 596 | + | ||
| 597 | + This variant of `napi_env` is passed to synchronous finalizers | ||
| 598 | + ([`node_api_nogc_finalize`][]). There is a subset of Node-APIs which accept | ||
| 599 | + a parameter of type `node_api_nogc_env` as their first argument. These APIs do | ||
| 600 | + not access the state of the JavaScript engine and are thus safe to call from | ||
| 601 | + synchronous finalizers. Passing a parameter of type `napi_env` to these APIs is | ||
| 602 | + allowed, however, passing a parameter of type `node_api_nogc_env` to APIs that | ||
| 603 | + access the JavaScript engine state is not allowed. Attempting to do so without | ||
| 604 | + a cast will produce a compiler warning or an error when add-ons are compiled | ||
| 605 | + with flags which cause them to emit warnings and/or errors when incorrect | ||
| 606 | + pointer types are passed into a function. Calling such APIs from a synchronous | ||
| 607 | + finalizer will ultimately result in the termination of the application. | ||
| 608 | + | ||
| 580 | 609 | ### `napi_value` | |
| 581 | 610 | ||
| 582 | 611 | This is an opaque pointer that is used to represent a JavaScript value. | |
@@ -741,32 +770,36 @@ typedef napi_value (*napi_callback)(napi_env, napi_callback_info); | |||
| 741 | 770 | Unless for reasons discussed in [Object Lifetime Management][], creating a | |
| 742 | 771 | handle and/or callback scope inside a `napi_callback` is not necessary. | |
| 743 | 772 | ||
| 744 | - #### `napi_finalize` | ||
| 773 | + #### `node_api_nogc_finalize` | ||
| 745 | 774 | ||
| 746 | 775 | <!-- YAML | |
| 747 | - added: v8.0.0 | ||
| 748 | - napiVersion: 1 | ||
| 776 | + added: REPLACEME | ||
| 749 | 777 | --> | |
| 750 | 778 | ||
| 779 | + > Stability: 1 - Experimental | ||
| 780 | + | ||
| 751 | 781 | Function pointer type for add-on provided functions that allow the user to be | |
| 752 | 782 | notified when externally-owned data is ready to be cleaned up because the | |
| 753 | - object with which it was associated with has been garbage-collected. The user | ||
| 754 | - must provide a function satisfying the following signature which would get | ||
| 755 | - called upon the object's collection. Currently, `napi_finalize` can be used for | ||
| 783 | + object it was associated with has been garbage-collected. The user must provide | ||
| 784 | + a function satisfying the following signature which would get called upon the | ||
| 785 | + object's collection. Currently, `node_api_nogc_finalize` can be used for | ||
| 756 | 786 | finding out when objects that have external data are collected. | |
| 757 | 787 | ||
| 758 | 788 | ```c | |
| 759 | - typedef void (*napi_finalize)(napi_env env, | ||
| 760 | - void* finalize_data, | ||
| 761 | - void* finalize_hint); | ||
| 789 | + typedef void (*node_api_nogc_finalize)(node_api_nogc_env env, | ||
| 790 | + void* finalize_data, | ||
| 791 | + void* finalize_hint); | ||
| 762 | 792 | ``` | |
| 763 | 793 | ||
| 764 | 794 | Unless for reasons discussed in [Object Lifetime Management][], creating a | |
| 765 | 795 | handle and/or callback scope inside the function body is not necessary. | |
| 766 | 796 | ||
| 767 | 797 | Since these functions may be called while the JavaScript engine is in a state | |
| 768 | - where it cannot execute JavaScript code, some Node-API calls may return | ||
| 769 | - `napi_pending_exception` even when there is no exception pending. | ||
| 798 | + where it cannot execute JavaScript code, only Node-APIs which accept a | ||
| 799 | + `node_api_nogc_env` as their first parameter may be called. | ||
| 800 | + [`node_api_post_finalizer`][] can be used to schedule Node-API calls that | ||
| 801 | + require access to the JavaScript engine's state to run after the current | ||
| 802 | + garbage collection cycle has completed. | ||
| 770 | 803 | ||
| 771 | 804 | In the case of [`node_api_create_external_string_latin1`][] and | |
| 772 | 805 | [`node_api_create_external_string_utf16`][] the `env` parameter may be null, | |
@@ -775,11 +808,39 @@ shutdown. | |||
| 775 | 808 | ||
| 776 | 809 | Change History: | |
| 777 | 810 | ||
| 811 | + * experimental (`NAPI_EXPERIMENTAL`): | ||
| 812 | + | ||
| 813 | + Only Node-API calls that accept a `node_api_nogc_env` as their first | ||
| 814 | + parameter may be called, otherwise the application will be terminated with an | ||
| 815 | + appropriate error message. This feature can be turned off by defining | ||
| 816 | + `NODE_API_EXPERIMENTAL_NOGC_ENV_OPT_OUT`. | ||
| 817 | + | ||
| 818 | + #### `napi_finalize` | ||
| 819 | + | ||
| 820 | + <!-- YAML | ||
| 821 | + added: v8.0.0 | ||
| 822 | + napiVersion: 1 | ||
| 823 | + --> | ||
| 824 | + | ||
| 825 | + Function pointer type for add-on provided function that allow the user to | ||
| 826 | + schedule a group of calls to Node-APIs in response to a garbage collection | ||
| 827 | + event, after the garbage collection cycle has completed. These function | ||
| 828 | + pointers can be used with [`node_api_post_finalizer`][]. | ||
| 829 | + | ||
| 830 | + ```c | ||
| 831 | + typedef void (*napi_finalize)(napi_env env, | ||
| 832 | + void* finalize_data, | ||
| 833 | + void* finalize_hint); | ||
| 834 | + ``` | ||
| 835 | + | ||
| 836 | + Change History: | ||
| 837 | + | ||
| 778 | 838 | * experimental (`NAPI_EXPERIMENTAL` is defined): | |
| 779 | 839 | ||
| 780 | - Node-API calls made from a finalizer will return `napi_cannot_run_js` when | ||
| 781 | - the JavaScript engine is unable to execute JavaScript, and will return | ||
| 782 | - `napi_exception_pending` if there is a pending exception. | ||
| 840 | + A function of this type may no longer be used as a finalizer, except with | ||
| 841 | + [`node_api_post_finalizer`][]. [`node_api_nogc_finalize`][] must be used | ||
| 842 | + instead. This feature can be turned off by defining | ||
| 843 | + `NODE_API_EXPERIMENTAL_NOGC_ENV_OPT_OUT`. | ||
| 783 | 844 | ||
| 784 | 845 | #### `napi_async_execute_callback` | |
| 785 | 846 | ||
@@ -979,7 +1040,7 @@ napiVersion: 1 | |||
| 979 | 1040 | ||
| 980 | 1041 | ```c | |
| 981 | 1042 | napi_status | |
| 982 | - napi_get_last_error_info(napi_env env, | ||
| 1043 | + napi_get_last_error_info(node_api_nogc_env env, | ||
| 983 | 1044 | const napi_extended_error_info** result); | |
| 984 | 1045 | ``` | |
| 985 | 1046 | ||
@@ -1798,7 +1859,7 @@ napiVersion: 3 | |||
| 1798 | 1859 | --> | |
| 1799 | 1860 | ||
| 1800 | 1861 | ```c | |
| 1801 | - NODE_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env, | ||
| 1862 | + NODE_EXTERN napi_status napi_add_env_cleanup_hook(node_api_nogc_env env, | ||
| 1802 | 1863 | napi_cleanup_hook fun, | |
| 1803 | 1864 | void* arg); | |
| 1804 | 1865 | ``` | |
@@ -1828,7 +1889,7 @@ napiVersion: 3 | |||
| 1828 | 1889 | --> | |
| 1829 | 1890 | ||
| 1830 | 1891 | ```c | |
| 1831 | - NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env, | ||
| 1892 | + NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(node_api_nogc_env env, | ||
| 1832 | 1893 | void (*fun)(void* arg), | |
| 1833 | 1894 | void* arg); | |
| 1834 | 1895 | ``` | |
@@ -1857,7 +1918,7 @@ changes: | |||
| 1857 | 1918 | ||
| 1858 | 1919 | ```c | |
| 1859 | 1920 | NAPI_EXTERN napi_status napi_add_async_cleanup_hook( | |
| 1860 | - napi_env env, | ||
| 1921 | + node_api_nogc_env env, | ||
| 1861 | 1922 | napi_async_cleanup_hook hook, | |
| 1862 | 1923 | void* arg, | |
| 1863 | 1924 | napi_async_cleanup_hook_handle* remove_handle); | |
@@ -2015,7 +2076,7 @@ You can also use the `NAPI_MODULE_INIT` macro, which acts as a shorthand | |||
| 2015 | 2076 | for `NAPI_MODULE` and defining an `Init` function: | |
| 2016 | 2077 | ||
| 2017 | 2078 | ```c | |
| 2018 | - NAPI_MODULE_INIT() { | ||
| 2079 | + NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) { | ||
| 2019 | 2080 | napi_value answer; | |
| 2020 | 2081 | napi_status result; | |
| 2021 | 2082 | ||
@@ -2029,6 +2090,9 @@ NAPI_MODULE_INIT() { | |||
| 2029 | 2090 | } | |
| 2030 | 2091 | ``` | |
| 2031 | 2092 | ||
| 2093 | + The parameters `env` and `exports` are provided to the body of the | ||
| 2094 | + `NAPI_MODULE_INIT` macro. | ||
| 2095 | + | ||
| 2032 | 2096 | All Node-API addons are context-aware, meaning they may be loaded multiple | |
| 2033 | 2097 | times. There are a few design considerations when declaring such a module. | |
| 2034 | 2098 | The documentation on [context-aware addons][] provides more details. | |
@@ -5391,7 +5455,7 @@ napiVersion: 5 | |||
| 5391 | 5455 | napi_status napi_add_finalizer(napi_env env, | |
| 5392 | 5456 | napi_value js_object, | |
| 5393 | 5457 | void* finalize_data, | |
| 5394 | - napi_finalize finalize_cb, | ||
| 5458 | + node_api_nogc_finalize finalize_cb, | ||
| 5395 | 5459 | void* finalize_hint, | |
| 5396 | 5460 | napi_ref* result); | |
| 5397 | 5461 | ``` | |
@@ -5429,7 +5493,7 @@ added: v18.19.0 | |||
| 5429 | 5493 | > Stability: 1 - Experimental | |
| 5430 | 5494 | ||
| 5431 | 5495 | ```c | |
| 5432 | - napi_status node_api_post_finalizer(napi_env env, | ||
| 5496 | + napi_status node_api_post_finalizer(node_api_nogc_env env, | ||
| 5433 | 5497 | napi_finalize finalize_cb, | |
| 5434 | 5498 | void* finalize_data, | |
| 5435 | 5499 | void* finalize_hint); | |
@@ -5499,7 +5563,7 @@ Once created the async worker can be queued | |||
| 5499 | 5563 | for execution using the [`napi_queue_async_work`][] function: | |
| 5500 | 5564 | ||
| 5501 | 5565 | ```c | |
| 5502 | - napi_status napi_queue_async_work(napi_env env, | ||
| 5566 | + napi_status napi_queue_async_work(node_api_nogc_env env, | ||
| 5503 | 5567 | napi_async_work work); | |
| 5504 | 5568 | ``` | |
| 5505 | 5569 | ||
@@ -5591,7 +5655,7 @@ napiVersion: 1 | |||
| 5591 | 5655 | --> | |
| 5592 | 5656 | ||
| 5593 | 5657 | ```c | |
| 5594 | - napi_status napi_queue_async_work(napi_env env, | ||
| 5658 | + napi_status napi_queue_async_work(node_api_nogc_env env, | ||
| 5595 | 5659 | napi_async_work work); | |
| 5596 | 5660 | ``` | |
| 5597 | 5661 | ||
@@ -5612,7 +5676,7 @@ napiVersion: 1 | |||
| 5612 | 5676 | --> | |
| 5613 | 5677 | ||
| 5614 | 5678 | ```c | |
| 5615 | - napi_status napi_cancel_async_work(napi_env env, | ||
| 5679 | + napi_status napi_cancel_async_work(node_api_nogc_env env, | ||
| 5616 | 5680 | napi_async_work work); | |
| 5617 | 5681 | ``` | |
| 5618 | 5682 | ||
@@ -5816,7 +5880,7 @@ typedef struct { | |||
| 5816 | 5880 | const char* release; | |
| 5817 | 5881 | } napi_node_version; | |
| 5818 | 5882 | ||
| 5819 | - napi_status napi_get_node_version(napi_env env, | ||
| 5883 | + napi_status napi_get_node_version(node_api_nogc_env env, | ||
| 5820 | 5884 | const napi_node_version** version); | |
| 5821 | 5885 | ``` | |
| 5822 | 5886 | ||
@@ -5839,7 +5903,7 @@ napiVersion: 1 | |||
| 5839 | 5903 | --> | |
| 5840 | 5904 | ||
| 5841 | 5905 | ```c | |
| 5842 | - napi_status napi_get_version(napi_env env, | ||
| 5906 | + napi_status napi_get_version(node_api_nogc_env env, | ||
| 5843 | 5907 | uint32_t* result); | |
| 5844 | 5908 | ``` | |
| 5845 | 5909 | ||
@@ -5872,7 +5936,7 @@ napiVersion: 1 | |||
| 5872 | 5936 | --> | |
| 5873 | 5937 | ||
| 5874 | 5938 | ```c | |
| 5875 | - NAPI_EXTERN napi_status napi_adjust_external_memory(napi_env env, | ||
| 5939 | + NAPI_EXTERN napi_status napi_adjust_external_memory(node_api_nogc_env env, | ||
| 5876 | 5940 | int64_t change_in_bytes, | |
| 5877 | 5941 | int64_t* result); | |
| 5878 | 5942 | ``` | |
@@ -6089,7 +6153,7 @@ napiVersion: 2 | |||
| 6089 | 6153 | --> | |
| 6090 | 6154 | ||
| 6091 | 6155 | ```c | |
| 6092 | - NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env, | ||
| 6156 | + NAPI_EXTERN napi_status napi_get_uv_event_loop(node_api_nogc_env env, | ||
| 6093 | 6157 | struct uv_loop_s** loop); | |
| 6094 | 6158 | ``` | |
| 6095 | 6159 | ||
@@ -6403,7 +6467,7 @@ napiVersion: 4 | |||
| 6403 | 6467 | ||
| 6404 | 6468 | ```c | |
| 6405 | 6469 | NAPI_EXTERN napi_status | |
| 6406 | - napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func); | ||
| 6470 | + napi_ref_threadsafe_function(node_api_nogc_env env, napi_threadsafe_function func); | ||
| 6407 | 6471 | ``` | |
| 6408 | 6472 | ||
| 6409 | 6473 | * `[in] env`: The environment that the API is invoked under. | |
@@ -6429,7 +6493,7 @@ napiVersion: 4 | |||
| 6429 | 6493 | ||
| 6430 | 6494 | ```c | |
| 6431 | 6495 | NAPI_EXTERN napi_status | |
| 6432 | - napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func); | ||
| 6496 | + napi_unref_threadsafe_function(node_api_nogc_env env, napi_threadsafe_function func); | ||
| 6433 | 6497 | ``` | |
| 6434 | 6498 | ||
| 6435 | 6499 | * `[in] env`: The environment that the API is invoked under. | |
@@ -6455,7 +6519,7 @@ napiVersion: 9 | |||
| 6455 | 6519 | ||
| 6456 | 6520 | ```c | |
| 6457 | 6521 | NAPI_EXTERN napi_status | |
| 6458 | - node_api_get_module_file_name(napi_env env, const char** result); | ||
| 6522 | + node_api_get_module_file_name(node_api_nogc_env env, const char** result); | ||
| 6459 | 6523 | ||
| 6460 | 6524 | ``` | |
| 6461 | 6525 | ||
@@ -6519,6 +6583,7 @@ the add-on's file name during loading. | |||
| 6519 | 6583 | [`Number.MIN_SAFE_INTEGER`]: https://tc39.github.io/ecma262/#sec-number.min_safe_integer | |
| 6520 | 6584 | [`Worker`]: worker_threads.md#class-worker | |
| 6521 | 6585 | [`async_hooks.executionAsyncResource()`]: async_hooks.md#async_hooksexecutionasyncresource | |
| 6586 | + [`build_with_cmake`]: https://github.com/nodejs/node-addon-examples/tree/main/build_with_cmake | ||
| 6522 | 6587 | [`global`]: globals.md#global | |
| 6523 | 6588 | [`init` hooks]: async_hooks.md#initasyncid-type-triggerasyncid-resource | |
| 6524 | 6589 | [`napi_add_async_cleanup_hook`]: #napi_add_async_cleanup_hook | |
@@ -6582,6 +6647,8 @@ the add-on's file name during loading. | |||
| 6582 | 6647 | [`node_api_create_external_string_latin1`]: #node_api_create_external_string_latin1 | |
| 6583 | 6648 | [`node_api_create_external_string_utf16`]: #node_api_create_external_string_utf16 | |
| 6584 | 6649 | [`node_api_create_syntax_error`]: #node_api_create_syntax_error | |
| 6650 | + [`node_api_nogc_finalize`]: #node_api_nogc_finalize | ||
| 6651 | + [`node_api_post_finalizer`]: #node_api_post_finalizer | ||
| 6585 | 6652 | [`node_api_throw_syntax_error`]: #node_api_throw_syntax_error | |
| 6586 | 6653 | [`process.release`]: process.md#processrelease | |
| 6587 | 6654 | [`uv_ref`]: https://docs.libuv.org/en/v1.x/handle.html#c.uv_ref | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -51,3 +51,16 @@ Node-API. | |||
| 51 | 51 | to the decision to take an API out of experimental status. | |
| 52 | 52 | * The API **must** be implemented in a Node.js implementation with an | |
| 53 | 53 | alternate VM. | |
| 54 | + | ||
| 55 | + Since the adoption of the policy whereby moving to a later version of Node-API | ||
| 56 | + from an earlier version may entail rework of existing code, it is possible to | ||
| 57 | + introduce modifications to already-released Node-APIs, as long as the | ||
| 58 | + modifications affect neither the ABI nor the API of earlier versions. Such | ||
| 59 | + modifications **must** be accompanied by an opt-out flag. This provides add-on | ||
| 60 | + maintainers who take advantage of the initial compile-time flag to track | ||
| 61 | + impending changes to Node-API with | ||
| 62 | + | ||
| 63 | + * a quick fix to the breakage caused, | ||
| 64 | + * a notification that such breakage is impending, and thus | ||
| 65 | + * a buffer to adoption above and beyond the one provided by the initial | ||
| 66 | + compile-time flag. | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments