Формат PCU

Материал из Вики проекта PascalABC.NET
Перейти к: навигация, поиск

PCU - промежуточный формат хранения семантического дерева в PascalABC.NET. Он служит для ускорения компиляции программ, поскольку отпадает фаза синтаксического и семантического анализа. Выходной размер PCU файла в среднем в 1,5 раза больше исходного текста модуля. При чтении PCU-файла в таблицу символов заносятся заглушки считываемых сущностей (типов, подпрограмм и т.д.) и по запросу разворачивается семантическое дерево этих сущностей. Таким образом считываются только используемые имена, поэтому размер выходного исполняемого файла сокращается.

Формат PCU файла

Размер Описание Примечания
3 Сигнатура PCU-файла 'PCU'
2 Версия PCU PCU разных версий несовместимы
8 Контрольная сумма (временно не используется)
1 Флаг, включена ли отладочная информация
- Имя исходного файла программы при включенной отладочной информации
4 Количество записей в таблице интерфеисных имен модуля
Таблица имен сущностей interface части модуля. Каждая запись имеет структуру:
  • имя сущности
  • смещение сущности в PCU-файле (4 байта)
  • семантический тип сущности (TreeConverter.SymbolKind) (1 байт)
  • флаг method extension (1 байт)
4 Количество записей в таблице имен implementation части модуля
Имеет ту же структуру, что и таблица интерфейсных имен
4 Количество элементов в таблице подключаемых модулей
Таблица подключаемых модулей. Каждая запись - имя файла модуля без расширения.
4 Количество элементов в таблице используемых пространств имен
Таблица используемых пространств имен (нужна отладчику и зашивается в exe)
4 Количество подключаемых модулей в interface части модуля
4 Количество записей в таблице подключаемых сборок
Таблица подключаемых сборок .NET. Каждая запись - полное имя сборки (Assembly.FullName).
4 Количество элементов в таблице директив компилятора
Таблица директив компилятора. Имеет структуру:
  • строка директивы (reference, apptype)
  • строка значения директивы
  • отладочная информация (начало строки, начало колонки, конец строки, конец колонки)
4 Количество элементов в таблице импортируемых сущностей
Таблица импортируемых сущностей. Имеет вид:
  • флаг, откуда импортируется сущность (0-модуль,1-сборка .NET)
  • для сущностей, импортируемых из модулей - индекс в таблице подключаемых модулей; из сборок - индекс в таблице подключаемых сборок. Если сущность находится в классе, то здесь указывается индекс класса в таблице импортируемых сущностей
  • для сущностей, импортируемых из модуля - фактическое смещение сущности в подключаемом модуле; из сборок - индекс в таблице используемых имен сущностей .NET (ниже)
4 Смещение, по которому находится таблица синонимов типов, описанных в interface части модуля
4 Смещение, по которому находится таблица синонимов типов, описанных в implementation части модуля
4 Количество элементов в таблице используемых имен сущностей .NET
Таблица используемых имен сущностей .NET. Имеет структуру:
  • семантический вид сущности (тип, поле, свойство, метод, конструктор)
  • имя сущности
  • дополнительная информация (параметры метода, шаблонного класса) - массив смещений на записи сущностей в данной таблице (например, типы параметров метода)
Имя namespace_node (пространство имен .NET) interface части модуля
16 Отладочная информация об interface части модуля
Имя namespace_node (пространство имен .NET) implementation части модуля
16 Отладочная информация об implementation части модуля
4 Количество элементов в таблице template-классов interface-часть модуля
Таблица template-классов. Каждая запись имеет следующую структуру:
  • semantic_node_type
  • имя класса
  • список имен подключаемых сборок
  • список имен подключаемых сборок 2
  • имя файла, где описан шаблон
  • сериализованное синтаксическое дерево шаблонного класса (если есть)
4 Количество элементов в таблице типов (классов, записей, перечислений и т. д.) interface части модуля
Таблица типов interface части модуля
  • semantic_node_type сущности
  • флаг, находится ли тип в interface части модуля
  • если сущность описана в interface части - индекс в таблице имен имен сущностей модуля, иначе имя сущности
  • флаг, является ли тип интерфейсом (IsInterface)
  • флаг, является ли тип делегатом (IsDelegate)
  • флаг, является ли тип генерик-типом
  • если тип является генериком
    • количество генерик-параметров типа
    • список имен генерик-параметров типа
  • ссылка на тип предка
  • флаг, является ли тип размерным (internal_is_value)
  • список ссылок на реализуемые интерфейсы
  • type_access_level (модификатор доступа типа)
  • type_special_kind
  • флаг, является ли тип финальным
  • флаг, является ли тип абстрактным
  • если тип является диапазоном
    • значение нижней границы диапазона
    • значение верхней границы диапазона
  • если тип является генериком, список ограничителей генерик-типа
    • флаг class, record или none
    • ссылка на базовый класс, присутствующий в ограничителе
    • список интерфейсов в ограничителе
    • флаг, есть ли в ограничителе конструктор по умолчанию
  • флаг, имеет ли тип element_type (например, для массивов - тип элементов массива)
  • element_type (ссылка на тип элемента, если имеется)
  • ссылка на объемлющее пространство имен
  • смещение в pcu, по которому расположены атрибуты (атрибуты .NET) типа
  • флаг, есть ли у класса свойство по умолчанию
  • смещение, по которому находится свойство по умолчанию (если оно есть)
  • отладочная информация
4 Количество элементов в таблице откомпилированных (в сборках .NET) типов
Таблица откомпилированных (в сборках .NET) типов
  • semantic_node_type сущности
  • флаг, находится ли тип в interface части модуля
  • если сущность описана в interface части - индекс в таблице имен имен сущностей модуля, иначе имя сущности
4 Количество элементов в таблице синонимов типов
Таблица синонимов типов:
  • имя синонима
  • ссылка на именуемый тип
  • отладочная информация
4 Количество элементов в таблице меток implementation часть модуля
Таблица меток. Каждая запись имеет следующую структуру:
  • имя метки
  • отладочная информация
4 Количество элементов в таблице template-классов
Таблица template-классов (см. выше)
4 Количество элементов в таблице типов (классов, записей, перечислений и т. д.) implementation части модуля
Таблица типов implementation части модуля (см. выше)
4 Количество элементов в таблице откомпилированных (в сборках .NET) типов (см. выше)
Таблица откомпилированных (в сборках .NET) типов (см. выше)
4 Количество элементов в таблице констант класса (для каждого класса отдельная таблица) interface часть модуля
Таблица констант класса. Каждая запись имеет следующую структуру:
  • semantic_node_type
  • индекс имени константы в таблице имен
  • ссылка на тип константы
  • смещение объемлющего класса
  • смещение в pcu, по которому находится значение константы (значения констант и переменных сохраняются в конце модуля)
  • field_acces_level (модификатор доступа)
  • отладочная информация
4 Количество элементов в таблице полей класса
Таблица полей класса. Каждая запись имеет следующую структуру:
  • semantic_node_type
  • индекс имени метода в таблице имен
  • ссылка на тип поля
  • флаг, имеет ли поле явно заданное начальное значение
  • смещение в pcu, по которому находится значение поля (если имеется)
  • смещение, по которому находится объемлющий класс
  • field_access_level (модификатор доступа)
  • polymorphic_state (статическое, обычное поле)
  • смещение в pcu, по которому расположены атрибуты поля
  • отладочная информация
4 Количество элементов в таблице методов класса interface
Таблица методов класса. Каждая запись имеет следующую структуру:
  • semantic_node_type
  • индекс имени метода в таблице имен
  • флаг is_final
  • флаг newslot_awaited (для генерации IL-кода)
  • флаг, является метод генериком
  • если метод является генериком
    • количество генерик-параметров метода
    • список имен генерик-параметров метода
    • список ограничителей на генерик-параметры (см. выше для типов)
  • флаг, имеет ли метод возвращаемое значение
  • если имеет:
    • ссылка на тип возвращаемого значения
    • переменная Result (если есть)
  • количество параметров метода
  • список параметров метода:
    • semantic_node_type
    • имя параметра
    • ссылка на тип параметра
    • var, const или обычный параметр
    • флаг, используется ли параметр во вложенных подпрограммах
    • флаг, имеет ли параметр модификатор params
    • флаг, задано ли начальное значение параметра
    • если задано, то смещение в pcu, по которому расположено значение параметра
    • смещение в pcu, по которому находятся атрибуты параметра
  • смещение, по которому находится объемлющий класс
  • смещение, по которому находятся атрибуты метода
  • флаг is_constructor
  • флаг is_forward
  • флаг is_overload
  • field_access_level (модификатор доступа)
  • polymorphic_state (virtual, static, обычный)
  • num_of_default_variables (число переменных, имеющих параметры по умолчанию, будет удалено)
  • num_of_cicles (число циклов for в функции, будет удалено)
  • флаг override
  • количество локальных переменных
  • список локальных переменных
    • имя переменной
    • ссылка на тип переменной
    • флаг, используется ли переменная как нелокальная
    • флаг, имеет ли переменная явно заданное значение по умолчанию
    • если имеет, смещение в pcu, по которому расположено значение переменной
  • количество констант, описанных в методе
  • список констант
    • имя константы
    • смещение в pcu, по которому расположено значение константы
  • количество вложенных подпрограмм
  • список вложенных подпрограмм
    • semantic_node_type
    • имя подпрограммы
    • флаг, имеет ли подпрограмма возвращаемое значение
    • если имеет:
      • ссылка на тип возвращаемого значения
      • переменная Result (если есть)
    • количество параметров подпрограмм
    • список параметров подпрограммы (см. выше)
    • 0 (4 байта)
    • флаг is_forward
    • флаг is_overload
    • num_of_default_variables (число переменных, имеющих параметры по умолчанию, будет удалено)
    • num_of_cicles (число циклов for в функции, будет удалено)
    • количество локальных переменных
    • список локальных переменных (см. выше)
    • количество констант, описанных в подпрограмме
    • список констант (см. выше)
    • количество вложенных подпрограмм
    • список вложенных подпрограмм
  • отладочная информация о методе
  • смещение, по которому находится код метода
4 Количество элементов в таблице свойств класса interface
Таблица свойств класса. Каждая запись имеет следующую структуру:
  • semantic_node_type
  • индекс имени метода в таблице имен
  • ссылка на тип свойства
  • флаг, имеет ли свойство get-аксессор
  • смещение get-аксессора
  • флаг, имеет ли свойство set-аксессор
  • смещение set-аксессора
  • число параметров свойства
  • список параметры свойства (см. список параметров для методов)
  • смещение объемлющего класса
  • field_access_level (модификатор доступа)
  • polymorphic_state
  • смещение в pcu, по которому находятся атрибуты свойства
  • отладочная информация
4 Количество элементов в таблице событий класса interface
Таблица событий класса. Каждая запись имеет следующую структуру:
  • semantic_node_type
  • индекс имени события в таблице имен
  • ссылка на делегат - тип события
  • флаг, имеет ли событие add-метод
  • смещение add-метода события
  • флаг, имеет ли событие remove-метод
  • смещение remove-метода события
  • флаг, имеет ли событие raise-метод
  • смещение raise-метода события
  • смещение поля для события
  • смещения объемлющего типа
  • field_access_level
  • polymorphic_state
  • смещение в pcu, по которому расположены атрибуты события
  • отладочная информация
4 Количество элементов в таблице констант класса implementation
Таблица констант класса: см. выше
4 Количество элементов в таблице полей класса implementation
Таблица полей класса: см. выше
4 Количество элементов в таблице методов класса implementation
Таблица методов класса: см. выше
4 Количество элементов в таблице свойств класса implementation
Таблица свойств класса: см. выше
4 Количество элементов в таблице событий класса implementation
Таблица событий класса: см. выше
4 Количество элементов в таблице констант модуля interface
Таблица констант модуля. Каждая запись имеет следующую структуру:
  • semantic_node_type
  • флаг, расположена ли константа в интерфейсной части модуля
  • для констант в interface части — индекс имени в таблице имен, implementation — имя константы
  • смещение секции модуля, в котором описана константа
  • смещение в pcu, по которому расположено значение константы
  • отладочная информация
4 Количество элементов в таблице переменных модуля interface
Таблица переменных модуля. Каждая запись имеет следующую структуру:
  • semantic_node_type
  • порядковый индекс переменной в семантическом дереве (нужен для восстановления переменных из pcu в том же порядке, в каком они были в сем. дереве)
  • флаг, расположена ли переменная в интерфейсной части модуля
  • для переменных в interface части — индекс имени в таблице имен, implementation — имя переменной
  • ссылка на тип переменной
  • смещение секции модуля, в котором описана переменная
  • флаг, имеет ли переменная явно заданное начальное значение
  • смещение в pcu, по которому расположено начальное значение переменной
  • отладочная информация
4 Количество элементов в таблице подпрограмм модуля interface
Таблица подпрограмм модуля. Каждая запись имеет следующую структуру:
  • semantic_node_type
  • флаг, является ли подпрограмма расширением (method extension)
  • если да, то ссылка на расширяемый тип
  • для подпрограмм в interface части — индекс имени в таблице имен, implementation — имя подпрограммы
  • флаг, является метод генериком
  • список генерик-параметров и ограничений подпрограммы (см. для методов)
  • флаг, имеет ли метод возвращаемое значение
  • если имеет:
    • ссылка на тип возвращаемого значения
    • переменная Result (если есть)
  • число параметров подпрограммы
  • список параметров подпрограммы (см. для методов)
  • смещение объемлющей секции модуля
  • смещение в pcu, по которому расположены атрибуты подпрограммы
  • флаг is_forward
  • флаг is_overload
  • num_of_default_variables
  • num_of_cicles
  • число переменных подпрограммы
  • список переменных подпрограммы (см. для методов)
  • число констант подпрограммы
  • список констант подпрограммы (см. для методов)
  • число вложенных подпрограмм
  • список вложенных подпрограмм (см. для методов)
  • отладочная информация
4 Количество элементов в таблице типов-указателей модуля interface
Таблица типов-указателей модуля:
4 Количество элементов в таблице констант модуля implementation
Таблица констант модуля: см. выше
4 Количество элементов в таблице переменных модуля implementation
Таблица переменных модуля: см. выше
4 Количество элементов в таблице подпрограмм модуля implementation
Таблица подпрограмм модуля: см. выше
4 Количество элементов в таблице типов-указателей модуля implementation
Таблица типов-указателей модуля: см. выше
Реализации всех методов и подпрограмм (сериализованные семантические деревья тел методов и подпрограмм)
Список атрибутов .NET. Каждая запись имеет следующий вид:
  • число элементов в списке атрибутов
  • список атрибутов:
    • ссылка на тип атрибута
    • ссылка на описание конструктора класс атрибута
    • квалификатор атрибута (method, type, param и т.д.)
    • число аргументов конструктора атрибута
    • список выражений-аргументов конструктора атрибута
    • число свойств, инициализируемых в атрибуте
    • список ссылок на инициализируемые свойства
    • число полей, инициализируемых в атрибуте
    • список ссылок на инициализируемые поля
    • число выражений - инициализаторов свойств атрибута
    • список выражений - инициализаторов свойств атрибута
    • число выражений - инициализаторов полей атрибута
    • список выражений - инициализаторов полей атрибута
    • отладочная информация
Семантические деревья для значений констант, переменных и параметров

Примечания

  1. Под ссылкой на тип понимается следующее: флаг, указывающий на род типа (обычный тип, массив, короткая строка, указатель). Обычный тип не сериализуется после флага, так как он уже определен, а массивы, указатели и т. д. сериализуются после флага (var p : ^integer). Для обычного типа после флага идет флаг, описан ли тип в этом модуле. Далее если тип описан в модуле, то пишется смещение в модуле, по которому хранится тип, иначе смещение в таблице импорта.
  2. Код методов хранится в виде сериализованного семантического дерева. Узлы семантического дерева распознаются по semantic_node_type. Код хранится в конце файла.
  3. Ссылки на сущности .NET сериализуются следующим образом. Для типов, событий, полей, свойств хранятся их полные имена (System.Collections.ArrayList). Для метода кроме имени записывается список имен типов параметров, чтобы можно было выбрать перегруженный метод. Имена считываются один раз и кэшируются.
  4. При десериализации семантических деревьев могут проводиться некоторые дополнительные семантические действия, например добавление в тип внутреннего интерфейса ordinal_type_interface, при котором тип становится порядковым.
  5. Отладочная информация имеет следующую структуру (если отладочной информации нет, то вместо номеров строк и колонок пишется -1):
    • номер начальной строки
    • номер начальной колонки
    • номер конечной строки
    • номер конечной колонки
Персональные инструменты