Skip to content

Commit edb8f22

Browse files
committed
console: move the inspector console wrapping in a separate file
Move the wrapping of the inspector console in a separate file for clarity. In addition, save the original console from the VM explicitly via an exported property `require('internal/console/inspector').consoleFromVM` that `require('inspector').console` can alias to it later, instead of hanging the original console onto `per_thread.js` during bootstrap and counting on that `per_thread.js` only gets evaluated once and gets cached. PR-URL: #24709 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent cfc2559 commit edb8f22

File tree

5 files changed

+84
-55
lines changed

5 files changed

+84
-55
lines changed

lib/inspector.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ const {
1212
const { validateString } = require('internal/validators');
1313
const util = require('util');
1414
const { Connection, open, url } = process.binding('inspector');
15-
const { originalConsole } = require('internal/process/per_thread');
1615

1716
if (!Connection)
1817
throw new ERR_INSPECTOR_NOT_AVAILABLE();
@@ -103,6 +102,8 @@ module.exports = {
103102
open: (port, host, wait) => open(port, host, !!wait),
104103
close: process._debugEnd,
105104
url: url,
106-
console: originalConsole,
105+
// This is dynamically added during bootstrap,
106+
// where the console from the VM is still available
107+
console: require('internal/console/inspector').consoleFromVM,
107108
Session
108109
};

lib/internal/bootstrap/node.js

+15-53
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,6 @@
121121

122122
const browserGlobals = !process._noBrowserGlobals;
123123
if (browserGlobals) {
124-
// we are setting this here to forward it to the inspector later
125-
perThreadSetup.originalConsole = global.console;
126124
setupGlobalTimeouts();
127125
setupGlobalConsole();
128126
setupGlobalURL();
@@ -487,16 +485,25 @@
487485
}
488486

489487
function setupGlobalConsole() {
490-
const originalConsole = global.console;
491-
// Setup Node.js global.console.
492-
const wrappedConsole = NativeModule.require('console');
488+
const consoleFromVM = global.console;
489+
const consoleFromNode =
490+
NativeModule.require('internal/console/global');
491+
// Override global console from the one provided by the VM
492+
// to the one implemented by Node.js
493493
Object.defineProperty(global, 'console', {
494494
configurable: true,
495495
enumerable: false,
496-
value: wrappedConsole,
496+
value: consoleFromNode,
497497
writable: true
498498
});
499-
setupInspector(originalConsole, wrappedConsole);
499+
// TODO(joyeecheung): can we skip this if inspector is not active?
500+
if (process.config.variables.v8_enable_inspector) {
501+
const inspector =
502+
NativeModule.require('internal/console/inspector');
503+
inspector.addInspectorApis(consoleFromNode, consoleFromVM);
504+
// This will be exposed by `require('inspector').console` later.
505+
inspector.consoleFromVM = consoleFromVM;
506+
}
500507
}
501508

502509
function setupGlobalURL() {
@@ -571,41 +578,6 @@
571578
registerDOMException(DOMException);
572579
}
573580

574-
function setupInspector(originalConsole, wrappedConsole) {
575-
if (!process.config.variables.v8_enable_inspector) {
576-
return;
577-
}
578-
const CJSModule = NativeModule.require('internal/modules/cjs/loader');
579-
const { addCommandLineAPI, consoleCall } = process.binding('inspector');
580-
// Setup inspector command line API.
581-
const { makeRequireFunction } =
582-
NativeModule.require('internal/modules/cjs/helpers');
583-
const path = NativeModule.require('path');
584-
const cwd = tryGetCwd(path);
585-
586-
const consoleAPIModule = new CJSModule('<inspector console>');
587-
consoleAPIModule.paths =
588-
CJSModule._nodeModulePaths(cwd).concat(CJSModule.globalPaths);
589-
addCommandLineAPI('require', makeRequireFunction(consoleAPIModule));
590-
const config = {};
591-
for (const key of Object.keys(wrappedConsole)) {
592-
if (!originalConsole.hasOwnProperty(key))
593-
continue;
594-
// If global console has the same method as inspector console,
595-
// then wrap these two methods into one. Native wrapper will preserve
596-
// the original stack.
597-
wrappedConsole[key] = consoleCall.bind(wrappedConsole,
598-
originalConsole[key],
599-
wrappedConsole[key],
600-
config);
601-
}
602-
for (const key of Object.keys(originalConsole)) {
603-
if (wrappedConsole.hasOwnProperty(key))
604-
continue;
605-
wrappedConsole[key] = originalConsole[key];
606-
}
607-
}
608-
609581
function noop() {}
610582

611583
function setupProcessFatal() {
@@ -684,17 +656,6 @@
684656
}
685657
}
686658

687-
function tryGetCwd(path) {
688-
try {
689-
return process.cwd();
690-
} catch {
691-
// getcwd(3) can fail if the current working directory has been deleted.
692-
// Fall back to the directory name of the (absolute) executable path.
693-
// It's not really correct but what are the alternatives?
694-
return path.dirname(process.execPath);
695-
}
696-
}
697-
698659
function wrapForBreakOnFirstLine(source) {
699660
if (!process._breakFirstLine)
700661
return source;
@@ -705,6 +666,7 @@
705666
function evalScript(name, body) {
706667
const CJSModule = NativeModule.require('internal/modules/cjs/loader');
707668
const path = NativeModule.require('path');
669+
const { tryGetCwd } = NativeModule.require('internal/util');
708670
const cwd = tryGetCwd(path);
709671

710672
const module = new CJSModule(name);

lib/internal/console/inspector.js

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
const CJSModule = require('internal/modules/cjs/loader');
5+
const { makeRequireFunction } = require('internal/modules/cjs/helpers');
6+
const { tryGetCwd } = require('internal/util');
7+
const { addCommandLineAPI, consoleCall } = process.binding('inspector');
8+
9+
// Wrap a console implemented by Node.js with features from the VM inspector
10+
function addInspectorApis(consoleFromNode, consoleFromVM) {
11+
// Setup inspector command line API.
12+
const cwd = tryGetCwd(path);
13+
const consoleAPIModule = new CJSModule('<inspector console>');
14+
consoleAPIModule.paths =
15+
CJSModule._nodeModulePaths(cwd).concat(CJSModule.globalPaths);
16+
addCommandLineAPI('require', makeRequireFunction(consoleAPIModule));
17+
const config = {};
18+
19+
// If global console has the same method as inspector console,
20+
// then wrap these two methods into one. Native wrapper will preserve
21+
// the original stack.
22+
for (const key of Object.keys(consoleFromNode)) {
23+
if (!consoleFromVM.hasOwnProperty(key))
24+
continue;
25+
consoleFromNode[key] = consoleCall.bind(consoleFromNode,
26+
consoleFromVM[key],
27+
consoleFromNode[key],
28+
config);
29+
}
30+
31+
// Add additional console APIs from the inspector
32+
for (const key of Object.keys(consoleFromVM)) {
33+
if (consoleFromNode.hasOwnProperty(key))
34+
continue;
35+
consoleFromNode[key] = consoleFromVM[key];
36+
}
37+
}
38+
39+
module.exports = {
40+
addInspectorApis
41+
};
42+
43+
// Stores the console from VM, should be set during bootstrap.
44+
let consoleFromVM;
45+
46+
Object.defineProperty(module.exports, 'consoleFromVM', {
47+
get() {
48+
return consoleFromVM;
49+
},
50+
set(val) {
51+
consoleFromVM = val;
52+
}
53+
});

lib/internal/util.js

+12
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,17 @@ function once(callback) {
373373
};
374374
}
375375

376+
function tryGetCwd(path) {
377+
try {
378+
return process.cwd();
379+
} catch {
380+
// getcwd(3) can fail if the current working directory has been deleted.
381+
// Fall back to the directory name of the (absolute) executable path.
382+
// It's not really correct but what are the alternatives?
383+
return path.dirname(process.execPath);
384+
}
385+
}
386+
376387
module.exports = {
377388
assertCrypto,
378389
cachedResult,
@@ -392,6 +403,7 @@ module.exports = {
392403
once,
393404
promisify,
394405
spliceOne,
406+
tryGetCwd,
395407
removeColors,
396408

397409
// Symbol used to customize promisify conversion

node.gyp

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
'lib/internal/cluster/worker.js',
9898
'lib/internal/console/constructor.js',
9999
'lib/internal/console/global.js',
100+
'lib/internal/console/inspector.js',
100101
'lib/internal/crypto/certificate.js',
101102
'lib/internal/crypto/cipher.js',
102103
'lib/internal/crypto/diffiehellman.js',

0 commit comments

Comments
 (0)