From 578144ac373b59a5242b6937d73fc0f3aa85721a Mon Sep 17 00:00:00 2001 From: Nicolas Savoire Date: Tue, 28 Feb 2023 15:38:58 +0100 Subject: [PATCH] Fix sourcemap lookup when line numbers are enabled When calling sites line numbers are reported (StartProfiling called with CpuProfilingMode::kCallerLineNumbers), sometimes locations point to the part of a code line before the first word. In that case, SourceMapConsumer.originalPositionFor will locate with a binary search the first generated position less or equal to the input. Since the input location does not point to a generated location and is at the start of a line, the binary search will return the last generated location from the previous line. But since the found location is on a different line from the input location, originalPositionFor will return null. Changes done to fix this: * do a first search with LEAST_UPPER_BOUND instead of GREATEST_LOWER_BOUND: binary search will search for the first element greater or equal to the input location. As a result, this will work for locations pointing to blank parts at the start of a line. Still it will not work for locations pointing at the end of a line, but this case does not seem to occur, therefore it makes sense to start with LEAST_UPPER_BOUND * if previous search fails, do a second lookup with GREATEST_LOWER_BOUND --- ts/src/sourcemapper/sourcemapper.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ts/src/sourcemapper/sourcemapper.ts b/ts/src/sourcemapper/sourcemapper.ts index 000fc880..123abebd 100644 --- a/ts/src/sourcemapper/sourcemapper.ts +++ b/ts/src/sourcemapper/sourcemapper.ts @@ -212,13 +212,21 @@ export class SourceMapper { return location; } - const generatedPos = {line: location.line, column: location.column}; + const generatedPos = { + line: location.line, + column: location.column, + bias: sourceMap.SourceMapConsumer.LEAST_UPPER_BOUND, + }; // TODO: Determine how to remove the explicit cast here. const consumer: sourceMap.SourceMapConsumer = entry.mapConsumer as {} as sourceMap.SourceMapConsumer; - const pos = consumer.originalPositionFor(generatedPos); + let pos = consumer.originalPositionFor(generatedPos); + if (pos.source === null) { + generatedPos.bias = sourceMap.SourceMapConsumer.GREATEST_LOWER_BOUND; + pos = consumer.originalPositionFor(generatedPos); + } if (pos.source === null) { return location; }