From a1c224c3d75893e39ab2bbf0f939092c9833dedc Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Wed, 24 May 2017 16:58:03 -0400 Subject: [PATCH 1/4] n-api: add napi_get_version Add napi_get_version function so that addons can query the level of N-API supported. Fixes: https://github.com/nodejs/abi-stable-node/issues/231 --- doc/api/n-api.md | 28 ++++++++++++++++++++ src/node_api.cc | 9 +++++++ src/node_api.h | 4 +++ test/addons-napi/test_general/test.js | 4 +++ test/addons-napi/test_general/test_general.c | 9 +++++++ 5 files changed, 54 insertions(+) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index 6136929e4a9567..5bf94de5830cc0 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -2946,6 +2946,34 @@ the `complete` callback will be invoked with a status value of `napi_cancelled`. The work should not be deleted before the `complete` callback invocation, even if it has been successfully cancelled. +## Version Management + +### napi_get_version + +```C +NAPI_EXTERN napi_status napi_get_version(napi_env env, + uint32_t* result); +``` + +- `[in] env`: The environment that the API is invoked under. +- `[out] result`: The highest version of N-API supported. + +Returns `napi_ok` if the API succeeded. + +This API returns the highest N-API version supported by the +Node.js runtime. N-API is planned to be additive such that +newer releases of Node.js may support additional API functions. Since +the goal is forward compatibility, older versions may not support +the new functions even if we port empty stubs to earlier Node.js +versions in order to facilitate use of the new functions with later +Node.js releases. To support this case an addon can call +`napi_get_version` to check which level of N-API is supported +at run time. Based on the result of this check the addon can +implement appropriate code paths when functions +are, or are not, fully implemented. + [Aynchronous Operations]: #n_api_asynchronous_operations [Basic N-API Data Types]: #n_api_basic_n_api_data_types diff --git a/src/node_api.cc b/src/node_api.cc index d0e535dca06c81..719ceacb4bdbd3 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -18,6 +18,8 @@ #include "uv.h" #include "node_api.h" +#define NAPI_VERSION 1 + static napi_status napi_set_last_error(napi_env env, napi_status error_code, uint32_t engine_error_code = 0, @@ -2713,6 +2715,13 @@ napi_status napi_get_typedarray_info(napi_env env, return napi_clear_last_error(env); } +napi_status napi_get_version(napi_env env, uint32_t* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + *result = NAPI_VERSION; + return napi_clear_last_error(env); +} + namespace uvimpl { static napi_status ConvertUVErrorCode(int code) { diff --git a/src/node_api.h b/src/node_api.h index 5a95c030a35272..a1840943602ce3 100644 --- a/src/node_api.h +++ b/src/node_api.h @@ -478,6 +478,10 @@ NAPI_EXTERN napi_status napi_queue_async_work(napi_env env, NAPI_EXTERN napi_status napi_cancel_async_work(napi_env env, napi_async_work work); + +// version management +NAPI_EXTERN napi_status napi_get_version(napi_env env, uint32_t* result); + EXTERN_C_END #endif // SRC_NODE_API_H_ diff --git a/test/addons-napi/test_general/test.js b/test/addons-napi/test_general/test.js index a2e57126ce8c22..614cf0f4f0e7c4 100644 --- a/test/addons-napi/test_general/test.js +++ b/test/addons-napi/test_general/test.js @@ -30,3 +30,7 @@ assert.strictEqual(test_general.testGetPrototype(extendedObject), assert.ok(test_general.testGetPrototype(baseObject) !== test_general.testGetPrototype(extendedObject), 'Prototypes for base and extended should be different'); + +// test version management funcitons +// expected version is currently 1 +assert.strictEqual(test_general.testGetVersion(), 1); diff --git a/test/addons-napi/test_general/test_general.c b/test/addons-napi/test_general/test_general.c index 17911b36253df1..585a3bf2b3ff0d 100644 --- a/test/addons-napi/test_general/test_general.c +++ b/test/addons-napi/test_general/test_general.c @@ -25,10 +25,19 @@ napi_value testGetPrototype(napi_env env, napi_callback_info info) { return result; } +napi_value testGetVersion(napi_env env, napi_callback_info info) { + uint32_t version; + napi_value result; + NAPI_CALL(env, napi_get_version(env, &version)); + NAPI_CALL(env ,napi_create_number(env, version, &result)); + return result; +} + void Init(napi_env env, napi_value exports, napi_value module, void* priv) { napi_property_descriptor descriptors[] = { DECLARE_NAPI_PROPERTY("testStrictEquals", testStrictEquals), DECLARE_NAPI_PROPERTY("testGetPrototype", testGetPrototype), + DECLARE_NAPI_PROPERTY("testGetVersion", testGetVersion), }; NAPI_CALL_RETURN_VOID(env, napi_define_properties( From fbee2f5771e0eb04d89ddee7b4933e69c4a55a72 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Thu, 25 May 2017 09:44:13 -0400 Subject: [PATCH 2/4] squash: address comments --- doc/api/n-api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index 5bf94de5830cc0..4417d4d92bbc02 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -2950,11 +2950,11 @@ callback invocation, even if it has been successfully cancelled. ### napi_get_version ```C NAPI_EXTERN napi_status napi_get_version(napi_env env, - uint32_t* result); + uint32_t* result); ``` - `[in] env`: The environment that the API is invoked under. From 86cc5700fb7fcb9c2e811524421201913c4ec453 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Thu, 25 May 2017 19:50:06 -0400 Subject: [PATCH 3/4] squash: address comments --- doc/api/n-api.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index 4417d4d92bbc02..73fcaed05abbe2 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -2964,16 +2964,17 @@ Returns `napi_ok` if the API succeeded. This API returns the highest N-API version supported by the Node.js runtime. N-API is planned to be additive such that -newer releases of Node.js may support additional API functions. Since -the goal is forward compatibility, older versions may not support -the new functions even if we port empty stubs to earlier Node.js -versions in order to facilitate use of the new functions with later -Node.js releases. To support this case an addon can call -`napi_get_version` to check which level of N-API is supported -at run time. Based on the result of this check the addon can -implement appropriate code paths when functions -are, or are not, fully implemented. - +newer releases of Node.js may support additional API functions. +In order to allow an addon to use a newer function when running with +versions of Node.js that support it, while providing +fallback behaviour when runnign with Node.js versions that don't +support it: + +* Call `napi_get_version()` to determine if the API is available. +* If available, dynamically load a pointer to the function using `uv_dlsym()`. +* Use the dynamically loaded pointer to invoke the function. +* If the function is not available, provide an alternate implementation + that does not use the function. [Aynchronous Operations]: #n_api_asynchronous_operations [Basic N-API Data Types]: #n_api_basic_n_api_data_types From fcb9f8ba443c74275d045909966005fd2a0821d3 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Fri, 26 May 2017 13:31:14 -0400 Subject: [PATCH 4/4] squash: address comments --- doc/api/n-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index 73fcaed05abbe2..da17eaa9c5011d 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -2967,7 +2967,7 @@ Node.js runtime. N-API is planned to be additive such that newer releases of Node.js may support additional API functions. In order to allow an addon to use a newer function when running with versions of Node.js that support it, while providing -fallback behaviour when runnign with Node.js versions that don't +fallback behavior when running with Node.js versions that don't support it: * Call `napi_get_version()` to determine if the API is available.