From aca5ed5563fb268b9ecc137e2bc557e0a38b363e Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Sun, 18 Nov 2018 04:25:05 +0100 Subject: [PATCH] events: simplify stack compare function This simplifies the `longestSeqContainedIn()` logic by checking for the first identical occurance of at least three frames instead of the longest one. It also removes an unused argument. PR-URL: https://github.com/nodejs/node/pull/24744 Reviewed-By: Matteo Collina --- lib/events.js | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/lib/events.js b/lib/events.js index 67febe9f00355d..aed1ab67920560 100644 --- a/lib/events.js +++ b/lib/events.js @@ -104,30 +104,29 @@ EventEmitter.prototype.getMaxListeners = function getMaxListeners() { return $getMaxListeners(this); }; -// Returns the longest sequence of `a` that fully appears in `b`, -// of length at least 3. -// This is a lazy approach but should work well enough, given that stack -// frames are usually unequal or otherwise appear in groups, and that -// we only run this code in case of an unhandled exception. -function longestSeqContainedIn(a, b) { - for (var len = a.length; len >= 3; --len) { - for (var i = 0; i < a.length - len; ++i) { - // Attempt to find a[i:i+len] in b - for (var j = 0; j < b.length - len; ++j) { - let matches = true; - for (var k = 0; k < len; ++k) { - if (a[i + k] !== b[j + k]) { - matches = false; - break; - } +// Returns the length and line number of the first sequence of `a` that fully +// appears in `b` with a length of at least 4. +function identicalSequenceRange(a, b) { + for (var i = 0; i < a.length - 3; i++) { + // Find the first entry of b that matches the current entry of a. + const pos = b.indexOf(a[i]); + if (pos !== -1) { + const rest = b.length - pos; + if (rest > 3) { + let len = 1; + const maxLen = Math.min(a.length - i, rest); + // Count the number of consecutive entries. + while (maxLen > len && a[i + len] === b[pos + len]) { + len++; + } + if (len > 3) { + return [len, i]; } - if (matches) - return [ len, i, j ]; } } } - return [ 0, 0, 0 ]; + return [0, 0]; } function enhanceStackTrace(err, own) { @@ -136,9 +135,9 @@ function enhanceStackTrace(err, own) { const errStack = err.stack.split('\n').slice(1); const ownStack = own.stack.split('\n').slice(1); - const [ len, off ] = longestSeqContainedIn(ownStack, errStack); + const [ len, off ] = identicalSequenceRange(ownStack, errStack); if (len > 0) { - ownStack.splice(off + 1, len - 1, + ownStack.splice(off + 1, len - 2, ' [... lines matching original stack trace ...]'); } // Do this last, because it is the only operation with side effects.