Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChengzhong Wu <legendecas@gmail.com>2022-08-31 16:47:10 +0300
committerGitHub <noreply@github.com>2022-08-31 16:47:10 +0300
commitad3c7bcb033ef98fe3452182c7e43727de069949 (patch)
tree28314fe839471907d1f9fb921265ad48627b36f2 /src
parent6239aeb157a3acb384484f812314fe5c65dbd170 (diff)
node-api: avoid calling virtual methods in base's dtor
Derived classes' fields are already destroyed if the virtual methods are invoked in the base class's destructor. It is not safe to call virtual methods in base's dtor. PR-URL: https://github.com/nodejs/node/pull/44424 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/js_native_api_v8.h16
-rw-r--r--src/node_api.cc4
-rw-r--r--src/node_api_internals.h3
3 files changed, 15 insertions, 8 deletions
diff --git a/src/js_native_api_v8.h b/src/js_native_api_v8.h
index 8e9a06ed894..766398744c5 100644
--- a/src/js_native_api_v8.h
+++ b/src/js_native_api_v8.h
@@ -55,9 +55,6 @@ struct napi_env__ {
CHECK_EQ(isolate, context->GetIsolate());
napi_clear_last_error(this);
}
- virtual ~napi_env__() { FinalizeAll(); }
- v8::Isolate* const isolate; // Shortcut for context()->GetIsolate()
- v8impl::Persistent<v8::Context> context_persistent;
inline v8::Local<v8::Context> context() const {
return v8impl::PersistentToLocal::Strong(context_persistent);
@@ -65,7 +62,7 @@ struct napi_env__ {
inline void Ref() { refs++; }
inline void Unref() {
- if (--refs == 0) delete this;
+ if (--refs == 0) DeleteMe();
}
virtual bool can_call_into_js() const { return true; }
@@ -99,7 +96,7 @@ struct napi_env__ {
CallIntoModule([&](napi_env env) { cb(env, data, hint); });
}
- void FinalizeAll() {
+ virtual void DeleteMe() {
// First we must finalize those references that have `napi_finalizer`
// callbacks. The reason is that addons might store other references which
// they delete during their `napi_finalizer` callbacks. If we deleted such
@@ -107,8 +104,12 @@ struct napi_env__ {
// `napi_finalizer` deleted them subsequently.
v8impl::RefTracker::FinalizeAll(&finalizing_reflist);
v8impl::RefTracker::FinalizeAll(&reflist);
+ delete this;
}
+ v8::Isolate* const isolate; // Shortcut for context()->GetIsolate()
+ v8impl::Persistent<v8::Context> context_persistent;
+
v8impl::Persistent<v8::Value> last_exception;
// We store references in two different lists, depending on whether they have
@@ -121,6 +122,11 @@ struct napi_env__ {
int open_callback_scopes = 0;
int refs = 1;
void* instance_data = nullptr;
+
+ protected:
+ // Should not be deleted directly. Delete with `napi_env__::DeleteMe()`
+ // instead.
+ virtual ~napi_env__() = default;
};
// This class is used to keep a napi_env live in a way that
diff --git a/src/node_api.cc b/src/node_api.cc
index dfe27f43734..922d6ffac19 100644
--- a/src/node_api.cc
+++ b/src/node_api.cc
@@ -25,9 +25,9 @@ node_napi_env__::node_napi_env__(v8::Local<v8::Context> context,
CHECK_NOT_NULL(node_env());
}
-node_napi_env__::~node_napi_env__() {
+void node_napi_env__::DeleteMe() {
destructing = true;
- FinalizeAll();
+ napi_env__::DeleteMe();
}
bool node_napi_env__::can_call_into_js() const {
diff --git a/src/node_api_internals.h b/src/node_api_internals.h
index 6478520fd55..de5d9dc0804 100644
--- a/src/node_api_internals.h
+++ b/src/node_api_internals.h
@@ -11,7 +11,6 @@
struct node_napi_env__ : public napi_env__ {
node_napi_env__(v8::Local<v8::Context> context,
const std::string& module_filename);
- ~node_napi_env__();
bool can_call_into_js() const override;
v8::Maybe<bool> mark_arraybuffer_as_untransferable(
@@ -24,6 +23,8 @@ struct node_napi_env__ : public napi_env__ {
template <bool enforceUncaughtExceptionPolicy, typename T>
void CallbackIntoModule(T&& call);
+ void DeleteMe() override;
+
inline node::Environment* node_env() const {
return node::Environment::GetCurrent(context());
}