Составители:
Рубрика:
Напомним также, что каждое предложение в массиве EH имеет следу-
ющий набор полей:
• Flags.
Задает тип обработчика исключений: обработчик с фильтрацией
по типу, обработчик с пользовательской фильтрацией, обработ-
чик finally или обработчик fault.
• TryOffset.
Номер инструкции в массиве P, с которой начинается защищен-
ная область.
• TryLength.
Количество инструкций, входящих в защищенную область.
• HandlerOffset.
Номер инструкции в массиве P, с которой начинается область
обработчика.
• HandlerLength.
Количество инструкций, входящих в область обработчика.
• ClassToken.
Токен метаданных, обозначающий тип исключения (использу-
ется в случае обработчика с фильтрацией по типу).
• FilterOffset.
Номер инструкции в массиве P, с которой начинается область
фильтра (используется в случае обработчика с пользовательской
фильтрацией).
4.2.1. Создание массива узлов
На первом этапе работы алгоритма мы создаем узел графа для каждой
инструкции и формируем из созданных узлов массив.
На входе первого этапа мы имеем массив P. Для каждой инструкции,
входящей в массив P, мы создаем соответствующий ей узел графа. В этот
узел записываются все данные об инструкции, кроме информации о пере-
даче управления и принадлежности блокам. Другими словами, созданные
узлы не связываются друг с другом дугами и не имеют ссылки на родитель-
ский блок.
Узлы записываются в массив Nodes, состоящий из N элементов. При
этом в массиве Nodes сохраняется порядок инструкций, то есть если неко-
торая инструкция располагается в массиве P по индексу i, то соответству-
ющий ей узел будет размещен в i-том элементе массива Nodes.
На C#-подобном псевдоязыке первый этап работы алгоритма можно
записать следующим образом:
Nodes = новый массив узлов размера N;
for (int i = 0; i < N; i++)
{
Анализ кода на CIL
141
Однако путем введения в граф дополнительных дуг, задающих иерар-
хию блоков, мы можем сделать операцию поиска блока, в который непо-
средственно входит некоторая инструкция, очень эффективной.
Пусть каждый узел графа, кроме блока тела метода, будет соединен
особой дугой с блоком, в который этот узел непосредственно входит. В ре-
зультате добавления таких дуг в структуре графа получается дерево блоков.
На рис. 4.4 изображена схема такого дерева, на которой наши дополни-
тельные дуги обозначены незакрашенными стрелками, а дуги, соединяю-
щие защищенные блоки с блоками обработки исключений, обозначены
пунктирными стрелками. Обычные дуги графа потока управления, задаю-
щие передачу управления между инструкциями, на схеме не изображены.
Понятно, что операция поиска блока, в который входит инструкция,
на графе, включающем дерево блоков, сводится к переходу по одной дуге
от инструкции к блоку. Эта операция выполняется за константное время,
то есть не зависит ни от количества защищенных блоков, ни от количест-
ва инструкций в блоке.
4.2. Преобразование линейной
последовательности инструкций
в граф потока управления
Разработчик любого метаинструмента, использующего граф потока
управления в процессе анализа CIL-кода, сталкивается с проблемой преоб-
разования линейной последовательности инструкций в граф потока упра-
вления. В данной главе мы рассмотрим алгоритм такого преобразования.
Наш алгоритм будет работать на уровне метода, то есть в качестве
входных данных для него будут выступать тело метода и массив предложе-
ний обработки исключений для этого метода. На выходе алгоритма будет
построенный граф потока управления. Таким образом, для того чтобы по-
строить набор графов потока управления для всей сборки, необходимо за-
пустить этот алгоритм для каждого метода, входящего в сборку.
Итак, пусть дан массив инструкций P размера N и массив предложе-
ний обработки исключений EH размера M. Требуется построить граф пото-
ка управления и возвратить ссылку на блок тела метода построенного
графа.
Мы будем предполагать, что в массивах P и EH адреса инструкций
предварительно заменены на их номера (это касается встроенных операн-
дов инструкций перехода, а также границ областей в предложениях обра-
ботки исключений). Кроме того, все массивы, которые мы будем рассма-
тривать при описании алгоритма, включая массивы P и EH, будут индекси-
роваться, начиная с нуля.
140
CIL и системное программирование в Microsoft .NET
140 CIL и системное программирование в Microsoft .NET Анализ кода на CIL 141
Однако путем введения в граф дополнительных дуг, задающих иерар- Напомним также, что каждое предложение в массиве EH имеет следу-
хию блоков, мы можем сделать операцию поиска блока, в который непо- ющий набор полей:
средственно входит некоторая инструкция, очень эффективной. • Flags.
Пусть каждый узел графа, кроме блока тела метода, будет соединен Задает тип обработчика исключений: обработчик с фильтрацией
особой дугой с блоком, в который этот узел непосредственно входит. В ре- по типу, обработчик с пользовательской фильтрацией, обработ-
зультате добавления таких дуг в структуре графа получается дерево блоков. чик finally или обработчик fault.
На рис. 4.4 изображена схема такого дерева, на которой наши дополни- • TryOffset.
тельные дуги обозначены незакрашенными стрелками, а дуги, соединяю- Номер инструкции в массиве P, с которой начинается защищен-
щие защищенные блоки с блоками обработки исключений, обозначены ная область.
пунктирными стрелками. Обычные дуги графа потока управления, задаю- • TryLength.
щие передачу управления между инструкциями, на схеме не изображены. Количество инструкций, входящих в защищенную область.
Понятно, что операция поиска блока, в который входит инструкция, • HandlerOffset.
на графе, включающем дерево блоков, сводится к переходу по одной дуге Номер инструкции в массиве P, с которой начинается область
от инструкции к блоку. Эта операция выполняется за константное время, обработчика.
то есть не зависит ни от количества защищенных блоков, ни от количест- • HandlerLength.
ва инструкций в блоке. Количество инструкций, входящих в область обработчика.
• ClassToken.
4.2. Преобразование линейной Токен метаданных, обозначающий тип исключения (использу-
ется в случае обработчика с фильтрацией по типу).
последовательности инструкций • FilterOffset.
в граф потока управления Номер инструкции в массиве P, с которой начинается область
фильтра (используется в случае обработчика с пользовательской
Разработчик любого метаинструмента, использующего граф потока фильтрацией).
управления в процессе анализа CIL-кода, сталкивается с проблемой преоб-
разования линейной последовательности инструкций в граф потока упра- 4.2.1. Создание массива узлов
вления. В данной главе мы рассмотрим алгоритм такого преобразования. На первом этапе работы алгоритма мы создаем узел графа для каждой
Наш алгоритм будет работать на уровне метода, то есть в качестве инструкции и формируем из созданных узлов массив.
входных данных для него будут выступать тело метода и массив предложе- На входе первого этапа мы имеем массив P. Для каждой инструкции,
ний обработки исключений для этого метода. На выходе алгоритма будет входящей в массив P, мы создаем соответствующий ей узел графа. В этот
построенный граф потока управления. Таким образом, для того чтобы по- узел записываются все данные об инструкции, кроме информации о пере-
строить набор графов потока управления для всей сборки, необходимо за- даче управления и принадлежности блокам. Другими словами, созданные
пустить этот алгоритм для каждого метода, входящего в сборку. узлы не связываются друг с другом дугами и не имеют ссылки на родитель-
Итак, пусть дан массив инструкций P размера N и массив предложе- ский блок.
ний обработки исключений EH размера M. Требуется построить граф пото- Узлы записываются в массив Nodes, состоящий из N элементов. При
ка управления и возвратить ссылку на блок тела метода построенного этом в массиве Nodes сохраняется порядок инструкций, то есть если неко-
графа. торая инструкция располагается в массиве P по индексу i, то соответству-
Мы будем предполагать, что в массивах P и EH адреса инструкций ющий ей узел будет размещен в i-том элементе массива Nodes.
предварительно заменены на их номера (это касается встроенных операн- На C#-подобном псевдоязыке первый этап работы алгоритма можно
дов инструкций перехода, а также границ областей в предложениях обра- записать следующим образом:
ботки исключений). Кроме того, все массивы, которые мы будем рассма- Nodes = новый массив узлов размера N;
тривать при описании алгоритма, включая массивы P и EH, будут индекси- for (int i = 0; i < N; i++)
роваться, начиная с нуля. {
Страницы
- « первая
- ‹ предыдущая
- …
- 75
- 76
- 77
- 78
- 79
- …
- следующая ›
- последняя »
