Skip to content
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

console: fix issues with frozen intrinsics #54070

Merged
merged 2 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 19 additions & 20 deletions lib/internal/console/constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ function lazyUtilColors() {
}

// Track amount of indentation required via `console.group()`.
const kGroupIndent = Symbol('kGroupIndent');
const kGroupIndentationWidth = Symbol('kGroupIndentWidth');
const kFormatForStderr = Symbol('kFormatForStderr');
const kFormatForStdout = Symbol('kFormatForStdout');
Expand All @@ -91,7 +90,6 @@ const kBindStreamsEager = Symbol('kBindStreamsEager');
const kBindStreamsLazy = Symbol('kBindStreamsLazy');
const kUseStdout = Symbol('kUseStdout');
const kUseStderr = Symbol('kUseStderr');
const kInternalTimeLogImpl = Symbol('kInternalTimeLogImpl');

const optionsMap = new SafeWeakMap();
function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
Expand Down Expand Up @@ -178,6 +176,8 @@ ObjectDefineProperty(Console, SymbolHasInstance, {
const kColorInspectOptions = { colors: true };
const kNoColorInspectOptions = {};

const internalIndentationMap = new SafeWeakMap();

ObjectDefineProperties(Console.prototype, {
[kBindStreamsEager]: {
__proto__: null,
Expand Down Expand Up @@ -247,7 +247,6 @@ ObjectDefineProperties(Console.prototype, {
[kCounts]: { __proto__: null, ...consolePropAttributes, value: new SafeMap() },
[kColorMode]: { __proto__: null, ...consolePropAttributes, value: colorMode },
[kIsConsole]: { __proto__: null, ...consolePropAttributes, value: true },
[kGroupIndent]: { __proto__: null, ...consolePropAttributes, value: '' },
[kGroupIndentationWidth]: {
__proto__: null,
...consolePropAttributes,
Expand All @@ -268,7 +267,7 @@ ObjectDefineProperties(Console.prototype, {
...consolePropAttributes,
value: function(streamSymbol, string, color = '') {
const ignoreErrors = this._ignoreErrors;
const groupIndent = this[kGroupIndent];
const groupIndent = internalIndentationMap.get(this) || '';

const useStdout = streamSymbol === kUseStdout;
const stream = useStdout ? this._stdout : this._stderr;
Expand Down Expand Up @@ -372,11 +371,11 @@ function createWriteErrorHandler(instance, streamSymbol) {
};
}

function timeLogImpl(label, formatted, args) {
function timeLogImpl(consoleRef, label, formatted, args) {
if (args === undefined) {
this.log('%s: %s', label, formatted);
consoleRef.log('%s: %s', label, formatted);
} else {
this.log('%s: %s', label, formatted, ...new SafeArrayIterator(args));
consoleRef.log('%s: %s', label, formatted, ...new SafeArrayIterator(args));
}
}

Expand Down Expand Up @@ -407,17 +406,11 @@ const consoleMethods = {
},

timeEnd(label = 'default') {
if (this[kInternalTimeLogImpl] === undefined)
this[kInternalTimeLogImpl] = FunctionPrototypeBind(timeLogImpl, this);

timeEnd(this._times, kTraceConsoleCategory, 'console.timeEnd()', kNone, this[kInternalTimeLogImpl], label, `time::${label}`);
timeEnd(this._times, kTraceConsoleCategory, 'console.timeEnd()', kNone, (label, formatted, args) => timeLogImpl(this, label, formatted, args), label, `time::${label}`);
},

timeLog(label = 'default', ...data) {
if (this[kInternalTimeLogImpl] === undefined)
this[kInternalTimeLogImpl] = FunctionPrototypeBind(timeLogImpl, this);

timeLog(this._times, kTraceConsoleCategory, 'console.timeLog()', kNone, this[kInternalTimeLogImpl], label, `time::${label}`, data);
timeLog(this._times, kTraceConsoleCategory, 'console.timeLog()', kNone, (label, formatted, args) => timeLogImpl(this, label, formatted, args), label, `time::${label}`, data);
Copy link
Member

Choose a reason for hiding this comment

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

I believe it would be possible to add the timeLogImpl to the instance during construction time.
That way it is not required to recreate the function on each call.

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried adding inside the constructor but I always get undefined.

diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js
index 6c34a9eded..8d88d429b0 100644
--- a/lib/internal/console/constructor.js
+++ b/lib/internal/console/constructor.js
@@ -90,6 +90,7 @@ const kBindStreamsEager = Symbol('kBindStreamsEager');
 const kBindStreamsLazy = Symbol('kBindStreamsLazy');
 const kUseStdout = Symbol('kUseStdout');
 const kUseStderr = Symbol('kUseStderr');
+const kInternalTimeLogImpl = Symbol('kInternalTimeLogImpl');
 
 const optionsMap = new SafeWeakMap();
 function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
@@ -155,6 +156,8 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
     });
   });
 
+  this[kInternalTimeLogImpl] = FunctionPrototypeBind(timeLogImpl, this);
+
   this[kBindStreamsEager](stdout, stderr);
   this[kBindProperties](ignoreErrors, colorMode, groupIndentation);
 }
@@ -371,11 +374,11 @@ function createWriteErrorHandler(instance, streamSymbol) {
   };
 }
 
-function timeLogImpl(consoleRef, label, formatted, args) {
+function timeLogImpl(label, formatted, args) {
   if (args === undefined) {
-    consoleRef.log('%s: %s', label, formatted);
+    this.log('%s: %s', label, formatted);
   } else {
-    consoleRef.log('%s: %s', label, formatted, ...new SafeArrayIterator(args));
+    this.log('%s: %s', label, formatted, ...new SafeArrayIterator(args));
   }
 }
 
@@ -406,11 +409,11 @@ const consoleMethods = {
   },
 
   timeEnd(label = 'default') {
-    timeEnd(this._times, kTraceConsoleCategory, 'console.timeEnd()', kNone, (label, formatted, args) => timeLogImpl(this, label, formatted, args), label, `time::${label}`);
+    timeEnd(this._times, kTraceConsoleCategory, 'console.timeEnd()', kNone, this[kInternalTimeLogImpl], label, `time::${label}`);
   },
 
   timeLog(label = 'default', ...data) {
-    timeLog(this._times, kTraceConsoleCategory, 'console.timeLog()', kNone, (label, formatted, args) => timeLogImpl(this, label, formatted, args), label, `time::${label}`, data);
+    timeLog(this._times, kTraceConsoleCategory, 'console.timeLog()', kNone, this[kInternalTimeLogImpl], label, `time::${label}`, data);
   },
 
   trace: function trace(...args) {
node:internal/util/debuglog:206
    logImp(label, formatted, args);
    ^

TypeError <Object <Object <[Object: null prototype] {}>>>: logImp is not a function
    at timeLogImpl (node:internal/util/debuglog:206:5)
    at timeLog (node:internal/util/debuglog:313:5)
    at console.timeLog (node:internal/console/constructor:423:5)
    at Object.<anonymous> (/home/h4ad/Projects/opensource/node-copy-4/test/parallel/test-console-with-frozen-intrinsics.js:18:9)

},

trace: function trace(...args) {
Expand Down Expand Up @@ -489,16 +482,22 @@ const consoleMethods = {
if (data.length > 0) {
ReflectApply(this.log, this, data);
}
this[kGroupIndent] +=
StringPrototypeRepeat(' ', this[kGroupIndentationWidth]);

let currentIndentation = internalIndentationMap.get(this) || '';
currentIndentation += StringPrototypeRepeat(' ', this[kGroupIndentationWidth]);

internalIndentationMap.set(this, currentIndentation);
},

groupEnd() {
this[kGroupIndent] = StringPrototypeSlice(
this[kGroupIndent],
const currentIndentation = internalIndentationMap.get(this) || '';
const newIndentation = StringPrototypeSlice(
currentIndentation,
0,
this[kGroupIndent].length - this[kGroupIndentationWidth],
currentIndentation.length - this[kGroupIndentationWidth],
);

internalIndentationMap.set(this, newIndentation);
},

// https://console.spec.whatwg.org/#table
Expand Down
30 changes: 30 additions & 0 deletions test/parallel/test-console-with-frozen-intrinsics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// flags: --frozen-intrinsics
'use strict';
require('../common');
console.clear();

const consoleMethods = ['log', 'info', 'warn', 'error', 'debug', 'trace'];

for (const method of consoleMethods) {
console[method]('foo');
console[method]('foo', 'bar');
console[method]('%s %s', 'foo', 'bar', 'hop');
}

console.dir({ slashes: '\\\\' });
console.dirxml({ slashes: '\\\\' });

console.time('label');
console.timeLog('label', 'hi');
console.timeEnd('label');

console.assert(true, 'true');

console.count('label');
console.countReset('label');

console.group('label');
console.groupCollapsed('label');
console.groupEnd();

console.table([{ a: 1, b: 2 }, { a: 'foo', b: 'bar' }]);
Loading