Метод MethodBody.GetILAsByteArray(); возвращает IL-код в байтовом представлении, сие ясно. Однако я не нашел конкретики в описании работы данного метода на MSDN: возвращает ли он "дословную" инструкцию, которую описывал я, либо же эта функция возвращает именно ту инструкцию, которая будет исполняться?
Поясню:
В Debug-режиме компилятор никак не оптимизирует код, так что
исполняемая инструкция идентична той, которую описывал сам
программист.
В Release-режиме же компилятор инлайнит, упраздняет и в целом
меняет многие вещи, так что конечная исполняемая инструкция может
серьезно разниться с тем, что изначально описывалось.
Влияет ли как-то на GetILAsByteArray() режим компиляции, или же данный метод всегда возвращает "дословную" инструкцию метода?
Ответ
Влияет ли как-то на GetILAsByteArray() режим компиляции
Ответ - "да". В этом легко убедиться на практике. Напишем тестовый метод:
public void Method(int a, int b)
{
string str = (a+b).ToString();
MessageBox.Show(str);
}
Далее, напишем такой код для извлечения первого операнда из его MSIL-кода и отображения имени операции:
using System;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
...
var mi = this.GetType().GetMethod("Method");
byte[] msil = mi.GetMethodBody().GetILAsByteArray();
ushort op;
if(msil[0]==0xfe)
op = (ushort)(msil[1] | 0xfe00);
else
op = (ushort)(msil[0]);
//найдем имя операции
string str="";
FieldInfo[] mas = typeof(OpCodes).GetFields();
for(int i=0;i
Результат:
Debug - 0x0000: nop
Release - 0x0003: ldarg.1
Объясняется это тем, что в отладочной сборке в начале каждого метода вставляется пустой оператор для облегчения отладки (чтобы можно было поставить точку останова на самое начало метода, тогда как в релизной сборке можно только на первую строку). Таким образом, режим компиляции действительно влияет на IL-код метода.
Комментариев нет:
Отправить комментарий