OpCodes.Tailcall 字段


执行后缀的方法调用指令,以便在执行实际调用指令前移除当前方法的堆栈帧。Performs a postfixed method call instruction such that the current method's stack frame is removed before the actual call instruction is executed.

public: static initonly System::Reflection::Emit::OpCode Tailcall;
public static readonly System.Reflection.Emit.OpCode Tailcall;
 staticval mutable Tailcall : System.Reflection.Emit.OpCode
Public Shared ReadOnly Tailcall As OpCode 



下表列出了指令的十六进制和 Microsoft 中间语言(MSIL)程序集格式以及简短的参考摘要:The following table lists the instruction's hexadecimal and Microsoft Intermediate Language (MSIL) assembly format, along with a brief reference summary:

格式Format 程序集格式Assembly Format 说明Description
FE 14FE 14 侧.tail. 后续调用终止当前方法Subsequent call terminates current methods

没有为此指令定义堆栈转换行为。There is no stack transition behavior defined for this instruction.

@No__t 的前缀指令必须紧跟在 CallCalli 或 @no__t 3 指令之前。The tail prefix instruction must immediately precede a Call, Calli, or Callvirt instruction. 它指示在执行调用指令之前应移除当前方法的堆栈帧。It indicates that the current method's stack frame should be removed before the call instruction is executed. 它还意味着从以下调用返回的值也是当前方法返回的值,因此可以将调用转换为交叉方法跳转。It also implies that the value returned from the following call is also the value returned by the current method, and the call can therefore be converted into a cross-method jump.

堆栈必须为空,但通过以下调用传输的参数除外。The stack must be empty except for the arguments being transferred by the following call. 调用指令后面的指令必须是 ret。因此,唯一有效的代码序列是 tail. call (或 callicallvirt)。The instruction following the call instruction must be a ret. Thus the only valid code sequence is tail. call (or calli or callvirt). 更正 Microsoft 中间语言(MSIL)指令不得作为 call 指令的分支,但它们可能会分支到后续的 @no__t。Correct Microsoft Intermediate Language (MSIL) instructions must not branch to the call instruction, but they may branch to the subsequent Ret.

如果控件从不受信任的代码传输到受信任的代码,则无法放弃当前帧,因为这会危及代码标识安全性。The current frame cannot be discarded when control is transferred from untrusted code to trusted code, since this would jeopardize code identity security. 因此,.NET Framework 安全检查可能会导致忽略 @no__t,而保留标准 @no__t 1 指令。The .NET Framework security checks can therefore cause the tail to be ignored, leaving a standard Call instruction. 同样,若要允许在调用返回后退出已同步的区域,则在使用退出标记为同步的方法时,将忽略 @no__t 的前缀。Similarly, in order to allow the exit of a synchronized region to occur after the call returns, the tail prefix is ignored when used to exit a method that is marked synchronized.

以下 @no__t 0 方法重载可以使用 @no__t 操作码:The following Emit method overload can use the tail opcode:

  • ILGenerator.Emit(OpCode)ILGenerator.Emit(OpCode)