public override unsafe void Complete()
{
// Check there aren't any outstanding exception blocks.
if (this.activeExceptionRegions != null && this.activeExceptionRegions.Count > 0)
throw new InvalidOperationException("The current method contains unclosed exception blocks.");
Return();
FixLabels();
fixed (byte* bytes = this.bytes)
this.dynamicILInfo.SetCode(bytes, this.offset, this.maxStackSize);
this.dynamicILInfo.SetLocalSignature(this.LocalSignature);
if (this.exceptionRegions != null && this.exceptionRegions.Count > 0)
{
// Count the number of exception clauses.
int clauseCount = 0;
foreach (var exceptionRegion in this.exceptionRegions)
clauseCount += exceptionRegion.Clauses.Count;
var exceptionBytes = new byte[4 + 24 * clauseCount];
var writer = new System.IO.BinaryWriter(new System.IO.MemoryStream(exceptionBytes));
// 4-byte header, see Partition II, section 25.4.5.
writer.Write((byte)0x41); // Flags: CorILMethod_Sect_EHTable | CorILMethod_Sect_FatFormat
writer.Write(exceptionBytes.Length); // 3-byte data size.
writer.Flush();
writer.BaseStream.Seek(4, System.IO.SeekOrigin.Begin);
// Exception clauses, see Partition II, section 25.4.6.
foreach (var exceptionRegion in this.exceptionRegions)
{
foreach (var clause in exceptionRegion.Clauses)
{
switch (clause.Type)
{
case ExceptionClauseType.Catch:
writer.Write(0); // Flags
break;
case ExceptionClauseType.Filter:
writer.Write(1); // Flags
break;
case ExceptionClauseType.Finally:
writer.Write(2); // Flags
break;
case ExceptionClauseType.Fault:
writer.Write(4); // Flags
break;
}
writer.Write(exceptionRegion.Start); // TryOffset
writer.Write(clause.ILStart - exceptionRegion.Start); // TryLength
writer.Write(clause.ILStart); // HandlerOffset
writer.Write(clause.ILLength); // HandlerLength
if (clause.Type == ExceptionClauseType.Catch)
writer.Write(clause.CatchToken); // ClassToken
else if (clause.Type == ExceptionClauseType.Filter)
writer.Write(clause.FilterHandlerStart); // FilterOffset
else
writer.Write(0);
}
}
writer.Flush();
this.dynamicILInfo.SetExceptions(exceptionBytes);
}
}