Каким образом CLR C# компилирует байткод,
задача, есть байткод, на выход машинный код, с такой задачей справляется допустим ILGenerator.
Почему байткод не через ILGenerator компилируется? Типа не понимаю, почему разработчики типа самое вкусное себе оставили, а клиенту, типа на получи фигу.
Я не могут понять как откомпилировать метод, если он содержит вызовы на еще не скомпилированные методы.
- Тут либо сразу фул статическая компиляция
- либо N! Факториал перекомпиляций ждет. (зато последняя компиляция вернет весь код одним методом в процедурном стиле наверное)
В учебниках написано, сделать заглушку. Это ILGenerator позволяет. Можно сделать Jump из метода в спец метод. Окей, скомпилировали такой метод.
il.Emit(OpCodes.Jmp, getMethod(_break));
...
void _break(int indexFunc){
// вызвать в режиме интерпретатора функцию
}
Теперь когда внутренняя функция откомпилируется, то ее адрес вызова должен вставляется туда вместо Jmp, и еще скорей даже вместо OpCodes.Jump должно быть OpCodesCall, что бы управление вернуть.
Замена пары байтов, Но ILGenerator мне не позволяет этого сделать, и через рефлексию не удается Итог мне нужно пересоздавать весь метод, что довольно долго.
Но самое страшное дальше. Окей перекомпилировали. Но внутренний метод так же будет содержать заглушки, отсюда и он должен быть перекомпилирован, и так по всем возможным путям графа потока управления.
И
перекомпиляция это не перекомпиляция, это создания вообще другого метода, так как среда не дает мне пересоздавать тот же метод. А после того как его пересоздали, то теперь внешний метод будет содержать ссылку на старую версию метода, и мне ее опять ILGenerator не дает заменить, и мне и его нужно пересоздавать, и Так все все возможные комбинации.
В общем вопросы, такие,
как можно обновить ссылку Метода.
Как можно его перекомпилировать. После создания IL кода динамического метода.
Есть какие DynamicILInfo.SetCode но не работает, сколько не пытался
Возможно там ка-то можно, есть сотни методов, дор которых еще не добрался.