diff --git a/src/README.md b/src/README.md index a97e1b9ba52e8f..a40162ef819c35 100644 --- a/src/README.md +++ b/src/README.md @@ -344,8 +344,6 @@ Typical ways of accessing the current `Environment` in the Node.js code are: This requires that `context` has been associated with the `Environment` instance, e.g. is the main `Context` for the `Environment` or one of its `vm.Context`s. -* Given an [`Isolate`][], using `Environment::GetCurrent(isolate)`. This looks - up the current [`Context`][] and then uses that. diff --git a/src/api/async_resource.cc b/src/api/async_resource.cc index 38d53a9aec0e58..6d0dcabdd00d11 100644 --- a/src/api/async_resource.cc +++ b/src/api/async_resource.cc @@ -16,7 +16,7 @@ AsyncResource::AsyncResource(Isolate* isolate, Local resource, const char* name, async_id trigger_async_id) - : env_(Environment::GetCurrent(isolate)), + : env_(Environment::GetCurrent(isolate->GetCurrentContext())), resource_(isolate, resource), context_frame_(isolate, async_context_frame::current(isolate)) { CHECK_NOT_NULL(env_); diff --git a/src/api/callback.cc b/src/api/callback.cc index 6ca7cda3a5d3f1..08234c46cae598 100644 --- a/src/api/callback.cc +++ b/src/api/callback.cc @@ -22,7 +22,9 @@ using v8::Value; CallbackScope::CallbackScope(Isolate* isolate, Local object, async_context async_context) - : CallbackScope(Environment::GetCurrent(isolate), object, async_context) {} + : CallbackScope(Environment::GetCurrent(isolate->GetCurrentContext()), + object, + async_context) {} CallbackScope::CallbackScope(Environment* env, Local object, @@ -76,9 +78,8 @@ InternalCallbackScope::InternalCallbackScope(Environment* env, // likely *are* the same, in which case we can skip the slightly more // expensive Environment::GetCurrent() call. if (env->context() != current_context) [[unlikely]] { - CHECK_EQ(Environment::GetCurrent(isolate), env); + CHECK_EQ(Environment::GetCurrent(current_context), env); } - isolate->SetIdle(false); prior_context_frame_.Reset( diff --git a/src/api/environment.cc b/src/api/environment.cc index cdc0c5afb7541d..43e7a03f42639e 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -58,9 +58,8 @@ bool AllowWasmCodeGenerationCallback(Local context, bool ShouldAbortOnUncaughtException(Isolate* isolate) { DebugSealHandleScope scope(isolate); - Environment* env = Environment::GetCurrent(isolate); - return env != nullptr && - (env->is_main_thread() || !env->is_stopping()) && + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); + return env != nullptr && (env->is_main_thread() || !env->is_stopping()) && env->abort_on_uncaught_exception() && env->should_abort_on_uncaught_toggle()[0] && !env->inside_should_not_abort_on_uncaught_scope(); diff --git a/src/api/exceptions.cc b/src/api/exceptions.cc index 871fe78de95154..69437c55ec428d 100644 --- a/src/api/exceptions.cc +++ b/src/api/exceptions.cc @@ -25,7 +25,7 @@ Local ErrnoException(Isolate* isolate, const char* syscall, const char* msg, const char* path) { - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); CHECK_NOT_NULL(env); Local e; @@ -94,7 +94,7 @@ Local UVException(Isolate* isolate, const char* msg, const char* path, const char* dest) { - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); CHECK_NOT_NULL(env); if (!msg || !msg[0]) diff --git a/src/api/hooks.cc b/src/api/hooks.cc index f74950ae3de219..7fa545ce263878 100644 --- a/src/api/hooks.cc +++ b/src/api/hooks.cc @@ -1,7 +1,7 @@ +#include "async_wrap.h" #include "env-inl.h" #include "node_internals.h" #include "node_process-inl.h" -#include "async_wrap.h" namespace node { @@ -127,10 +127,8 @@ struct ACHHandle final { // this. void DeleteACHHandle::operator ()(ACHHandle* handle) const { delete handle; } -void AddEnvironmentCleanupHook(Isolate* isolate, - CleanupHook fun, - void* arg) { - Environment* env = Environment::GetCurrent(isolate); +void AddEnvironmentCleanupHook(Isolate* isolate, CleanupHook fun, void* arg) { + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); CHECK_NOT_NULL(env); env->AddCleanupHook(fun, arg); } @@ -138,7 +136,7 @@ void AddEnvironmentCleanupHook(Isolate* isolate, void RemoveEnvironmentCleanupHook(Isolate* isolate, CleanupHook fun, void* arg) { - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); CHECK_NOT_NULL(env); env->RemoveCleanupHook(fun, arg); } @@ -158,11 +156,10 @@ static void RunAsyncCleanupHook(void* arg) { info->fun(info->arg, FinishAsyncCleanupHook, info); } -ACHHandle* AddEnvironmentCleanupHookInternal( - Isolate* isolate, - AsyncCleanupHook fun, - void* arg) { - Environment* env = Environment::GetCurrent(isolate); +ACHHandle* AddEnvironmentCleanupHookInternal(Isolate* isolate, + AsyncCleanupHook fun, + void* arg) { + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); CHECK_NOT_NULL(env); auto info = std::make_shared(); info->env = env; @@ -191,7 +188,7 @@ void RequestInterrupt(Environment* env, void (*fun)(void* arg), void* arg) { } async_id AsyncHooksGetExecutionAsyncId(Isolate* isolate) { - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); if (env == nullptr) return -1; return env->execution_async_id(); } @@ -203,12 +200,11 @@ async_id AsyncHooksGetExecutionAsyncId(Local context) { } async_id AsyncHooksGetTriggerAsyncId(Isolate* isolate) { - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); if (env == nullptr) return -1; return env->trigger_async_id(); } - async_context EmitAsyncInit(Isolate* isolate, Local resource, const char* name, @@ -225,7 +221,7 @@ async_context EmitAsyncInit(Isolate* isolate, Local name, async_id trigger_async_id) { DebugSealHandleScope handle_scope(isolate); - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); CHECK_NOT_NULL(env); // Initialize async context struct @@ -245,7 +241,8 @@ async_context EmitAsyncInit(Isolate* isolate, } void EmitAsyncDestroy(Isolate* isolate, async_context asyncContext) { - EmitAsyncDestroy(Environment::GetCurrent(isolate), asyncContext); + EmitAsyncDestroy(Environment::GetCurrent(isolate->GetCurrentContext()), + asyncContext); } void EmitAsyncDestroy(Environment* env, async_context asyncContext) { diff --git a/src/async_context_frame.cc b/src/async_context_frame.cc index d96f8ee95eb0d1..ee634a987f2e33 100644 --- a/src/async_context_frame.cc +++ b/src/async_context_frame.cc @@ -38,7 +38,7 @@ Local current(Isolate* isolate) { } void set(Isolate* isolate, Local value) { - auto env = Environment::GetCurrent(isolate); + auto env = Environment::GetCurrent(isolate->GetCurrentContext()); if (!env->options()->async_context_frame) { return; } diff --git a/src/env-inl.h b/src/env-inl.h index 9b8d8f6ab070ff..47250b8af3ff56 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -174,13 +174,6 @@ inline bool TickInfo::has_rejection_to_warn() const { return fields_[kHasRejectionToWarn] == 1; } -inline Environment* Environment::GetCurrent(v8::Isolate* isolate) { - if (!isolate->InContext()) [[unlikely]] - return nullptr; - v8::HandleScope handle_scope(isolate); - return GetCurrent(isolate->GetCurrentContext()); -} - inline Environment* Environment::GetCurrent(v8::Local context) { if (!ContextEmbedderTag::IsNodeContext(context)) [[unlikely]] { return nullptr; diff --git a/src/env.h b/src/env.h index b428f5937b96fd..81c39ded4dc2ab 100644 --- a/src/env.h +++ b/src/env.h @@ -643,7 +643,6 @@ class Environment final : public MemoryRetainer { inline void PushAsyncCallbackScope(); inline void PopAsyncCallbackScope(); - static inline Environment* GetCurrent(v8::Isolate* isolate); static inline Environment* GetCurrent(v8::Local context); static inline Environment* GetCurrent( const v8::FunctionCallbackInfo& info); diff --git a/src/node_buffer.cc b/src/node_buffer.cc index f6329856e6ea93..3188168eac9fa3 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -290,7 +290,7 @@ MaybeLocal New(Isolate* isolate, Local ab, size_t byte_offset, size_t length) { - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); if (env == nullptr) { THROW_ERR_BUFFER_CONTEXT_NOT_AVAILABLE(isolate); return MaybeLocal(); @@ -348,7 +348,7 @@ MaybeLocal New(Isolate* isolate, MaybeLocal New(Isolate* isolate, size_t length) { EscapableHandleScope handle_scope(isolate); Local obj; - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); if (env == nullptr) { THROW_ERR_BUFFER_CONTEXT_NOT_AVAILABLE(isolate); return MaybeLocal(); @@ -389,7 +389,7 @@ MaybeLocal New(Environment* env, size_t length) { MaybeLocal Copy(Isolate* isolate, const char* data, size_t length) { EscapableHandleScope handle_scope(isolate); - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); if (env == nullptr) { THROW_ERR_BUFFER_CONTEXT_NOT_AVAILABLE(isolate); return MaybeLocal(); @@ -434,7 +434,7 @@ MaybeLocal New(Isolate* isolate, FreeCallback callback, void* hint) { EscapableHandleScope handle_scope(isolate); - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); if (env == nullptr) { callback(data, hint); THROW_ERR_BUFFER_CONTEXT_NOT_AVAILABLE(isolate); @@ -478,7 +478,7 @@ MaybeLocal New(Environment* env, // necessarily isolate's ArrayBuffer::Allocator. MaybeLocal New(Isolate* isolate, char* data, size_t length) { EscapableHandleScope handle_scope(isolate); - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); if (env == nullptr) { free(data); THROW_ERR_BUFFER_CONTEXT_NOT_AVAILABLE(isolate); diff --git a/src/node_errors.cc b/src/node_errors.cc index 5f51add4cdf68a..bb6f77c193f514 100644 --- a/src/node_errors.cc +++ b/src/node_errors.cc @@ -101,7 +101,7 @@ static std::string GetErrorSource(Isolate* isolate, // If source maps have been enabled, the exception line will instead be // added in the JavaScript context: - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(context); const bool has_source_map_url = !message->GetScriptOrigin().SourceMapUrl().IsEmpty() && !message->GetScriptOrigin().SourceMapUrl()->IsUndefined(); @@ -1017,9 +1017,10 @@ const char* errno_string(int errorno) { void PerIsolateMessageListener(Local message, Local error) { Isolate* isolate = message->GetIsolate(); + auto context = isolate->GetCurrentContext(); switch (message->ErrorLevel()) { case Isolate::MessageErrorLevel::kMessageWarning: { - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(context); if (!env) { break; } @@ -1028,7 +1029,7 @@ void PerIsolateMessageListener(Local message, Local error) { std::stringstream warning; warning << *filename; warning << ":"; - warning << message->GetLineNumber(env->context()).FromMaybe(-1); + warning << message->GetLineNumber(context).FromMaybe(-1); warning << " "; v8::String::Utf8Value msg(isolate, message->Get()); warning << *msg; @@ -1086,7 +1087,7 @@ static void NoSideEffectsToString(const FunctionCallbackInfo& args) { static void TriggerUncaughtException(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); Local exception = args[0]; Local message = Exception::CreateMessage(isolate, exception); if (env != nullptr && env->abort_on_uncaught_exception()) { diff --git a/src/node_platform.cc b/src/node_platform.cc index a4def82142d8b7..33c58efe4202c3 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -539,10 +539,9 @@ int NodePlatform::NumberOfWorkerThreads() { void PerIsolatePlatformData::RunForegroundTask(std::unique_ptr task) { if (isolate_->IsExecutionTerminating()) return; - DebugSealHandleScope scope(isolate_); - Environment* env = Environment::GetCurrent(isolate_); + v8::HandleScope scope(isolate_); + Environment* env = Environment::GetCurrent(isolate_->GetCurrentContext()); if (env != nullptr) { - v8::HandleScope scope(isolate_); InternalCallbackScope cb_scope(env, Object::New(isolate_), { 0, 0 }, InternalCallbackScope::kNoFlags); task->Run(); diff --git a/src/node_report.cc b/src/node_report.cc index c64fc1a2d5f08f..eb69f972973fdb 100644 --- a/src/node_report.cc +++ b/src/node_report.cc @@ -14,8 +14,8 @@ #include #else // !_WIN32 #include -#include #include +#include #endif #include @@ -965,7 +965,7 @@ std::string TriggerNodeReport(Isolate* isolate, Local error) { Environment* env = nullptr; if (isolate != nullptr) { - env = Environment::GetCurrent(isolate); + env = Environment::GetCurrent(isolate->GetCurrentContext()); } return TriggerNodeReport(isolate, env, message, trigger, name, error); } @@ -992,7 +992,7 @@ void GetNodeReport(Isolate* isolate, std::ostream& out) { Environment* env = nullptr; if (isolate != nullptr) { - env = Environment::GetCurrent(isolate); + env = Environment::GetCurrent(isolate->GetCurrentContext()); } bool exclude_network = env != nullptr ? env->options()->report_exclude_network : per_process::cli_options->per_isolate diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index 0295ee4ff2f739..03d665009c1a36 100644 --- a/src/node_sqlite.cc +++ b/src/node_sqlite.cc @@ -118,7 +118,7 @@ inline MaybeLocal CreateSQLiteError(Isolate* isolate, const char* message) { Local js_msg; Local e; - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); if (!String::NewFromUtf8(isolate, message).ToLocal(&js_msg) || !Exception::Error(js_msg) ->ToObject(isolate->GetCurrentContext()) @@ -136,7 +136,7 @@ inline MaybeLocal CreateSQLiteError(Isolate* isolate, int errcode) { const char* errstr = sqlite3_errstr(errcode); Local js_errmsg; Local e; - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); if (!String::NewFromUtf8(isolate, errstr).ToLocal(&js_errmsg) || !CreateSQLiteError(isolate, errstr).ToLocal(&e) || e->Set(env->context(), @@ -155,7 +155,7 @@ inline MaybeLocal CreateSQLiteError(Isolate* isolate, sqlite3* db) { const char* errmsg = sqlite3_errmsg(db); Local js_errmsg; Local e; - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); if (!String::NewFromUtf8(isolate, errstr).ToLocal(&js_errmsg) || !CreateSQLiteError(isolate, errmsg).ToLocal(&e) || e->Set(isolate->GetCurrentContext(), @@ -225,7 +225,7 @@ inline void THROW_ERR_SQLITE_ERROR(Isolate* isolate, const char* message) { inline void THROW_ERR_SQLITE_ERROR(Isolate* isolate, int errcode) { const char* errstr = sqlite3_errstr(errcode); - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); Local error; if (CreateSQLiteError(isolate, errstr).ToLocal(&error) && error diff --git a/src/node_task_queue.cc b/src/node_task_queue.cc index 0a5aba6e31fa79..ef92f6c48e0208 100644 --- a/src/node_task_queue.cc +++ b/src/node_task_queue.cc @@ -51,7 +51,7 @@ void PromiseRejectCallback(PromiseRejectMessage message) { Isolate* isolate = promise->GetIsolate(); PromiseRejectEvent event = message.GetEvent(); - Environment* env = Environment::GetCurrent(isolate); + Environment* env = Environment::GetCurrent(isolate->GetCurrentContext()); if (env == nullptr || !env->can_call_into_js()) return; diff --git a/src/node_url_pattern.cc b/src/node_url_pattern.cc index e84e9b0de9ab20..cdee525d0aeb54 100644 --- a/src/node_url_pattern.cc +++ b/src/node_url_pattern.cc @@ -76,7 +76,7 @@ std::optional URLPatternRegexProvider::create_instance(std::string_view pattern, bool ignore_case) { auto isolate = Isolate::GetCurrent(); - auto env = Environment::GetCurrent(isolate); + auto env = Environment::GetCurrent(isolate->GetCurrentContext()); int flags = RegExp::Flags::kUnicodeSets | RegExp::Flags::kDotAll; if (ignore_case) { flags |= static_cast(RegExp::Flags::kIgnoreCase); @@ -100,7 +100,7 @@ URLPatternRegexProvider::create_instance(std::string_view pattern, bool URLPatternRegexProvider::regex_match(std::string_view input, const regex_type& pattern) { auto isolate = Isolate::GetCurrent(); - auto env = Environment::GetCurrent(isolate); + auto env = Environment::GetCurrent(isolate->GetCurrentContext()); Local local_input; if (!String::NewFromUtf8( isolate, input.data(), NewStringType::kNormal, input.size()) @@ -121,7 +121,7 @@ std::optional>> URLPatternRegexProvider::regex_search(std::string_view input, const regex_type& global_pattern) { auto isolate = Isolate::GetCurrent(); - auto env = Environment::GetCurrent(isolate); + auto env = Environment::GetCurrent(isolate->GetCurrentContext()); Local local_input; if (!String::NewFromUtf8( isolate, input.data(), NewStringType::kNormal, input.size()) diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc index f57e638f80064e..398808f8b6ef22 100644 --- a/test/cctest/test_environment.cc +++ b/test/cctest/test_environment.cc @@ -1,13 +1,13 @@ +#include "libplatform/libplatform.h" #include "node_buffer.h" #include "node_internals.h" -#include "libplatform/libplatform.h" #include "util.h" +#include +#include #include #include "gtest/gtest.h" #include "node_test_fixture.h" -#include -#include using node::AtExit; using node::RunAtExit; @@ -74,7 +74,7 @@ TEST_F(EnvironmentTest, EnvironmentWithoutBrowserGlobals) { TEST_F(EnvironmentTest, EnvironmentWithESMLoader) { const v8::HandleScope handle_scope(isolate_); Argv argv; - Env env {handle_scope, argv}; + Env env{handle_scope, argv}; node::Environment* envi = *env; envi->options()->experimental_vm_modules = true; @@ -89,19 +89,19 @@ TEST_F(EnvironmentTest, EnvironmentWithESMLoader) { *env, "const { SourceTextModule } = require('vm');" "(async () => {" - "const stmString = 'globalThis.importResult = import(\"\")';" - "const m = new SourceTextModule(stmString, {" - "importModuleDynamically: (async () => {" - "const m = new SourceTextModule('');" - "await m.link(() => 0);" - "await m.evaluate();" - "return m.namespace;" - "})," - "});" - "await m.link(() => 0);" - "await m.evaluate();" - "delete globalThis.importResult;" - "process.exit(0);" + "const stmString = 'globalThis.importResult = import(\"\")';" + "const m = new SourceTextModule(stmString, {" + "importModuleDynamically: (async () => {" + "const m = new SourceTextModule('');" + "await m.link(() => 0);" + "await m.evaluate();" + "return m.namespace;" + "})," + "});" + "await m.link(() => 0);" + "await m.evaluate();" + "delete globalThis.importResult;" + "process.exit(0);" "})()"); } @@ -135,7 +135,7 @@ TEST_F(EnvironmentTest, EnvironmentWithNoESMLoader) { RedirectStdErr redirect_scope("environment_test.log"); const v8::HandleScope handle_scope(isolate_); Argv argv; - Env env {handle_scope, argv, node::EnvironmentFlags::kNoRegisterESMLoader}; + Env env{handle_scope, argv, node::EnvironmentFlags::kNoRegisterESMLoader}; node::Environment* envi = *env; envi->options()->experimental_vm_modules = true; @@ -150,39 +150,40 @@ TEST_F(EnvironmentTest, EnvironmentWithNoESMLoader) { *env, "const { SourceTextModule } = require('vm');" "(async () => {" - "const stmString = 'globalThis.importResult = import(\"\")';" - "const m = new SourceTextModule(stmString, {" - "importModuleDynamically: (async () => {" - "const m = new SourceTextModule('');" - "await m.link(() => 0);" - "await m.evaluate();" - "return m.namespace;" - "})," - "});" - "await m.link(() => 0);" - "await m.evaluate();" - "delete globalThis.importResult;" + "const stmString = 'globalThis.importResult = import(\"\")';" + "const m = new SourceTextModule(stmString, {" + "importModuleDynamically: (async () => {" + "const m = new SourceTextModule('');" + "await m.link(() => 0);" + "await m.evaluate();" + "return m.namespace;" + "})," + "});" + "await m.link(() => 0);" + "await m.evaluate();" + "delete globalThis.importResult;" "})()"); } TEST_F(EnvironmentTest, PreExecutionPreparation) { const v8::HandleScope handle_scope(isolate_); const Argv argv; - Env env {handle_scope, argv}; + Env env{handle_scope, argv}; - node::LoadEnvironment(*env, [&](const node::StartExecutionCallbackInfo& info) - -> v8::MaybeLocal { - return v8::Null(isolate_); - }); + node::LoadEnvironment( + *env, + [&](const node::StartExecutionCallbackInfo& info) + -> v8::MaybeLocal { return v8::Null(isolate_); }); v8::Local context = isolate_->GetCurrentContext(); const char* run_script = "process.argv0"; - v8::Local script = v8::Script::Compile( - context, - v8::String::NewFromOneByte(isolate_, - reinterpret_cast(run_script)) - .ToLocalChecked()) - .ToLocalChecked(); + v8::Local script = + v8::Script::Compile( + context, + v8::String::NewFromOneByte( + isolate_, reinterpret_cast(run_script)) + .ToLocalChecked()) + .ToLocalChecked(); v8::Local result = script->Run(context).ToLocalChecked(); CHECK(result->IsString()); } @@ -190,28 +191,30 @@ TEST_F(EnvironmentTest, PreExecutionPreparation) { TEST_F(EnvironmentTest, LoadEnvironmentWithCallback) { const v8::HandleScope handle_scope(isolate_); const Argv argv; - Env env {handle_scope, argv}; + Env env{handle_scope, argv}; v8::Local context = isolate_->GetCurrentContext(); bool called_cb = false; - node::LoadEnvironment(*env, - [&](const node::StartExecutionCallbackInfo& info) - -> v8::MaybeLocal { - called_cb = true; - - CHECK(info.process_object->IsObject()); - CHECK(info.native_require->IsFunction()); - - v8::Local argv0 = info.process_object->Get( - context, - v8::String::NewFromOneByte( - isolate_, - reinterpret_cast("argv0")) - .ToLocalChecked()).ToLocalChecked(); - CHECK(argv0->IsString()); - - return info.process_object; - }); + node::LoadEnvironment( + *env, + [&](const node::StartExecutionCallbackInfo& info) + -> v8::MaybeLocal { + called_cb = true; + + CHECK(info.process_object->IsObject()); + CHECK(info.native_require->IsFunction()); + + v8::Local argv0 = + info.process_object + ->Get(context, + v8::String::NewFromOneByte( + isolate_, reinterpret_cast("argv0")) + .ToLocalChecked()) + .ToLocalChecked(); + CHECK(argv0->IsString()); + + return info.process_object; + }); CHECK(called_cb); } @@ -219,34 +222,34 @@ TEST_F(EnvironmentTest, LoadEnvironmentWithCallback) { TEST_F(EnvironmentTest, LoadEnvironmentWithSource) { const v8::HandleScope handle_scope(isolate_); const Argv argv; - Env env {handle_scope, argv}; + Env env{handle_scope, argv}; v8::Local context = isolate_->GetCurrentContext(); v8::Local main_ret = - node::LoadEnvironment(*env, - "return { process, require };").ToLocalChecked(); + node::LoadEnvironment(*env, "return { process, require };") + .ToLocalChecked(); CHECK(main_ret->IsObject()); - CHECK(main_ret.As()->Get( - context, - v8::String::NewFromOneByte( - isolate_, - reinterpret_cast("process")) - .ToLocalChecked()) - .ToLocalChecked()->IsObject()); - CHECK(main_ret.As()->Get( - context, - v8::String::NewFromOneByte( - isolate_, - reinterpret_cast("require")) - .ToLocalChecked()) - .ToLocalChecked()->IsFunction()); + CHECK(main_ret.As() + ->Get(context, + v8::String::NewFromOneByte( + isolate_, reinterpret_cast("process")) + .ToLocalChecked()) + .ToLocalChecked() + ->IsObject()); + CHECK(main_ret.As() + ->Get(context, + v8::String::NewFromOneByte( + isolate_, reinterpret_cast("require")) + .ToLocalChecked()) + .ToLocalChecked() + ->IsFunction()); } TEST_F(EnvironmentTest, AtExitWithEnvironment) { const v8::HandleScope handle_scope(isolate_); const Argv argv; - Env env {handle_scope, argv}; + Env env{handle_scope, argv}; AtExit(*env, at_exit_callback1, nullptr); RunAtExit(*env); @@ -256,7 +259,7 @@ TEST_F(EnvironmentTest, AtExitWithEnvironment) { TEST_F(EnvironmentTest, AtExitOrder) { const v8::HandleScope handle_scope(isolate_); const Argv argv; - Env env {handle_scope, argv}; + Env env{handle_scope, argv}; // Test that callbacks are run in reverse order. AtExit(*env, at_exit_callback_ordered1, nullptr); @@ -269,7 +272,7 @@ TEST_F(EnvironmentTest, AtExitOrder) { TEST_F(EnvironmentTest, AtExitWithArgument) { const v8::HandleScope handle_scope(isolate_); const Argv argv; - Env env {handle_scope, argv}; + Env env{handle_scope, argv}; std::string arg{"some args"}; AtExit(*env, at_exit_callback1, static_cast(&arg)); @@ -280,7 +283,7 @@ TEST_F(EnvironmentTest, AtExitWithArgument) { TEST_F(EnvironmentTest, AtExitRunsJS) { const v8::HandleScope handle_scope(isolate_); const Argv argv; - Env env {handle_scope, argv}; + Env env{handle_scope, argv}; AtExit(*env, at_exit_js, static_cast(isolate_)); EXPECT_FALSE(called_at_exit_js); @@ -292,8 +295,8 @@ TEST_F(EnvironmentTest, MultipleEnvironmentsPerIsolate) { const v8::HandleScope handle_scope(isolate_); const Argv argv; // Only one of the Environments can have default flags and own the inspector. - Env env1 {handle_scope, argv}; - Env env2 {handle_scope, argv, node::EnvironmentFlags::kNoFlags}; + Env env1{handle_scope, argv}; + Env env2{handle_scope, argv, node::EnvironmentFlags::kNoFlags}; AtExit(*env1, at_exit_callback1, nullptr); AtExit(*env2, at_exit_callback2, nullptr); @@ -310,35 +313,30 @@ TEST_F(EnvironmentTest, NoEnvironmentSanity) { v8::Local context = v8::Context::New(isolate_); EXPECT_EQ(node::Environment::GetCurrent(context), nullptr); EXPECT_EQ(node::GetCurrentEnvironment(context), nullptr); - EXPECT_EQ(node::Environment::GetCurrent(isolate_), nullptr); v8::Context::Scope context_scope(context); EXPECT_EQ(node::Environment::GetCurrent(context), nullptr); EXPECT_EQ(node::GetCurrentEnvironment(context), nullptr); - EXPECT_EQ(node::Environment::GetCurrent(isolate_), nullptr); } TEST_F(EnvironmentTest, NonNodeJSContext) { const v8::HandleScope handle_scope(isolate_); const Argv argv; - Env test_env {handle_scope, argv}; + Env test_env{handle_scope, argv}; EXPECT_EQ(node::Environment::GetCurrent(v8::Local()), nullptr); node::Environment* env = *test_env; - EXPECT_EQ(node::Environment::GetCurrent(isolate_), env); EXPECT_EQ(node::Environment::GetCurrent(env->context()), env); EXPECT_EQ(node::GetCurrentEnvironment(env->context()), env); v8::Local context = v8::Context::New(isolate_); EXPECT_EQ(node::Environment::GetCurrent(context), nullptr); EXPECT_EQ(node::GetCurrentEnvironment(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::GetCurrentEnvironment(context), nullptr); - EXPECT_EQ(node::Environment::GetCurrent(isolate_), nullptr); } static void at_exit_callback1(void* arg) { @@ -378,22 +376,25 @@ TEST_F(EnvironmentTest, SetImmediateCleanup) { { const v8::HandleScope handle_scope(isolate_); const Argv argv; - Env env {handle_scope, argv}; - - node::LoadEnvironment(*env, - [&](const node::StartExecutionCallbackInfo& info) - -> v8::MaybeLocal { - return v8::Object::New(isolate_); - }); - - (*env)->SetImmediate([&](node::Environment* env_arg) { - EXPECT_EQ(env_arg, *env); - called++; - }, node::CallbackFlags::kRefed); - (*env)->SetImmediate([&](node::Environment* env_arg) { - EXPECT_EQ(env_arg, *env); - called_unref++; - }, node::CallbackFlags::kUnrefed); + Env env{handle_scope, argv}; + + node::LoadEnvironment( + *env, + [&](const node::StartExecutionCallbackInfo& info) + -> v8::MaybeLocal { return v8::Object::New(isolate_); }); + + (*env)->SetImmediate( + [&](node::Environment* env_arg) { + EXPECT_EQ(env_arg, *env); + called++; + }, + node::CallbackFlags::kRefed); + (*env)->SetImmediate( + [&](node::Environment* env_arg) { + EXPECT_EQ(env_arg, *env); + called_unref++; + }, + node::CallbackFlags::kUnrefed); } EXPECT_EQ(called, 1); @@ -412,16 +413,17 @@ TEST_F(EnvironmentTest, BufferWithFreeCallbackIsDetached) { v8::Local ab; { - Env env {handle_scope, argv}; + Env env{handle_scope, argv}; v8::Local buf_obj = node::Buffer::New( - isolate_, - hello, - sizeof(hello), - [](char* data, void* hint) { - CHECK_EQ(data, hello); - ++*static_cast(hint); - }, - &callback_calls).ToLocalChecked(); + isolate_, + hello, + sizeof(hello), + [](char* data, void* hint) { + CHECK_EQ(data, hello); + ++*static_cast(hint); + }, + &callback_calls) + .ToLocalChecked(); CHECK(buf_obj->IsUint8Array()); ab = buf_obj.As()->Buffer(); CHECK_EQ(ab->ByteLength(), sizeof(hello)); @@ -441,10 +443,11 @@ TEST_F(EnvironmentTest, InspectorMultipleEmbeddedEnvironments) { v8::Locker locker(isolate_); const v8::HandleScope handle_scope(isolate_); const Argv argv; - Env env {handle_scope, argv}; + Env env{handle_scope, argv}; v8::Local context = isolate_->GetCurrentContext(); - node::LoadEnvironment(*env, + node::LoadEnvironment( + *env, "'use strict';\n" "const { Worker } = require('worker_threads');\n" "const { Session } = require('inspector');\n" @@ -470,7 +473,7 @@ TEST_F(EnvironmentTest, InspectorMultipleEmbeddedEnvironments) { " });\n" " }));\n" "session.post('NodeWorker.enable', { waitForDebuggerOnStart: false });\n") - .ToLocalChecked(); + .ToLocalChecked(); struct ChildEnvironmentData { node::ThreadId thread_id; @@ -498,58 +501,60 @@ TEST_F(EnvironmentTest, InspectorMultipleEmbeddedEnvironments) { data.thread_stopped_async.data = &thread_stopped; uv_thread_t thread; - err = uv_thread_create(&thread, [](void* arg) { - ChildEnvironmentData* data = static_cast(arg); - std::shared_ptr aba = - node::ArrayBufferAllocator::Create(); - uv_loop_t loop; - uv_loop_init(&loop); - v8::Isolate* isolate = NewIsolate(aba, &loop, data->platform); - CHECK_NOT_NULL(isolate); - - { - v8::Locker locker(isolate); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); - - v8::Local context = node::NewContext(isolate); - CHECK(!context.IsEmpty()); - v8::Context::Scope context_scope(context); - - node::IsolateData* isolate_data = node::CreateIsolateData( - isolate, - &loop, - data->platform); - CHECK_NOT_NULL(isolate_data); - node::Environment* environment = node::CreateEnvironment( - isolate_data, - context, - { "dummy" }, - {}, - node::EnvironmentFlags::kNoFlags, - data->thread_id, - std::move(data->inspector_parent_handle)); - CHECK_NOT_NULL(environment); - - v8::Local extracted_value = LoadEnvironment( - environment, - "while (!global.variableFromParent) {}\n" - "return global.variableFromParent;").ToLocalChecked(); - - uv_run(&loop, UV_RUN_DEFAULT); - CHECK(extracted_value->IsInt32()); - data->extracted_value = extracted_value.As()->Value(); - - node::FreeEnvironment(environment); - node::FreeIsolateData(isolate_data); - } - - data->platform->DisposeIsolate(isolate); - uv_run(&loop, UV_RUN_DEFAULT); - CHECK_EQ(uv_loop_close(&loop), 0); - - uv_async_send(&data->thread_stopped_async); - }, &data); + err = uv_thread_create( + &thread, + [](void* arg) { + ChildEnvironmentData* data = static_cast(arg); + std::shared_ptr aba = + node::ArrayBufferAllocator::Create(); + uv_loop_t loop; + uv_loop_init(&loop); + v8::Isolate* isolate = NewIsolate(aba, &loop, data->platform); + CHECK_NOT_NULL(isolate); + + { + v8::Locker locker(isolate); + v8::Isolate::Scope isolate_scope(isolate); + v8::HandleScope handle_scope(isolate); + + v8::Local context = node::NewContext(isolate); + CHECK(!context.IsEmpty()); + v8::Context::Scope context_scope(context); + + node::IsolateData* isolate_data = + node::CreateIsolateData(isolate, &loop, data->platform); + CHECK_NOT_NULL(isolate_data); + node::Environment* environment = + node::CreateEnvironment(isolate_data, + context, + {"dummy"}, + {}, + node::EnvironmentFlags::kNoFlags, + data->thread_id, + std::move(data->inspector_parent_handle)); + CHECK_NOT_NULL(environment); + + v8::Local extracted_value = + LoadEnvironment(environment, + "while (!global.variableFromParent) {}\n" + "return global.variableFromParent;") + .ToLocalChecked(); + + uv_run(&loop, UV_RUN_DEFAULT); + CHECK(extracted_value->IsInt32()); + data->extracted_value = extracted_value.As()->Value(); + + node::FreeEnvironment(environment); + node::FreeIsolateData(isolate_data); + } + + data->platform->DisposeIsolate(isolate); + uv_run(&loop, UV_RUN_DEFAULT); + CHECK_EQ(uv_loop_close(&loop), 0); + + uv_async_send(&data->thread_stopped_async); + }, + &data); CHECK_EQ(err, 0); bool more; @@ -562,13 +567,13 @@ TEST_F(EnvironmentTest, InspectorMultipleEmbeddedEnvironments) { uv_thread_join(&thread); v8::Local from_inspector = - context->Global()->Get( - context, - v8::String::NewFromOneByte( - isolate_, - reinterpret_cast("messageFromWorker")) - .ToLocalChecked()) - .ToLocalChecked(); + context->Global() + ->Get(context, + v8::String::NewFromOneByte( + isolate_, + reinterpret_cast("messageFromWorker")) + .ToLocalChecked()) + .ToLocalChecked(); CHECK_EQ(data.extracted_value, 42); CHECK_EQ(from_inspector->IntegerValue(context).FromJust(), 42); } @@ -580,7 +585,7 @@ TEST_F(EnvironmentTest, ExitHandlerTest) { int callback_calls = 0; - Env env {handle_scope, argv}; + Env env{handle_scope, argv}; SetProcessExitHandler(*env, [&](node::Environment* env_, int exit_code) { EXPECT_EQ(*env, env_); EXPECT_EQ(exit_code, 42); @@ -599,20 +604,20 @@ TEST_F(EnvironmentTest, SetImmediateMicrotasks) { { const v8::HandleScope handle_scope(isolate_); const Argv argv; - Env env {handle_scope, argv}; - - node::LoadEnvironment(*env, - [&](const node::StartExecutionCallbackInfo& info) - -> v8::MaybeLocal { - return v8::Object::New(isolate_); - }); - - (*env)->SetImmediate([&](node::Environment* env_arg) { - EXPECT_EQ(env_arg, *env); - isolate_->EnqueueMicrotask([](void* arg) { - ++*static_cast(arg); - }, &called); - }, node::CallbackFlags::kRefed); + Env env{handle_scope, argv}; + + node::LoadEnvironment( + *env, + [&](const node::StartExecutionCallbackInfo& info) + -> v8::MaybeLocal { return v8::Object::New(isolate_); }); + + (*env)->SetImmediate( + [&](node::Environment* env_arg) { + EXPECT_EQ(env_arg, *env); + isolate_->EnqueueMicrotask( + [](void* arg) { ++*static_cast(arg); }, &called); + }, + node::CallbackFlags::kRefed); uv_run(¤t_loop, UV_RUN_DEFAULT); } @@ -643,25 +648,23 @@ TEST_F(NodeZeroIsolateTestFixture, CtrlCWithOnlySafeTerminationTest) { v8::Context::Scope context_scope(context); std::unique_ptr - isolate_data{node::CreateIsolateData(isolate, - ¤t_loop, - platform.get()), - node::FreeIsolateData}; + isolate_data{ + node::CreateIsolateData(isolate, ¤t_loop, platform.get()), + node::FreeIsolateData}; CHECK(isolate_data); std::unique_ptr - environment{node::CreateEnvironment(isolate_data.get(), - context, - {}, - {}), - node::FreeEnvironment}; + environment{ + node::CreateEnvironment(isolate_data.get(), context, {}, {}), + node::FreeEnvironment}; CHECK(environment); EXPECT_EQ(node::GetEnvironmentIsolateData(environment.get()), isolate_data.get()); EXPECT_EQ(node::GetArrayBufferAllocator(isolate_data.get()), nullptr); v8::Local main_ret = - node::LoadEnvironment(environment.get(), + node::LoadEnvironment( + environment.get(), "'use strict';\n" "const { runInThisContext } = require('vm');\n" "try {\n" @@ -671,7 +674,8 @@ TEST_F(NodeZeroIsolateTestFixture, CtrlCWithOnlySafeTerminationTest) { " return 'unreachable';\n" "} catch (err) {\n" " return err.code;\n" - "}").ToLocalChecked(); + "}") + .ToLocalChecked(); node::Utf8Value main_ret_str(isolate, main_ret); EXPECT_EQ(std::string(*main_ret_str), "ERR_SCRIPT_EXECUTION_INTERRUPTED"); } @@ -685,8 +689,8 @@ TEST_F(EnvironmentTest, NestedMicrotaskQueue) { const v8::HandleScope handle_scope(isolate_); const Argv argv; - std::unique_ptr queue = v8::MicrotaskQueue::New( - isolate_, v8::MicrotasksPolicy::kExplicit); + std::unique_ptr queue = + v8::MicrotaskQueue::New(isolate_, v8::MicrotasksPolicy::kExplicit); v8::Local context = v8::Context::New(isolate_, nullptr, @@ -699,58 +703,60 @@ TEST_F(EnvironmentTest, NestedMicrotaskQueue) { using IntVec = std::vector; IntVec callback_calls; - v8::Local must_call = v8::Function::New( - context, - [](const v8::FunctionCallbackInfo& info) { - IntVec* callback_calls = static_cast( - info.Data().As()->Value()); - callback_calls->push_back(info[0].As()->Value()); - }, - v8::External::New(isolate_, static_cast(&callback_calls))) + v8::Local must_call = + v8::Function::New( + context, + [](const v8::FunctionCallbackInfo& info) { + IntVec* callback_calls = + static_cast(info.Data().As()->Value()); + callback_calls->push_back(info[0].As()->Value()); + }, + v8::External::New(isolate_, static_cast(&callback_calls))) .ToLocalChecked(); - context->Global()->Set( - context, - v8::String::NewFromUtf8Literal(isolate_, "mustCall"), - must_call).Check(); + context->Global() + ->Set(context, + v8::String::NewFromUtf8Literal(isolate_, "mustCall"), + must_call) + .Check(); node::Environment* env = node::CreateEnvironment(isolate_data_, context, {}, {}); CHECK_NE(nullptr, env); - v8::Local eval_in_env = node::LoadEnvironment( - env, - "mustCall(1);\n" - "Promise.resolve().then(() => mustCall(2));\n" - "require('vm').runInNewContext(" - " 'Promise.resolve().then(() => mustCall(3))'," - " { mustCall }," - " { microtaskMode: 'afterEvaluate' }" - ");\n" - "require('vm').runInNewContext(" - " 'Promise.resolve().then(() => mustCall(4))'," - " { mustCall }" - ");\n" - "setTimeout(() => {" - " Promise.resolve().then(() => mustCall(5));" - "}, 10);\n" - "mustCall(6);\n" - "return eval;\n").ToLocalChecked().As(); - EXPECT_EQ(callback_calls, (IntVec { 1, 3, 6, 2, 4 })); + v8::Local eval_in_env = + node::LoadEnvironment(env, + "mustCall(1);\n" + "Promise.resolve().then(() => mustCall(2));\n" + "require('vm').runInNewContext(" + " 'Promise.resolve().then(() => mustCall(3))'," + " { mustCall }," + " { microtaskMode: 'afterEvaluate' }" + ");\n" + "require('vm').runInNewContext(" + " 'Promise.resolve().then(() => mustCall(4))'," + " { mustCall }" + ");\n" + "setTimeout(() => {" + " Promise.resolve().then(() => mustCall(5));" + "}, 10);\n" + "mustCall(6);\n" + "return eval;\n") + .ToLocalChecked() + .As(); + EXPECT_EQ(callback_calls, (IntVec{1, 3, 6, 2, 4})); v8::Local queue_microtask_code = v8::String::NewFromUtf8Literal( isolate_, "queueMicrotask(() => mustCall(7));"); - eval_in_env->Call(context, - v8::Null(isolate_), - 1, - &queue_microtask_code).ToLocalChecked(); - EXPECT_EQ(callback_calls, (IntVec { 1, 3, 6, 2, 4 })); + eval_in_env->Call(context, v8::Null(isolate_), 1, &queue_microtask_code) + .ToLocalChecked(); + EXPECT_EQ(callback_calls, (IntVec{1, 3, 6, 2, 4})); isolate_->PerformMicrotaskCheckpoint(); - EXPECT_EQ(callback_calls, (IntVec { 1, 3, 6, 2, 4 })); + EXPECT_EQ(callback_calls, (IntVec{1, 3, 6, 2, 4})); queue->PerformCheckpoint(isolate_); - EXPECT_EQ(callback_calls, (IntVec { 1, 3, 6, 2, 4, 7 })); + EXPECT_EQ(callback_calls, (IntVec{1, 3, 6, 2, 4, 7})); int exit_code = SpinEventLoop(env).FromJust(); EXPECT_EQ(exit_code, 0); - EXPECT_EQ(callback_calls, (IntVec { 1, 3, 6, 2, 4, 7, 5 })); + EXPECT_EQ(callback_calls, (IntVec{1, 3, 6, 2, 4, 7, 5})); node::FreeEnvironment(env); }