Статьи

Как работает виртуальная машина ActionScript

Если вы участвуете в разработке AS3, вы, возможно, слышали о виртуальной машине, которая находится внутри Flash Player, или о так называемом байт-коде, в который преобразуется ваш код. Но что именно они?

Значительная часть Flash Player — это AVM — виртуальная машина ActionScript. Когда вы компилируете код AS3, он преобразуется в двоичный набор инструкций, называемый байт-кодом, который встроен в созданный SWF. Когда пользователь загружает SWF-файл во Flash Player, AVM анализирует байт-код и выполняет его шаг за шагом.

Давайте рассмотрим этот процесс чуть подробнее: взгляните на следующее утверждение и представьте, что мы хотим его выполнить (вычислите результат и присвойте ему «foo»):

1
foo = 2 + 3 * 4;

С человеческой точки зрения эта строка означает «Умножить 3 на 4, добавить 2 к результату и присвоить его переменной с именем foo».

С другой стороны, если компьютер читает эту строку, он будет хранить ее как «символ f, после которого следует символ o, затем символ o, затем пробел, затем символ равенства, а затем…». И так далее. В этом состоянии эта информация довольно бесполезна, и необходимо предпринять дополнительные шаги, чтобы превратить оператор в нечто, что машина может выполнить. По сути, нам нужно скомпилировать исходный код.


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

Первый шаг преобразования символов в слова выполняется токенизатором, который в основном выполняет лексический анализ исходного кода. Он перебирает символы и группирует их в серии «токенов» (а также определяет их тип — идентификаторы, операторы, константы…). После того, как токенизатор (его также называют лексером) завершает свою работу, мы получаем массив, который можно проиллюстрировать следующим образом:

1
[Identifier foo][Operator equals][Integer 2][Operator plus][Integer 3][Operator multiply][Integer 4]

Это структура более высокого уровня, которая содержит «слова» вместо необработанных символов.

Полученные токены подаются в парсер. Он выполняет семантический анализ токенов и собирает их в машинные инструкции. Проще говоря, он строит предложения из слов (токенов) и имеет смысл из них (т.е. составляет из них инструкции). Например, если парсеру дано выражение 2 + 3; я ++; в качестве токенов синтаксический анализатор должен сначала разделить токены на «предложения» (2 + 3 и i ++), а затем на самом деле их понять (первая — операция добавления, а вторая — приращение). После того, как мы понимаем инструкцию, мы можем фактически скомпилировать инструкции для машины из ввода.

После анализа токенов нашей строки мы получаем следующие инструкции:

1
2
3
4
5
6
push 2
push 3
push 4
multiply
add
assign «foo»

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


После того, как мы скомпилировали исходный код в байт-код, мы можем выполнить его с виртуальной машиной. ВМ — это программное обеспечение, которое выполняет байт-код по одной инструкции за раз, поэтому давайте просто рассмотрим интерпретацию нашего оператора:

  1. push 2 — команда состоит в том, чтобы вставить номер 2 в стек. Во время выполнения виртуальная машина поддерживает стек, над которым могут работать команды, то есть вставлять и извлекать значения (http://en.wikipedia.org/wiki/Stack_(data_structure)). На данный момент стек выглядит так: [2]
  2. push 3 — вставить еще одно целое число в стек. Теперь это выглядит как [2, 3];
  3. push 4 — вставьте еще одно целое число в стек. Теперь это выглядит как [2, 3, 4];
  4. multiply — эта команда отбрасывает 2 значения из стека, умножает их и переносит результат обратно в стек. Он извлекает значения 3 и 4 (которые в настоящее время находятся на вершине стека), умножает их и помещает полученные 12 в стек. Это влияет на стек, чтобы выглядеть как [2, 12];
  5. add — вы, наверное, догадались: команда выкинет 12 и 2 из стека, добавит их и поместит полученные 14 в стек. Теперь только 14 остается внутри стека.
  6. assign "foo" — эта команда извлекает значение из стека и присваивает его переменной с именем foo. Теперь переменная foo содержит значение 14, а стек пуст.

Это оно! Это пример чрезвычайно простого оператора, выполняемого чрезвычайно простой виртуальной машиной. Давайте рассмотрим немного более сложный пример:

1
bar = 12 / (4 + 2) — (6 — 9) * 3

Это может скомпилировать (я говорю «может», потому что есть разные способы скомпилировать утверждение):

01
02
03
04
05
06
07
08
09
10
11
12
push 12
push 4
push 2
add
divide
push 6
push 9
subtract
push 3
multiply
subtract
assign «bar»

Это будет интерпретировано как:

  1. Первые 3 нажатия будут добавлены в стек: [12, 4, 2]
  2. add — суммирует 2 значения в верхней части стека: [12, 6]
  3. divide — появится 6, затем 12, разделить 12 на 6 и поместить результат в стек: [2]
  4. Следующие 2 команды поместят целые числа в стек: [2, 6, 9]
  5. subtract — вычтет 2 числа в верхней части стека. Выскочит 9, затем 6, затем вычтите 6 из 9 и поместите результат в стек: [2, -3]
  6. Другое целое число будет помещено в стек: [2, -3, 3]
  7. multiply — выскочит и умножит 2 числа в верхней части стека. -9, то есть 3 раза -3, будет возвращен в стек: [2, -9]
  8. subtract — вычтет -9 из 2 и поместит результат в стек: [11]
  9. assign — появится 11 и назначит его переменной с именем «bar». Стек сейчас пуст.

Результат теперь хранится в переменной с именем «bar» и равен 11. Yay!


Это самая основная информация о ВМ, она может пригодиться, когда вы начнете изучать некоторые низкоуровневые Flash Player. ВМ внутри Flash Player, конечно, намного сложнее, но база такая же, как в примере, представленном выше.

Если вы хотите узнать больше о виртуальной машине ActionScript, вы можете взглянуть на этот PDF-документ Adobe . Спасибо за прочтение!