Визуализация JavaScript: движок JavaScript

  • 23 февраля, 11:53
  • 1742
  • 0

JavaScript - это круто, но как машина может понимать написанный вами код? Как разработчики JavaScript, нам обычно не приходится иметь дело с компиляторами самим. Тем не менее, определенно полезно знать основы движка JavaScript и видеть, как он обрабатывает наш удобный для человека JS-код и превращает его в то, что понимают машины! 

Этот пост в основном основан на движке V8, который используется в браузерах на базе Node.js и Chromium.

Парсер HTML обнаруживает scriptтег с источником. Код из этого источника загружается либо из сети , либо из кеша , либо из установленного сервис-воркера . Ответом является запрошенный сценарий в виде потока байтов , о котором позаботится декодер байтового потока! Поток байтов декодер декодирует поток байтов , как это загружается.

Альтернативный текст


Декодер потока байтов создает токены из декодированного потока байтов. Например, 0066 декодируется в f , 0075в u, 006eв n, 0063в c, 0074в t, 0069в i, 006fв oи 006eв, nза которыми следует пробел. Похоже, ты написал function! Это зарезервированное ключевое слово в JavaScript, токен создается и отправляется синтаксическому анализатору.  То же самое происходит с остальной частью байтового потока.

Альтернативный текст

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

Парсер создает узлы на основе токенов, которые он получает от декодера байтового потока. С помощью этих узлов он создает абстрактное синтаксическое дерево или AST. 

Альтернативный текст

Далее пора интерпретатора! Интерпретатор, который проходит через AST и генерирует байтовый код на основе информации, содержащейся в AST. Как только байт-код будет полностью сгенерирован, AST удаляется, освобождая место в памяти. Наконец-то у нас есть то, с чем может работать машина! 🎉

Альтернативный текст


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

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

Альтернативный текст


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

Чтобы сократить время, необходимое для интерпретации кода, оптимизированный машинный код обрабатывает только те случаи, которые механизм видел раньше при выполнении байт-кода. Если мы неоднократно использовали определенный фрагмент кода, который снова и снова возвращал один и тот же тип данных, оптимизированный машинный код можно просто повторно использовать, чтобы ускорить процесс. Однако, поскольку JavaScript динамически типизирован, может случиться так, что один и тот же фрагмент кода внезапно вернет другой тип данных. В этом случае машинный код деоптимизируется, и движок возвращается к интерпретации сгенерированного байтового кода. Скажем, определенная функция вызывается 100 раз и до сих пор всегда возвращала одно и то же значение. Движек будет считать , что она также будет возвращать это значение 101 - й раз.

Допустим, у нас есть следующая функция sum, которая  всегда вызывалась с числовыми значениями в качестве аргументов каждый раз:

Она возвращает число 3! В следующий раз, когда мы вызовем ее, движек предположит, что мы снова вызываем его с двумя числовыми значениями.

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

Например, в следующий раз, когда мы вызываем его, мы передаем строку вместо числа. Поскольку JavaScript динамически типизирован, мы можем сделать это без ошибок!

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


Теги: js
0 комментариев
Сортировка:
Добавить комментарий

IT Новости

Смотреть все