Skip to content

Commit 75d0a93

Browse files
committed
src: move more process methods initialization in bootstrap/node.js
Instead of: - Writing methods onto the process directly in C++ during `SetupProcessObject()` and overwrite with argument checks later - Or, wrapping and writing them in `internal/process/*.js` Do: - Move the C++ implementations in node_process.cc and mark them static wherever possible - Expose the C++ methods through a new `internalBinding('process_methods')` - Wrap the methods in `internal/process/*.js` in a side-effect-free manner and return them back to `internal/bootstrap/node.js` - Centralize the write to the process object based on conditions in `bootstrap/node.js` So it's easier to see what methods are attached to the process object during bootstrap under what condition and in what order. The eventual goal is to figure out the dependency of process methods and the write/read access to the process object during bootstrap, group these access properly and remove the process properties that should not be exposed to users this way. Also correct the NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE milestone which should be marked before code execution. Refs: #24961 PR-URL: #25127 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 4884ca6 commit 75d0a93

File tree

9 files changed

+322
-317
lines changed

9 files changed

+322
-317
lines changed

lib/internal/bootstrap/node.js

Lines changed: 77 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,7 @@
2020
const {
2121
_setupTraceCategoryState,
2222
_setupNextTick,
23-
_setupPromises, _chdir, _cpuUsage,
24-
_hrtime, _hrtimeBigInt,
25-
_memoryUsage, _rawDebug,
26-
_umask,
27-
_shouldAbortOnUncaughtToggle
23+
_setupPromises
2824
} = bootstrappers;
2925
const { internalBinding, NativeModule } = loaderExports;
3026

@@ -57,15 +53,57 @@ function startup() {
5753
);
5854
}
5955

60-
perThreadSetup.setupAssert();
61-
perThreadSetup.setupConfig();
56+
// process.config is serialized config.gypi
57+
process.config = JSON.parse(internalBinding('native_module').config);
6258

59+
const rawMethods = internalBinding('process_methods');
60+
// Set up methods and events on the process object for the main thread
6361
if (isMainThread) {
62+
// This depends on process being an event emitter
6463
mainThreadSetup.setupSignalHandlers(internalBinding);
64+
65+
process.abort = rawMethods.abort;
66+
const wrapped = mainThreadSetup.wrapProcessMethods(rawMethods);
67+
process.umask = wrapped.umask;
68+
process.chdir = wrapped.chdir;
69+
70+
// TODO(joyeecheung): deprecate and remove these underscore methods
71+
process._debugProcess = rawMethods._debugProcess;
72+
process._debugEnd = rawMethods._debugEnd;
73+
process._startProfilerIdleNotifier =
74+
rawMethods._startProfilerIdleNotifier;
75+
process._stopProfilerIdleNotifier = rawMethods._stopProfilerIdleNotifier;
6576
}
6677

67-
perThreadSetup.setupUncaughtExceptionCapture(exceptionHandlerState,
68-
_shouldAbortOnUncaughtToggle);
78+
// Set up methods on the process object for all threads
79+
{
80+
process.cwd = rawMethods.cwd;
81+
process.dlopen = rawMethods.dlopen;
82+
process.uptime = rawMethods.uptime;
83+
84+
// TODO(joyeecheung): either remove them or make them public
85+
process._getActiveRequests = rawMethods._getActiveRequests;
86+
process._getActiveHandles = rawMethods._getActiveHandles;
87+
88+
// TODO(joyeecheung): remove these
89+
process.reallyExit = rawMethods.reallyExit;
90+
process._kill = rawMethods._kill;
91+
92+
const wrapped = perThreadSetup.wrapProcessMethods(
93+
rawMethods, exceptionHandlerState
94+
);
95+
process._rawDebug = wrapped._rawDebug;
96+
process.hrtime = wrapped.hrtime;
97+
process.hrtime.bigint = wrapped.hrtimeBigInt;
98+
process.cpuUsage = wrapped.cpuUsage;
99+
process.memoryUsage = wrapped.memoryUsage;
100+
process.kill = wrapped.kill;
101+
process.exit = wrapped.exit;
102+
process.setUncaughtExceptionCaptureCallback =
103+
wrapped.setUncaughtExceptionCaptureCallback;
104+
process.hasUncaughtExceptionCaptureCallback =
105+
wrapped.hasUncaughtExceptionCaptureCallback;
106+
}
69107

70108
NativeModule.require('internal/process/warning').setup();
71109
NativeModule.require('internal/process/next_tick').setup(_setupNextTick,
@@ -91,22 +129,10 @@ function startup() {
91129

92130
if (isMainThread) {
93131
mainThreadSetup.setupStdio();
94-
mainThreadSetup.setupProcessMethods(_chdir, _umask);
95132
} else {
96133
workerThreadSetup.setupStdio();
97134
}
98135

99-
const perf = internalBinding('performance');
100-
const {
101-
NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE,
102-
} = perf.constants;
103-
104-
perThreadSetup.setupRawDebug(_rawDebug);
105-
perThreadSetup.setupHrtime(_hrtime, _hrtimeBigInt);
106-
perThreadSetup.setupCpuUsage(_cpuUsage);
107-
perThreadSetup.setupMemoryUsage(_memoryUsage);
108-
perThreadSetup.setupKillAndExit();
109-
110136
if (global.__coverage__)
111137
NativeModule.require('internal/process/write-coverage').setup();
112138

@@ -209,9 +235,37 @@ function startup() {
209235
}
210236
}
211237

212-
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE);
238+
// process.allowedNodeEnvironmentFlags
239+
Object.defineProperty(process, 'allowedNodeEnvironmentFlags', {
240+
get() {
241+
const flags = perThreadSetup.buildAllowedFlags();
242+
process.allowedNodeEnvironmentFlags = flags;
243+
return process.allowedNodeEnvironmentFlags;
244+
},
245+
// If the user tries to set this to another value, override
246+
// this completely to that value.
247+
set(value) {
248+
Object.defineProperty(this, 'allowedNodeEnvironmentFlags', {
249+
value,
250+
configurable: true,
251+
enumerable: true,
252+
writable: true
253+
});
254+
},
255+
enumerable: true,
256+
configurable: true
257+
});
258+
// process.assert
259+
process.assert = deprecate(
260+
perThreadSetup.assert,
261+
'process.assert() is deprecated. Please use the `assert` module instead.',
262+
'DEP0100');
213263

214-
perThreadSetup.setupAllowedFlags();
264+
const perf = internalBinding('performance');
265+
const {
266+
NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE,
267+
} = perf.constants;
268+
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE);
215269

216270
startExecution();
217271
}

lib/internal/process/main_thread_only.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,25 @@ function setupStdio() {
2727
setupProcessStdio(getMainThreadStdio());
2828
}
2929

30-
// Non-POSIX platforms like Windows don't have certain methods.
31-
// Workers also lack these methods since they change process-global state.
32-
function setupProcessMethods(_chdir, _umask) {
33-
process.chdir = function chdir(directory) {
30+
// The execution of this function itself should not cause any side effects.
31+
function wrapProcessMethods(binding) {
32+
function chdir(directory) {
3433
validateString(directory, 'directory');
35-
return _chdir(directory);
36-
};
34+
return binding.chdir(directory);
35+
}
3736

38-
process.umask = function umask(mask) {
37+
function umask(mask) {
3938
if (mask === undefined) {
4039
// Get the mask
41-
return _umask(mask);
40+
return binding.umask(mask);
4241
}
4342
mask = validateMode(mask, 'mask');
44-
return _umask(mask);
43+
return binding.umask(mask);
44+
}
45+
46+
return {
47+
chdir,
48+
umask
4549
};
4650
}
4751

@@ -175,7 +179,7 @@ function setupChildProcessIpcChannel() {
175179

176180
module.exports = {
177181
setupStdio,
178-
setupProcessMethods,
182+
wrapProcessMethods,
179183
setupSignalHandlers,
180184
setupChildProcessIpcChannel,
181185
wrapPosixCredentialSetters

0 commit comments

Comments
 (0)