[DevTools] Fix symbolication with Index Source Maps (#34300)

This commit is contained in:
Sebastian "Sebbie" Silbermann 2025-08-26 15:18:20 +02:00 committed by GitHub
parent 26e87b5f15
commit ad4ecb6e6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 58 deletions

View File

@ -136,9 +136,9 @@ function BasicSourceMapConsumer(sourceMapJSON: BasicSourceMap) {
} }
type Section = { type Section = {
+generatedColumn: number, +offsetColumn0: number,
+generatedLine: number, +offsetLine0: number,
+map: MixedSourceMap, +map: BasicSourceMap,
// Lazily parsed only when/as the section is needed. // Lazily parsed only when/as the section is needed.
sourceMapConsumer: SourceMapConsumerType | null, sourceMapConsumer: SourceMapConsumerType | null,
@ -160,12 +160,12 @@ function IndexedSourceMapConsumer(sourceMapJSON: IndexSourceMap) {
column: number, column: number,
... ...
} = section.offset; } = section.offset;
const offsetLine = offset.line; const offsetLine0 = offset.line;
const offsetColumn = offset.column; const offsetColumn0 = offset.column;
if ( if (
offsetLine < lastOffset.line || offsetLine0 < lastOffset.line ||
(offsetLine === lastOffset.line && offsetColumn < lastOffset.column) (offsetLine0 === lastOffset.line && offsetColumn0 < lastOffset.column)
) { ) {
throw new Error('Section offsets must be ordered and non-overlapping.'); throw new Error('Section offsets must be ordered and non-overlapping.');
} }
@ -173,9 +173,8 @@ function IndexedSourceMapConsumer(sourceMapJSON: IndexSourceMap) {
lastOffset = offset; lastOffset = offset;
return { return {
// The offset fields are 0-based, but we use 1-based indices when encoding/decoding from VLQ. offsetLine0,
generatedLine: offsetLine + 1, offsetColumn0,
generatedColumn: offsetColumn + 1,
map: section.map, map: section.map,
sourceMapConsumer: null, sourceMapConsumer: null,
}; };
@ -186,55 +185,29 @@ function IndexedSourceMapConsumer(sourceMapJSON: IndexSourceMap) {
lineNumber, lineNumber,
}: SearchPosition): ResultPosition { }: SearchPosition): ResultPosition {
// Error.prototype.stack columns are 1-based (like most IDEs) but ASTs are 0-based. // Error.prototype.stack columns are 1-based (like most IDEs) but ASTs are 0-based.
const targetColumnNumber = columnNumber - 1; const column0 = columnNumber - 1;
const line0 = lineNumber - 1;
let section = null; // Sections must not overlap and must be sorted: https://tc39.es/source-map/#section-object
// Therefore the last section that has an offset less than or equal to the frame is the applicable one.
let left = 0;
let right = sections.length - 1;
let section: Section | null = null;
let startIndex = 0; while (left <= right) {
let stopIndex = sections.length - 1; // fast Math.floor
let index = -1; const middle = ~~((left + right) / 2);
while (startIndex <= stopIndex) { const currentSection = sections[middle];
index = Math.floor((stopIndex + startIndex) / 2);
section = sections[index];
const currentLine = section.generatedLine; if (
if (currentLine === lineNumber) { currentSection.offsetLine0 < line0 ||
const currentColumn = section.generatedColumn; (currentSection.offsetLine0 === line0 &&
if (currentColumn === lineNumber) { currentSection.offsetColumn0 <= column0)
break; ) {
} else { section = currentSection;
if (currentColumn > targetColumnNumber) { left = middle + 1;
if (stopIndex - index > 0) {
stopIndex = index;
} else {
index = stopIndex;
break;
}
} else {
if (index - startIndex > 0) {
startIndex = index;
} else {
index = startIndex;
break;
}
}
}
} else { } else {
if (currentLine > lineNumber) { right = middle - 1;
if (stopIndex - index > 0) {
stopIndex = index;
} else {
index = stopIndex;
break;
}
} else {
if (index - startIndex > 0) {
startIndex = index;
} else {
index = startIndex;
break;
}
}
} }
} }
@ -252,8 +225,9 @@ function IndexedSourceMapConsumer(sourceMapJSON: IndexSourceMap) {
} }
return section.sourceMapConsumer.originalPositionFor({ return section.sourceMapConsumer.originalPositionFor({
columnNumber, // The mappings in a Source Map section are relative to the section offset.
lineNumber, columnNumber: columnNumber - section.offsetColumn0,
lineNumber: lineNumber - section.offsetLine0,
}); });
} }

View File

@ -29,7 +29,7 @@ export type BasicSourceMap = {
}; };
export type IndexSourceMapSection = { export type IndexSourceMapSection = {
map: IndexSourceMap | BasicSourceMap, map: BasicSourceMap,
offset: { offset: {
line: number, line: number,
column: number, column: number,