public void BuildLabelGroups(JSFunctionExpression function) { // If a label is applied to the first statement in a block, hoist it upward // onto the parent block. var lh = new LabelHoister(); do { lh.HoistedALabel = false; lh.Visit(function); } while (lh.HoistedALabel); // Walk the function to build our list of labels and gotos. Visit(function); // When a goto crosses block boundaries, we need to move the target label // upwards so that the goto can reach it. foreach (var g in Gotos) { var targetLabel = Labels[g.TargetLabel]; if (targetLabel.EnclosingBlock.Depth > g.EnclosingBlock.Depth) { targetLabel.EnclosingBlock = g.EnclosingBlock; } } foreach (var l in Labels.Values) { l.EnsureLabelGroupExists(LabelGroups); var replacementGoto = new JSExpressionStatement( new JSGotoExpression(l.LabelledStatement.Label) ); l.EnclosingBlock.Block.ReplaceChildRecursive(l.LabelledStatement, replacementGoto); l.LabelGroup.Add(l.LabelledStatement); } // If a label group only contains one label (plus an entry label), // and it has a parent label group, hoist the label up. var lgs = new LabelGroupFlattener(); do { lgs.FlattenedAGroup = false; lgs.Visit(function); } while (lgs.FlattenedAGroup); // Remove any labels within a label group that contain no statements (as long // as no goto targets that label directly). This will prune empty entry/exit labels. var elr = new EmptyLabelRemover(UsedLabels); elr.Visit(function); }
public void BuildLabelGroups(JSFunctionExpression function) { // If a label is applied to the first statement in a block, hoist it upward // onto the parent block. var lh = new LabelHoister(); do { lh.HoistedALabel = false; lh.Visit(function); } while (lh.HoistedALabel); // Walk the function to build our list of labels and gotos. Visit(function); // When a goto crosses block boundaries, we need to move the target label // upwards so that the goto can reach it. foreach (var g in Gotos) { var targetLabel = Labels[g.TargetLabel]; if (targetLabel.EnclosingBlock.Depth > g.EnclosingBlock.Depth) targetLabel.EnclosingBlock = g.EnclosingBlock; } foreach (var l in Labels.Values) { l.EnsureLabelGroupExists(LabelGroups); var replacementGoto = new JSExpressionStatement( new JSGotoExpression(l.LabelledStatement.Label) ); l.EnclosingBlock.Block.ReplaceChildRecursive(l.LabelledStatement, replacementGoto); l.LabelGroup.Add(l.LabelledStatement); } // If a label group only contains one label (plus an entry label), // and it has a parent label group, hoist the label up. var lgs = new LabelGroupFlattener(); do { lgs.FlattenedAGroup = false; lgs.Visit(function); } while (lgs.FlattenedAGroup); // Remove any labels within a label group that contain no statements (as long // as no goto targets that label directly). This will prune empty entry/exit labels. var elr = new EmptyLabelRemover(UsedLabels); elr.Visit(function); }