예제 #1
0
        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);
        }
예제 #2
0
        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);
        }