Поделиться через


InstructionEncoder Структура

Определение

Кодирует инструкции CIL.

public value class InstructionEncoder
public readonly struct InstructionEncoder
public struct InstructionEncoder
type InstructionEncoder = struct
Public Structure InstructionEncoder
Наследование
InstructionEncoder

Примеры

В этом примере показано, как создать тело метода с помощью 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;
}

Комментарии

Класс InstructionEncoder используется для выдачи инструкций CIL, составляющих тело метода. Полный пример создания метода см. в документации по классу MetadataBuilder .

Конструкторы

InstructionEncoder(BlobBuilder, ControlFlowBuilder)

Создает кодировщик, поддерживающий код и сборщики потока управления.

Свойства

CodeBuilder

Базовый построитель, в котором записываются закодированные инструкции.

ControlFlowBuilder

Метки отслеживания построителя, ветви и обработчики исключений.

Offset

Смещение следующей закодированной инструкции.

Методы

Branch(ILOpCode, LabelHandle)

Кодирует инструкцию ветви.

Call(EntityHandle)

Кодирует инструкцию call и ее операнд.

Call(MemberReferenceHandle)

Кодирует инструкцию call и ее операнд.

Call(MethodDefinitionHandle)

Кодирует инструкцию call и ее операнд.

Call(MethodSpecificationHandle)

Кодирует инструкцию call и ее операнд.

CallIndirect(StandaloneSignatureHandle)

Кодирует инструкцию calli и ее операнд.

DefineLabel()

Определяет метку, которую впоследствии можно использовать для пометки и ссылки на расположение в потоке инструкций.

LoadArgument(Int32)

Кодирует инструкцию загрузки аргументов.

LoadArgumentAddress(Int32)

Кодирует инструкцию загрузки адреса аргумента.

LoadConstantI4(Int32)

Кодирует инструкцию загрузки константы Int32.

LoadConstantI8(Int64)

Кодирует инструкцию загрузки константы Int64.

LoadConstantR4(Single)

Кодирует инструкцию загрузки константы Single.

LoadConstantR8(Double)

Кодирует инструкцию загрузки константы Double.

LoadLocal(Int32)

Кодирует инструкцию загрузки локальных переменных.

LoadLocalAddress(Int32)

Кодирует инструкцию загрузки адресов локальной переменной.

LoadString(UserStringHandle)

Кодирует инструкцию ldstr и ее операнд.

MarkLabel(LabelHandle)

Связывает указанную метку с текущим смещением IL.

OpCode(ILOpCode)

Кодирует указанный код операции.

StoreArgument(Int32)

Кодирует инструкцию хранилища аргументов.

StoreLocal(Int32)

Кодирует инструкцию хранилища локальной переменной.

Switch(Int32)

Начинает кодирование инструкции переключателя.

Token(EntityHandle)

Кодирует маркер.

Token(Int32)

Кодирует маркер.

Применяется к