Добро пожаловать в другие главы Давайте разберемся с Chrome V8

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

1. Тестовый пример

Примечание. Тестовый пример очень простой, поэтому он не может охватить весь поток сканера.

2. Токен: функция, JsPrint

V8_INLINE Token::Value Scanner::ScanSingleToken() — это начало сканирования токена. Мы уже знаем, что c0_ уже указал на первый символ потока JS во время инициализации. В нашем тестовом случае c0_ указывает на «f». Посмотрим, как это работает.

(1):5-я строка приведенного выше кода. Проверяет, является ли c0_ кодом Ascii. В нашем случае это правда (c0_ есть f).

(2):6-я строка приведенного выше кода. one_char_tokens — это предопределенный шаблон в V8, представляющий собой массив типов символов. Это ниже:

one_char_tokens состоит из трех вышеуказанных частей кода. В нашем случае «f» — это идентификатор IsAsciiIdentifier(c), его тип — Token::IDENTIFIER, а IsAsciiIdentifier ниже:

(3): посмотрите на ScanSingleToken(). Тип c0_ — Token::IDENTIFIER, поэтому будет вызываться ScanIdentifierOrKeyword(). Мы можем видеть несколько методов в ScanIdentifierOrKeyword, эти методы используются для переноса отношений между классами. На рис. 1 показан стек вызовов этих методов.

Выполнив поиск ScanSingleToken в V8, а затем установив на нем точку останова, вы можете воспроизвести стек, показанный на рисунке 1.

(4): перед сканированием следующего символа необходимо сохранить букву «f». Ниже приведен способ сохранения символов.

Рисунок 2 — это окно переменных, мы видим, что one_byte_char — это c0_, который хранится в backing_store_.

Давайте начнем сканировать второй символ, код ниже.

Метод AdvanceUntil считывает каждый символ по очереди и останавливается, когда встречается терминатор.

На рис. 3 мы видим, что эти восемь символов и есть первая функция строки — — в нашем случае. Теперь мы получаем полный токен, следующий шаг — проанализировать, является ли токен ключевым словом или идентификатором. Код ниже.

GetToken используется для определения того, является ли токен ключевым словом или идентификатором. Определение очень простое — получите тип токена, просмотрев предопределенную хеш-таблицу. На рис. 4 показаны важные члены хеш-таблицы.

На данный момент функция токена сгенерирована, и ее тип — Token::FUNCTION. Токен JsPrint аналогичен, его тип Token::IDENTIFIER.

3. Разница между функцией и JsPrint

Мы знаем, что функция — это ключевое слово, а JsPrint — это пользовательский идентификатор. Давайте посмотрим, как Parser выражает разницу между ними двумя.

Приведенный выше код анализирует эти два токена. Уточним, что за генерацию токенов отвечает сканер, а разницу между токенами идентифицирует парсер.

В ParserBase‹Impl›::ParseHoistableDeclaration() будет вызываться указанный выше метод. В нашем случае ParseIdentifier использует следующий метод символов при разборе нашей функции и JsPrint.

В таблице символов сохраняется соответствие между идентификаторами и исходным кодом JS. А именно, он сохраняет связь между идентификатором и информацией о его объявлении. В нашем случае функция и JsPrint являются парой в таблице символов. На рис. 5 показан стек вызовов таблицы символов.

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

Хорошо, на этом мы закончили. Увидимся в следующий раз, берегите себя!

Мой блог cncyclops.com. Пожалуйста, свяжитесь со мной, если у вас есть какие-либо проблемы.

WeChat: qq9123013 Электронная почта: [email protected]