Repository navigation
node-api: enable napi_ref for all value types #42557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
579d44c
e108b5e
e629646
246e224
c794f31
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -576,7 +576,9 @@ Reference::Reference(napi_env env, v8::Local<v8::Value> value, Args&&... args) | |||||
| : RefBase(env, std::forward<Args>(args)...), | ||||||
| _persistent(env->isolate, value), | ||||||
| _secondPassParameter(new SecondPassCallParameterRef(this)), | ||||||
| _secondPassScheduled(false) { | ||||||
| _secondPassScheduled(false), | ||||||
| _canBeWeak(!env->IsFeatureEnabled(napi_feature_reference_all_types) || | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We never allowed creating a reference on primitive values (except
Suggested change
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The intent here is to stop offering weak references for Symbols with the new flag and only do it for Objects and Functions to better match the JavaScript spec. But since currently we support weak references for Symbols and have unit tests in
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed the It almost feels like that allowing use of |
||||||
| value->IsObject() || value->IsFunction()) { | ||||||
| if (RefCount() == 0) { | ||||||
| SetWeak(); | ||||||
| } | ||||||
|
|
@@ -652,7 +654,7 @@ void Reference::Finalize(bool is_env_teardown) { | |||||
| // the secondPassParameter so that even if it has been | ||||||
| // scheduled no Finalization will be run. | ||||||
| void Reference::ClearWeak() { | ||||||
| if (!_persistent.IsEmpty()) { | ||||||
| if (!_persistent.IsEmpty() && _canBeWeak) { | ||||||
| _persistent.ClearWeak(); | ||||||
| } | ||||||
| if (_secondPassParameter != nullptr) { | ||||||
|
|
@@ -669,8 +671,13 @@ void Reference::SetWeak() { | |||||
| // nothing | ||||||
| return; | ||||||
| } | ||||||
| _persistent.SetWeak( | ||||||
| _secondPassParameter, FinalizeCallback, v8::WeakCallbackType::kParameter); | ||||||
| if (_canBeWeak) { | ||||||
| _persistent.SetWeak(_secondPassParameter, | ||||||
| FinalizeCallback, | ||||||
| v8::WeakCallbackType::kParameter); | ||||||
| } else { | ||||||
| _persistent.Reset(); | ||||||
| } | ||||||
| *_secondPassParameter = this; | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -2495,9 +2502,11 @@ napi_status NAPI_CDECL napi_create_reference(napi_env env, | |||||
| CHECK_ARG(env, result); | ||||||
|
|
||||||
| v8::Local<v8::Value> v8_value = v8impl::V8LocalValueFromJsValue(value); | ||||||
| if (!(v8_value->IsObject() || v8_value->IsFunction() || | ||||||
| v8_value->IsSymbol())) { | ||||||
| return napi_set_last_error(env, napi_invalid_arg); | ||||||
| if (!env->IsFeatureEnabled(napi_feature_reference_all_types)) { | ||||||
| if (!(v8_value->IsObject() || v8_value->IsFunction() || | ||||||
| v8_value->IsSymbol())) { | ||||||
| return napi_set_last_error(env, napi_invalid_arg); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| v8impl::Reference* reference = | ||||||
|
|
@@ -3257,3 +3266,12 @@ napi_status NAPI_CDECL napi_is_detached_arraybuffer(napi_env env, | |||||
|
|
||||||
| return napi_clear_last_error(env); | ||||||
| } | ||||||
|
|
||||||
| napi_status NAPI_CDECL napi_is_feature_enabled(napi_env env, | ||||||
| napi_features feature, | ||||||
| bool* result) { | ||||||
| CHECK_ENV(env); | ||||||
| CHECK_ARG(env, result); | ||||||
| *result = env->IsFeatureEnabled(feature); | ||||||
| return napi_clear_last_error(env); | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,7 +38,12 @@ typedef struct napi_module { | |
| napi_addon_register_func nm_register_func; | ||
| const char* nm_modname; | ||
| void* nm_priv; | ||
| #ifdef NAPI_EXPERIMENTAL | ||
| napi_features* nm_features; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be a good start for node-api to get started with backward-compatible feature additions! As you mentioned in the node-api meetings, this bit flag (an enum is an int size) may only represent 32 features at most. I'm wondering if it would be more extensible to save the module's defined The drawback of the alternative is that people have to pick up all feature changes with the new NAPI_VERSION, not part of it. But this could also be a relief that we don't need to maintain a long list of features, but a version support list instead. What do you think?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the idea of passing Node-API version used for a module. This way we can enforce the version compatibility. As for the 32-bit feature set limit, the proposal is to pass not the feature bits to the module, but rather the pointer to the feature set. This way we can use the first 31 bits normally. In case if we need more, then we can set the 32nd bit and it will mean that the feature set has the second 32bit number, and the feature set pointer becomes a pointer to the feature set array with two elements. We can extend this array to be as long as needed. Obviously, each new entry in this array will require its own enum type. In practice I doubt that we ever exceed the 31 bit limit, but if we do, then we can extend it using this approach. |
||
| void* reserved[3]; | ||
| #else | ||
| void* reserved[4]; | ||
| #endif | ||
| } napi_module; | ||
|
|
||
| #define NAPI_MODULE_VERSION 1 | ||
|
|
@@ -73,18 +78,43 @@ typedef struct napi_module { | |
| static void fn(void) | ||
| #endif | ||
|
|
||
| #ifdef NAPI_EXPERIMENTAL | ||
| #ifdef NAPI_CUSTOM_FEATURES | ||
|
|
||
| // Define value of napi_module_features variable in your module when | ||
| // NAPI_CUSTOM_FEATURES is set in gyp file. | ||
| extern napi_features napi_module_features; | ||
| #define NAPI_DEFINE_DEFAULT_FEATURES | ||
|
|
||
| #else // NAPI_CUSTOM_FEATURES | ||
|
|
||
| #define NAPI_DEFINE_DEFAULT_FEATURES \ | ||
| static napi_features napi_module_features = napi_default_features; | ||
|
|
||
| #endif // NAPI_CUSTOM_FEATURES | ||
|
|
||
| #define NAPI_FEATURES_PTR /* NOLINT */ &napi_module_features, | ||
|
|
||
| #else // NAPI_EXPERIMENTAL | ||
| #define NAPI_DEFINE_DEFAULT_FEATURES | ||
| #define NAPI_FEATURES_PTR | ||
| #endif // NAPI_EXPERIMENTAL | ||
|
|
||
| #define NAPI_MODULE_X(modname, regfunc, priv, flags) \ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we just create a new NAPI_MODULE_X_FEATURES which takes the features parameter?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It may be simpler - let me try. |
||
| EXTERN_C_START \ | ||
| NAPI_DEFINE_DEFAULT_FEATURES \ | ||
| static napi_module _module = { \ | ||
| NAPI_MODULE_VERSION, \ | ||
| flags, \ | ||
| __FILE__, \ | ||
| regfunc, \ | ||
| #modname, \ | ||
| priv, \ | ||
| {0}, \ | ||
| NAPI_FEATURES_PTR{0}, \ | ||
| }; \ | ||
| NAPI_C_CTOR(_register_##modname) { napi_module_register(&_module); } \ | ||
| NAPI_C_CTOR(_register_##modname) { \ | ||
| napi_module_register(&_module); \ | ||
| } \ | ||
| EXTERN_C_END | ||
|
|
||
| #define NAPI_MODULE_INITIALIZER_X(base, version) \ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed. Though I am not sure why we need to use plural form, while the parameter is singular. Should I also rename the parameter?