Как удалить последние несколько сегментов Emit IL во время выполнения - PullRequest
1 голос
/ 25 сентября 2019

Как удалить последние несколько сегментов Emit IL во время выполнения

Я попытался изменить некоторую логику в тысяче строк кода, я хочу использовать способ отката IL, чтобы добавить новую логику, избегая измененияпредыдущий код.

простой, например:

Я надеюсь удалить последние несколько сегментов Emit IL и затем выдать новый il, когда isSomeLogic истинно.

void Main()
{
    DynamicMethod methodbuilder = new DynamicMethod("Deserialize" + Guid.NewGuid().ToString(), typeof(void), null);
    var il = methodbuilder.GetILGenerator();
    il.Emit(OpCodes.Ldstr, "Hello World");
    Type[] types = new Type[1]{typeof(string)};
    MethodInfo method = typeof(Console).GetMethod("WriteLine", types);
    il.Emit(OpCodes.Call, method);
    il.Emit(OpCodes.Ret);

    // do some thing...
    var isSomeLogic = true;
    if( isSomeLogic ){
        //remove the il OpCodes.Ret and add new logic Emit
        il.Emit(OpCodes.Ret);
    }

    var func = (Action)methodbuilder.CreateDelegate(typeof(Action));
    func();
}

1 Ответ

3 голосов
/ 25 сентября 2019

ILGenerator только для форвардов.Вы не можете удалить коды операций, которые вы добавили.Вместо этого просто ... не добавлять их?Кроме того, вы можете использовать Label и операции перехода;Ret не обязательно должен находиться на конце метода;Следующее совершенно верно, если стек находится на правильной высоте в ретрите, а высота стека одинакова для всех путей к конкретному месту.

  • делать вещи
  • перейти к X
  • метка: Y
  • сделать больше вещей
  • ret
  • метка: X
  • сделать еще больше вещей
  • переход к Y
...