Опубликован: 28.06.2006 | Уровень: специалист | Доступ: платный | ВУЗ: Московский государственный технический университет им. Н.Э. Баумана
Лекция 6:

Язык CIL: инструкции для поддержки объектной модели

< Лекция 5 || Лекция 6: 1234 || Лекция 7 >
Аннотация: Инструкции для работы с объектами и массивами. Инструкции для работы с типами-значениями и типизированными ссылками.

Язык CIL, в отличие от большинства других ассемблерных языков, содержит богатый набор инструкций, предназначенных для поддержки объектной модели. Этот набор можно разделить на четыре основные категории:

  • инструкции для работы с объектами;
  • инструкции для работы с массивами;
  • инструкции для работы с типами-значениями;
  • инструкции для работы с типизированными ссылками.

Инструкции для работы с объектами

Инструкции для работы с объектами - это базовые инструкции для поддержки объектно-ориентированной парадигмы.

Создание объектов

Инструкция newobj (см. таблицу 3.25) выполняет выделение памяти для объекта в куче и затем вызывает для этого объекта конструктор. Операции выделения памяти и вызова конструктора объединены в одной инструкции не случайно, так как это гарантирует отсутствие в куче неинициализированных объектов.

Таблица 3.25. Инструкция newobj
Код Инструкция Встроенный операнд Описание
0x73 newobj token Создает новый объект и вызывает для него конструктор

Токен метаданных, находящийся во встроенном операнде инструкции, указывает на описатель конструктора в таблицах метаданных. Тип создаваемого объекта определяется через информацию о конструкторе (это тот класс, внутри которого объявлен конструктор).

Диаграмма стека для инструкции newobj:

... , arg1, ... , argN -> ... , obj

Инструкция newobj потребляет со стека вычислений параметры конструктора и оставляет на стеке ссылку на созданный объект. Параметры вызываемого конструктора должны быть расположены в стеке слева направо, то есть сначала на стек должен быть загружен первый аргумент, затем второй и т.д.

Хотя первым (неявным) параметром для любого конструктора является ссылка на инициализируемый объект (параметр this ), перед вызовом инструкции newobj этот параметр не должен загружаться на стек вычислений. Дело в том, что ссылка на объект формируется в процессе выполнения инструкции (после выделения памяти в куче и до вызова конструктора) и затем автоматически передается конструктору. Происходит как бы "подкладывание" ссылки this под другие параметры конструктора на стеке вычислений.

Особый случай применения инструкции newobj связан с созданием экземпляров типов-значений на стеке вычислений. Если указанный во встроенном операнде конструктор принадлежит типу-значению, то новый экземпляр этого типа создается не в куче, а прямо на стеке вычислений.

Проверка типа объекта

В таблице 3.26 приведены две инструкции, осуществляющие проверку типа объекта, ссылка на который лежит на вершине стека вычислений. Токен метаданных, находящийся во встроенном операнде инструкции, указывает на описатель типа в таблицах метаданных.

Таблица 3.26. Инструкции проверки типа объекта
Код Инструкция Встроенный операнд Описание
0x74 castclass token Проверяет, соответствует ли тип объекта на вершине стека. В случае несоответствия генерирует исключение InvalidCastException
0x75 isinst token Проверяет, соответствует ли тип объекта на вершине стека. Если соответствует, то оставляет объект на стеке, в противном случае заменяет объект на null

Диаграмма стека для инструкций проверки типа объекта:

... , obj -> ... , obj

Через инструкции проверки типа объекта реализуются операции приведения типов в языках высокого уровня.

Работа с полями объектов

В таблице 3.27 приведены инструкции, которые загружают на стек вычислений значения и адреса полей объектов, а также сохраняют значения со стека в полях объектов. Токены метаданных во встроенных операндах инструкций указывают на информацию о нужном поле.

Таблица 3.27. Инструкции для работы с полями объектов
Код Инструкция Встроенный операнд Описание
0x7B ldfld token Загружает значение поля объекта. Диаграмма стека:
..., obj -> ..., value
0x7C ldflda token Загружает адрес поля объекта. Диаграмма стека:
..., obj -> ..., addr
0x7D stfld token Сохраняет значение в поле объекта. Диаграмма стека:
..., obj, value -> ...
0x7E ldsfld token Загружает значение статического поля объекта. Диаграмма стека:
... -> ..., value
0x7F ldsflda token Загружает адрес статического поля объекта. Диаграмма стека:
...  -> ..., addr
0x80 stsfld token Сохраняет значение в статическом поле объекта. Диаграмма стека:
..., val -> ...
Вызов виртуальных методов

Инструкция callvirt (см. таблицу 3.28) отличается от инструкции call главным образом тем, что адрес вызываемого метода определяется во время выполнения программы путем анализа типа объекта, для которого вызывается метод. Тем самым реализуется идея позднего связывания, необходимая для поддержки полиморфизма.

Диаграмма стека для инструкции callvirt:

... , obj, arg1, ... , argN -> ... , retVal
Таблица 3.28. Инструкция callvirt
Код Инструкция Встроенный операнд Описание
0x6F callvirt token Вызов метода с использованием позднего связывания

Токен метаданных, находящийся во встроенном операнде инструкции, указывает на информацию о вызываемом методе в таблицах метаданных (имя метода, класс и сигнатура). Определение метода, который нужно вызвать, происходит следующим образом. Система выполнения анализирует класс объекта, для которого вызывается метод (на диаграмме стека этот объект обозначен как obj ), выполняя поиск принадлежащего этому классу экземплярного метода, имеющего нужные имя и сигнатуру. Если такой метод отсутствует, аналогичный поиск производится по порядку на всей цепочке суперклассов, от которых наследует класс объекта. Если в результате метод не будет найден, то генерируется исключение MissingMethodException, но эта ситуация невозможна в верифицированном коде.

Загрузка строковых констант

Для загрузки на стек вычислений строковых констант предусмотрена отдельная инструкция ldstr, приведенная в таблице 3.29. Токен, находящийся во встроенном операнде инструкции, указывает на образ строки в куче пользовательских строк, находящейся в составе метаданных. Инструкция создает объект класса System.String, копирует в него образ строки и оставляет ссылку на созданный объект на вершине стека вычислений.

Таблица 3.29. Инструкция ldstr
Код Инструкция Встроенный операнд Описание
0x72 ldstr token Создает на вершине стека объект-строку

Диаграмма стека для инструкции ldstr:

... -> ... , obj
< Лекция 5 || Лекция 6: 1234 || Лекция 7 >
Анастасия Булинкова
Анастасия Булинкова
Рабочим названием платформы .NET было
Bogdan Drumov
Bogdan Drumov
Молдова, Республика
Azamat Nurmanbetov
Azamat Nurmanbetov
Киргизия, Bishkek