Пример #1
0
        private LatticeCell EvaluateInstruction(
            Instruction instruction,
            IReadOnlyDictionary <ValueTag, LatticeCell> cells,
            FlowGraph graph)
        {
            if (instruction.Prototype is CopyPrototype)
            {
                // Special case on copy instructions because they're
                // easy to deal with: just return the lattice cell for
                // the argument.
                return(GetCellForValue(instruction.Arguments[0], cells));
            }

            var foundTop = false;
            var args     = new Constant[instruction.Arguments.Count];

            for (int i = 0; i < args.Length; i++)
            {
                var argCell = GetCellForValue(instruction.Arguments[i], cells);

                if (argCell.Kind == LatticeCellKind.Top)
                {
                    // We can't evaluate this value *yet*. Keep looking
                    // for bottom argument cells and set a flag to record
                    // that this value cannot be evaluated yet.
                    foundTop = true;
                }
                else if (argCell.Kind == LatticeCellKind.Constant)
                {
                    // Yay. We found a compile-time constant.
                    args[i] = argCell.Value;
                }
                else
                {
                    // We can't evaluate this value at compile-time
                    // because one if its arguments is unknown.
                    // Time to early-out.
                    return(EvaluateNonConstantInstruction(instruction, graph));
                }
            }

            if (foundTop)
            {
                // We can't evaluate this value yet.
                return(LatticeCell.Top);
            }
            else
            {
                // Evaluate the instruction.
                var constant = Evaluate(instruction.Prototype, args);
                if (constant == null)
                {
                    // Turns out we can't evaluate the instruction. But maybe
                    // we can say something sensible about its nullability?
                    return(EvaluateNonConstantInstruction(instruction, graph));
                }
                else
                {
                    return(LatticeCell.Constant(constant));
                }
            }
        }