Skip to content

Commit a2bbce9

Browse files
fix: rewrite recordRefsOfVariable to avoid blowing the stack (#443)
Fixes #442
1 parent 876dad7 commit a2bbce9

1 file changed

Lines changed: 13 additions & 10 deletions

File tree

packages/compile/src/model/model.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -395,14 +395,12 @@ function removeUnusedVariables(spec) {
395395
// ensures that we include all subscripts for a variable, which might mean we
396396
// include some subscripts that aren't needed, but it is safer than trying to
397397
// eliminate those and possibly omit something that is needed.
398-
const referencedVarNames = []
398+
const referencedVarNames = new Set()
399399

400400
// Add the given variable name to the list of referenced variables, if it's not
401401
// already there.
402402
const recordUsedVarName = varName => {
403-
if (!referencedVarNames.includes(varName)) {
404-
referencedVarNames.push(varName)
405-
}
403+
referencedVarNames.add(varName)
406404
}
407405

408406
// Add the given variable to the list of referenced variables, and do the same for
@@ -443,16 +441,21 @@ function removeUnusedVariables(spec) {
443441
// that are referenced by this variable, either directly (`v.references`) or
444442
// in an "INITIAL" expression (`v.initReferences`). It's OK if we end up with
445443
// duplicates in this list, because we will examine each reference only once.
446-
let refIds = refIdsWithName(v.varName)
447-
refIds = refIds.concat(v.references)
448-
refIds = refIds.concat(v.initReferences)
449-
for (const refId of refIds) {
444+
let refStack = []
445+
function pushRefs(v) {
446+
refStack.push(...refIdsWithName(v.varName))
447+
refStack.push(...v.references)
448+
refStack.push(...v.initReferences)
449+
}
450+
pushRefs(v)
451+
while (refStack.length > 0) {
452+
const refId = refStack.pop()
450453
if (!referencedRefIds.has(refId)) {
451454
referencedRefIds.add(refId)
452455
const refVar = varWithRefId(refId)
453456
if (refVar) {
454457
recordUsedVariable(refVar)
455-
recordRefsOfVariable(refVar)
458+
pushRefs(refVar)
456459
} else {
457460
throw new Error(`No var found for ${refId} when recording references for ${v.varName}`)
458461
}
@@ -490,7 +493,7 @@ function removeUnusedVariables(spec) {
490493
}
491494

492495
// Filter out unneeded variables so we're left with the minimal set of variables to emit
493-
variables = R.filter(v => referencedVarNames.includes(v.varName), variables)
496+
variables = R.filter(v => referencedVarNames.has(v.varName), variables)
494497

495498
// Rebuild the variables-by-name map
496499
variablesByName.clear()

0 commit comments

Comments
 (0)