Пример #1
0
        public StackTransition(IEnumerable <TypeOnStack> popped, IEnumerable <TypeOnStack> pushed, VerificationCallback before = null)
        {
            PoppedFromStack = LinqEnumerable <TypeOnStack> .For(popped).ToArray();

            PushedToStack = LinqEnumerable <TypeOnStack> .For(pushed).ToArray();

            Before = before;
        }
Пример #2
0
 public StackTransition(IEnumerable <Type> popped, IEnumerable <Type> pushed, VerificationCallback before = null)
     : this
     (
         LinqEnumerable <Type> .For(popped).Select(s => TypeOnStack.Get(s)).AsEnumerable(),
         LinqEnumerable <Type> .For(pushed).Select(s => TypeOnStack.Get(s)).AsEnumerable(),
         before
     )
 {
 }
Пример #3
0
        /// <summary>
        /// Cast a reference on the stack to the given reference type.
        ///
        /// If the cast is not legal, a CastClassException will be thrown at runtime.
        /// </summary>
        public Emit <DelegateType> CastClass(Type referenceType)
        {
            if (referenceType == null)
            {
                throw new ArgumentNullException("referenceType");
            }

            if (referenceType.IsValueType)
            {
                throw new ArgumentException("Can only cast to ReferenceTypes, found " + referenceType);
            }

            var  curIndex = IL.Index;
            bool elided   = false;

            VerificationCallback before =
                (stack, baseless) =>
            {
                // Can't reason about stack unless it's completely known
                if (baseless || elided)
                {
                    return;
                }

                var onStack = stack.First();

                if (onStack.All(a => ExtensionMethods.IsAssignableFrom(referenceType, a)))
                {
                    ElidableCasts.Add(curIndex);
                    elided = true;
                }
            };

            var newType = TypeOnStack.Get(referenceType);

            var transitions =
                new[]
            {
                new StackTransition(new [] { typeof(object) }, new [] { referenceType }, before: before)
            };

            UpdateState(OpCodes.Castclass, referenceType, Wrap(transitions, "CastClass"));

            return(this);
        }
Пример #4
0
        /// <summary>
        /// Pops a value from the stack and casts to the given type if possible pushing the result, otherwise pushes a null.
        ///
        /// This is analogous to C#'s `as` operator.
        /// </summary>
        public Emit <DelegateType> IsInstance(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            var  curIndex = IL.Index;
            bool elided   = false;

            VerificationCallback before =
                (stack, baseless) =>
            {
                // Can't reason about stack unless it's completely known
                if (baseless || elided)
                {
                    return;
                }

                var onStack = stack.First();

                if (onStack.All(a => ExtensionMethods.IsAssignableFrom(type, a)))
                {
                    ElidableCasts.Add(curIndex);
                    elided = true;
                }
            };

            var transitions =
                new[]
            {
                new StackTransition(new[] { typeof(WildcardType) }, new [] { type }, before)
            };

            UpdateState(OpCodes.Isinst, type, Wrap(transitions, "IsInstance"));

            return(this);
        }