示例#1
0
 internal void AddBranch(int ilOffset, LabelHandle label, ILOpCode opCode)
 {
     Debug.Assert(ilOffset >= 0);
     Debug.Assert(_branches.Count == 0 || ilOffset > _branches.Last().ILOffset);
     ValidateLabel(label, nameof(label));
     _branches.Add(new BranchInfo(ilOffset, label, opCode));
 }
示例#2
0
        /// <summary>
        /// Adds catch region.
        /// </summary>
        /// <param name="tryStart">Label marking the first instruction of the try block.</param>
        /// <param name="tryEnd">Label marking the instruction immediately following the try block.</param>
        /// <param name="handlerStart">Label marking the first instruction of the handler.</param>
        /// <param name="handlerEnd">Label marking the instruction immediately following the handler.</param>
        /// <param name="catchType">The type of exception to be caught: <see cref="TypeDefinitionHandle"/>, <see cref="TypeReferenceHandle"/> or <see cref="TypeSpecificationHandle"/>.</param>
        /// <exception cref="ArgumentException">A label was not defined by an instruction encoder this builder is associated with.</exception>
        /// <exception cref="ArgumentException"><paramref name="catchType"/> is not a valid type handle.</exception>
        /// <exception cref="ArgumentNullException">A label has default value.</exception>
        public void AddCatchRegion(LabelHandle tryStart, LabelHandle tryEnd, LabelHandle handlerStart, LabelHandle handlerEnd, EntityHandle catchType)
        {
            if (!ExceptionRegionEncoder.IsValidCatchTypeHandle(catchType))
            {
                Throw.InvalidArgument_Handle(nameof(catchType));
            }

            AddExceptionRegion(ExceptionRegionKind.Catch, tryStart, tryEnd, handlerStart, handlerEnd, catchType: catchType);
        }
示例#3
0
        private int GetLabelOffsetChecked(LabelHandle label)
        {
            int offset = _labels[label.Id - 1];

            if (offset < 0)
            {
                Throw.InvalidOperation_LabelNotMarked(label.Id);
            }

            return(offset);
        }
示例#4
0
        private void ValidateLabel(LabelHandle label, string parameterName)
        {
            if (label.IsNil)
            {
                Throw.ArgumentNull(parameterName);
            }

            if (label.Id > _labels.Count)
            {
                Throw.LabelDoesntBelongToBuilder(parameterName);
            }
        }
示例#5
0
 public ExceptionHandlerInfo(
     ExceptionRegionKind kind,
     LabelHandle tryStart,
     LabelHandle tryEnd,
     LabelHandle handlerStart,
     LabelHandle handlerEnd,
     LabelHandle filterStart,
     EntityHandle catchType)
 {
     Kind         = kind;
     TryStart     = tryStart;
     TryEnd       = tryEnd;
     HandlerStart = handlerStart;
     HandlerEnd   = handlerEnd;
     FilterStart  = filterStart;
     CatchType    = catchType;
 }
示例#6
0
        private void AddExceptionRegion(
            ExceptionRegionKind kind,
            LabelHandle tryStart,
            LabelHandle tryEnd,
            LabelHandle handlerStart,
            LabelHandle handlerEnd,
            LabelHandle filterStart = default(LabelHandle),
            EntityHandle catchType  = default(EntityHandle))
        {
            ValidateLabel(tryStart, nameof(tryStart));
            ValidateLabel(tryEnd, nameof(tryEnd));
            ValidateLabel(handlerStart, nameof(handlerStart));
            ValidateLabel(handlerEnd, nameof(handlerEnd));

            if (_lazyExceptionHandlers == null)
            {
                _lazyExceptionHandlers = ImmutableArray.CreateBuilder <ExceptionHandlerInfo>();
            }

            _lazyExceptionHandlers.Add(new ExceptionHandlerInfo(kind, tryStart, tryEnd, handlerStart, handlerEnd, filterStart, catchType));
        }
示例#7
0
        /// <summary>
        /// Encodes a branch instruction.
        /// </summary>
        /// <param name="code">Branch instruction to encode.</param>
        /// <param name="label">Label of the target location in instruction stream.</param>
        /// <exception cref="ArgumentException"><paramref name="code"/> is not a branch instruction.</exception>
        /// <exception cref="ArgumentException"><paramref name="label"/> was not defined by this encoder.</exception>
        /// <exception cref="InvalidOperationException"><see cref="ControlFlowBuilder"/> is null.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="label"/> has default value.</exception>
        public void Branch(ILOpCode code, LabelHandle label)
        {
            // throws if code is not a branch:
            int size = code.GetBranchOperandSize();

            GetBranchBuilder().AddBranch(Offset, label, code);
            OpCode(code);

            // -1 points in the middle of the branch instruction and is thus invalid.
            // We want to produce invalid IL so that if the caller doesn't patch the branches
            // the branch instructions will be invalid in an obvious way.
            if (size == 1)
            {
                CodeBuilder.WriteSByte(-1);
            }
            else
            {
                Debug.Assert(size == 4);
                CodeBuilder.WriteInt32(-1);
            }
        }
示例#8
0
 internal BranchInfo(int ilOffset, LabelHandle label, ILOpCode opCode)
 {
     ILOffset = ilOffset;
     Label    = label;
     _opCode  = (byte)opCode;
 }
示例#9
0
 /// <summary>
 /// Adds catch region.
 /// </summary>
 /// <param name="tryStart">Label marking the first instruction of the try block.</param>
 /// <param name="tryEnd">Label marking the instruction immediately following the try block.</param>
 /// <param name="handlerStart">Label marking the first instruction of the handler.</param>
 /// <param name="handlerEnd">Label marking the instruction immediately following the handler.</param>
 /// <param name="filterStart">Label marking the first instruction of the filter block.</param>
 /// <exception cref="ArgumentException">A label was not defined by an instruction encoder this builder is associated with.</exception>
 /// <exception cref="ArgumentNullException">A label has default value.</exception>
 public void AddFilterRegion(LabelHandle tryStart, LabelHandle tryEnd, LabelHandle handlerStart, LabelHandle handlerEnd, LabelHandle filterStart)
 {
     ValidateLabel(filterStart, nameof(filterStart));
     AddExceptionRegion(ExceptionRegionKind.Filter, tryStart, tryEnd, handlerStart, handlerEnd, filterStart: filterStart);
 }
示例#10
0
 /// <summary>
 /// Adds fault region.
 /// </summary>
 /// <param name="tryStart">Label marking the first instruction of the try block.</param>
 /// <param name="tryEnd">Label marking the instruction immediately following the try block.</param>
 /// <param name="handlerStart">Label marking the first instruction of the handler.</param>
 /// <param name="handlerEnd">Label marking the instruction immediately following the handler.</param>
 /// <exception cref="ArgumentException">A label was not defined by an instruction encoder this builder is associated with.</exception>
 /// <exception cref="ArgumentNullException">A label has default value.</exception>
 public void AddFaultRegion(LabelHandle tryStart, LabelHandle tryEnd, LabelHandle handlerStart, LabelHandle handlerEnd) =>
 AddExceptionRegion(ExceptionRegionKind.Fault, tryStart, tryEnd, handlerStart, handlerEnd);
示例#11
0
 internal void MarkLabel(int ilOffset, LabelHandle label)
 {
     Debug.Assert(ilOffset >= 0);
     ValidateLabel(label, nameof(label));
     _labels[label.Id - 1] = ilOffset;
 }
示例#12
0
 /// <summary>
 /// Associates specified label with the current IL offset.
 /// </summary>
 /// <param name="label">Label to mark.</param>
 /// <remarks>
 /// A single label may be marked multiple times, the last offset wins.
 /// </remarks>
 /// <exception cref="InvalidOperationException"><see cref="ControlFlowBuilder"/> is null.</exception>
 /// <exception cref="ArgumentException"><paramref name="label"/> was not defined by this encoder.</exception>
 /// <exception cref="ArgumentNullException"><paramref name="label"/> has default value.</exception>
 public void MarkLabel(LabelHandle label)
 {
     GetBranchBuilder().MarkLabel(Offset, label);
 }