Введение

Common Intermediate Language (CIL), ранее называвшийся Microsoft Intermediate Language (MSIL) или Intermediate Language (IL), — это набор бинарных инструкций промежуточного языка, определённый в спецификации Common Language Infrastructure (CLI). Инструкции CIL выполняются средой выполнения, совместимой с CIL, такой как Common Language Runtime. Языки, ориентированные на CLI, компилируются в CIL. CIL является объектно-ориентированным байт-кодом, работающим со стеком. Среды выполнения обычно компилируют инструкции CIL в машинный код "на лету" (just-in-time compilation). Изначально CIL назывался Microsoft Intermediate Language (MSIL) во время бета-версий языков .NET. В связи со стандартизацией C# и CLI, байт-код теперь официально называется CIL. Однако в определениях вирусов Windows Defender бинарные файлы, скомпилированные с его использованием, по-прежнему упоминаются как MSIL.

Метаданные

Общая языковая инфраструктура (CLI) сохраняет информацию о скомпилированных классах в виде метаданных. Подобно библиотеке типов в компонентной объектной модели, это позволяет приложениям поддерживать и обнаруживать интерфейсы, классы, типы, методы и поля в сборке. Процесс чтения таких метаданных называется "рефлексией". Метаданные могут представлять собой данные в форме "атрибутов". Атрибуты можно настраивать, расширяя класс Attribute. Это мощная возможность, позволяющая разработчику класса добавлять к нему дополнительную информацию, которую потребители класса могут использовать различными способами в зависимости от области применения.

Поколение

Сборка CIL и инструкции генерируются либо компилятором, либо утилитой IL Assembler (ILAsm), поставляемой вместе со средой выполнения. Собранный CIL также можно дезассемблировать обратно в код с помощью IL Disassembler (ILDASM). Существуют и другие инструменты, такие как NET Reflector, которые могут декомпилировать CIL в язык высокого уровня (например, C# или Visual Basic). Это делает CIL очень уязвимым для реверс-инжиниринга. Эта особенность характерна и для байт-кода Java. Однако существуют инструменты, способные обфусцировать код, делая его трудночитаемым, но при этом сохраняя возможность выполнения.

Составление "только в срок"

Компиляция JIT (Just-In-Time) предполагает преобразование байт-кода в код, который может быть непосредственно выполнен процессором. Преобразование происходит постепенно в процессе выполнения программы. JIT-компиляция обеспечивает оптимизацию, специфичную для среды исполнения, типобезопасность во время выполнения и проверку сборки. Для этого JIT-компилятор анализирует метаданные сборки на предмет недопустимых обращений и соответствующим образом обрабатывает нарушения.

Предварительная компиляция

Совместимые с CLI среды выполнения также предоставляют возможность компиляции сборки заранее (Ahead of Time, AOT) для повышения скорости выполнения за счет исключения процесса JIT во время работы. В .NET Framework для этого существует специальный инструмент — генератор нативных образов (NGEN), выполняющий AOT. Альтернативным подходом к AOT является CoreRT, позволяющий компилировать код .NET Core в единый исполняемый файл без зависимости от среды выполнения. В Mono также предусмотрена возможность компиляции AOT.