ILGenerator.Emit Método
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
Coloca uma instrução no fluxo Microsoft Intermediate Language (MSIL) para o compilador just-in-time (JIT).
Sobrecargas
| Name | Description |
|---|---|
| Emit(OpCode, LocalBuilder) |
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) seguido pelo índice da variável local dada. |
| Emit(OpCode, Type) |
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) seguida pelo token de metadados para o tipo dado. |
| Emit(OpCode, String) |
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) seguida do token de metadados para a cadeia dada. |
| Emit(OpCode, Single) |
Coloca a instrução e o argumento numérico especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL). |
| Emit(OpCode, SByte) |
Coloca a instrução e o argumento de carácter especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL). |
| Emit(OpCode, MethodInfo) |
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) seguida do token de metadados para o método dado. |
| Emit(OpCode, SignatureHelper) |
Coloca a instrução especificada e um token de assinatura no fluxo de instruções da linguagem intermédia Microsoft (MSIL). |
| Emit(OpCode, Label[]) |
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) e deixa espaço para incluir um rótulo quando as correções são feitas. |
| Emit(OpCode, FieldInfo) |
Coloca a instrução e o token de metadados especificados para o campo especificado no fluxo de instruções da linguagem intermédia Microsoft (MSIL). |
| Emit(OpCode, ConstructorInfo) |
Coloca a instrução e o token de metadados especificados para o construtor especificado no fluxo de instruções da linguagem intermédia Microsoft (MSIL). |
| Emit(OpCode, Int64) |
Coloca a instrução e o argumento numérico especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL). |
| Emit(OpCode, Int32) |
Coloca a instrução e o argumento numérico especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL). |
| Emit(OpCode, Int16) |
Coloca a instrução e o argumento numérico especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL). |
| Emit(OpCode, Double) |
Coloca a instrução e o argumento numérico especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL). |
| Emit(OpCode, Byte) |
Coloca a instrução e o argumento de carácter especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL). |
| Emit(OpCode) |
Coloca a instrução especificada no fluxo de instruções. |
| Emit(OpCode, Label) |
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) e deixa espaço para incluir um rótulo quando as correções são feitas. |
Emit(OpCode, LocalBuilder)
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) seguido pelo índice da variável local dada.
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::LocalBuilder ^ local);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
Public Overridable Sub Emit (opcode As OpCode, local As LocalBuilder)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser emitida no fluxo.
- local
- LocalBuilder
Uma variável local.
Exceções
O método pai do local parâmetro não corresponde ao método associado a este ILGenerator.
local é null.
opcode é uma instrução de um único byte, e local representa uma variável local com um índice maior que Byte.MaxValue.
Observações
Os valores das instruções são definidos na OpCodes enumeração.
Aplica-se a
Emit(OpCode, Type)
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) seguida pelo token de metadados para o tipo dado.
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, Type ^ cls);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, Type cls);
abstract member Emit : System.Reflection.Emit.OpCode * Type -> unit
override this.Emit : System.Reflection.Emit.OpCode * Type -> unit
Public Overridable Sub Emit (opcode As OpCode, cls As Type)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser colocada no fluxo.
- cls
- Type
Um Type.
Exceções
cls é null.
Observações
Os valores das instruções são definidos na OpCodes enumeração. A localização de cls é registada para que o token possa ser atualizado, se necessário, ao persistir o módulo num ficheiro executável portátil (PE).
Aplica-se a
Emit(OpCode, String)
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) seguida do token de metadados para a cadeia dada.
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::String ^ str);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, string str);
abstract member Emit : System.Reflection.Emit.OpCode * string -> unit
override this.Emit : System.Reflection.Emit.OpCode * string -> unit
Public Overridable Sub Emit (opcode As OpCode, str As String)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser emitida no fluxo.
- str
- String
A String ser emitida.
Observações
Os valores das instruções são definidos na OpCodes enumeração. A localização de str é registada para futuras correções se o módulo for mantido num ficheiro executável portátil (PE).
Aplica-se a
Emit(OpCode, Single)
Coloca a instrução e o argumento numérico especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL).
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, float arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, float arg);
abstract member Emit : System.Reflection.Emit.OpCode * single -> unit
override this.Emit : System.Reflection.Emit.OpCode * single -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Single)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser colocada no fluxo.
Observações
Os valores das instruções são definidos na OpCodes enumeração.
Aplica-se a
Emit(OpCode, SByte)
Importante
Esta API não está em conformidade com CLS.
Coloca a instrução e o argumento de carácter especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL).
public:
void Emit(System::Reflection::Emit::OpCode opcode, System::SByte arg);
[System.CLSCompliant(false)]
public void Emit(System.Reflection.Emit.OpCode opcode, sbyte arg);
[<System.CLSCompliant(false)>]
member this.Emit : System.Reflection.Emit.OpCode * sbyte -> unit
Public Sub Emit (opcode As OpCode, arg As SByte)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser colocada no fluxo.
- arg
- SByte
O argumento do carácter foi empurrado para o stream imediatamente após a instrução.
- Atributos
Observações
Os valores das instruções são definidos na OpCodes enumeração.
Aplica-se a
Emit(OpCode, MethodInfo)
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) seguida do token de metadados para o método dado.
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::MethodInfo ^ meth);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
Public Overridable Sub Emit (opcode As OpCode, meth As MethodInfo)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser emitida no fluxo.
- meth
- MethodInfo
A MethodInfo representa um método.
Exceções
meth é null.
meth é um método genérico para o qual a IsGenericMethodDefinition propriedade é false.
Observações
Os valores das instruções são definidos na OpCodes enumeração.
A localização de meth é registada para que o fluxo de instruções possa ser corrigido, se necessário, ao persistir o módulo para um ficheiro executável portátil (PE).
Se meth representa um método genérico, deve ser uma definição genérica de método. Ou seja, a sua propriedade MethodInfo.IsGenericMethodDefinition deve ser true.
Aplica-se a
Emit(OpCode, SignatureHelper)
Coloca a instrução especificada e um token de assinatura no fluxo de instruções da linguagem intermédia Microsoft (MSIL).
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::SignatureHelper ^ signature);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
Public Overridable Sub Emit (opcode As OpCode, signature As SignatureHelper)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser emitida no fluxo.
- signature
- SignatureHelper
Um auxiliar para construir um token de assinatura.
Exceções
signature é null.
Observações
Os valores das instruções são definidos na OpCodes enumeração.
Aplica-se a
Emit(OpCode, Label[])
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) e deixa espaço para incluir um rótulo quando as correções são feitas.
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, cli::array <System::Reflection::Emit::Label> ^ labels);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
Public Overridable Sub Emit (opcode As OpCode, labels As Label())
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser emitida no fluxo.
- labels
- Label[]
O array de objetos de etiquetas para os quais se ramifica a partir desta localização. Todas as etiquetas serão usadas.
Exemplos
O exemplo de código abaixo ilustra a criação de um método dinâmico com uma tabela de salto. A tabela de salto é construída usando um array de Label.
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
Observações
Emite uma mesa de interruptores.
Os valores das instruções são definidos na OpCodes enumeração.
As etiquetas são criadas usando DefineLabel e a sua localização dentro do fluxo é fixada usando MarkLabel. Se for usada uma instrução de um byte, o rótulo pode representar um salto de no máximo 127 bytes ao longo do fluxo.
opcode deve representar uma instrução de desvio. Como os ramos são instruções relativas, label serão substituídos pelo deslocamento correto para ramificar durante o processo de fixup.
Aplica-se a
Emit(OpCode, FieldInfo)
Coloca a instrução e o token de metadados especificados para o campo especificado no fluxo de instruções da linguagem intermédia Microsoft (MSIL).
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::FieldInfo ^ field);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
Public Overridable Sub Emit (opcode As OpCode, field As FieldInfo)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser emitida no fluxo.
- field
- FieldInfo
A FieldInfo representa um campo.
Observações
Os valores das instruções são definidos na OpCodes enumeração. A localização de field é registada para que o fluxo de instruções possa ser corrigido, se necessário, ao persistir o módulo para um ficheiro executável portátil (PE).
Aplica-se a
Emit(OpCode, ConstructorInfo)
Coloca a instrução e o token de metadados especificados para o construtor especificado no fluxo de instruções da linguagem intermédia Microsoft (MSIL).
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::ConstructorInfo ^ con);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
[System.Runtime.InteropServices.ComVisible(true)]
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
[<System.Runtime.InteropServices.ComVisible(true)>]
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
Public Overridable Sub Emit (opcode As OpCode, con As ConstructorInfo)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser emitida no fluxo.
- con
- ConstructorInfo
A ConstructorInfo representa um construtor.
- Atributos
Exceções
con é null.
Observações
Os valores das instruções são definidos na OpCodes enumeração.
A localização de con é registada para que o fluxo de instruções possa ser corrigido, se necessário, ao persistir o módulo para um ficheiro executável portátil (PE).
Aplica-se a
Emit(OpCode, Int64)
Coloca a instrução e o argumento numérico especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL).
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, long arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, long arg);
abstract member Emit : System.Reflection.Emit.OpCode * int64 -> unit
override this.Emit : System.Reflection.Emit.OpCode * int64 -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Long)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser colocada no fluxo.
- arg
- Int64
O argumento numérico foi empurrado para o fluxo imediatamente após a instrução.
Observações
Os valores das instruções são definidos na OpCodes enumeração.
Aplica-se a
Emit(OpCode, Int32)
Coloca a instrução e o argumento numérico especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL).
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, int arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, int arg);
abstract member Emit : System.Reflection.Emit.OpCode * int -> unit
override this.Emit : System.Reflection.Emit.OpCode * int -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Integer)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser colocada no fluxo.
- arg
- Int32
O argumento numérico foi empurrado para o fluxo imediatamente após a instrução.
Observações
Os valores das instruções são definidos na OpCodes enumeração.
Aplica-se a
Emit(OpCode, Int16)
Coloca a instrução e o argumento numérico especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL).
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, short arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, short arg);
abstract member Emit : System.Reflection.Emit.OpCode * int16 -> unit
override this.Emit : System.Reflection.Emit.OpCode * int16 -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Short)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser emitida no fluxo.
- arg
- Int16
O Int argumento foi levado para o stream imediatamente após a instrução.
Observações
Os valores das instruções são definidos na OpCodes enumeração.
Aplica-se a
Emit(OpCode, Double)
Coloca a instrução e o argumento numérico especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL).
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, double arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, double arg);
abstract member Emit : System.Reflection.Emit.OpCode * double -> unit
override this.Emit : System.Reflection.Emit.OpCode * double -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Double)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser colocada no fluxo. Definido na OpCodes enumeração.
- arg
- Double
O argumento numérico foi empurrado para o fluxo imediatamente após a instrução.
Observações
Os valores das instruções são definidos na OpCodes enumeração.
Aplica-se a
Emit(OpCode, Byte)
Coloca a instrução e o argumento de carácter especificados no fluxo de instruções da linguagem intermédia Microsoft (MSIL).
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Byte arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, byte arg);
abstract member Emit : System.Reflection.Emit.OpCode * byte -> unit
override this.Emit : System.Reflection.Emit.OpCode * byte -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Byte)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser colocada no fluxo.
- arg
- Byte
O argumento do carácter foi empurrado para o stream imediatamente após a instrução.
Observações
Os valores das instruções são definidos na OpCodes enumeração.
Aplica-se a
Emit(OpCode)
Coloca a instrução especificada no fluxo de instruções.
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode);
public virtual void Emit(System.Reflection.Emit.OpCode opcode);
abstract member Emit : System.Reflection.Emit.OpCode -> unit
override this.Emit : System.Reflection.Emit.OpCode -> unit
Public Overridable Sub Emit (opcode As OpCode)
Parâmetros
- opcode
- OpCode
A instrução Microsoft Intermediate Language (MSIL) deve ser colocada no fluxo.
Exemplos
O exemplo de código abaixo demonstra a utilização de Emit para gerar saída MSIL através de uma instância de ILGenerator.
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
Observações
Se o opcode parâmetro exigir um argumento, o chamador deve garantir que o comprimento do argumento coincide com o comprimento do parâmetro declarado. Caso contrário, os resultados serão imprevisíveis. Por exemplo, se a instrução Emit exigir um operando de 2 bytes e o chamador fornecer um operando de 4 bytes, o runtime emitirá dois bytes adicionais para o fluxo de instruções. Estes bytes extra serão Nop instruções.
Os valores das instruções são definidos em OpCodes.
Aplica-se a
Emit(OpCode, Label)
Coloca a instrução especificada no fluxo da linguagem intermédia Microsoft (MSIL) e deixa espaço para incluir um rótulo quando as correções são feitas.
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::Label label);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
Public Overridable Sub Emit (opcode As OpCode, label As Label)
Parâmetros
- opcode
- OpCode
A instrução MSIL para ser emitida no fluxo.
- label
- Label
A editora para onde ramificar a partir deste local.
Exemplos
O exemplo de código abaixo ilustra a criação de um método dinâmico com uma tabela de salto. A tabela de salto é construída usando um array de Label.
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
Observações
Os valores das instruções são definidos na OpCodes enumeração.
As etiquetas são criadas usando DefineLabel, e a sua localização dentro do fluxo é fixada usando MarkLabel. Se for usada uma instrução de um byte, o rótulo pode representar um salto de no máximo 127 bytes ao longo do fluxo.
opcode deve representar uma instrução de desvio. Como os ramos são instruções relativas, label serão substituídos pelo deslocamento correto para ramificar durante o processo de fixup.