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)); }
/// <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); }
private int GetLabelOffsetChecked(LabelHandle label) { int offset = _labels[label.Id - 1]; if (offset < 0) { Throw.InvalidOperation_LabelNotMarked(label.Id); } return(offset); }
private void ValidateLabel(LabelHandle label, string parameterName) { if (label.IsNil) { Throw.ArgumentNull(parameterName); } if (label.Id > _labels.Count) { Throw.LabelDoesntBelongToBuilder(parameterName); } }
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; }
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)); }
/// <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); } }
internal BranchInfo(int ilOffset, LabelHandle label, ILOpCode opCode) { ILOffset = ilOffset; Label = label; _opCode = (byte)opCode; }
/// <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); }
/// <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);
internal void MarkLabel(int ilOffset, LabelHandle label) { Debug.Assert(ilOffset >= 0); ValidateLabel(label, nameof(label)); _labels[label.Id - 1] = ilOffset; }
/// <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); }