Common Intermediate Language и системное программирование в Microsoft.Net. Макаров А.В - 65 стр.

UptoLike

Основная трудность для понимания деталей реализации обработки
исключений в CLI заключается в том, что обработка исключений частично
закодирована в телах методов (в виде специальных инструкций), а частич-
но – в заголовках методов. Скорее всего, такая смешанная схема была вы-
брана разработчиками CLI для обеспечения компактности сборок. Поэто-
му мы в данном разделе сначала рассмотрим ту часть информации об обра-
ботке исключений, которая расположена в заголовках методов, затем пе-
рейдем к инструкциям CIL и, в конце концов, свяжем все воедино, приве-
дя семантику обработки исключений виртуальной системой выполнения.
3.4.1. Предложения обработки исключений в заголовках методов
Для дальнейшего изложения нам понадобится ввести понятия обла-
сти в коде метода и координат области.
Будем называть областью непрерывную последовательность инструк-
ций в коде метода. При этом область будет определяться своими координа-
тами, а именно парой чисел (offset, length), где offset – это смещение
первой инструкции области относительно начала тела метода, а length
длина области. Как смещение, так и длину будем измерять в байтах.
Заголовок каждого метода содержит специальный массив, элементы
которого называются предложениями обработки исключений (exception
handling clause).
Каждое предложение обработки исключений представляет собой
структуру, состоящую из нескольких полей. В этих полях записаны коор-
динаты двух или трех областей, а именно: в любом предложении присут-
ствуют координаты защищенной области (protected block) и области обра-
ботчика (exception handler), а в некоторых предложениях дополнительно
описана область фильтра (filter block).
Если говорить в терминах языка C#, то защищенная область – это
try-блок, а область обработчика – это либо catch-блок, либо finally-блок.
Аналог для области фильтра в языке C# отсутствует, но зато он есть в Visual
Basic .NET и в Visual C++ with Managed Extensions. Область фильтра со-
держит код, принимающий решение о том, может ли данное исключение
быть обработано обработчиком. Естественно, такое представление о на-
значении областей в предложении обработки исключений несколько при-
митивно и понадобится нам лишь на начальном этапе.
Давайте рассмотрим два возможных формата, в которых кодируется
массив предложений обработки исключений. В каждом из двух форматов
содержатся одни и те же поля, и различаются они только размерами полей.
Первый формат называется коротким форматом (см. таблицу 3.43) и ис-
пользуется тогда, когда смещения областей не превышают 65535 байт, а
длины областей не превышают 255 байт. Во втором, длинном формате
(см. таблицу 3.44) допускаются любые смещения и длины. Строго говоря,
Common Intermediate Language
117
Диаграмма стека для инструкций refanytype:
... , typedRef -> ... , type
3.3.4.3. Загрузка значения типизированной ссылки
Инструкция refanyval (см. таблицу 3.42) загружает управляемый ука-
затель, хранящийся в типизированной ссылке, на вершину стека вычисле-
ний.
Таблица 3.42. Инструкция refanyval
Диаграмма стека для инструкций refanyval:
... , typedRef -> ... , ptr
3.4. Язык CIL: обработка исключений
Существует два основных способа перехвата ошибок, возникающих в
процессе работы программы:
Обработка кодов возврата.
Функция, выполнение которой может привести к ошибочной
ситуации, возвращает некоторое значение, сообщающее, ус-
пешно или неуспешно функция выполнила свою задачу. Перех-
ват ошибок заключается в том, что в коде, вызывающем такую
функцию, стоят проверки ее возвращаемого значения.
Этот способ хорошо работает, если глубина стека вызовов функ-
ций в программе относительно невелика. В противном случае
код программы из-за постоянных проверок становится громозд-
ким и трудночитаемым.
Обработка исключений.
Этот способ заключается в том, что в случае возникновения
ошибки генерируется так называемая исключительная ситуация
(исключение), которая описывается некоторым объектом. Гене-
рация исключения приводит к передаче управления на фраг-
мент кода программы, называемый обработчиком исключения.
Преимуществом такого подхода является то, что перехват оши-
бок локализован в отдельной части программы, а не распреде-
лен по всему коду, как в случае с обработкой кодов возврата.
116
CIL и системное программирование в Microsoft .NET
Код Инструкция Встроенный Описание
операнд
0xC2 refanyval token Загружает адрес, хранящийся в
типизированной ссылке
116                          CIL и системное программирование в Microsoft .NET   Common Intermediate Language                                           117


      Диаграмма стека для инструкций refanytype:                                      Основная трудность для понимания деталей реализации обработки
      ... , typedRef -> ... , type                                               исключений в CLI заключается в том, что обработка исключений частично
                                                                                 закодирована в телах методов (в виде специальных инструкций), а частич-
3.3.4.3. Загрузка значения типизированной ссылки                                 но – в заголовках методов. Скорее всего, такая смешанная схема была вы-
     Инструкция refanyval (см. таблицу 3.42) загружает управляемый ука-          брана разработчиками CLI для обеспечения компактности сборок. Поэто-
затель, хранящийся в типизированной ссылке, на вершину стека вычисле-            му мы в данном разделе сначала рассмотрим ту часть информации об обра-
ний.                                                                             ботке исключений, которая расположена в заголовках методов, затем пе-
                                                                                 рейдем к инструкциям CIL и, в конце концов, свяжем все воедино, приве-
      Таблица 3.42. Инструкция refanyval                                         дя семантику обработки исключений виртуальной системой выполнения.
Код           Инструкция    Встроенный Описание                                  3.4.1. Предложения обработки исключений в заголовках методов
                            операнд                                                   Для дальнейшего изложения нам понадобится ввести понятия обла-
0xC2          refanyval     token      Загружает адрес, хранящийся в             сти в коде метода и координат области.
                                       типизированной ссылке                          Будем называть областью непрерывную последовательность инструк-
                                                                                 ций в коде метода. При этом область будет определяться своими координа-
      Диаграмма стека для инструкций refanyval:                                  тами, а именно парой чисел (offset, length), где offset – это смещение
      ... , typedRef -> ... , ptr                                                первой инструкции области относительно начала тела метода, а length –
                                                                                 длина области. Как смещение, так и длину будем измерять в байтах.
                                                                                      Заголовок каждого метода содержит специальный массив, элементы
3.4. Язык CIL: обработка исключений                                              которого называются предложениями обработки исключений (exception
                                                                                 handling clause).
    Существует два основных способа перехвата ошибок, возникающих в                   Каждое предложение обработки исключений представляет собой
процессе работы программы:                                                       структуру, состоящую из нескольких полей. В этих полях записаны коор-
      • Обработка кодов возврата.                                                динаты двух или трех областей, а именно: в любом предложении присут-
         Функция, выполнение которой может привести к ошибочной                  ствуют координаты защищенной области (protected block) и области обра-
         ситуации, возвращает некоторое значение, сообщающее, ус-                ботчика (exception handler), а в некоторых предложениях дополнительно
         пешно или неуспешно функция выполнила свою задачу. Перех-               описана область фильтра (filter block).
         ват ошибок заключается в том, что в коде, вызывающем такую                   Если говорить в терминах языка C#, то защищенная область – это
         функцию, стоят проверки ее возвращаемого значения.                      try-блок, а область обработчика – это либо catch-блок, либо finally-блок.
         Этот способ хорошо работает, если глубина стека вызовов функ-           Аналог для области фильтра в языке C# отсутствует, но зато он есть в Visual
         ций в программе относительно невелика. В противном случае               Basic .NET и в Visual C++ with Managed Extensions. Область фильтра со-
         код программы из-за постоянных проверок становится громозд-             держит код, принимающий решение о том, может ли данное исключение
         ким и трудночитаемым.                                                   быть обработано обработчиком. Естественно, такое представление о на-
      • Обработка исключений.                                                    значении областей в предложении обработки исключений несколько при-
         Этот способ заключается в том, что в случае возникновения               митивно и понадобится нам лишь на начальном этапе.
         ошибки генерируется так называемая исключительная ситуация                   Давайте рассмотрим два возможных формата, в которых кодируется
         (исключение), которая описывается некоторым объектом. Гене-             массив предложений обработки исключений. В каждом из двух форматов
         рация исключения приводит к передаче управления на фраг-                содержатся одни и те же поля, и различаются они только размерами полей.
         мент кода программы, называемый обработчиком исключения.                Первый формат называется коротким форматом (см. таблицу 3.43) и ис-
         Преимуществом такого подхода является то, что перехват оши-             пользуется тогда, когда смещения областей не превышают 65535 байт, а
         бок локализован в отдельной части программы, а не распреде-             длины областей не превышают 255 байт. Во втором, длинном формате
         лен по всему коду, как в случае с обработкой кодов возврата.            (см. таблицу 3.44) допускаются любые смещения и длины. Строго говоря,