Назад: Система сборки Выше: Содержание Вперед: Виртуальная машина

Начальная загрузка

Начальная загрузка --- это процесс запуска функций системы, подготавливающий возможность исполнения кода на Ruby. Она проходит семь стадий:

  1. VM: виртуальная машина способна загружать и выполнять байткод, посылать сообщения (то есть, находить и вызывать методы); все примитивные функции уже доступны, но еще не видны как методы Ruby.

    Класс Class на этой ранней стадии должен быть явно задан путем объявления самого себя своим классом, а своим суперклассом --- Module. В дополнение к Class и Module здесь же создаются еще несколько базовых классов, включая Object, Tuple, LookupTable и MethodTable.

    Теперь, когда уже можно определять классы, получают приказ начать самоинициализацию еще около 35 встроенных классов; создаются символы для методов высшего уровня :object_id, :call, protected и т.п.; определяются базовые исключения (exceptions) и регистрируются примитивы.

    В этот момент уже определено поведение, достаточное для того, чтобы начать загружать остальное runtime-ядро, целиком написанное на Ruby. Это, в свою очередь, также делается в несколько проходов по мере <<роста>> языка.

  2. Альфа: начало загрузки кода на Ruby. Уже есть возможность открывать классы и модули и определять методы. В kernel/alpha.rb реализованы минимальные средства для поддержки следующих методов:

    attr_reader :sym
    attr_writer :sym
    attr_accessor :sym
    private :sym
    protected :sym
    module_function :sym
    include mod
    

    Помимо этого код имеет возможность инициировать исключения и прекращать выполнение процесса. Эта стадия закладывает основание для следующих двух.

  3. Бутстрап: продолжается добавление минимального функционала для поддержки загружающихся <<платформы>> и <<основы>> ("platform" и "common", см. ниже). Функции-примитивы добавляются в большинство классов ядра.

  4. Платформа: запускается FFI (интерфейс внешних функций) и создаются интерфейсные методы платформо-специфических функций. Как только все это настроено, к системе подключаются платформо-специфические детали вроде указателей, файловых операций, арифметики и вызовов POSIX.

  5. Основа: создается подавляющее большинство классов Основной (core) библиотеки. Основные классы Ruby построены настолько независимо от конкретной реализации, насколько это возможно. На этом же этапе добавляется бóльшая часть функциональных возможностей Rubinius-специфических классов.

  6. Дельта: добавляются финальные версии методов из ряда #attr_reader и т.п. Кроме этого, подключаются зависимые от реализации версии методов Основы.

  7. Загрузчик: выполняется скомпилированная версия kernel/loader.rb.

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

    После всего либо запускается переданный в командной строке скрипт, либо стартует интерактивная оболочка Ruby. Когда и они заканчивают работу, отрабатываются все зарегистрированные блоки at_exit, финализируются все объекты и процесс прекращается.

Порядок загрузки

Ряд описанных стадий загрузки реализован в файлах, находящихся в соответствующих директориях ядра: bootstrap, platform, common, и delta. Порядок загрузки этих директорий определен в runtime/index.

Код уровня скрипта, тела класса или модуля выполняется после загрузки rbc-файла. К примеру, при загрузке фрагмента

class SomeClass
  attr_accessor :value
end

выполняется вызов #attr_accessor. Для этого требуется, чтобы до файла, содержащего некий код, было загружено все, что вызывается из содержащихся в нем описаний скриптов, классов и модулей. kernel/alpha.rb содержит бóльшую часть определений, необходимых на уровне скрипта или модуля. Вместе с тем, между некоторыми файлами платформы, основы, дельты и компилятора существуют и иные зависимости, влияющие на порядок загрузки.

Эти зависимости прописаны в файлах load_order.txt, находящихся в каждой из директорий kernel/**. Если Вы модифицируете код, добавляющий порядковую зависимость, Вам следует отредактировать соответствующий load_order.txt, поместив файл, который зависит, после того, от которого он зависит. Если Вы добавляете новый файл в одну из директорий ядра, Вы должны добавить его имя в load_order.txt его директории. При сборке эти файлы копируются в соответствующие директории runtime/**. Во время каждой из вышеописанных стадий запуска виртуальная машина загружает файлы в порядке их перечисления в load_order.txt.

Назад: Система сборки Выше: Содержание Вперед: Виртуальная машина

Tweet at @rubinius on Twitter or email community@rubini.us. Please report Rubinius issues to our issue tracker.