Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

PyPy

Глава 19 из книги "Архитектура приложений с открытым исходным кодом", том 2.
Оригинал: PyPy
Автор: Benjamin Peterson
Перевод: А.Панин

19.3. Интерпретатор языка Python

Так как RPython является подвидом языка Python и строго соответствует его синтаксису, интерпретатор языка Python проекта PyPy может работать поверх другой реализации языка Python без преобразования кода. Конечно же, он будет работать чрезвычайно медленно, но при этом появляется возможность быстрого тестирования изменений в интерпретаторе. Также это обстоятельство позволяет использовать обычные инструменты отладки для языка Python для отладки интерпретатора. Большинство тестов интерпретатора PyPy может быть выполнено как при работе интерпретатора без преобразования кода, так и при работе интерпретатора с преобразованием кода. Это позволяет проводить быстрое тестирование в процессе разработки, а также проверять то, что интерпретатор при осуществлении преобразования кода ведет себя также, как и интерпретатор без преобразования кода.

По большей части детали реализации интерпретатора языка Python проекта PyPy схожи с деталями реализации интерпретатора CPython; интерпретаторы PyPy и CPython используют практически идентичные представления байткода и структуры данных в ходе интерпретации. Основным отличием между ними является то, что PyPy использует интересную абстракцию под названием "пространства объектов" ("object spaces" или сокращенно "objspaces"). Пространство объектов инкапсулирует данные, необходимые для представления и управления типами данных языка Python. Например, выполнение бинарной операции с двумя объектами Python или получение атрибута объекта в полной мере обрабатывается пространством объектов. Это обстоятельство позволяет освободить интерпретатор от необходимости получения любых деталей реализации объектов Python. Интерпретатор байткода рассматривает объекты Python как черные ящики и вызывает методы пространства объектов в любой момент, когда сталкивается с необходимостью осуществления манипуляций с ними. Например, ниже приведена простейшая реализация кода операции BINARY_ADD, который вызывается при комбинировании двух объектов с помощью оператора +. Обратите внимание на то, что операнды не проверяются интерпретатором; все действия по обработке объектов немедленно делегируются пространству объектов.
def BINARY_ADD(space, frame):
    object1 = frame.pop() # извлечение левого операнда из стека
    object2 = frame.pop() # извлечение правого операнда из стека
    result = space.add(object1, object2) # осуществление операции
    frame.push(result) # запись результата в стек

Абстракция пространства объектов имеет множество преимуществ. Она позволяет получать от объектов или передавать объектам новые реализации типов данных без модификации интерпретатора. Также ввиду того, что единственный способ осуществления манипуляций с объектами связан с использованием пространства объектов, на уровне пространства объектов могут осуществляться вмешательство, буферизация или запись операций с объектами. В ходе использования мощной абстракции пространств объектов в рамках PyPy были проведены эксперименты по внедрению технологии переключения (thunking), при использовании которой вычисление результатов может быть отложено, но осуществляться полностью прозрачно по требованию, а также технологии создания исключений (tainting), при использовании которой любая операция с объектом будет вызывать генерацию исключения (что полезно при передаче важных данных с использованием кода, вызывающего недоверие). Наиболее важный способ применения пространства объектов, однако, будет обсуждаться в Разделе 19.4.

Пространство объектов, используемое в оригинальной версии интерпретатора PyPy, называется стандартным пространством объектов (standard objspace или std objspace для краткости). В дополнение к абстракции, предоставляемой системой пространства объектов, стандартное пространство объектов предоставляет новый уровень абстракции: один и тот же тип данных может иметь множество реализаций. При его использования операции с типами данных осуществляются с применением мультиметодов. Это позволяет выбирать наиболее эффективное представление заданного набора данных. Например, тип long в рамках языка Python (очевидно, целочисленный тип данных большой разрядности) может быть представлен в виде стандартного целочисленного значения размером в одно машинное слово в том случае, если это значение достаточно мало. Более затратная в плане памяти и вычислений реализация типа данных произвольной точности большой разрядности должна использоваться только в случае необходимости. Существует даже реализация целочисленного типа данных Python на основе маркированных указателей. Контейнерные типы также могут быть специализированными по отношению к определенным типами данных. Например, в рамках PyPy реализован словарь (тип хэш-таблицы в Python), предназначенный для работы со строковыми ключами. Тот факт, что один и тот же тип данных может быть представлен различными реализациями, позволяет абсолютно прозрачно использовать объекты из кода уровня приложения; словарь для хранения строк идентичен словарю общего назначения и позволяет корректно отклонять нестроковые значения в случае их добавления.

В PyPy производится разделение между кодом уровня интерпретатора (interp-level) и кодом уровня приложения (app-level). Код уровня интерпретатора, который используется для реализации большей части интерпретатора, должен быть разработан с использованием языка RPython и подвергаться преобразованию. Он напрямую взаимодействует с пространством объектов и объектами Python в специальных обертках. Код уровня приложения всегда обрабатывается с помощью интерпретатора байткода PyPy. Ввиду простоты кода уровня интерпретатора на языке RPython по сравнению с кодом на языке C или Java, разработчики посчитали наиболее простым решением использование кода уровня приложения в некоторых частях интерпретатора. Следовательно, PyPy поддерживает встраивание кода уровня приложения в интерпретатор. Например, функции объявления print языка Python, с помощью которого производится запись данных объектов в поток стандартного вывода, реализованы на уровне приложения Python. Встроенные модули также могут быть разработаны с частичным использованием кода уровня интерпретатора и приложения.


Продолжение статьи: Инструменты преобразования кода для языка RPython