-
Notifications
You must be signed in to change notification settings - Fork 30k
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: bootstrap internals loaders before bootstrapping Node.js #19112
Conversation
lib/internal/native_module.js
Outdated
}; | ||
} | ||
|
||
// Set up internalBinding in the closure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Come to think of it, we may also put internalBinding
in the returned object and rename this file inernal_loaders
which seem to be more accurate..so it will become const { NativeModule, internalBinding } = require('internal/internal_loaders')
(somewhat clashes with internal/loader/*
though..)
src/node.cc
Outdated
|
||
static bool ExecuteFactory(Environment* env, Local<Function> factory, int argc, | ||
Local<Value> argv[], Local<Value>* out) { | ||
bool ret = factory->Call( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This now calls into JS from C++ twice during bootstrapping..maybe passing the loader bootstrapper into the core bootstrapper and call JS from JS will lower the performance impact..are there any existing benchmarks for measuring startup time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’d expect this to be fine, tbh. It might be nice to have a single call into JS again at some point, but that doesn’t have to be a strict rule.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, great work!
lib/internal/bootstrap_node.js
Outdated
|
||
'use strict'; | ||
|
||
(function(process) { | ||
let internalBinding; | ||
(function bootstrapNodeJSCore(process, NativeModule) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m wondering whether this function name showing up is more helpful or more confusing when showing up ni embedder code…
lib/internal/native_module.js
Outdated
const bindingObj = Object.create(null); | ||
|
||
const getInternalBinding = process._internalBinding; | ||
delete process._internalBinding; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you’re at it – how about passing this to bootstrapInternalLoaders
as an argument, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, also getLinkedBinding and getBinding can be passed in as well so we don’t need to override the original property, which kind of hard to understand at first glance
src/node.cc
Outdated
|
||
static bool ExecuteFactory(Environment* env, Local<Function> factory, int argc, | ||
Local<Value> argv[], Local<Value>* out) { | ||
bool ret = factory->Call( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’d expect this to be fine, tbh. It might be nice to have a single call into JS again at some point, but that doesn’t have to be a strict rule.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I agree with @addaleax that passing in internalBinding
into native_module.js
would probably be a good idea, instead of declaring it on the process and then deleting it.
0240c6f
to
9239ca3
Compare
Updates:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still LGTM with a tiny nit.
lib/internal/bootstrap_loaders.js
Outdated
@@ -109,9 +109,12 @@ | |||
|
|||
const config = process.binding('config'); | |||
|
|||
// Think of this as module.exports in this file even though it is not | |||
// written in CommonJS style. | |||
const exports_ = { internalBinding, NativeModule }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not generally a huge fan of trailing _
variables in JS, esp since it looks similar enough to exports
. Could this be like loaderExports
or something?
i'm feeling -1ish on this with this change, is there any reason it can't be kept in the module wrapper? also we could move these two files to internal/bootstrap or internal/startup or something and remove the |
Doesn't have to move it out, but this way we have less globals in core modules and this can now be used in |
I'm +1 on having it be an export rather than a wrapper-introduced global. Given how few modules actually use it, I don't think there's a great argument for having it be a part of the wrapper. |
this makes it so that it can't be used even if --expose-internals is used, i think that was something @addaleax explicitly did/wanted with her pr, and personally i agree with that change. |
Given that (Edit: Or was it not because of the different module id?) |
That can be fixed by changing |
I don’t really care how it is exposed, but I think the argument that few modules use it shouldn’t have a strong weight, because we really should be and are moving towards using it in place of
At least I couldn’t figure out how (and thought that that was a good thing). ¯\_(ツ)_/¯ |
I like the idea of having a file named |
I just don't love globals, so the fewer, the better in my mind and the exceptions should be things that we can't really run a module without (or are just used that often). (Needless to say, I would obviously prefer if But anyway, don't have a strong opinion so I'm fine with whatever direction this ends up going in. |
actually its worse than i thought, internalBinding can be gotten without any flags on current release/master, so maybe this pr actually makes it harder to get? 😓
|
@devsnek Yes, that sounds pretty bad :/ I guess we could and should freeze |
ideally it shouldn't be exposed at all, perhaps we can deprecate and remove it? i'm worried that packages might be using this, mostly for reading, not writing (and it also seems that v8_prof_processor modifies several scripts by adding newlines to the ends of them, i'm not quite sure what to make of that) |
it should be noted that even with that last commit by joyee, native module can still be gotten with the same tomfoolery i posted above |
I’m on board with doing that, but it might be a while before we can do it – right now, the latest verions of
I think that’s still just reading, it basically concatenates them with newlines? |
- Moves the creation of `process.binding()`, `process._linkedBinding()` `internalBinding()` and `NativeModule` into a separate file `lib/internal/bootstrap_loaders.js`, and documents them there. This file will be compiled and run before `bootstrap_node.js`, which means we now bootstrap the internal module & binding system before actually bootstrapping Node.js. - Rename the special ID that can be used to require `NativeModule` as `internal/bootstrap_loaders` since it is setup there. Also put `internalBinding` in the object exported by `NativeModule.require` instead of putting it inside the `NativeModule.wrapper` - Use the original `getBinding()` to get the source code of native modules instead of getting it from `process.binding('native')` so that users cannot fake native modules by modifying the binding object. - Names the bootstrapping functions so their names show up in the stack trace. PR-URL: nodejs#19112 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Anatoli Papirovski <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Gus Caplan <[email protected]>
Otherwise the debug log output might be mixed up with the expected errors and the assertion matching the error message would fail. PR-URL: nodejs#19177 Refs: nodejs#19112 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
Create `lib/internal/bootstrap/` and put bootstrappers there: Before: ``` lib/internal ├── ... ├── bootstrap_loaders.js └── bootstrap_node.js ``` After: ``` lib/internal ├── ... └── bootstrap ├── loaders.js └── node.js ``` PR-URL: nodejs#19177 Refs: nodejs#19112 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
Create `lib/internal/modules` and restructure the module loaders to make the purpose of those files clearer. Also make it clear in the code that the object exported by `lib/internal/modules/cjs/loader.js` is `CJSModule` instead of the ambiguous `Module`. Before: ``` lib ├── ... ├── internal │ ├── loaders │ │ ├── CreateDynamicModule.js │ │ ├── DefaultResolve.js │ │ ├── Loader.js │ │ ├── ModuleJob.js │ │ ├── ModuleMap.js │ │ ├── ModuleWrap.js │ │ └── Translators.js │ └── module.js └── module.js ``` After: ``` lib ├── ... ├── internal │ ├── ... │ └── modules │ ├── cjs │ │ ├── helpers.js │ │ └── loader.js │ └── esm │ ├── CreateDynamicModule.js │ ├── DefaultResolve.js │ ├── Loader.js │ ├── ModuleJob.js │ ├── ModuleMap.js │ └── Translators.js └── module.js # deleted in this commit to work with git file mode ``` PR-URL: nodejs#19177 Refs: nodejs#19112 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
The previous commit deleted lib/module.js so that git recognize the file move `lib/module.js` -> `lib/internal/modules/cjs/loader.js`. This commit add the redirection back. PR-URL: nodejs#19177 Refs: nodejs#19112 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
- Moves the creation of `process.binding()`, `process._linkedBinding()` `internalBinding()` and `NativeModule` into a separate file `lib/internal/bootstrap_loaders.js`, and documents them there. This file will be compiled and run before `bootstrap_node.js`, which means we now bootstrap the internal module & binding system before actually bootstrapping Node.js. - Rename the special ID that can be used to require `NativeModule` as `internal/bootstrap_loaders` since it is setup there. Also put `internalBinding` in the object exported by `NativeModule.require` instead of putting it inside the `NativeModule.wrapper` - Use the original `getBinding()` to get the source code of native modules instead of getting it from `process.binding('native')` so that users cannot fake native modules by modifying the binding object. - Names the bootstrapping functions so their names show up in the stack trace. Backport-PR-URL: #19374 PR-URL: #19112 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Anatoli Papirovski <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Gus Caplan <[email protected]>
Create `lib/internal/bootstrap/` and put bootstrappers there: Before: ``` lib/internal ├── ... ├── bootstrap_loaders.js └── bootstrap_node.js ``` After: ``` lib/internal ├── ... └── bootstrap ├── loaders.js └── node.js ``` Backport-PR-URL: #19374 PR-URL: #19177 Refs: #19112 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
Otherwise the debug log output might be mixed up with the expected errors and the assertion matching the error message would fail. Backport-PR-URL: #19374 PR-URL: #19177 Refs: #19112 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
Create `lib/internal/modules` and restructure the module loaders to make the purpose of those files clearer. Also make it clear in the code that the object exported by `lib/internal/modules/cjs/loader.js` is `CJSModule` instead of the ambiguous `Module`. Before: ``` lib ├── ... ├── internal │ ├── loaders │ │ ├── CreateDynamicModule.js │ │ ├── DefaultResolve.js │ │ ├── Loader.js │ │ ├── ModuleJob.js │ │ ├── ModuleMap.js │ │ ├── ModuleWrap.js │ │ └── Translators.js │ └── module.js └── module.js ``` After: ``` lib ├── ... ├── internal │ ├── ... │ └── modules │ ├── cjs │ │ ├── helpers.js │ │ └── loader.js │ └── esm │ ├── CreateDynamicModule.js │ ├── DefaultResolve.js │ ├── Loader.js │ ├── ModuleJob.js │ ├── ModuleMap.js │ └── Translators.js └── module.js # deleted in this commit to work with git file mode ``` Backport-PR-URL: #19374 PR-URL: #19177 Refs: #19112 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
The previous commit deleted lib/module.js so that git recognize the file move `lib/module.js` -> `lib/internal/modules/cjs/loader.js`. This commit add the redirection back. Backport-PR-URL: #19374 PR-URL: #19177 Refs: #19112 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
- Moves the creation of `process.binding()`, `process._linkedBinding()` `internalBinding()` and `NativeModule` into a separate file `lib/internal/bootstrap_loaders.js`, and documents them there. This file will be compiled and run before `bootstrap_node.js`, which means we now bootstrap the internal module & binding system before actually bootstrapping Node.js. - Rename the special ID that can be used to require `NativeModule` as `internal/bootstrap_loaders` since it is setup there. Also put `internalBinding` in the object exported by `NativeModule.require` instead of putting it inside the `NativeModule.wrapper` - Use the original `getBinding()` to get the source code of native modules instead of getting it from `process.binding('native')` so that users cannot fake native modules by modifying the binding object. - Names the bootstrapping functions so their names show up in the stack trace. PR-URL: nodejs#19112 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Anatoli Papirovski <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Gus Caplan <[email protected]>
Would very much like to see this backported to v8.x along with #18365 |
- Moves the creation of `process.binding()`, `process._linkedBinding()` `internalBinding()` and `NativeModule` into a separate file `lib/internal/bootstrap_loaders.js`, and documents them there. This file will be compiled and run before `bootstrap_node.js`, which means we now bootstrap the internal module & binding system before actually bootstrapping Node.js. - Rename the special ID that can be used to require `NativeModule` as `internal/bootstrap_loaders` since it is setup there. Also put `internalBinding` in the object exported by `NativeModule.require` instead of putting it inside the `NativeModule.wrapper` - Use the original `getBinding()` to get the source code of native modules instead of getting it from `process.binding('native')` so that users cannot fake native modules by modifying the binding object. - Names the bootstrapping functions so their names show up in the stack trace. PR-URL: nodejs#19112 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Anatoli Papirovski <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Gus Caplan <[email protected]>
Otherwise the debug log output might be mixed up with the expected errors and the assertion matching the error message would fail. PR-URL: nodejs#19177 Refs: nodejs#19112 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
Create `lib/internal/bootstrap/` and put bootstrappers there: Before: ``` lib/internal ├── ... ├── bootstrap_loaders.js └── bootstrap_node.js ``` After: ``` lib/internal ├── ... └── bootstrap ├── loaders.js └── node.js ``` PR-URL: nodejs#19177 Refs: nodejs#19112 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
process.binding()
,process._linkedBinding()
internalBinding()
andNativeModule
into a separate filelib/internal/bootstrap_loaders.js
, and documents them there.This file will be compiled and run before
bootstrap_node.js
, whichmeans we now bootstrap the internal module & binding system before
actually bootstrapping Node.js.
NativeModule
as
internal/bootstrap_loaders
since it is setup there. Also putinternalBinding
in the object exported byNativeModule.require
instead of putting it inside the
NativeModule.wrapper
in the stack trace.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
process, modules