Пример #1
0
            public LatticeCell Meet(LatticeCell other)
            {
                if (other.Kind == LatticeCellKind.Top)
                {
                    return(this);
                }

                switch (Kind)
                {
                case LatticeCellKind.Top:
                    return(other);

                case LatticeCellKind.Constant:
                    if (other.Kind == LatticeCellKind.Constant &&
                        Value.Equals(other.Value))
                    {
                        return(this);
                    }
                    else
                    {
                        return(Bottom);
                    }

                case LatticeCellKind.NonNull:
                    if (other.Kind == LatticeCellKind.NonNull)
                    {
                        return(this);
                    }
                    else
                    {
                        return(Bottom);
                    }

                case LatticeCellKind.Bottom:
                default:
                    return(this);
                }
            }
Пример #2
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));
                }
            }
        }