Skip to content

Conversation

@gabrielschulhof
Copy link
Contributor

Support napi_get_instance_data() and napi_set_instance_data().
Fixes: #654

@tniessen
Copy link
Member

Is the implicit initialization really helpful? I would imagine most use cases to be one of these:

  1. For all calls into the module that require instance data, the module checks if instance data exists, and if it doesn't, it creates and initializes instance data. This PR takes away the ability to check if the instance data was newly created or if it previously existed.
  2. One call into the module creates and initializes instance data, all other calls only retrieve it. In this case, if due to a bug the instance data is not initialized correctly, the consuming functions have no way to check that, and since this PR silently creates a new object in the background, it might not even crash immediately. With separate APIs to set and get instance data, the consuming functions could just do the equivalent of CHECK on the returned pointer to make sure it has been initialized correctly.

To work around these issues, most objects would probably have to have a member is_initialized or something similar, instead of just checking whether the instance data is NULL or not. In all cases, requiring T to be default constructible is restrictive.

@gabrielschulhof
Copy link
ContributorAuthor

@tniessen@legendecas@addaleax I changed the interface to an accessor pair as @tniessen suggested.

Landing this requires nodejs/node#31638 otherwise it crashes 😕

gabrielschulhof pushed a commit to gabrielschulhof/node that referenced this pull request Feb 6, 2020
Instance data associated with a `napi_env` is no longer stored on the env itself but is instead rendered as a reference. Since `v8impl::Reference` is tied to a JS object, this modification factors out the `v8impl::Reference` refcounting and the deletion process into a base class for `v8impl::Reference`, called `v8impl::RefBase`. The instance data is then stored as a `v8impl::RefBase`, along with other references, preventing a segfault that arises from the fact that, up until now, upon `napi_env` destruction, the instance data was freed after all references had already been forcefully freed. If the addon freed a reference during the `napi_set_instance_data` finalizer callback, such a reference had already been freed during environment teardown, causing a double free. Re: nodejs/node-addon-api#663
gabrielschulhof pushed a commit to nodejs/node that referenced this pull request Feb 6, 2020
Instance data associated with a `napi_env` is no longer stored on the env itself but is instead rendered as a reference. Since `v8impl::Reference` is tied to a JS object, this modification factors out the `v8impl::Reference` refcounting and the deletion process into a base class for `v8impl::Reference`, called `v8impl::RefBase`. The instance data is then stored as a `v8impl::RefBase`, along with other references, preventing a segfault that arises from the fact that, up until now, upon `napi_env` destruction, the instance data was freed after all references had already been forcefully freed. If the addon freed a reference during the `napi_set_instance_data` finalizer callback, such a reference had already been freed during environment teardown, causing a double free. Re: nodejs/node-addon-api#663 PR-URL: #31638 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: David Carlier <[email protected]>
codebytere pushed a commit to nodejs/node that referenced this pull request Feb 17, 2020
Instance data associated with a `napi_env` is no longer stored on the env itself but is instead rendered as a reference. Since `v8impl::Reference` is tied to a JS object, this modification factors out the `v8impl::Reference` refcounting and the deletion process into a base class for `v8impl::Reference`, called `v8impl::RefBase`. The instance data is then stored as a `v8impl::RefBase`, along with other references, preventing a segfault that arises from the fact that, up until now, upon `napi_env` destruction, the instance data was freed after all references had already been forcefully freed. If the addon freed a reference during the `napi_set_instance_data` finalizer callback, such a reference had already been freed during environment teardown, causing a double free. Re: nodejs/node-addon-api#663 PR-URL: #31638 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: David Carlier <[email protected]>
codebytere pushed a commit to nodejs/node that referenced this pull request Mar 15, 2020
Instance data associated with a `napi_env` is no longer stored on the env itself but is instead rendered as a reference. Since `v8impl::Reference` is tied to a JS object, this modification factors out the `v8impl::Reference` refcounting and the deletion process into a base class for `v8impl::Reference`, called `v8impl::RefBase`. The instance data is then stored as a `v8impl::RefBase`, along with other references, preventing a segfault that arises from the fact that, up until now, upon `napi_env` destruction, the instance data was freed after all references had already been forcefully freed. If the addon freed a reference during the `napi_set_instance_data` finalizer callback, such a reference had already been freed during environment teardown, causing a double free. Re: nodejs/node-addon-api#663 PR-URL: #31638 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: David Carlier <[email protected]>
codebytere pushed a commit to nodejs/node that referenced this pull request Mar 17, 2020
Instance data associated with a `napi_env` is no longer stored on the env itself but is instead rendered as a reference. Since `v8impl::Reference` is tied to a JS object, this modification factors out the `v8impl::Reference` refcounting and the deletion process into a base class for `v8impl::Reference`, called `v8impl::RefBase`. The instance data is then stored as a `v8impl::RefBase`, along with other references, preventing a segfault that arises from the fact that, up until now, upon `napi_env` destruction, the instance data was freed after all references had already been forcefully freed. If the addon freed a reference during the `napi_set_instance_data` finalizer callback, such a reference had already been freed during environment teardown, causing a double free. Re: nodejs/node-addon-api#663 PR-URL: #31638 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: David Carlier <[email protected]>
@mhdawsonmhdawson mentioned this pull request Mar 23, 2020
8 tasks
napi-inl.h Outdated
returnValue(_env, result);
}

#ifdef NAPI_EXPERIMENTAL
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this guard can be replaced with NAPI_VERSION > 5?

napi.h Outdated
///
/// In the V8 JavaScript engine, a N-API environment approximately corresponds to an Isolate.
classEnv{
#ifdef NAPI_EXPERIMENTAL
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as before here as well with respect to NAPI_VERSION > 5 and the next one as well.

Copy link
Member

@mhdawsonmhdawson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM once guards are updated.

codebytere pushed a commit to nodejs/node that referenced this pull request Mar 30, 2020
Instance data associated with a `napi_env` is no longer stored on the env itself but is instead rendered as a reference. Since `v8impl::Reference` is tied to a JS object, this modification factors out the `v8impl::Reference` refcounting and the deletion process into a base class for `v8impl::Reference`, called `v8impl::RefBase`. The instance data is then stored as a `v8impl::RefBase`, along with other references, preventing a segfault that arises from the fact that, up until now, upon `napi_env` destruction, the instance data was freed after all references had already been forcefully freed. If the addon freed a reference during the `napi_set_instance_data` finalizer callback, such a reference had already been freed during environment teardown, causing a double free. Re: nodejs/node-addon-api#663 PR-URL: #31638 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: David Carlier <[email protected]>
@gabrielschulhof
Copy link
ContributorAuthor

@mhdawson@legendecas I have updated the guards.

napi-inl.h Outdated
napi_status status =
napi_set_instance_data(_env, data, [](napi_env, void* data, void*){
fini(static_cast<T*>(data));
}, nullptr);
Copy link
Member

@legendecaslegendecasApr 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noted finalize hint has been hardcoded here. Is this intended?

@gabrielschulhof
Copy link
ContributorAuthor

@legendecas I added an option that takes a hint.

@gabrielschulhof
Copy link
ContributorAuthor

gabrielschulhof commented Apr 24, 2020

@gabrielschulhof
Copy link
ContributorAuthor

Investigating .o0o.o0o.

Support `napi_get_instance_data()` and `napi_set_instance_data()`. Fixes: nodejs#654
@gabrielschulhof
Copy link
ContributorAuthor

The failure was caused by Windows' use of escape characters as path separators. The path to the addon was being passed through an unescape step.

@gabrielschulhof
Copy link
ContributorAuthor

gabrielschulhof commented Apr 25, 2020

gabrielschulhof pushed a commit that referenced this pull request Apr 25, 2020
Support `napi_get_instance_data()` and `napi_set_instance_data()`. Signed-off-by: Gabriel Schulhof <[email protected]> Fixes: #654 PR-URL: #663 Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
@gabrielschulhof
Copy link
ContributorAuthor

Landed in 9c9accf.

@KevinEadyKevinEady mentioned this pull request Jun 22, 2020
@gabrielschulhofgabrielschulhof deleted the addon-class branch August 6, 2020 20:43
kevindavies8 added a commit to kevindavies8/node-addon-api-Develop that referenced this pull request Aug 24, 2022
Support `napi_get_instance_data()` and `napi_set_instance_data()`. Signed-off-by: Gabriel Schulhof <[email protected]> Fixes: nodejs/node-addon-api#654 PR-URL: nodejs/node-addon-api#663 Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
Marlyfleitas added a commit to Marlyfleitas/node-api-addon-Development that referenced this pull request Aug 26, 2022
Support `napi_get_instance_data()` and `napi_set_instance_data()`. Signed-off-by: Gabriel Schulhof <[email protected]> Fixes: nodejs/node-addon-api#654 PR-URL: nodejs/node-addon-api#663 Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
wroy7860 added a commit to wroy7860/addon-api-benchmark-node that referenced this pull request Sep 19, 2022
Support `napi_get_instance_data()` and `napi_set_instance_data()`. Signed-off-by: Gabriel Schulhof <[email protected]> Fixes: nodejs/node-addon-api#654 PR-URL: nodejs/node-addon-api#663 Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
johnfrench3 pushed a commit to johnfrench3/node-addon-api-git that referenced this pull request Aug 11, 2023
Support `napi_get_instance_data()` and `napi_set_instance_data()`. Signed-off-by: Gabriel Schulhof <[email protected]> Fixes: nodejs/node-addon-api#654 PR-URL: nodejs/node-addon-api#663 Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Best practice to store context-aware class constructor reference

5 participants

@gabrielschulhof@tniessen@addaleax@legendecas@mhdawson