Esempio n. 1
0
        private LNode Encode(
            Branch branch,
            UniqueNameMap <UniqueTag> blockNameMap,
            UniqueNameMap <UniqueTag> valueNameMap)
        {
            var argNodes = new List <LNode>();

            foreach (var arg in branch.Arguments)
            {
                switch (arg.Kind)
                {
                case BranchArgumentKind.TryException:
                    argNodes.Add(Factory.Id(tryFlowExceptionSymbol));
                    break;

                case BranchArgumentKind.TryResult:
                    argNodes.Add(Factory.Id(CodeSymbols.Result));
                    break;

                default:
                    argNodes.Add(EncodeUniqueTag(arg.ValueOrNull, valueNameMap));
                    break;
                }
            }

            return(Factory.Call(EncodeUniqueTag(branch.Target, blockNameMap), argNodes));
        }
Esempio n. 2
0
        private LNode Encode(
            BlockFlow flow,
            UniqueNameMap <UniqueTag> blockNameMap,
            UniqueNameMap <UniqueTag> valueNameMap)
        {
            if (flow is UnreachableFlow)
            {
                return(Factory.Id(unreachableFlowSymbol));
            }
            else if (flow is JumpFlow)
            {
                return(Factory.Call(
                           CodeSymbols.Goto,
                           Encode(((JumpFlow)flow).Branch, blockNameMap, valueNameMap)));
            }
            else if (flow is ReturnFlow)
            {
                return(Factory.Call(
                           CodeSymbols.Return,
                           Encode(((ReturnFlow)flow).ReturnValue, valueNameMap)));
            }
            else if (flow is TryFlow)
            {
                var tryFlow = (TryFlow)flow;

                return(Factory.Call(
                           CodeSymbols.Try,
                           Encode(tryFlow.Instruction, valueNameMap),
                           Encode(tryFlow.SuccessBranch, blockNameMap, valueNameMap),
                           Encode(tryFlow.ExceptionBranch, blockNameMap, valueNameMap)));
            }
            else if (flow is SwitchFlow)
            {
                var switchFlow = (SwitchFlow)flow;

                var caseNodes = new List <LNode>();
                foreach (var switchCase in switchFlow.Cases)
                {
                    caseNodes.Add(
                        Factory.Call(
                            CodeSymbols.Case,
                            Factory.Call(CodeSymbols.AltList, switchCase.Values.Select(Encode)),
                            Encode(switchCase.Branch, blockNameMap, valueNameMap)));
                }

                return(Factory.Call(
                           CodeSymbols.Switch,
                           Encode(switchFlow.SwitchValue, valueNameMap),
                           Encode(switchFlow.DefaultBranch, blockNameMap, valueNameMap),
                           Factory.Call(CodeSymbols.Braces, caseNodes)));
            }
            else
            {
                throw new NotSupportedException(
                          "Cannot encode unknown block flow '" + flow + "'.");
            }
        }
Esempio n. 3
0
 private LNode Encode(
     Instruction instruction,
     UniqueNameMap <UniqueTag> valueNameMap)
 {
     return(Factory.Call(
                Encode(instruction.Prototype),
                instruction.Arguments.Select(
                    tag => EncodeUniqueTag(tag, valueNameMap))));
 }
Esempio n. 4
0
        /// <summary>
        /// Encodes a control-flow graph.
        /// </summary>
        /// <param name="graph">The control-flow graph to encode.</param>
        /// <returns>An LNode that represents the control-flow graph.</returns>
        public LNode Encode(FlowGraph graph)
        {
            var blockNameSet = new UniqueNameSet <UniqueTag>(
                tag => tag.Name, "block_");
            var valueNameSet = new UniqueNameSet <UniqueTag>(
                tag => tag.Name, "val_", blockNameSet);

            // Reserve special names.
            valueNameSet.ReserveName(CodeSymbols.Result.Name);
            valueNameSet.ReserveName(tryFlowExceptionSymbol.Name);

            var blockNameMap = new UniqueNameMap <UniqueTag>(blockNameSet);
            var valueNameMap = new UniqueNameMap <UniqueTag>(valueNameSet);

            var blockNodes = new List <LNode>();

            foreach (var block in graph.BasicBlocks)
            {
                var paramNodes = block.Parameters
                                 .EagerSelect(param =>
                                              Factory.Call(
                                                  parameterSymbol,
                                                  Encode(param.Type),
                                                  EncodeUniqueTag(param.Tag, valueNameMap)));

                var instrNodes = block.NamedInstructions
                                 .Select(instr =>
                                         Factory.Call(
                                             CodeSymbols.Assign,
                                             EncodeUniqueTag(instr.Tag, valueNameMap),
                                             Encode(instr.Instruction, valueNameMap)))
                                 .ToArray();

                blockNodes.Add(
                    Factory.Call(
                        block.Tag == graph.EntryPointTag
                            ? entryPointBlockSymbol
                            : basicBlockSymbol,
                        EncodeUniqueTag(block.Tag, blockNameMap),
                        Factory.Call(CodeSymbols.AltList, paramNodes),
                        Factory.Call(CodeSymbols.Braces, instrNodes),
                        Encode(block.Flow, blockNameMap, valueNameMap)));
            }
            return(Factory.Braces(blockNodes));
        }
Esempio n. 5
0
 private LNode EncodeUniqueTag(UniqueTag tag, UniqueNameMap <UniqueTag> nameMap)
 {
     return(Factory.Id(nameMap[tag]));
 }