Как среда выполнения Objective-C создает корневой метакласс и другие описания классов?

Я пытаюсь реализовать базовую объектно-ориентированную среду выполнения ANSI C и использую Objective-C в качестве руководства.

Кажется, они состоят из трех частей. Описание класса, интерфейс класса и реализация класса. Чтобы создать экземпляр интерфейса класса, знакомый метод использования объекта класса для создания экземпляра объекта может произойти только в том случае, если среда выполнения уже создала экземпляр вашего объекта класса, используя описание класса.

Итак, все ли определения класса выделяются статически при первом запуске, чтобы обеспечить возможность создания экземпляра с использованием объекта класса? Или если они распределяются динамически (при первом вызове), то как? Является ли это частью цикла выполнения или класс на самом деле является функцией, которая определяет, был ли он уже выделен или нет до пересылки сообщения?


person Anderson    schedule 08.02.2010    source источник


Ответы (1)


Среда выполнения выполняет некоторую инициализацию с помощью функций-конструкторов, которые вызываются до фактического выполнения программы. Они обозначаются __attribute__((constructor)) как в gcc, так и в clang.

В случае с Objective-C некоторые из них встраиваются компилятором в двоичный файл. Вам нужно будет включить их в свои заголовки для аналогичного эффекта.

Эти функции используют данные, автоматически внедряемые компилятором. Они делают такие вещи, как создание хеш-таблиц для функции поиска класса, которые затем используются для фактической передачи сообщений.

С другой стороны, экземпляры распределяются динамически.

Я делаю что-то подобное, поэтому я действительно не знаю ничего лучше этого, но это так глубоко, как я копал.

person Community    schedule 08.02.2010
comment
Итак, лексер Obj-C внутри компилятора генерирует общие описания классов из вашего интерфейса (файл .h), сохраняет список в хеш-таблице для поиска классов, но что запускает инициализацию с использованием упомянутых конструкторов? разве не нужно что-то вызывать в основном, чтобы настроить это? - person Anderson; 08.02.2010
comment
Компилятор вводит вызов конструкторам среды выполнения во время компиляции? - person Anderson; 08.02.2010
comment
Нет, есть раздел двоичного файла с именем .ctors, который содержит список указателей на функции, которые нужно вызвать. Этот список записывается компилятором-компоновщиком из списка функций, имеющих атрибут конструктора, и выполняется либо в стартовом коде, если это статическая библиотека, либо в коде инициализации в динамически подключаемых файлах. - person ; 08.02.2010
comment
Под кодом запуска я подразумеваю код среды выполнения C, который компонуется автоматически. Он вызывает их по умолчанию. Однако компоновщик должен включать конструктор, который для статических библиотек работает только в том случае, если на функцию ссылаются в другом месте. - person ; 08.02.2010
comment
Эти конструкторы генерируют хеш-таблицу, по крайней мере, во время выполнения GNU. Реализация Apple может выполнять некоторые из этих операций статически. - person ; 08.02.2010
comment
Я следую? Компилятор: 1. Определить описания метаклассов на основе интерфейсов класса 2. Генерировать функции-конструкторы для создания экземпляра объекта класса 3. Вставить последовательные указатели функций на все функции-конструкторы в раздел .ctor с помощью вызова __attribute__((constructor)) Время выполнения: 1 . открыта разделяемая библиотека libobjc 2. Среда выполнения Obj-C создает экземпляр корневого метакласса и класса 3. двоичный файл программы инициализирует свои метаклассы и классы как часть раздела .ctor 4. основной раздел двоичного файла программы начинает обработку - person Anderson; 09.02.2010
comment
Я не уверен насчет шага 2 вашего компилятора (и времени выполнения). Функции конструктора генерируют метаданные времени выполнения. Объекты класса и все соответствующие данные и т. д. уже сгенерированы во время компиляции (подумайте о статических структурах). По сути, происходит следующее: 1- libobjc и файлы модулей добавляют метаданные 2- main выполняется / BTW, класс Root не является волшебным в ObjC, это просто еще один класс, который обеспечивает всех своих дочерних элементов. - person ; 09.02.2010
comment
Конструктор модуля (файл .m) — это функция, которая вызывает среду выполнения с указателем на сгенерированную компилятором структуру модуля, которая содержит ссылки на все остальное. - person ; 09.02.2010
comment
Да, этого я и добивался. Как хранится структура модуля (описание класса)? В качестве дескрипторов типа @encoded, т. е. struct { int i; поплавок f[3]; в: 3; интервал б:2; char c;} преобразуется в {?=i[3f]b128i3b131i2c} - person Anderson; 10.02.2010
comment
Поскольку в данный момент я не заинтересован в анализе компилятора или создании отдельной среды выполнения, в ANSI C можно ли использовать обобщенный конструктор, который считывает все дескрипторы типов и генерирует объекты класса во время выполнения. - person Anderson; 10.02.2010
comment
Конечно, это сделано для удобства, но если бы ваши описания классов хранились в файлах данных, вы могли бы создавать нужные вам структуры из файла. Разница в том, что скомпилированный объект Objc генерирует структуры, которые могут быть легко использованы во время выполнения, поэтому вы будете выполнять эту часть работы JIT. - person ; 11.02.2010