Библиотека сайта rus-linux.net
Среда времени выполнения динамических языков и языки Iron
Глава 8 из книги "Архитектура приложений с открытым исходным кодом", том 2.
Оригинал: The Dynamic Language Runtime and the Iron Languages
Автор: Jeff Hardy
Перевод: Н.Ромоданов
8.2. Принципы реализации среды времени выполнения динамических языков
Среда CLR создана с учетом использования статически-типизированных языков; то, что типы данных известны, используется в среде времени выполнения очень глубоко, и одним из ключевых условий является то, что эти типы не должны изменяться, — что переменная никогда не изменит свой тип или, что в типе никогда нет будет никаких полей или членов типа, которые добавляются или удаляются во время работы программы. Это нормально для таких языков, как C# или Java, но в динамических языках эти правила, по определению, не выполняются. В среде CLR также предоставлена единая система объектов статических типов, что означает, что любой язык платформы .NET может вызывать объекты, написанные на любом другом языке платформы .NET, причем без дополнительных усилий.
Без среды DLR в каждом динамическом языке потребовалось бы создавать свою собственную модель объектов; разные динамические языки не могли бы обращаться к объектам других динамических языков, а C# не мог бы одинаковым образом обрабатывать языки IronPython и IronRuby. Поэтому сердцем среды DLR является стандартный способ реализации динамических объектов и, при этом, с помощью средств привязок (binders) все еще есть возможность настраивать свойства объектов для каждого конкретного языка. Также есть механизм, называющийся кэшированием точек вызовов (call-site caching), который обеспечивает выполнение динамических операции настолько быстро, насколько это возможно, и набор классов для создания деревьев выражений (expression trees), которые позволяют сохранять код в виде данных и легко им манипулировать.
В среде CLR также предоставляется ряд других возможностей, которые полезны для динамических языков, в том числе интеллектуальный сборщик мусора; компилятор Just-in-Time (JIT), преобразующий во время выполнения программы на байт-коде в обобщенный промежуточный язык Common Intermediate Language (IL), который компиляторы платформы .NET предобразуют в машинный код; система интроспекции времени выполнения, позволяющая динамическим языкам вызывать объекты, написанные на любом статическом языке; и, наконец, динамические методы (также известные как легковесная генерация кода), которые позволяют во время выполнения программы генерировать код, а затем исполнять его с затратами, лишь чуть-чуть превышающими затраты на статические методы вызовов (в в виртуальной машине JVM языка Java 7 аналогичный механизм реализуется с помощью >invokedynamic>
).
Благодаря такой архитектуре среды DLR языки, такие как IronPython и IronRuby, могут вызвать объекты друг друга (а также любого другого языка DLR), поскольку у них общая динамическую модель объектов. Поддержка такой объектной модели была также добавлена в язык C# 4 (с помощью ключевого слова dynamic
) и в Visual Basic 10 (в дополнение к методу «позднего связывания», уже существующему в VB), так что в них также можно выполнять динамические вызовы объектов. Таким образом среда DLR делает динамические языки основными игроками платформы .NET.
Интересно то, что среда DLR полностью реализована в виде набора библиотек и может также быть встроена и работать на платформе .NET 2.0. Для ее реализации в среде CLR не требуются делать никаких изменений.
8.3.Особенности реализации языков
Реализация каждого языка содержит в себе два основных этапа — синтаксический анализ или разбор (представление языка) и генерацию кода (движок). В среде DLR в каждом языке реализуется свое собственное представление языка, которое содержит синтаксический анализатор языка и генератор синтаксического дерева; среда DLR предоставляет общий движок, который использует деревья выражений для того, чтобы создать код на промежуточном языке Intermediate Language (IL) для его использования в среде CLR; среда CLR передает код на языке IL в компилятор JIT (Just-In-Time — компиляция «на лету»), с помощью которого создается машинный код, предназначенный для выполнения в процессоре. Код, который определяется во время выполнения (и работает с использованием команды eval
) обрабатывается аналогичным образом, за исключением лишь того, что все это происходит исключительно в точке вызова eval
, а не когда загружается файл.
Есть несколько различных способов реализации ключевых элементов представления языка, и хотя языки IronPython и IronRuby очень похожи друг на друга ( в конце концов, они разрабатывались бок о бок,) они различаются в нескольких ключевых аспектах. Оба языка IronPython и IronRuby имеют довольно стандартные структуры синтаксических анализаторов — оба они используют tokenizer (также известный как лексический анализатор), который разделяет текст на лексемы, а затем синтаксический анализатор / парсер преобразует эти лексемы в абстрактное синтаксическое дерево AST (abstract syntax tree), которое представляет собой программу. Однако реализация этих компонентов в этих языках совершенно разная.
Продолжение статьи: Синтаксический анализ