InstructionEncoder Struktura

Definicja

Koduje instrukcje języka Common Intermediate Language (CIL).

public value class InstructionEncoder
public readonly struct InstructionEncoder
public struct InstructionEncoder
type InstructionEncoder = struct
Public Structure InstructionEncoder
Dziedziczenie
InstructionEncoder

Przykłady

W tym przykładzie pokazano, jak emitować treść metody przy użyciu polecenia InstructionEncoder:

// The following code emits a method body similar to this C# code:

/*public static double CalcRectangleArea(double length, double width)
{
    if (length < 0.0)
    {
        throw new ArgumentOutOfRangeException("length");
    }

    if (width < 0.0)
    {
        throw new ArgumentOutOfRangeException("width");
    }

    return length * width;
}*/

private static InstructionEncoder EmitMethodBody(MetadataBuilder metadata, AssemblyReferenceHandle corlibAssemblyRef)
{
    var codeBuilder = new BlobBuilder();
    var encoder = new InstructionEncoder(codeBuilder, new ControlFlowBuilder());

    // Get a reference to the System.ArgumentOutOfRangeException type
    TypeReferenceHandle typeRefHandle = metadata.AddTypeReference(
    corlibAssemblyRef,
    metadata.GetOrAddString("System"),
    metadata.GetOrAddString("ArgumentOutOfRangeException"));

    // Signature: .ctor(string)
    var ctorSignature = new BlobBuilder();

    new BlobEncoder(ctorSignature).
        MethodSignature(isInstanceMethod: true).
        Parameters(1, returnType => returnType.Void(), parameters => parameters.AddParameter().Type().String());

    BlobHandle ctorBlobIndex = metadata.GetOrAddBlob(ctorSignature);

    // Get a reference to the System.ArgumentOutOfRangeException constructor
    MemberReferenceHandle ctorMemberRef = metadata.AddMemberReference(
        typeRefHandle,
        metadata.GetOrAddString(".ctor"),
        ctorBlobIndex);

    LabelHandle label1 = encoder.DefineLabel();
    LabelHandle label2 = encoder.DefineLabel();

    // ldarg.0
    encoder.OpCode(ILOpCode.Ldarg_0);

    // ldc.r8 0
    encoder.LoadConstantR8(0);

    // bge.un.s LABEL1
    encoder.Branch(ILOpCode.Bge_un_s, label1);

    // ldstr "length"
    encoder.LoadString(metadata.GetOrAddUserString("length"));

    // newobj instance void [System.Runtime]System.ArgumentOutOfRangeException::.ctor(string)
    encoder.OpCode(ILOpCode.Newobj);
    encoder.Token(ctorMemberRef);

    // throw
    encoder.OpCode(ILOpCode.Throw);

    // LABEL1: ldarg.1
    encoder.MarkLabel(label1);
    encoder.OpCode(ILOpCode.Ldarg_1);

    // ldc.r8 0
    encoder.LoadConstantR8(0);

    // bge.un.s LABEL2
    encoder.Branch(ILOpCode.Bge_un_s, label2);

    // ldstr "width"
    encoder.LoadString(metadata.GetOrAddUserString("width"));

    // newobj instance void [System.Runtime]System.ArgumentOutOfRangeException::.ctor(string)
    encoder.OpCode(ILOpCode.Newobj);
    encoder.Token(ctorMemberRef);

    // throw
    encoder.OpCode(ILOpCode.Throw);

    // LABEL2: ldarg.0
    encoder.MarkLabel(label2);
    encoder.OpCode(ILOpCode.Ldarg_0);

    // ldarg.1
    encoder.OpCode(ILOpCode.Ldarg_1);

    // mul
    encoder.OpCode(ILOpCode.Mul);

    // ret
    encoder.OpCode(ILOpCode.Ret);

    return encoder;
}

Uwagi

Klasa InstructionEncoder służy do emitowania instrukcji CIL tworzących treść metody. Pełny przykład emitowania metody można znaleźć w MetadataBuilder dokumentacji klasy.

Konstruktory

InstructionEncoder(BlobBuilder, ControlFlowBuilder)

Tworzy koder wspierany przez konstruktory kodu i przepływu sterowania.

Właściwości

CodeBuilder

Konstruktor bazowy, w którym są zapisywane zakodowane instrukcje.

ControlFlowBuilder

Konstruktor śledzenia etykiet, gałęzi i procedur obsługi wyjątków.

Offset

Przesunięcie następnej zakodowanej instrukcji.

Metody

Branch(ILOpCode, LabelHandle)

Koduje instrukcję gałęzi.

Call(EntityHandle)

Koduje instrukcje call i jego operand.

Call(MemberReferenceHandle)

Koduje instrukcje call i jego operand.

Call(MethodDefinitionHandle)

Koduje instrukcje call i jego operand.

Call(MethodSpecificationHandle)

Koduje instrukcje call i jego operand.

CallIndirect(StandaloneSignatureHandle)

Koduje instrukcje calli i jego operand.

DefineLabel()

Definiuje etykietę, która może być później używana do oznaczania i odwoływania się do lokalizacji w strumieniu instrukcji.

LoadArgument(Int32)

Koduje instrukcję ładowania argumentów.

LoadArgumentAddress(Int32)

Koduje instrukcję ładowania argumentów.

LoadConstantI4(Int32)

Koduje stałą Int32 instrukcję ładowania.

LoadConstantI8(Int64)

Koduje stałą Int64 instrukcję ładowania.

LoadConstantR4(Single)

Koduje stałą Single instrukcję ładowania.

LoadConstantR8(Double)

Koduje stałą Double instrukcję ładowania.

LoadLocal(Int32)

Koduje instrukcje ładowania zmiennych lokalnych.

LoadLocalAddress(Int32)

Koduje instrukcje ładowania adresów zmiennych lokalnych.

LoadString(UserStringHandle)

Koduje instrukcje ldstr i jego operand.

MarkLabel(LabelHandle)

Kojarzy określoną etykietę z bieżącym przesunięciem IL.

OpCode(ILOpCode)

Koduje określony kod op-code.

StoreArgument(Int32)

Koduje instrukcje magazynu argumentów.

StoreLocal(Int32)

Koduje instrukcje magazynu zmiennych lokalnych.

Switch(Int32)

Rozpoczyna kodowanie instrukcji przełącznika.

Token(EntityHandle)

Koduje token.

Token(Int32)

Koduje token.

Dotyczy