private void EmitGotoExpression(Expression expr, CompilationFlags flags)
{
var node = (GotoExpression)expr;
LabelInfo labelInfo = ReferenceLabel(node.Target);
CompilationFlags tailCall = flags & CompilationFlags.EmitAsTailCallMask;
if (tailCall != CompilationFlags.EmitAsNoTail)
{
// Since tail call flags are not passed into EmitTryExpression, CanReturn
// means the goto will be emitted as Ret. Therefore we can emit the goto's
// default value with tail call. This can be improved by detecting if the
// target label is equivalent to the return label.
tailCall = labelInfo.CanReturn ? CompilationFlags.EmitAsTail : CompilationFlags.EmitAsNoTail;
flags = UpdateEmitAsTailCallFlag(flags, tailCall);
}
if (node.Value != null)
{
if (node.Target.Type == typeof(void))
{
EmitExpressionAsVoid(node.Value, flags);
}
else
{
flags = UpdateEmitExpressionStartFlag(flags, CompilationFlags.EmitExpressionStart);
EmitExpression(node.Value, flags);
}
}
labelInfo.EmitJump();
EmitUnreachable(node, flags);
}