void EndMethodBody(Method method)
{
if (!_returnImplicit)
_returnImplicit = !AstUtil.AllCodePathsReturnOrRaise(method.Body);
//At most a method epilogue contains 3 independent load instructions:
//1) load of the value of an actual return (emitted elsewhere and branched to _returnLabel)
//2) load of a default value (implicit returns [e.g return without expression])
//3) load of the `leave' stored value
bool hasDefaultValueReturn = _returnImplicit && !IsVoid(_returnType);
if (hasDefaultValueReturn)
{
if (_returnStatements == -1) //emit branch only if instructed to do so (-1)
_il.Emit(OpCodes.Br_S, _returnLabel);
//load default return value for implicit return
_il.MarkLabel(_implicitLabel);
EmitDefaultValue(_returnType);
PopType();
}
if (_hasLeaveWithStoredValue)
{
if (hasDefaultValueReturn || _returnStatements == -1)
_il.Emit(OpCodes.Br_S, _returnLabel);
//load the stored return value and `ret'
_il.MarkLabel(_leaveLabel);
_il.Emit(OpCodes.Ldloc, GetDefaultValueHolder(_returnType));
}
if (_returnImplicit || _returnStatements != 0)
{
_il.MarkLabel(_returnLabel);
_il.Emit(OpCodes.Ret);
}
}