Ejemplo n.º 1
0
        /// <summary>
        /// Ends the execution of the current method.
        ///
        /// If the current method does not return void, pops a value from the stack and returns it to the calling method.
        ///
        /// Return should leave the stack empty.
        /// </summary>
        public Emit <DelegateType> Return()
        {
            if (ReturnType == TypeOnStack.Get(typeof(void)))
            {
                UpdateState(Wrap(new[] { new StackTransition(0) }, "Return"));

                UpdateState(OpCodes.Ret, Wrap(StackTransition.None(), "Return"));

                Returns.Add(IL.Index);
                MustMark = true;

                return(this);
            }

            UpdateState(OpCodes.Ret, Wrap(StackTransition.Pop(ReturnType), "Return"));

            Returns.Add(IL.Index);

            UpdateState(Wrap(new[] { new StackTransition(0) }, "Return"));
            MustMark = true;

            var verify = CurrentVerifiers.Return();

            if (!verify.Success)
            {
                throw new SigilVerificationException("Return", verify, IL.Instructions(AllLocals));
            }

            return(this);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Pops a value off the stack and stores it into the argument to the current method identified by index.
        /// </summary>
        public Emit <DelegateType> StoreArgument(ushort index)
        {
            if (ParameterTypes.Length == 0)
            {
                throw new InvalidOperationException("Delegate of type " + typeof(DelegateType) + " takes no parameters");
            }

            if (index >= ParameterTypes.Length)
            {
                throw new ArgumentException("index must be between 0 and " + (ParameterTypes.Length - 1) + ", inclusive");
            }

            if (index >= byte.MinValue && index <= byte.MaxValue)
            {
                byte asByte;
                unchecked
                {
                    asByte = (byte)index;
                }

                UpdateState(OpCodes.Starg_S, asByte, Wrap(StackTransition.Pop(ParameterTypes[index]), "StoreArgument"));
                return(this);
            }

            short asShort;

            unchecked
            {
                asShort = (short)index;
            }

            UpdateState(OpCodes.Starg, asShort, Wrap(StackTransition.Pop(ParameterTypes[index]), "StoreArgument"));

            return(this);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Pops a value off the stack and stores it into the given local.
        ///
        /// To create a local, use DeclareLocal().
        /// </summary>
        public Emit <DelegateType> StoreLocal(Local local)
        {
            if (local == null)
            {
                throw new ArgumentNullException("local");
            }

            if (((IOwned)local).Owner != this)
            {
                if (((IOwned)local).Owner is DisassembledOperations <DelegateType> )
                {
                    return(StoreLocal(local.Name));
                }

                FailOwnership(local);
            }

            UnusedLocals.Remove(local);

            switch (local.Index)
            {
            case 0: UpdateState(OpCodes.Stloc_0, Wrap(StackTransition.Pop(local.StackType), "StoreLocal")); return(this);

            case 1: UpdateState(OpCodes.Stloc_1, Wrap(StackTransition.Pop(local.StackType), "StoreLocal")); return(this);

            case 2: UpdateState(OpCodes.Stloc_2, Wrap(StackTransition.Pop(local.StackType), "StoreLocal")); return(this);

            case 3: UpdateState(OpCodes.Stloc_3, Wrap(StackTransition.Pop(local.StackType), "StoreLocal")); return(this);
            }

            if (local.Index >= byte.MinValue && local.Index <= byte.MaxValue)
            {
                byte asByte;
                unchecked
                {
                    asByte = (byte)local.Index;
                }

                UpdateState(OpCodes.Stloc_S, asByte, Wrap(StackTransition.Pop(local.StackType), "StoreLocal"));
                return(this);
            }

            UpdateState(OpCodes.Stloc, local, Wrap(StackTransition.Pop(local.StackType), "StoreLocal"));

            return(this);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Pops a value off the stack and throws it as an exception.
        ///
        /// Throw expects the value to be or extend from a System.Exception.
        /// </summary>
        public Emit <DelegateType> Throw()
        {
            UpdateState(OpCodes.Throw, Wrap(StackTransition.Pop <Exception>(), "Throw"));
            UpdateState(Wrap(new[] { new StackTransition(new[] { typeof(PopAllType) }, TypeHelpers.EmptyTypes) }, "Throw"));

            Throws.Add(IL.Index);

            MustMark = true;

            var verify = CurrentVerifiers.Throw();

            if (!verify.Success)
            {
                throw new SigilVerificationException("Throw", verify, IL.Instructions(AllLocals));
            }

            return(this);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Removes the top value on the stack.
        /// </summary>
        public Emit <DelegateType> Pop()
        {
            UpdateState(OpCodes.Pop, Wrap(StackTransition.Pop <WildcardType>(), "Pop"));

            return(this);
        }