summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2018-10-16 10:38:37 +0200
committerAnna Henningsen <anna@addaleax.net>2018-10-24 19:59:38 +0200
commit449c0ca9f1bf247089781d67a109ebc7e6c1d5a5 (patch)
tree00a52f40175767e3cf086be0716aa3fb56ed58fd /src
parent205b6672361d8926ba2e1169254838dad3707e5b (diff)
downloadandroid-node-v8-449c0ca9f1bf247089781d67a109ebc7e6c1d5a5.tar.gz
android-node-v8-449c0ca9f1bf247089781d67a109ebc7e6c1d5a5.tar.bz2
android-node-v8-449c0ca9f1bf247089781d67a109ebc7e6c1d5a5.zip
n-api: make per-`Context`-ness of `napi_env` explicit
Because instances of `napi_env` are created on a per-global-object basis and because since most N-API functions refer to builtin JS objects, `napi_env` is essentially in 1:1 correspondence with `v8::Context`. This was not clear from the implementation by itself, but has emerged from conversations with the N-API team. This patch changes the `napi_env` implementation to: - Actually store the `v8::Context` it represents. - Provide more direct access to the `node::Environment` to which the `Context` belongs. - Do not store the `uv_loop_t*` explicitly, since it can be inferred from the `node::Environment` and we actually have an N-API method for that. - Replace calls to `isolate->GetCurrentContext()` with the more appropriate `napi_env` `Context`. - Implement a better (although not perfect) way of cleaning up `napi_env` instances. PR-URL: https://github.com/nodejs/node/pull/23689 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Matheus Marchini <mat@mmarchini.me> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/node_api.cc184
1 files changed, 86 insertions, 98 deletions
diff --git a/src/node_api.cc b/src/node_api.cc
index 83eef0ff2e..c92175c75f 100644
--- a/src/node_api.cc
+++ b/src/node_api.cc
@@ -18,16 +18,32 @@ static
napi_status napi_clear_last_error(napi_env env);
struct napi_env__ {
- explicit napi_env__(v8::Isolate* _isolate, uv_loop_t* _loop)
- : isolate(_isolate),
- last_error(),
- loop(_loop) {}
- v8::Isolate* isolate;
+ explicit napi_env__(v8::Local<v8::Context> context)
+ : isolate(context->GetIsolate()),
+ context_persistent(isolate, context) {
+ CHECK_EQ(isolate, context->GetIsolate());
+ CHECK_NOT_NULL(node_env());
+ }
+
+ v8::Isolate* const isolate; // Shortcut for context()->GetIsolate()
+ node::Persistent<v8::Context> context_persistent;
+
+ inline v8::Local<v8::Context> context() const {
+ return StrongPersistentToLocal(context_persistent);
+ }
+
+ inline node::Environment* node_env() const {
+ return node::Environment::GetCurrent(context());
+ }
+
+ inline void Ref() { refs++; }
+ inline void Unref() { if (--refs == 0) delete this; }
+
node::Persistent<v8::Value> last_exception;
napi_extended_error_info last_error;
int open_handle_scopes = 0;
int open_callback_scopes = 0;
- uv_loop_t* loop = nullptr;
+ int refs = 1;
};
#define NAPI_PRIVATE_KEY(context, suffix) \
@@ -720,10 +736,6 @@ v8::Local<v8::Value> CreateAccessorCallbackData(napi_env env,
return cbdata;
}
-static void DeleteEnv(napi_env env, void* data, void* hint) {
- delete env;
-}
-
static
napi_env GetEnv(v8::Local<v8::Context> context) {
napi_env result;
@@ -742,7 +754,7 @@ napi_env GetEnv(v8::Local<v8::Context> context) {
if (value->IsExternal()) {
result = static_cast<napi_env>(value.As<v8::External>()->Value());
} else {
- result = new napi_env__(isolate, node::GetCurrentEventLoop(isolate));
+ result = new napi_env__(context);
auto external = v8::External::New(isolate, result);
// We must also stop hard if the result of assigning the env to the global
@@ -750,9 +762,18 @@ napi_env GetEnv(v8::Local<v8::Context> context) {
CHECK(global->SetPrivate(context, NAPI_PRIVATE_KEY(context, env), external)
.FromJust());
- // Create a self-destructing reference to external that will get rid of the
- // napi_env when external goes out of scope.
- Reference::New(result, external, 0, true, DeleteEnv, nullptr, nullptr);
+ // TODO(addaleax): There was previously code that tried to delete the
+ // napi_env when its v8::Context was garbage collected;
+ // However, as long as N-API addons using this napi_env are in place,
+ // the Context needs to be accessible and alive.
+ // Ideally, we’d want an on-addon-unload hook that takes care of this
+ // once all N-API addons using this napi_env are unloaded.
+ // For now, a per-Environment cleanup hook is the best we can do.
+ result->node_env()->AddCleanupHook(
+ [](void* arg) {
+ static_cast<napi_env>(arg)->Unref();
+ },
+ static_cast<void*>(result));
}
return result;
@@ -774,8 +795,7 @@ napi_status Unwrap(napi_env env,
CHECK_ARG(env, result);
}
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue(js_object);
RETURN_STATUS_IF_FALSE(env, value->IsObject(), napi_invalid_arg);
@@ -808,7 +828,7 @@ napi_status ConcludeDeferred(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, result);
- v8::Local<v8::Context> context = env->isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
node::Persistent<v8::Value>* deferred_ref =
NodePersistentFromJsDeferred(deferred);
v8::Local<v8::Value> v8_deferred =
@@ -853,10 +873,12 @@ class ThreadSafeFunction : public node::AsyncResource {
handles_closing(false) {
ref.Reset(env->isolate, func);
node::AddEnvironmentCleanupHook(env->isolate, Cleanup, this);
+ env->Ref();
}
~ThreadSafeFunction() {
node::RemoveEnvironmentCleanupHook(env->isolate, Cleanup, this);
+ env->Unref();
}
// These methods can be called from any thread.
@@ -935,18 +957,21 @@ class ThreadSafeFunction : public node::AsyncResource {
// These methods must only be called from the loop thread.
napi_status Init() {
+ uv_loop_t* loop = nullptr;
+ CHECK_EQ(napi_get_uv_event_loop(env, &loop), napi_ok);
+
ThreadSafeFunction* ts_fn = this;
- if (uv_async_init(env->loop, &async, AsyncCb) == 0) {
+ if (uv_async_init(loop, &async, AsyncCb) == 0) {
if (max_queue_size > 0) {
cond.reset(new node::ConditionVariable);
}
if ((max_queue_size == 0 || cond.get() != nullptr) &&
- uv_idle_init(env->loop, &idle) == 0) {
+ uv_idle_init(loop, &idle) == 0) {
return napi_ok;
}
- NodeEnv()->CloseHandle(
+ env->node_env()->CloseHandle(
reinterpret_cast<uv_handle_t*>(&async),
[](uv_handle_t* handle) -> void {
ThreadSafeFunction* ts_fn =
@@ -1035,15 +1060,6 @@ class ThreadSafeFunction : public node::AsyncResource {
}
}
- node::Environment* NodeEnv() {
- // Grabbing the Node.js environment requires a handle scope because it
- // looks up fields on the current context.
- v8::HandleScope scope(env->isolate);
- node::Environment* node_env = node::Environment::GetCurrent(env->isolate);
- CHECK_NOT_NULL(node_env);
- return node_env;
- }
-
void MaybeStartIdle() {
if (uv_idle_start(&idle, IdleCb) != 0) {
v8::HandleScope scope(env->isolate);
@@ -1079,13 +1095,13 @@ class ThreadSafeFunction : public node::AsyncResource {
return;
}
handles_closing = true;
- NodeEnv()->CloseHandle(
+ env->node_env()->CloseHandle(
reinterpret_cast<uv_handle_t*>(&async),
[](uv_handle_t* handle) -> void {
ThreadSafeFunction* ts_fn =
node::ContainerOf(&ThreadSafeFunction::async,
reinterpret_cast<uv_async_t*>(handle));
- ts_fn->NodeEnv()->CloseHandle(
+ ts_fn->env->node_env()->CloseHandle(
reinterpret_cast<uv_handle_t*>(&ts_fn->idle),
[](uv_handle_t* handle) -> void {
ThreadSafeFunction* ts_fn =
@@ -1175,8 +1191,7 @@ napi_status Wrap(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, js_object);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue(js_object);
RETURN_STATUS_IF_FALSE(env, value->IsObject(), napi_invalid_arg);
@@ -1211,7 +1226,7 @@ napi_status Wrap(napi_env env,
if (wrap_type == retrievable) {
CHECK(obj->SetPrivate(context, NAPI_PRIVATE_KEY(context, wrapper),
- v8::External::New(isolate, reference)).FromJust());
+ v8::External::New(env->isolate, reference)).FromJust());
}
return GET_RETURN_STATUS(env);
@@ -1418,7 +1433,7 @@ napi_status napi_create_function(napi_env env,
RETURN_STATUS_IF_FALSE(env, !cbdata.IsEmpty(), napi_generic_failure);
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::MaybeLocal<v8::Function> maybe_function =
v8::Function::New(context,
v8impl::FunctionCallbackWrapper::Invoke,
@@ -1518,7 +1533,7 @@ napi_status napi_define_class(napi_env env,
}
}
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
*result = v8impl::JsValueFromV8LocalValue(
scope.Escape(tpl->GetFunction(context).ToLocalChecked()));
@@ -1550,8 +1565,7 @@ napi_status napi_get_property_names(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -1572,8 +1586,7 @@ napi_status napi_set_property(napi_env env,
CHECK_ARG(env, key);
CHECK_ARG(env, value);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -1595,8 +1608,7 @@ napi_status napi_has_property(napi_env env,
CHECK_ARG(env, result);
CHECK_ARG(env, key);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -1618,8 +1630,7 @@ napi_status napi_get_property(napi_env env,
CHECK_ARG(env, key);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Value> k = v8impl::V8LocalValueFromJsValue(key);
v8::Local<v8::Object> obj;
@@ -1641,8 +1652,7 @@ napi_status napi_delete_property(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, key);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Value> k = v8impl::V8LocalValueFromJsValue(key);
v8::Local<v8::Object> obj;
@@ -1663,8 +1673,7 @@ napi_status napi_has_own_property(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, key);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -1684,8 +1693,7 @@ napi_status napi_set_named_property(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, value);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -1708,8 +1716,7 @@ napi_status napi_has_named_property(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -1732,8 +1739,7 @@ napi_status napi_get_named_property(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Name> key;
CHECK_NEW_FROM_UTF8(env, key, utf8name);
@@ -1758,8 +1764,7 @@ napi_status napi_set_element(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, value);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -1779,8 +1784,7 @@ napi_status napi_has_element(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -1800,8 +1804,7 @@ napi_status napi_get_element(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -1820,8 +1823,7 @@ napi_status napi_delete_element(napi_env env,
bool* result) {
NAPI_PREAMBLE(env);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -1843,8 +1845,7 @@ napi_status napi_define_properties(napi_env env,
CHECK_ARG(env, properties);
}
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -1965,8 +1966,7 @@ napi_status napi_get_prototype(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, object);
@@ -2141,7 +2141,7 @@ napi_status napi_create_bigint_words(napi_env env,
CHECK_ARG(env, words);
CHECK_ARG(env, result);
- v8::Local<v8::Context> context = env->isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
if (word_count > INT_MAX) {
napi_throw_range_error(env, nullptr, "Maximum BigInt size exceeded");
@@ -2202,7 +2202,7 @@ static napi_status set_error_code(napi_env env,
const char* code_cstring) {
if ((code != nullptr) || (code_cstring != nullptr)) {
v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> err_object = error.As<v8::Object>();
v8::Local<v8::Value> code_value = v8impl::V8LocalValueFromJsValue(code);
@@ -2435,8 +2435,7 @@ napi_status napi_call_function(napi_env env,
CHECK_ARG(env, argv);
}
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Value> v8recv = v8impl::V8LocalValueFromJsValue(recv);
@@ -2461,11 +2460,7 @@ napi_status napi_get_global(napi_env env, napi_value* result) {
CHECK_ENV(env);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- // TODO(ianhall): what if we need the global object from a different
- // context in the same isolate?
- // Should napi_env be the current context rather than the current isolate?
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
*result = v8impl::JsValueFromV8LocalValue(context->Global());
return napi_clear_last_error(env);
@@ -2857,8 +2852,7 @@ napi_status napi_coerce_to_object(napi_env env,
CHECK_ARG(env, value);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> obj;
CHECK_TO_OBJECT(env, context, obj, value);
@@ -2873,8 +2867,7 @@ napi_status napi_coerce_to_bool(napi_env env,
CHECK_ARG(env, value);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Boolean> b;
CHECK_TO_BOOL(env, context, b, value);
@@ -2890,8 +2883,7 @@ napi_status napi_coerce_to_number(napi_env env,
CHECK_ARG(env, value);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Number> num;
CHECK_TO_NUMBER(env, context, num, value);
@@ -2907,8 +2899,7 @@ napi_status napi_coerce_to_string(napi_env env,
CHECK_ARG(env, value);
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::String> str;
CHECK_TO_STRING(env, context, str, value);
@@ -3169,7 +3160,7 @@ napi_status napi_open_callback_scope(napi_env env,
CHECK_ENV(env);
CHECK_ARG(env, result);
- v8::Local<v8::Context> context = env->isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
node::async_context* node_async_context =
reinterpret_cast<node::async_context*>(async_context_handle);
@@ -3212,8 +3203,7 @@ napi_status napi_new_instance(napi_env env,
}
CHECK_ARG(env, result);
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Function> ctor;
CHECK_TO_FUNCTION(env, ctor, constructor);
@@ -3238,8 +3228,7 @@ napi_status napi_instanceof(napi_env env,
*result = false;
v8::Local<v8::Object> ctor;
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
CHECK_TO_OBJECT(env, context, ctor, constructor);
@@ -3269,7 +3258,7 @@ napi_status napi_async_init(napi_env env,
CHECK_ARG(env, result);
v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> v8_resource;
if (async_resource != nullptr) {
@@ -3319,8 +3308,7 @@ napi_status napi_make_callback(napi_env env,
CHECK_ARG(env, argv);
}
- v8::Isolate* isolate = env->isolate;
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> v8recv;
CHECK_TO_OBJECT(env, context, v8recv, recv);
@@ -3336,7 +3324,7 @@ napi_status napi_make_callback(napi_env env,
}
v8::MaybeLocal<v8::Value> callback_result = node::MakeCallback(
- isolate, v8recv, v8func, argc,
+ env->isolate, v8recv, v8func, argc,
reinterpret_cast<v8::Local<v8::Value>*>(const_cast<napi_value*>(argv)),
*node_async_context);
@@ -3848,7 +3836,7 @@ class Work : public node::AsyncResource, public node::ThreadPoolWork {
: AsyncResource(env->isolate,
async_resource,
*v8::String::Utf8Value(env->isolate, async_resource_name)),
- ThreadPoolWork(node::Environment::GetCurrent(env->isolate)),
+ ThreadPoolWork(env->node_env()),
_env(env),
_data(data),
_execute(execute),
@@ -3935,7 +3923,7 @@ napi_status napi_create_async_work(napi_env env,
CHECK_ARG(env, execute);
CHECK_ARG(env, result);
- v8::Local<v8::Context> context = env->isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
v8::Local<v8::Object> resource;
if (async_resource != nullptr) {
@@ -3968,7 +3956,7 @@ napi_status napi_delete_async_work(napi_env env, napi_async_work work) {
napi_status napi_get_uv_event_loop(napi_env env, uv_loop_t** loop) {
CHECK_ENV(env);
CHECK_ARG(env, loop);
- *loop = env->loop;
+ *loop = env->node_env()->event_loop();
return napi_clear_last_error(env);
}
@@ -4007,7 +3995,7 @@ napi_status napi_create_promise(napi_env env,
CHECK_ARG(env, deferred);
CHECK_ARG(env, promise);
- auto maybe = v8::Promise::Resolver::New(env->isolate->GetCurrentContext());
+ auto maybe = v8::Promise::Resolver::New(env->context());
CHECK_MAYBE_EMPTY(env, maybe, napi_generic_failure);
auto v8_resolver = maybe.ToLocalChecked();
@@ -4056,7 +4044,7 @@ napi_status napi_run_script(napi_env env,
return napi_set_last_error(env, napi_string_expected);
}
- v8::Local<v8::Context> context = env->isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = env->context();
auto maybe_script = v8::Script::Compile(context,
v8::Local<v8::String>::Cast(v8_script));
@@ -4093,7 +4081,7 @@ napi_create_threadsafe_function(napi_env env,
v8::Local<v8::Function> v8_func;
CHECK_TO_FUNCTION(env, v8_func, func);
- v8::Local<v8::Context> v8_context = env->isolate->GetCurrentContext();
+ v8::Local<v8::Context> v8_context = env->context();
v8::Local<v8::Object> v8_resource;
if (async_resource == nullptr) {