internal void CreateMethodBodyHelper(ILGenerator il)
{
// Sets the IL of the method. An ILGenerator is passed as an argument and the method
// queries this instance to get all of the information which it needs.
if (il == null)
{
throw new ArgumentNullException(nameof(il));
}
__ExceptionInfo[] excp;
int counter = 0;
int[] filterAddrs;
int[] catchAddrs;
int[] catchEndAddrs;
Type[] catchClass;
int[] type;
int numCatch;
int start, end;
ModuleBuilder dynMod = (ModuleBuilder)m_module;
m_containingType.ThrowIfCreated();
if (m_bIsBaked)
{
throw new InvalidOperationException(SR.InvalidOperation_MethodHasBody);
}
if (il.m_methodBuilder != this && il.m_methodBuilder != null)
{
// you don't need to call DefineBody when you get your ILGenerator
// through MethodBuilder::GetILGenerator.
//
throw new InvalidOperationException(SR.InvalidOperation_BadILGeneratorUsage);
}
ThrowIfShouldNotHaveBody();
if (il.m_ScopeTree.m_iOpenScopeCount != 0)
{
// There are still unclosed local scope
throw new InvalidOperationException(SR.InvalidOperation_OpenLocalVariableScope);
}
m_ubBody = il.BakeByteArray();
m_mdMethodFixups = il.GetTokenFixups();
//Okay, now the fun part. Calculate all of the exceptions.
excp = il.GetExceptions();
int numExceptions = CalculateNumberOfExceptions(excp);
if (numExceptions > 0)
{
m_exceptions = new ExceptionHandler[numExceptions];
for (int i = 0; i < excp.Length; i++)
{
filterAddrs = excp[i].GetFilterAddresses();
catchAddrs = excp[i].GetCatchAddresses();
catchEndAddrs = excp[i].GetCatchEndAddresses();
catchClass = excp[i].GetCatchClass();
numCatch = excp[i].GetNumberOfCatches();
start = excp[i].GetStartAddress();
end = excp[i].GetEndAddress();
type = excp[i].GetExceptionTypes();
for (int j = 0; j < numCatch; j++)
{
int tkExceptionClass = 0;
if (catchClass[j] != null)
{
tkExceptionClass = dynMod.GetTypeTokenInternal(catchClass[j]).Token;
}
switch (type[j])
{
case __ExceptionInfo.None:
case __ExceptionInfo.Fault:
case __ExceptionInfo.Filter:
m_exceptions[counter++] = new ExceptionHandler(start, end, filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass);
break;
case __ExceptionInfo.Finally:
m_exceptions[counter++] = new ExceptionHandler(start, excp[i].GetFinallyEndAddress(), filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass);
break;
}
}
}
}
m_bIsBaked = true;
if (dynMod.GetSymWriter() != null)
{
// set the debugging information such as scope and line number
// if it is in a debug module
//
SymbolToken tk = new SymbolToken(MetadataTokenInternal);
ISymbolWriter symWriter = dynMod.GetSymWriter();
// call OpenMethod to make this method the current method
symWriter.OpenMethod(tk);
// call OpenScope because OpenMethod no longer implicitly creating
// the top-levelsmethod scope
//
symWriter.OpenScope(0);
if (m_symCustomAttrs != null)
{
foreach (SymCustomAttr symCustomAttr in m_symCustomAttrs)
{
dynMod.GetSymWriter().SetSymAttribute(
new SymbolToken(MetadataTokenInternal),
symCustomAttr.m_name,
symCustomAttr.m_data);
}
}
if (m_localSymInfo != null)
{
m_localSymInfo.EmitLocalSymInfo(symWriter);
}
il.m_ScopeTree.EmitScopeTree(symWriter);
il.m_LineNumberInfo.EmitLineNumberInfo(symWriter);
symWriter.CloseScope(il.ILOffset);
symWriter.CloseMethod();
}
}