Exemplo n.º 1
0
        /// <summary>
        /// <para>Leave an exception or catch block, branching to the given label.</para>
        /// <para>This instruction empties the stack.</para>
        /// </summary>
        public Emit <DelegateType> Leave(Label label)
        {
            if (label == null)
            {
                throw new ArgumentNullException("label");
            }

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

                FailOwnership(label);
            }

            if (!TryBlocks.Any(t => t.Value.Item2 == -1) && !CatchBlocks.Any(c => c.Value.Item2 == -1))
            {
                throw new InvalidOperationException("Leave can only be used within an exception or catch block");
            }

            // Note that Leave *always* nuked the stack; nothing survies exiting an exception block
            UpdateOpCodeDelegate update;

            UpdateState(OpCodes.Leave, label, Wrap(new[] { new StackTransition(new [] { typeof(PopAllType) }, TypeHelpers.EmptyTypes) }, "Leave"), out update);

            Branches.Add(SigilTuple.Create(OpCodes.Leave, label, IL.Index));

            BranchPatches[IL.Index] = SigilTuple.Create(label, update, OpCodes.Leave);
            MustMark = true;

            var valid = CurrentVerifiers.UnconditionalBranch(label);

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

            return(this);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Unconditionally branches to the given label.
        /// </summary>
        public Emit <DelegateType> Branch(Label label)
        {
            if (label == null)
            {
                throw new ArgumentNullException("label");
            }

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

                FailOwnership(label);
            }

            UnusedLabels.Remove(label);

            UpdateOpCodeDelegate update;

            UpdateState(OpCodes.Br, label, Wrap(StackTransition.None(), "Branch"), out update);

            var valid = CurrentVerifiers.UnconditionalBranch(label);

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

            Branches.Add(SigilTuple.Create(OpCodes.Br, label, IL.Index));

            BranchPatches[IL.Index] = SigilTuple.Create(label, update, OpCodes.Br);

            MustMark = true;

            return(this);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Pops two arguments from the stack, branches to the given label if the second value is greater than the first value (when treated as unsigned values).
        /// </summary>
        public Emit <DelegateType> UnsignedBranchIfGreater(Label label)
        {
            if (label == null)
            {
                throw new ArgumentNullException("label");
            }

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

                FailOwnership(label);
            }

            UnusedLabels.Remove(label);

            UpdateOpCodeDelegate update;

            UpdateState(OpCodes.Bgt_Un, label, BranchComparableTransitions("UnsignedBranchIfGreater"), out update);

            var valid = CurrentVerifiers.UnconditionalBranch(label);

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

            Branches.Add(SigilTuple.Create(OpCodes.Bgt_Un, label, IL.Index));

            BranchPatches[IL.Index] = SigilTuple.Create(label, update, OpCodes.Bgt_Un);

            return(this);
        }