@@ -18,6 +18,8 @@ namespace ts {
1818 const names : string [ ] = [ ] ;
1919 let nameToNameIndexMap : ESMap < string , number > | undefined ;
2020 const mappingCharCodes : number [ ] = [ ] ;
21+ // We will create a string from the char code buffer whenever it exceeds this length
22+ const mappingCommitThreshold = 1000 ;
2123 let mappings = "" ;
2224
2325 // Last recorded and encoded mappings
@@ -221,12 +223,14 @@ namespace ts {
221223 // Line/Comma delimiters
222224 if ( lastGeneratedLine < pendingGeneratedLine ) {
223225 // Emit line delimiters
226+ // This loop can potentially overflow the stack on the char code conversion if it were a single operation
224227 do {
225228 mappingCharCodes . push ( CharacterCodes . semicolon ) ; // ';'
226229 lastGeneratedLine ++ ;
227- lastGeneratedCharacter = 0 ;
228230 }
229231 while ( lastGeneratedLine < pendingGeneratedLine ) ;
232+ // Only need to set this once
233+ lastGeneratedCharacter = 0 ;
230234 }
231235 else {
232236 Debug . assertEqual ( lastGeneratedLine , pendingGeneratedLine , "generatedLine cannot backtrack" ) ;
@@ -260,20 +264,29 @@ namespace ts {
260264 }
261265 }
262266
267+ if ( mappings . length > mappingCommitThreshold ) {
268+ flushMappingBuffer ( ) ;
269+ }
270+
263271 hasLast = true ;
264272 exit ( ) ;
265273 }
266274
267- function serializeMappings ( ) : void {
268- for ( let i = 0 , len = mappingCharCodes . length ; i < len ; i += 1024 ) {
269- mappings += String . fromCharCode . apply ( undefined , mappingCharCodes . slice ( i , i + 1024 ) ) ;
275+ function flushMappingBuffer ( ) : void {
276+ const len = mappingCharCodes . length ;
277+ if ( len > 0 ) {
278+ // If there are a very large number of skipped lines in the source mapping, this loop can iterate multiple times
279+ // Otherwise it should always have 1 iteration
280+ for ( let i = 0 ; i < len ; i += 1024 ) {
281+ mappings += String . fromCharCode . apply ( undefined , mappingCharCodes . slice ( i , i + 1024 ) ) ;
282+ }
283+ mappingCharCodes . length = 0 ;
270284 }
271- mappingCharCodes . length = 0 ;
272285 }
273286
274287 function toJSON ( ) : RawSourceMap {
275288 commitPendingMapping ( ) ;
276- serializeMappings ( ) ;
289+ flushMappingBuffer ( ) ;
277290 return {
278291 version : 3 ,
279292 file,
0 commit comments