Skip to content

Conversation

@anonrig
Copy link
Member

Removes Environment::GetCurrent(isolate) calls

cc @nodejs/cpp-reviewers

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/sqlite

@nodejs-github-botnodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels May 13, 2025
@anonriganonrigforce-pushed the yagiz/refactor-environment-getcurrent branch 2 times, most recently from 3f4dfa8 to 9a1be50CompareMay 13, 2025 13:58
@codecov
Copy link

codecovbot commented May 13, 2025

Codecov Report

❌ Patch coverage is 88.09524% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.68%. Comparing base (2281a04) to head (ea46cf2).
⚠️ Report is 1479 commits behind head on main.

Files with missing linesPatch %Lines
src/api/hooks.cc80.00%2 Missing ⚠️
src/api/callback.cc75.00%0 Missing and 1 partial ⚠️
src/api/environment.cc50.00%0 Missing and 1 partial ⚠️
src/node_buffer.cc80.00%1 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #58311 +/- ## ========================================== - Coverage 90.21% 89.68% -0.54%  ========================================== Files 633 633 Lines 186834 186832 -2 Branches 36683 36363 -320 ========================================== - Hits 168549 167556 -993 - Misses 11089 12023 +934 - Partials 7196 7253 +57 
Files with missing linesCoverage Δ
src/api/async_resource.cc95.23% <100.00%> (ø)
src/api/exceptions.cc90.69% <100.00%> (-3.49%)⬇️
src/async_context_frame.cc100.00% <100.00%> (ø)
src/env-inl.h94.11% <ø> (-0.08%)⬇️
src/env.h98.14% <ø> (ø)
src/node_errors.cc64.23% <100.00%> (+0.05%)⬆️
src/node_platform.cc76.00% <100.00%> (-0.24%)⬇️
src/node_report.cc93.23% <100.00%> (ø)
src/node_sqlite.cc80.58% <100.00%> (ø)
src/node_task_queue.cc83.48% <100.00%> (-0.92%)⬇️
... and 5 more

... and 95 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@anonriganonrigforce-pushed the yagiz/refactor-environment-getcurrent branch from 9a1be50 to ea46cf2CompareMay 13, 2025 15:34
@jasnelljasnell added the semver-major PRs that contain breaking changes and should be released in the next major version. label May 17, 2025
Copy link
Member

@jasnelljasnell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defensively marking this semver-major as this may be an ABI-breaking changing. Environment is used via node.h and directly depended on by native addons that might be using this method. Instead of removing right away we likely need to take it through a proper deprecation cycle.

Putting the red x on this until the possible downstream impact can be determined.

@targos
Copy link
Member

@jasnell I don't think what you wrote is correct. env.h only declares Environment to use it as a pointer. We don't expose env.h in the public headers.

classEnvironment;

@jasnell
Copy link
Member

While that is true, native addons do make use of Environment directly. A quick search on cs.github.com reveals a number of native addons that directly use this API.

@targos
Copy link
Member

Can you post a couple examples ?

@jasnell
Copy link
Member

@anonrig
Copy link
MemberAuthor

anonrig commented May 19, 2025

https://github.com/search?type=code&q=%22node%3A%3AEnvironment%3A%3AGetCurrent%28%22+language%3AC%2B%2B&l=C%2B%2B

I see that most usage comes from Electron. Although, this might look like a breaking change, this function isn't exposed using similar. I wonder if semver-major holds for functions that are not publicly exposed.

The reason I want to remove this because this is an anti-pattern. Removing isolate constructor, and accessing through isolate's context gives the same outcome, but gives the option to create a handleScope or not, to the user.

My 2 cents, it to move forward with this, and later put environment into slow/fast path callback data, and eventually getting rid of similar usages (and potentially limiting the creation scope of environment object)

@nodejs/tsc any input is appreciated

@targos
Copy link
Member

It's not clear to me that there are legitimate native addons in the search result. I only see Node.js source code and Electron source code.

@jasnell
Copy link
Member

Electron's use doesn't count? At this point I'm not comfortable lifting my -1 on this. I think it should go through at least a deprecation cycle (deprecate now, removed only after the next major release)

@joyeecheung
Copy link
Member

joyeecheung commented May 19, 2025

If the idea is to avoid creating the HandleScope don't think the changes here do the job

and accessing through isolate's context gives the same outcome, but gives the option to create a handleScope or not, to the user.

The HandleScope is needed because the v8::Isolate::GetCurrentContext() call needs to return the context in a Local<Context> handle (as you can see from the failures), and this PR is merely inlining that call, not removing the need to create a HandleScope. The right way to avoid the HandleScope is, of course, avoid creating any handles, which includes avoiding calling v8::Isolate::GetCurrentContext() at all - or not depending on any context since contexts are passed around in handles for that matter. Environment::GetCurrent(isolate) is just one of the many things that call v8::Isolate::GetCurrentContext(). The problem for fast API is not Environment, it's the context, and you are only seeing it from Environment::GetCurrent since the Envrionment is looked up from the context.

The reason I want to remove this because this is an anti-pattern.

I think the anti-pattern is to require an Environment when all the binding needs is only the isolate, or the context. If the binding really needs an Environment/the context (many of the code being touched here do) then a HandleScope must still be created to hold Local<Context>. But if it just needs the isolate or if it doesn't even need the isolate then it doesn't need an Environment or a context or a HandleScope. The bindings being touched here still rely on the Environment and the context so it doesn't really improve much other than making the code more verbose and making it crash since it's not safe to create Local<Context> without a handle scope.

constchar* name,
async_id trigger_async_id)
: env_(Environment::GetCurrent(isolate)),
: env_(Environment::GetCurrent(isolate->GetCurrentContext())),
Copy link
Member

@joyeecheungjoyeecheungMay 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, this is not doing what the comment above claims. The code here still needs the Environment, therefore it still needs to look it up from the context, therefore it still needs a HandleScope. It's not up to the caller to choose to create it or not - if it doesn't, V8 can just crash.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++Issues and PRs that require attention from people who are familiar with C++.lib / srcIssues and PRs related to general changes in the lib or src directory.needs-ciPRs that need a full CI run.semver-majorPRs that contain breaking changes and should be released in the next major version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@anonrig@nodejs-github-bot@targos@jasnell@joyeecheung@legendecas