Skip to content

Commit 5d5c3fa

Browse files
addaleaxtargos
authored andcommitted
src: refactor Environment::GetCurrent() usage
Make `Environment::GetCurrent()` return `nullptr` if the current `Context` is not a Node.js context, and for the relevant usage of this function, either: - Switch to the better `GetCurrent(args)` variant - Turn functions in to no-ops where it makes sense - Make it a `CHECK`, i.e. an API requirement, where it make sense - Leave a `TODO` comment for verifying what, if anything, is to be done PR-URL: #22819 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Gireesh Punathil <[email protected]> Reviewed-By: Eugene Ostroukhov <[email protected]> Reviewed-By: Refael Ackermann <[email protected]>
1 parent 5c5d881 commit 5d5c3fa

15 files changed

+82
-38
lines changed

src/async_wrap.cc

+7-2
Original file line numberDiff line numberDiff line change
@@ -681,12 +681,16 @@ MaybeLocal<Value> AsyncWrap::MakeCallback(const Local<Function> cb,
681681

682682

683683
async_id AsyncHooksGetExecutionAsyncId(Isolate* isolate) {
684-
return Environment::GetCurrent(isolate)->execution_async_id();
684+
Environment* env = Environment::GetCurrent(isolate);
685+
if (env == nullptr) return -1;
686+
return env->execution_async_id();
685687
}
686688

687689

688690
async_id AsyncHooksGetTriggerAsyncId(Isolate* isolate) {
689-
return Environment::GetCurrent(isolate)->trigger_async_id();
691+
Environment* env = Environment::GetCurrent(isolate);
692+
if (env == nullptr) return -1;
693+
return env->trigger_async_id();
690694
}
691695

692696

@@ -705,6 +709,7 @@ async_context EmitAsyncInit(Isolate* isolate,
705709
v8::Local<v8::String> name,
706710
async_id trigger_async_id) {
707711
Environment* env = Environment::GetCurrent(isolate);
712+
CHECK_NOT_NULL(env);
708713

709714
// Initialize async context struct
710715
if (trigger_async_id == -1)

src/bootstrapper.cc

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ void PromiseRejectCallback(PromiseRejectMessage message) {
6161
PromiseRejectEvent event = message.GetEvent();
6262

6363
Environment* env = Environment::GetCurrent(isolate);
64+
if (env == nullptr) return;
6465
Local<Function> callback;
6566
Local<Value> value;
6667

src/callback_scope.cc

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ InternalCallbackScope::InternalCallbackScope(Environment* env,
4343
object_(object),
4444
callback_scope_(env) {
4545
CHECK_IMPLIES(expect == kRequireResource, !object.IsEmpty());
46+
CHECK_NOT_NULL(env);
4647

4748
if (!env->can_call_into_js()) {
4849
failed_ = true;

src/env-inl.h

+9
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,15 @@ inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
302302
}
303303

304304
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
305+
if (UNLIKELY(context.IsEmpty() ||
306+
context->GetNumberOfEmbedderDataFields() <
307+
ContextEmbedderIndex::kContextTag ||
308+
context->GetAlignedPointerFromEmbedderData(
309+
ContextEmbedderIndex::kContextTag) !=
310+
Environment::kNodeContextTagPtr)) {
311+
return nullptr;
312+
}
313+
305314
return static_cast<Environment*>(
306315
context->GetAlignedPointerFromEmbedderData(
307316
ContextEmbedderIndex::kEnvironment));

src/env.cc

+2-11
Original file line numberDiff line numberDiff line change
@@ -449,18 +449,9 @@ void Environment::EnvPromiseHook(v8::PromiseHookType type,
449449
v8::Local<v8::Value> parent) {
450450
Local<v8::Context> context = promise->CreationContext();
451451

452-
// Grow the embedder data if necessary to make sure we are not out of bounds
453-
// when reading the magic number.
454-
context->SetAlignedPointerInEmbedderData(
455-
ContextEmbedderIndex::kContextTagBoundary, nullptr);
456-
int* magicNumberPtr = reinterpret_cast<int*>(
457-
context->GetAlignedPointerFromEmbedderData(
458-
ContextEmbedderIndex::kContextTag));
459-
if (magicNumberPtr != Environment::kNodeContextTagPtr) {
460-
return;
461-
}
462-
463452
Environment* env = Environment::GetCurrent(context);
453+
if (env == nullptr) return;
454+
464455
for (const PromiseHookCallback& hook : env->promise_hooks_) {
465456
hook.cb_(type, promise, parent, hook.arg_);
466457
}

src/inspector_js_api.cc

+2-3
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,11 @@ void CallAndPauseOnStart(const FunctionCallbackInfo<v8::Value>& args) {
149149
}
150150

151151
void InspectorConsoleCall(const FunctionCallbackInfo<Value>& info) {
152-
Isolate* isolate = info.GetIsolate();
153-
HandleScope handle_scope(isolate);
152+
Environment* env = Environment::GetCurrent(info);
153+
Isolate* isolate = env->isolate();
154154
Local<Context> context = isolate->GetCurrentContext();
155155
CHECK_LT(2, info.Length());
156156
SlicedArguments call_args(info, /* start */ 3);
157-
Environment* env = Environment::GetCurrent(isolate);
158157
if (InspectorEnabled(env)) {
159158
Local<Value> inspector_method = info[0];
160159
CHECK(inspector_method->IsFunction());

src/module_wrap.cc

+4-2
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ MaybeLocal<Module> ModuleWrap::ResolveCallback(Local<Context> context,
362362
Local<String> specifier,
363363
Local<Module> referrer) {
364364
Environment* env = Environment::GetCurrent(context);
365+
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
365366
Isolate* isolate = env->isolate();
366367
if (env->module_map.count(referrer->GetIdentityHash()) == 0) {
367368
env->ThrowError("linking error, unknown module");
@@ -700,6 +701,7 @@ static MaybeLocal<Promise> ImportModuleDynamically(
700701
Local<String> specifier) {
701702
Isolate* iso = context->GetIsolate();
702703
Environment* env = Environment::GetCurrent(context);
704+
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
703705
v8::EscapableHandleScope handle_scope(iso);
704706

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

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

757759
if (module_wrap == nullptr) {
@@ -762,7 +764,7 @@ void ModuleWrap::HostInitializeImportMetaObjectCallback(
762764
Local<Function> callback =
763765
env->host_initialize_import_meta_object_callback();
764766
Local<Value> args[] = { wrap, meta };
765-
callback->Call(context, Undefined(isolate), arraysize(args), args)
767+
callback->Call(context, Undefined(env->isolate()), arraysize(args), args)
766768
.ToLocalChecked();
767769
}
768770

src/node.cc

+13-4
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,8 @@ namespace {
630630
bool ShouldAbortOnUncaughtException(Isolate* isolate) {
631631
HandleScope scope(isolate);
632632
Environment* env = Environment::GetCurrent(isolate);
633-
return env->should_abort_on_uncaught_toggle()[0] &&
633+
return env != nullptr &&
634+
env->should_abort_on_uncaught_toggle()[0] &&
634635
!env->inside_should_not_abort_on_uncaught_scope();
635636
}
636637

@@ -639,13 +640,15 @@ bool ShouldAbortOnUncaughtException(Isolate* isolate) {
639640

640641
void AddPromiseHook(Isolate* isolate, promise_hook_func fn, void* arg) {
641642
Environment* env = Environment::GetCurrent(isolate);
643+
CHECK_NOT_NULL(env);
642644
env->AddPromiseHook(fn, arg);
643645
}
644646

645647
void AddEnvironmentCleanupHook(Isolate* isolate,
646648
void (*fun)(void* arg),
647649
void* arg) {
648650
Environment* env = Environment::GetCurrent(isolate);
651+
CHECK_NOT_NULL(env);
649652
env->AddCleanupHook(fun, arg);
650653
}
651654

@@ -654,6 +657,7 @@ void RemoveEnvironmentCleanupHook(Isolate* isolate,
654657
void (*fun)(void* arg),
655658
void* arg) {
656659
Environment* env = Environment::GetCurrent(isolate);
660+
CHECK_NOT_NULL(env);
657661
env->RemoveCleanupHook(fun, arg);
658662
}
659663

@@ -738,6 +742,7 @@ MaybeLocal<Value> MakeCallback(Isolate* isolate,
738742
// Because of the AssignToContext() call in src/node_contextify.cc,
739743
// the two contexts need not be the same.
740744
Environment* env = Environment::GetCurrent(callback->CreationContext());
745+
CHECK_NOT_NULL(env);
741746
Context::Scope context_scope(env->context());
742747
MaybeLocal<Value> ret = InternalMakeCallback(env, recv, callback,
743748
argc, argv, asyncContext);
@@ -1376,6 +1381,7 @@ void FatalException(Isolate* isolate,
13761381
HandleScope scope(isolate);
13771382

13781383
Environment* env = Environment::GetCurrent(isolate);
1384+
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
13791385
Local<Object> process_object = env->process_object();
13801386
Local<String> fatal_exception_string = env->fatal_exception_string();
13811387
Local<Value> fatal_exception_function =
@@ -1601,7 +1607,7 @@ static void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
16011607
}
16021608

16031609
static void GetLinkedBinding(const FunctionCallbackInfo<Value>& args) {
1604-
Environment* env = Environment::GetCurrent(args.GetIsolate());
1610+
Environment* env = Environment::GetCurrent(args);
16051611

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

@@ -2705,10 +2711,13 @@ void RunAtExit(Environment* env) {
27052711

27062712
uv_loop_t* GetCurrentEventLoop(Isolate* isolate) {
27072713
HandleScope handle_scope(isolate);
2708-
auto context = isolate->GetCurrentContext();
2714+
Local<Context> context = isolate->GetCurrentContext();
27092715
if (context.IsEmpty())
27102716
return nullptr;
2711-
return Environment::GetCurrent(context)->event_loop();
2717+
Environment* env = Environment::GetCurrent(context);
2718+
if (env == nullptr)
2719+
return nullptr;
2720+
return env->event_loop();
27122721
}
27132722

27142723

src/node_api.cc

+9-4
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@ class ThreadSafeFunction : public node::AsyncResource {
946946
return napi_ok;
947947
}
948948

949-
node::Environment::GetCurrent(env->isolate)->CloseHandle(
949+
NodeEnv()->CloseHandle(
950950
reinterpret_cast<uv_handle_t*>(&async),
951951
[](uv_handle_t* handle) -> void {
952952
ThreadSafeFunction* ts_fn =
@@ -1036,9 +1036,12 @@ class ThreadSafeFunction : public node::AsyncResource {
10361036
}
10371037

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

10441047
void MaybeStartIdle() {
@@ -1234,7 +1237,9 @@ void napi_module_register_by_symbol(v8::Local<v8::Object> exports,
12341237
v8::Local<v8::Context> context,
12351238
napi_addon_register_func init) {
12361239
if (init == nullptr) {
1237-
node::Environment::GetCurrent(context)->ThrowError(
1240+
node::Environment* node_env = node::Environment::GetCurrent(context);
1241+
CHECK_NOT_NULL(node_env);
1242+
node_env->ThrowError(
12381243
"Module has no declared entry point.");
12391244
return;
12401245
}

src/node_buffer.cc

+6-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,9 @@ MaybeLocal<Object> New(Isolate* isolate,
274274
MaybeLocal<Object> New(Isolate* isolate, size_t length) {
275275
EscapableHandleScope handle_scope(isolate);
276276
Local<Object> obj;
277-
if (Buffer::New(Environment::GetCurrent(isolate), length).ToLocal(&obj))
277+
Environment* env = Environment::GetCurrent(isolate);
278+
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
279+
if (Buffer::New(env, length).ToLocal(&obj))
278280
return handle_scope.Escape(obj);
279281
return Local<Object>();
280282
}
@@ -316,6 +318,7 @@ MaybeLocal<Object> New(Environment* env, size_t length) {
316318
MaybeLocal<Object> Copy(Isolate* isolate, const char* data, size_t length) {
317319
EscapableHandleScope handle_scope(isolate);
318320
Environment* env = Environment::GetCurrent(isolate);
321+
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
319322
Local<Object> obj;
320323
if (Buffer::Copy(env, data, length).ToLocal(&obj))
321324
return handle_scope.Escape(obj);
@@ -365,6 +368,7 @@ MaybeLocal<Object> New(Isolate* isolate,
365368
void* hint) {
366369
EscapableHandleScope handle_scope(isolate);
367370
Environment* env = Environment::GetCurrent(isolate);
371+
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
368372
Local<Object> obj;
369373
if (Buffer::New(env, data, length, callback, hint).ToLocal(&obj))
370374
return handle_scope.Escape(obj);
@@ -403,6 +407,7 @@ MaybeLocal<Object> New(Environment* env,
403407
MaybeLocal<Object> New(Isolate* isolate, char* data, size_t length) {
404408
EscapableHandleScope handle_scope(isolate);
405409
Environment* env = Environment::GetCurrent(isolate);
410+
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
406411
Local<Object> obj;
407412
if (Buffer::New(env, data, length).ToLocal(&obj))
408413
return handle_scope.Escape(obj);

src/node_context_data.h

-5
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,11 @@ namespace node {
2525
#define NODE_CONTEXT_TAG 35
2626
#endif
2727

28-
#ifndef NODE_CONTEXT_TAG_BOUNDARY
29-
#define NODE_CONTEXT_TAG_BOUNDARY 36
30-
#endif
31-
3228
enum ContextEmbedderIndex {
3329
kEnvironment = NODE_CONTEXT_EMBEDDER_DATA_INDEX,
3430
kSandboxObject = NODE_CONTEXT_SANDBOX_OBJECT_INDEX,
3531
kAllowWasmCodeGeneration = NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX,
3632
kContextTag = NODE_CONTEXT_TAG,
37-
kContextTagBoundary = NODE_CONTEXT_TAG_BOUNDARY,
3833
};
3934

4035
} // namespace node

src/node_file.cc

+4-5
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ void FSReqWrap::SetReturnValue(const FunctionCallbackInfo<Value>& args) {
431431

432432
void NewFSReqWrap(const FunctionCallbackInfo<Value>& args) {
433433
CHECK(args.IsConstructCall());
434-
Environment* env = Environment::GetCurrent(args.GetIsolate());
434+
Environment* env = Environment::GetCurrent(args);
435435
new FSReqWrap(env, args.This(), args[0]->IsTrue());
436436
}
437437

@@ -772,7 +772,7 @@ inline FSReqBase* GetReqWrap(Environment* env, Local<Value> value,
772772
}
773773

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

778778
const int argc = args.Length();
@@ -2089,9 +2089,8 @@ void Initialize(Local<Object> target,
20892089

20902090
StatWatcher::Initialize(env, target);
20912091

2092-
// Create FunctionTemplate for FSReqWrap
2093-
Local<FunctionTemplate> fst =
2094-
FunctionTemplate::New(env->isolate(), NewFSReqWrap);
2092+
// Create FunctionTemplate for FSReqCallback
2093+
Local<FunctionTemplate> fst = env->NewFunctionTemplate(NewFSReqWrap);
20952094
fst->InstanceTemplate()->SetInternalFieldCount(1);
20962095
AsyncWrap::AddWrapMethods(env, fst);
20972096
Local<String> wrapString =

src/node_internals.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,9 @@ class InternalCallbackScope {
501501

502502
class ThreadPoolWork {
503503
public:
504-
explicit inline ThreadPoolWork(Environment* env) : env_(env) {}
504+
explicit inline ThreadPoolWork(Environment* env) : env_(env) {
505+
CHECK_NOT_NULL(env);
506+
}
505507
inline virtual ~ThreadPoolWork() = default;
506508

507509
inline void ScheduleWork();

src/node_perf.cc

+1
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ void TimerFunctionCall(const FunctionCallbackInfo<Value>& args) {
310310
Isolate* isolate = args.GetIsolate();
311311
HandleScope scope(isolate);
312312
Environment* env = Environment::GetCurrent(isolate);
313+
CHECK_NOT_NULL(env); // TODO(addaleax): Verify that this is correct.
313314
Local<Context> context = env->context();
314315
Local<Function> fn = args.Data().As<Function>();
315316
size_t count = args.Length();

test/cctest/test_environment.cc

+20
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,26 @@ TEST_F(EnvironmentTest, MultipleEnvironmentsPerIsolate) {
7070
EXPECT_TRUE(called_cb_2);
7171
}
7272

73+
TEST_F(EnvironmentTest, NonNodeJSContext) {
74+
const v8::HandleScope handle_scope(isolate_);
75+
const Argv argv;
76+
Env test_env {handle_scope, argv};
77+
78+
EXPECT_EQ(node::Environment::GetCurrent(v8::Local<v8::Context>()), nullptr);
79+
80+
node::Environment* env = *test_env;
81+
EXPECT_EQ(node::Environment::GetCurrent(isolate_), env);
82+
EXPECT_EQ(node::Environment::GetCurrent(env->context()), env);
83+
84+
v8::Local<v8::Context> context = v8::Context::New(isolate_);
85+
EXPECT_EQ(node::Environment::GetCurrent(context), nullptr);
86+
EXPECT_EQ(node::Environment::GetCurrent(isolate_), env);
87+
88+
v8::Context::Scope context_scope(context);
89+
EXPECT_EQ(node::Environment::GetCurrent(context), nullptr);
90+
EXPECT_EQ(node::Environment::GetCurrent(isolate_), nullptr);
91+
}
92+
7393
static void at_exit_callback1(void* arg) {
7494
called_cb_1 = true;
7595
if (arg) {

0 commit comments

Comments
 (0)