Skip to content
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

src: refactor Environment::GetCurrent() usage #22819

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/async_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -687,12 +687,16 @@ MaybeLocal<Value> AsyncWrap::MakeCallback(const Local<Function> cb,


async_id AsyncHooksGetExecutionAsyncId(Isolate* isolate) {
return Environment::GetCurrent(isolate)->execution_async_id();
Environment* env = Environment::GetCurrent(isolate);
if (env == nullptr) return -1;
return env->execution_async_id();
}


async_id AsyncHooksGetTriggerAsyncId(Isolate* isolate) {
return Environment::GetCurrent(isolate)->trigger_async_id();
Environment* env = Environment::GetCurrent(isolate);
if (env == nullptr) return -1;
return env->trigger_async_id();
}


Expand All @@ -711,6 +715,7 @@ async_context EmitAsyncInit(Isolate* isolate,
v8::Local<v8::String> name,
async_id trigger_async_id) {
Environment* env = Environment::GetCurrent(isolate);
CHECK_NOT_NULL(env);

// Initialize async context struct
if (trigger_async_id == -1)
Expand Down
1 change: 1 addition & 0 deletions src/bootstrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ void PromiseRejectCallback(PromiseRejectMessage message) {
PromiseRejectEvent event = message.GetEvent();

Environment* env = Environment::GetCurrent(isolate);
if (env == nullptr) return;
Local<Function> callback;
Local<Value> value;

Expand Down
1 change: 1 addition & 0 deletions src/callback_scope.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ InternalCallbackScope::InternalCallbackScope(Environment* env,
object_(object),
callback_scope_(env) {
CHECK_IMPLIES(expect == kRequireResource, !object.IsEmpty());
CHECK_NOT_NULL(env);

if (!env->can_call_into_js()) {
failed_ = true;
Expand Down
9 changes: 9 additions & 0 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,15 @@ inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
}

inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
addaleax marked this conversation as resolved.
Show resolved Hide resolved
if (UNLIKELY(context.IsEmpty() ||
context->GetNumberOfEmbedderDataFields() <
ContextEmbedderIndex::kContextTag ||
context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kContextTag) !=
Environment::kNodeContextTagPtr)) {
return nullptr;
}

return static_cast<Environment*>(
context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kEnvironment));
Expand Down
13 changes: 2 additions & 11 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -488,18 +488,9 @@ void Environment::EnvPromiseHook(v8::PromiseHookType type,
v8::Local<v8::Value> parent) {
Local<v8::Context> context = promise->CreationContext();

// Grow the embedder data if necessary to make sure we are not out of bounds
// when reading the magic number.
context->SetAlignedPointerInEmbedderData(
ContextEmbedderIndex::kContextTagBoundary, nullptr);
int* magicNumberPtr = reinterpret_cast<int*>(
context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kContextTag));
if (magicNumberPtr != Environment::kNodeContextTagPtr) {
return;
}

Environment* env = Environment::GetCurrent(context);
if (env == nullptr) return;

for (const PromiseHookCallback& hook : env->promise_hooks_) {
hook.cb_(type, promise, parent, hook.arg_);
}
Expand Down
5 changes: 2 additions & 3 deletions src/inspector_js_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,11 @@ void CallAndPauseOnStart(const FunctionCallbackInfo<v8::Value>& args) {
}

void InspectorConsoleCall(const FunctionCallbackInfo<Value>& info) {
Isolate* isolate = info.GetIsolate();
HandleScope handle_scope(isolate);
Environment* env = Environment::GetCurrent(info);
Isolate* isolate = env->isolate();
Local<Context> context = isolate->GetCurrentContext();
CHECK_LT(2, info.Length());
SlicedArguments call_args(info, /* start */ 3);
Environment* env = Environment::GetCurrent(isolate);
if (InspectorEnabled(env)) {
Local<Value> inspector_method = info[0];
CHECK(inspector_method->IsFunction());
Expand Down
6 changes: 4 additions & 2 deletions src/module_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ MaybeLocal<Module> ModuleWrap::ResolveCallback(Local<Context> context,
Local<String> specifier,
Local<Module> referrer) {
Environment* env = Environment::GetCurrent(context);
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
Isolate* isolate = env->isolate();
if (env->module_map.count(referrer->GetIdentityHash()) == 0) {
env->ThrowError("linking error, unknown module");
Expand Down Expand Up @@ -700,6 +701,7 @@ static MaybeLocal<Promise> ImportModuleDynamically(
Local<String> specifier) {
Isolate* iso = context->GetIsolate();
Environment* env = Environment::GetCurrent(context);
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
v8::EscapableHandleScope handle_scope(iso);

if (env->context() != context) {
Expand Down Expand Up @@ -750,8 +752,8 @@ void ModuleWrap::SetImportModuleDynamicallyCallback(

void ModuleWrap::HostInitializeImportMetaObjectCallback(
Local<Context> context, Local<Module> module, Local<Object> meta) {
Isolate* isolate = context->GetIsolate();
Environment* env = Environment::GetCurrent(context);
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
ModuleWrap* module_wrap = GetFromModule(env, module);

if (module_wrap == nullptr) {
Expand All @@ -762,7 +764,7 @@ void ModuleWrap::HostInitializeImportMetaObjectCallback(
Local<Function> callback =
env->host_initialize_import_meta_object_callback();
Local<Value> args[] = { wrap, meta };
callback->Call(context, Undefined(isolate), arraysize(args), args)
callback->Call(context, Undefined(env->isolate()), arraysize(args), args)
.ToLocalChecked();
}

Expand Down
17 changes: 13 additions & 4 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,8 @@ namespace {
bool ShouldAbortOnUncaughtException(Isolate* isolate) {
HandleScope scope(isolate);
Environment* env = Environment::GetCurrent(isolate);
return env->should_abort_on_uncaught_toggle()[0] &&
return env != nullptr &&
env->should_abort_on_uncaught_toggle()[0] &&
!env->inside_should_not_abort_on_uncaught_scope();
}

Expand All @@ -640,13 +641,15 @@ bool ShouldAbortOnUncaughtException(Isolate* isolate) {

void AddPromiseHook(Isolate* isolate, promise_hook_func fn, void* arg) {
Environment* env = Environment::GetCurrent(isolate);
CHECK_NOT_NULL(env);
env->AddPromiseHook(fn, arg);
}

void AddEnvironmentCleanupHook(Isolate* isolate,
void (*fun)(void* arg),
void* arg) {
Environment* env = Environment::GetCurrent(isolate);
CHECK_NOT_NULL(env);
env->AddCleanupHook(fun, arg);
}

Expand All @@ -655,6 +658,7 @@ void RemoveEnvironmentCleanupHook(Isolate* isolate,
void (*fun)(void* arg),
void* arg) {
Environment* env = Environment::GetCurrent(isolate);
CHECK_NOT_NULL(env);
env->RemoveCleanupHook(fun, arg);
}

Expand Down Expand Up @@ -739,6 +743,7 @@ MaybeLocal<Value> MakeCallback(Isolate* isolate,
// Because of the AssignToContext() call in src/node_contextify.cc,
// the two contexts need not be the same.
Environment* env = Environment::GetCurrent(callback->CreationContext());
CHECK_NOT_NULL(env);
Context::Scope context_scope(env->context());
MaybeLocal<Value> ret = InternalMakeCallback(env, recv, callback,
argc, argv, asyncContext);
Expand Down Expand Up @@ -1433,6 +1438,7 @@ void FatalException(Isolate* isolate,
HandleScope scope(isolate);

Environment* env = Environment::GetCurrent(isolate);
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
Local<Object> process_object = env->process_object();
Local<String> fatal_exception_string = env->fatal_exception_string();
Local<Value> fatal_exception_function =
Expand Down Expand Up @@ -1658,7 +1664,7 @@ static void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
}

static void GetLinkedBinding(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate());
Environment* env = Environment::GetCurrent(args);

CHECK(args[0]->IsString());

Expand Down Expand Up @@ -2789,10 +2795,13 @@ void RunAtExit(Environment* env) {

uv_loop_t* GetCurrentEventLoop(Isolate* isolate) {
HandleScope handle_scope(isolate);
auto context = isolate->GetCurrentContext();
Local<Context> context = isolate->GetCurrentContext();
if (context.IsEmpty())
return nullptr;
return Environment::GetCurrent(context)->event_loop();
Environment* env = Environment::GetCurrent(context);
if (env == nullptr)
return nullptr;
return env->event_loop();
}


Expand Down
15 changes: 11 additions & 4 deletions src/node_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,8 @@ napi_env GetEnv(v8::Local<v8::Context> context) {
// because we need to stop hard if either of them is empty.
//
// Re https://github.com/nodejs/node/pull/14217#discussion_r128775149
// TODO(addaleax): This requires a Node.js Environment attached to the
// current context.
auto value = global->GetPrivate(context, NAPI_PRIVATE_KEY(context, env))
.ToLocalChecked();

Expand Down Expand Up @@ -946,7 +948,7 @@ class ThreadSafeFunction : public node::AsyncResource {
return napi_ok;
}

node::Environment::GetCurrent(env->isolate)->CloseHandle(
NodeEnv()->CloseHandle(
reinterpret_cast<uv_handle_t*>(&async),
[](uv_handle_t* handle) -> void {
ThreadSafeFunction* ts_fn =
Expand Down Expand Up @@ -1036,9 +1038,12 @@ class ThreadSafeFunction : public node::AsyncResource {
}

node::Environment* NodeEnv() {
// For some reason grabbing the Node.js environment requires a handle scope.
// Grabbing the Node.js environment requires a handle scope because it
// looks up fields on the current context.
v8::HandleScope scope(env->isolate);
return node::Environment::GetCurrent(env->isolate);
node::Environment* node_env = node::Environment::GetCurrent(env->isolate);
CHECK_NOT_NULL(node_env);
return node_env;
}

void MaybeStartIdle() {
Expand Down Expand Up @@ -1177,7 +1182,9 @@ void napi_module_register_by_symbol(v8::Local<v8::Object> exports,
v8::Local<v8::Context> context,
napi_addon_register_func init) {
if (init == nullptr) {
node::Environment::GetCurrent(context)->ThrowError(
node::Environment* node_env = node::Environment::GetCurrent(context);
CHECK_NOT_NULL(node_env);
node_env->ThrowError(
"Module has no declared entry point.");
return;
}
Expand Down
7 changes: 6 additions & 1 deletion src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,9 @@ MaybeLocal<Object> New(Isolate* isolate,
MaybeLocal<Object> New(Isolate* isolate, size_t length) {
EscapableHandleScope handle_scope(isolate);
Local<Object> obj;
if (Buffer::New(Environment::GetCurrent(isolate), length).ToLocal(&obj))
Environment* env = Environment::GetCurrent(isolate);
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
if (Buffer::New(env, length).ToLocal(&obj))
return handle_scope.Escape(obj);
return Local<Object>();
}
Expand Down Expand Up @@ -316,6 +318,7 @@ MaybeLocal<Object> New(Environment* env, size_t length) {
MaybeLocal<Object> Copy(Isolate* isolate, const char* data, size_t length) {
EscapableHandleScope handle_scope(isolate);
Environment* env = Environment::GetCurrent(isolate);
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
Local<Object> obj;
if (Buffer::Copy(env, data, length).ToLocal(&obj))
return handle_scope.Escape(obj);
Expand Down Expand Up @@ -365,6 +368,7 @@ MaybeLocal<Object> New(Isolate* isolate,
void* hint) {
EscapableHandleScope handle_scope(isolate);
Environment* env = Environment::GetCurrent(isolate);
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
Local<Object> obj;
if (Buffer::New(env, data, length, callback, hint).ToLocal(&obj))
return handle_scope.Escape(obj);
Expand Down Expand Up @@ -403,6 +407,7 @@ MaybeLocal<Object> New(Environment* env,
MaybeLocal<Object> New(Isolate* isolate, char* data, size_t length) {
EscapableHandleScope handle_scope(isolate);
Environment* env = Environment::GetCurrent(isolate);
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
Local<Object> obj;
if (Buffer::New(env, data, length).ToLocal(&obj))
return handle_scope.Escape(obj);
Expand Down
5 changes: 0 additions & 5 deletions src/node_context_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,11 @@ namespace node {
#define NODE_CONTEXT_TAG 35
#endif

#ifndef NODE_CONTEXT_TAG_BOUNDARY
#define NODE_CONTEXT_TAG_BOUNDARY 36
#endif

enum ContextEmbedderIndex {
kEnvironment = NODE_CONTEXT_EMBEDDER_DATA_INDEX,
kSandboxObject = NODE_CONTEXT_SANDBOX_OBJECT_INDEX,
kAllowWasmCodeGeneration = NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX,
kContextTag = NODE_CONTEXT_TAG,
kContextTagBoundary = NODE_CONTEXT_TAG_BOUNDARY,
};

} // namespace node
Expand Down
7 changes: 3 additions & 4 deletions src/node_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ void FSReqCallback::SetReturnValue(const FunctionCallbackInfo<Value>& args) {

void NewFSReqCallback(const FunctionCallbackInfo<Value>& args) {
CHECK(args.IsConstructCall());
Environment* env = Environment::GetCurrent(args.GetIsolate());
Environment* env = Environment::GetCurrent(args);
new FSReqCallback(env, args.This(), args[0]->IsTrue());
}

Expand Down Expand Up @@ -782,7 +782,7 @@ inline FSReqBase* GetReqWrap(Environment* env, Local<Value> value,
}

void Access(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate());
Environment* env = Environment::GetCurrent(args);
HandleScope scope(env->isolate());

const int argc = args.Length();
Expand Down Expand Up @@ -2234,8 +2234,7 @@ void Initialize(Local<Object> target,
StatWatcher::Initialize(env, target);

// Create FunctionTemplate for FSReqCallback
Local<FunctionTemplate> fst =
FunctionTemplate::New(env->isolate(), NewFSReqCallback);
Local<FunctionTemplate> fst = env->NewFunctionTemplate(NewFSReqCallback);
fst->InstanceTemplate()->SetInternalFieldCount(1);
AsyncWrap::AddWrapMethods(env, fst);
Local<String> wrapString =
Expand Down
4 changes: 3 additions & 1 deletion src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,9 @@ class InternalCallbackScope {

class ThreadPoolWork {
public:
explicit inline ThreadPoolWork(Environment* env) : env_(env) {}
explicit inline ThreadPoolWork(Environment* env) : env_(env) {
CHECK_NOT_NULL(env);
}
inline virtual ~ThreadPoolWork() = default;

inline void ScheduleWork();
Expand Down
1 change: 1 addition & 0 deletions src/node_perf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ void TimerFunctionCall(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope scope(isolate);
Environment* env = Environment::GetCurrent(isolate);
CHECK_NOT_NULL(env); // TODO(addaleax): Verify that this is correct.
Local<Context> context = env->context();
Local<Function> fn = args.Data().As<Function>();
size_t count = args.Length();
Expand Down
20 changes: 20 additions & 0 deletions test/cctest/test_environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,26 @@ TEST_F(EnvironmentTest, MultipleEnvironmentsPerIsolate) {
EXPECT_TRUE(called_cb_2);
}

TEST_F(EnvironmentTest, NonNodeJSContext) {
const v8::HandleScope handle_scope(isolate_);
const Argv argv;
Env test_env {handle_scope, argv};

EXPECT_EQ(node::Environment::GetCurrent(v8::Local<v8::Context>()), nullptr);

node::Environment* env = *test_env;
EXPECT_EQ(node::Environment::GetCurrent(isolate_), env);
EXPECT_EQ(node::Environment::GetCurrent(env->context()), env);

v8::Local<v8::Context> context = v8::Context::New(isolate_);
EXPECT_EQ(node::Environment::GetCurrent(context), nullptr);
EXPECT_EQ(node::Environment::GetCurrent(isolate_), env);

v8::Context::Scope context_scope(context);
EXPECT_EQ(node::Environment::GetCurrent(context), nullptr);
EXPECT_EQ(node::Environment::GetCurrent(isolate_), nullptr);
}

static void at_exit_callback1(void* arg) {
called_cb_1 = true;
if (arg) {
Expand Down