В исправлении C# Harmony. как сравнить метки в CodeInstruction.labels с известными значениями меток

Итак, у меня есть такой поток IL-кода:

          IL_0047: ldarg.0
    IL_0048: ldc.i4.m1
    IL_0049: stfld int32 classname/innerclassname::'<>1__state'
    IL_004e: ldstr ""
    IL_0053: call void classname::set_aProperty(string)
    IL_0058: ldstr ""
    IL_005d: call void classname::set_aProperty(string)
    IL_0062: call int32 classname::get_aProperty()
    IL_0067: ldc.i4.8
    IL_0068: ble.s IL_0076

Я хочу заменить IL_004e переходом на IL_0067 (например). Класс System.Reflection.Emit.Label непрозрачен. Вы можете сравнить равенство. Но невозможно указать метку, с которой вы хотите ее сравнить, если вы еще не нашли метку посредством отражения. Итак, хотя я вижу, что ярлык существует, я понятия не имею, что это за ярлык. Label.ToString() просто возвращает «System.Reflection.Emit.Label». Есть ли способ создать ярлык:

      if (instruction.labels.Contains(x => x == Label.FromString("IL_0067")))

или какой-то аналогичный метод расширения?

1 ответ

Судя по ответам на этот вопрос , метки — это абстракция для удобства; в байт-коде ассемблера операндом перехода является смещение относительно следующей инструкции. Насколько мне известно, не существует метода создания экземпляра System.Reflection.Emit.Label из имен меток, созданных декомпиляторами.

Однако вы можете ввестиILGeneratorв ваш транспилятор, который вы можете использовать для создания новой метки с помощью ILGenerator.DefineLabel. Вы можете использовать эту метку как операнд перехода и добавить ее в.labelsполе инструкции, к которой вы хотите перейти. Вы можете найти эту целевую инструкцию, просматривая некоторый контекст, например, первую инструкцию послеcallкclassname.get_aProperty.

Для получения дополнительной информации вы можете проверить документацию Harmony: Transpiler — CodeInstruction .

Другие вопросы по тегам