From 69e4d6a56ec2bc34da68e9fc78d18570af1222ff Mon Sep 17 00:00:00 2001 From: Gabriel Schulhof Date: Fri, 1 Nov 2024 07:47:24 -0700 Subject: [PATCH] node-api: define version 10 Notable runtime changes to existing APIs: - returning `node_api_cannot_run_js` instead of `napi_pending_exception`. - allow creating references to objects, functions, and symbols. --- doc/api/n-api.md | 18 ++++++------------ doc/contributing/releases-node-api.md | 18 +++++++++--------- src/js_native_api.h | 8 ++------ src/js_native_api_v8.cc | 2 +- src/js_native_api_v8.h | 10 +++++----- src/node_api.cc | 4 +++- src/node_api.h | 5 ++--- src/node_version.h | 2 +- .../test_cannot_run_js/binding.gyp | 4 ++-- .../test_cannot_run_js/test_cannot_run_js.c | 16 +++------------- test/js-native-api/test_general/test.js | 2 +- test/js-native-api/test_string/binding.gyp | 2 +- test/node-api/test_buffer/binding.gyp | 2 +- .../binding.gyp | 4 ++-- 14 files changed, 39 insertions(+), 58 deletions(-) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index 61b43a2aca2e5b..69c0b51318ffe8 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -2702,10 +2702,9 @@ JavaScript `TypedArray` objects are described in added: - v23.0.0 - v22.12.0 +napiVersion: 10 --> -> Stability: 1 - Experimental - ```c napi_status NAPI_CDECL node_api_create_buffer_from_arraybuffer(napi_env env, napi_value arraybuffer, @@ -2967,10 +2966,9 @@ The JavaScript `string` type is described in added: - v20.4.0 - v18.18.0 +napiVersion: 10 --> -> Stability: 1 - Experimental - ```c napi_status node_api_create_external_string_latin1(napi_env env, @@ -3047,10 +3045,9 @@ The JavaScript `string` type is described in added: - v20.4.0 - v18.18.0 +napiVersion: 10 --> -> Stability: 1 - Experimental - ```c napi_status node_api_create_external_string_utf16(napi_env env, @@ -3142,10 +3139,9 @@ creation methods. added: - v22.9.0 - v20.18.0 +napiVersion: 10 --> -> Stability: 1 - Experimental - ```c napi_status NAPI_CDECL node_api_create_property_key_latin1(napi_env env, const char* str, @@ -3177,10 +3173,9 @@ The JavaScript `string` type is described in added: - v21.7.0 - v20.12.0 +napiVersion: 10 --> -> Stability: 1 - Experimental - ```c napi_status NAPI_CDECL node_api_create_property_key_utf16(napi_env env, const char16_t* str, @@ -3210,10 +3205,9 @@ The JavaScript `string` type is described in added: - v22.9.0 - v20.18.0 +napiVersion: 10 --> -> Stability: 1 - Experimental - ```c napi_status NAPI_CDECL node_api_create_property_key_utf8(napi_env env, const char* str, diff --git a/doc/contributing/releases-node-api.md b/doc/contributing/releases-node-api.md index 088900f88c91e0..f8bcd273e39e70 100644 --- a/doc/contributing/releases-node-api.md +++ b/doc/contributing/releases-node-api.md @@ -85,7 +85,7 @@ with: ```bash grep \ - -E \ + -nHE \ 'N(ODE_)?API_EXPERIMENTAL' \ src/js_native_api{_types,}.h \ src/node_api{_types,}.h @@ -95,13 +95,13 @@ and update the define version guards with the release version: ```diff - #ifdef NAPI_EXPERIMENTAL -+ #if NAPI_VERSION >= 10 ++ #if NAPI_VERSION >= 11 NAPI_EXTERN napi_status NAPI_CDECL node_api_function(napi_env env); - #endif // NAPI_EXPERIMENTAL -+ #endif // NAPI_VERSION >= 10 ++ #endif // NAPI_VERSION >= 11 ``` Remove any feature flags of the form `NODE_API_EXPERIMENTAL_HAS_`. @@ -121,11 +121,11 @@ Also, update the Node-API version value of the `napi_get_version` test in #### Step 2. Update runtime version guards If this release includes runtime behavior version guards, the relevant commits -should already include `NAPI_VERSION_EXPERIMENTAL` guard for the change. Check -for these guards with: +should already include the `NAPI_VERSION_EXPERIMENTAL` guard for the change. +Check for these guards with: ```bash -grep NAPI_VERSION_EXPERIMENTAL src/js_native_api_v8* src/node_api.cc +grep -nH NAPI_VERSION_EXPERIMENTAL src/js_native_api_v8* src/node_api.cc ``` and substitute this guard version with the release version `x`. @@ -138,7 +138,7 @@ Check for these definitions with: ```bash grep \ - -E \ + -nHE \ 'N(ODE_)?API_EXPERIMENTAL' \ test/node-api/*/{*.{h,c},binding.gyp} \ test/js-native-api/*/{*.{h,c},binding.gyp} @@ -170,7 +170,7 @@ stability banner: - > Stability: 1 - Experimental @@ -186,7 +186,7 @@ For all runtime version guards updated in Step 2, check for these definitions with: ```bash -grep NAPI_EXPERIMENTAL doc/api/n-api.md +grep -nH NAPI_EXPERIMENTAL doc/api/n-api.md ``` In `doc/api/n-api.md`, update the `experimental` change history item to be the diff --git a/src/js_native_api.h b/src/js_native_api.h index 07e3df13407030..8ef079b5158249 100644 --- a/src/js_native_api.h +++ b/src/js_native_api.h @@ -92,8 +92,7 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_create_string_utf16(napi_env env, const char16_t* str, size_t length, napi_value* result); -#ifdef NAPI_EXPERIMENTAL -#define NODE_API_EXPERIMENTAL_HAS_EXTERNAL_STRINGS +#if NAPI_VERSION >= 10 NAPI_EXTERN napi_status NAPI_CDECL node_api_create_external_string_latin1( napi_env env, char* str, @@ -110,17 +109,14 @@ node_api_create_external_string_utf16(napi_env env, void* finalize_hint, napi_value* result, bool* copied); -#endif // NAPI_EXPERIMENTAL -#ifdef NAPI_EXPERIMENTAL -#define NODE_API_EXPERIMENTAL_HAS_PROPERTY_KEYS NAPI_EXTERN napi_status NAPI_CDECL node_api_create_property_key_latin1( napi_env env, const char* str, size_t length, napi_value* result); NAPI_EXTERN napi_status NAPI_CDECL node_api_create_property_key_utf8( napi_env env, const char* str, size_t length, napi_value* result); NAPI_EXTERN napi_status NAPI_CDECL node_api_create_property_key_utf16( napi_env env, const char16_t* str, size_t length, napi_value* result); -#endif // NAPI_EXPERIMENTAL +#endif // NAPI_VERSION >= 10 NAPI_EXTERN napi_status NAPI_CDECL napi_create_symbol(napi_env env, napi_value description, diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index 3159cd7f69b6f4..6e1680a74e2124 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -2753,7 +2753,7 @@ napi_status NAPI_CDECL napi_create_reference(napi_env env, CHECK_ARG(env, result); v8::Local v8_value = v8impl::V8LocalValueFromJsValue(value); - if (env->module_api_version != NAPI_VERSION_EXPERIMENTAL) { + if (env->module_api_version < 10) { if (!(v8_value->IsObject() || v8_value->IsFunction() || v8_value->IsSymbol())) { return napi_set_last_error(env, napi_invalid_arg); diff --git a/src/js_native_api_v8.h b/src/js_native_api_v8.h index 99bb30cfbe9a9d..27aeac589b19cd 100644 --- a/src/js_native_api_v8.h +++ b/src/js_native_api_v8.h @@ -234,11 +234,11 @@ inline napi_status napi_set_last_error(node_api_basic_env basic_env, CHECK_ENV_NOT_IN_GC((env)); \ RETURN_STATUS_IF_FALSE( \ (env), (env)->last_exception.IsEmpty(), napi_pending_exception); \ - RETURN_STATUS_IF_FALSE((env), \ - (env)->can_call_into_js(), \ - (env->module_api_version == NAPI_VERSION_EXPERIMENTAL \ - ? napi_cannot_run_js \ - : napi_pending_exception)); \ + RETURN_STATUS_IF_FALSE( \ + (env), \ + (env)->can_call_into_js(), \ + (env->module_api_version >= 10 ? napi_cannot_run_js \ + : napi_pending_exception)); \ napi_clear_last_error((env)); \ v8impl::TryCatch try_catch((env)) diff --git a/src/node_api.cc b/src/node_api.cc index cccb2fd0a17f3a..42fa05290a0842 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -678,11 +678,13 @@ node::addon_context_register_func get_node_api_context_register_func( const char* module_name, int32_t module_api_version) { static_assert( - NODE_API_SUPPORTED_VERSION_MAX == 9, + NODE_API_SUPPORTED_VERSION_MAX == 10, "New version of Node-API requires adding another else-if statement below " "for the new version and updating this assert condition."); if (module_api_version == 9) { return node_api_context_register_func<9>; + } else if (module_api_version == 10) { + return node_api_context_register_func<10>; } else if (module_api_version == NAPI_VERSION_EXPERIMENTAL) { return node_api_context_register_func; } else if (module_api_version >= NODE_API_SUPPORTED_VERSION_MIN && diff --git a/src/node_api.h b/src/node_api.h index c8c7bc6ffb9b94..35e5c3e49dd426 100644 --- a/src/node_api.h +++ b/src/node_api.h @@ -133,8 +133,7 @@ napi_create_external_buffer(napi_env env, napi_value* result); #endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED -#ifdef NAPI_EXPERIMENTAL -#define NODE_API_EXPERIMENTAL_HAS_CREATE_BUFFER_FROM_ARRAYBUFFER +#if NAPI_VERSION >= 10 NAPI_EXTERN napi_status NAPI_CDECL node_api_create_buffer_from_arraybuffer(napi_env env, @@ -142,7 +141,7 @@ node_api_create_buffer_from_arraybuffer(napi_env env, size_t byte_offset, size_t byte_length, napi_value* result); -#endif // NAPI_EXPERIMENTAL +#endif // NAPI_VERSION >= 10 NAPI_EXTERN napi_status NAPI_CDECL napi_create_buffer_copy(napi_env env, size_t length, diff --git a/src/node_version.h b/src/node_version.h index dc4c9f3b07f47c..81808db0fa349e 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -100,7 +100,7 @@ // The NAPI_VERSION supported by the runtime. This is the inclusive range of // versions which the Node.js binary being built supports. -#define NODE_API_SUPPORTED_VERSION_MAX 9 +#define NODE_API_SUPPORTED_VERSION_MAX 10 #define NODE_API_SUPPORTED_VERSION_MIN 1 // Node API modules use NAPI_VERSION 8 by default if it is not explicitly diff --git a/test/js-native-api/test_cannot_run_js/binding.gyp b/test/js-native-api/test_cannot_run_js/binding.gyp index 0b827ff34d129f..dfaaf408296d1d 100644 --- a/test/js-native-api/test_cannot_run_js/binding.gyp +++ b/test/js-native-api/test_cannot_run_js/binding.gyp @@ -5,14 +5,14 @@ "sources": [ "test_cannot_run_js.c" ], - "defines": [ "NAPI_EXPERIMENTAL" ], + "defines": [ "NAPI_VERSION=10" ], }, { "target_name": "test_pending_exception", "sources": [ "test_cannot_run_js.c" ], - "defines": [ "NAPI_VERSION=8" ], + "defines": [ "NAPI_VERSION=9" ], } ] } diff --git a/test/js-native-api/test_cannot_run_js/test_cannot_run_js.c b/test/js-native-api/test_cannot_run_js/test_cannot_run_js.c index 9a4b9547493505..dddb8b59421419 100644 --- a/test/js-native-api/test_cannot_run_js/test_cannot_run_js.c +++ b/test/js-native-api/test_cannot_run_js/test_cannot_run_js.c @@ -22,7 +22,7 @@ static void Finalize(napi_env env, void* data, void* hint) { // napi_pending_exception is returned). This is not deterministic from // the point of view of the addon. -#ifdef NAPI_EXPERIMENTAL +#if NAPI_VERSION > 9 NODE_API_BASIC_ASSERT_RETURN_VOID( result == napi_cannot_run_js || result == napi_ok, "getting named property from global in finalizer should succeed " @@ -32,19 +32,10 @@ static void Finalize(napi_env env, void* data, void* hint) { result == napi_pending_exception || result == napi_ok, "getting named property from global in finalizer should succeed " "or return napi_pending_exception"); -#endif // NAPI_EXPERIMENTAL +#endif // NAPI_VERSION > 9 free(ref); } -static void BasicFinalize(node_api_basic_env env, void* data, void* hint) { -#ifdef NAPI_EXPERIMENTAL - NODE_API_BASIC_CALL_RETURN_VOID( - env, node_api_post_finalizer(env, Finalize, data, hint)); -#else - Finalize(env, data, hint); -#endif -} - static napi_value CreateRef(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value cb; @@ -55,8 +46,7 @@ static napi_value CreateRef(napi_env env, napi_callback_info info) { NODE_API_CALL(env, napi_typeof(env, cb, &value_type)); NODE_API_ASSERT( env, value_type == napi_function, "argument must be function"); - NODE_API_CALL(env, - napi_add_finalizer(env, cb, ref, BasicFinalize, NULL, ref)); + NODE_API_CALL(env, napi_add_finalizer(env, cb, ref, Finalize, NULL, ref)); return cb; } diff --git a/test/js-native-api/test_general/test.js b/test/js-native-api/test_general/test.js index 3d4f2f9715678e..843c6aee3af47f 100644 --- a/test/js-native-api/test_general/test.js +++ b/test/js-native-api/test_general/test.js @@ -34,7 +34,7 @@ assert.notStrictEqual(test_general.testGetPrototype(baseObject), test_general.testGetPrototype(extendedObject)); // Test version management functions -assert.strictEqual(test_general.testGetVersion(), 9); +assert.strictEqual(test_general.testGetVersion(), 10); [ 123, diff --git a/test/js-native-api/test_string/binding.gyp b/test/js-native-api/test_string/binding.gyp index 7fc4d9c24226d4..82a1185c3d9d76 100644 --- a/test/js-native-api/test_string/binding.gyp +++ b/test/js-native-api/test_string/binding.gyp @@ -7,7 +7,7 @@ "test_null.c", ], "defines": [ - "NAPI_EXPERIMENTAL", + "NAPI_VERSION=10", ], }, ], diff --git a/test/node-api/test_buffer/binding.gyp b/test/node-api/test_buffer/binding.gyp index 2fd28280d404c4..0a1dc92de7ffb4 100644 --- a/test/node-api/test_buffer/binding.gyp +++ b/test/node-api/test_buffer/binding.gyp @@ -3,7 +3,7 @@ { "target_name": "test_buffer", "defines": [ - 'NAPI_EXPERIMENTAL' + 'NAPI_VERSION=10' ], "sources": [ "test_buffer.c" ] }, diff --git a/test/node-api/test_reference_by_node_api_version/binding.gyp b/test/node-api/test_reference_by_node_api_version/binding.gyp index 2ee1d24763b0b3..4987828ffb3d86 100644 --- a/test/node-api/test_reference_by_node_api_version/binding.gyp +++ b/test/node-api/test_reference_by_node_api_version/binding.gyp @@ -3,12 +3,12 @@ { "target_name": "test_reference_all_types", "sources": [ "test_reference_by_node_api_version.c" ], - "defines": [ "NAPI_EXPERIMENTAL" ], + "defines": [ "NAPI_VERSION=10" ], }, { "target_name": "test_reference_obj_only", "sources": [ "test_reference_by_node_api_version.c" ], - "defines": [ "NAPI_VERSION=8" ], + "defines": [ "NAPI_VERSION=9" ], } ] }