Глава 30. Загрузка JS-функции и выполнение байт-кода
Добро пожаловать в другие главы Давайте разберемся с Chrome V8
В этой статье я расскажу о зажигании и дам вам представление о том, как оно работает, как оно загружает JS-функцию и что она будет делать перед выполнением.
1. Вызов JS-функции
Для интерпретатора V8 все это начинается с загрузки JS-функции (термин V8 — invoke), поскольку он имеет массив байт-кода. Ниже приведена функция вызова.
Перед вызовом JS-функции V8 оборачивает ее в invoke-params, но не добавляет другие новые вещи, поэтому нас это не волнует, но мы помним, какой член является в ней JSfcuntion. Я выкладываю важное содержание ниже.
(1) Строки 1–13, SetupForCall() — это функция-оболочка, о которой я упоминал.
(2) Строка 17, код представляет собой адрес функции Builtin::kJSEntry.
(3) Строка 24, stub_entry — это первая инструкция Builtin::kJSEntry.
(4) Строка 27, func — это JS-функция, которая будет выполняться.
(5) Строка 31, stub_entry.Call начинает переходить в Ignition для выполнения вашего JavaScript. Примечание.ваш код JavaScript еще не вызван, так как Ignition создает стек вызовов, а затем переходит к вашему коду.
2. Встроенный::kJSEntry
Прежде чем говорить о Builtin::kJSEntry, я хочу подчеркнуть некоторые члены JSFunction, которые часто используются в Ignition.
(1) SharedFunction является членом JSFunction, важно знать, что SharedFunction имеет массив байт-кода, который будет выполнять Ignition.
(2) код – это встроенный модуль::kInterpreterEntryTrampoline.
(3) контекст — это контекст, соответствующий текущей среде выполнения.
Перейдем к файлу Builtin::kJSEntry.
В приведенном выше коде строка 2 вызывает Generate_JSEntryVariant(), третий параметр которой — это батут, который в конечном итоге вызывает наш байт-код.
В строке 15 arg_reg_1 представляет собой isolate-›isolate_data()-›isolate_root(), причина, по которой я подчеркиваю это, заключается в том, что isolate_root() содержит все необходимые вещи, такие как встроенные модули и куча, которые полезны во время выполнения.
Строки 17–22, поместите верхний фрейм в стек, как мы это делаем в X86.
Строки 24–26 загружают текущий контекст в ScratchRegister.
Строки 46–48, выполните JSEntryTrampoline.
3. Встроенный::kJSEntryTrampoline
В приведенном выше коде строки 7–28 помещают параметры в стек, в котором функция параметра представляет собой байт-код, полученный из нашего JavaScript. В строках 40–49 комментарии описывают структуру стекового фрейма. Строка 53, получите встроенный адрес, то есть Builtin::kCall_ReceiverIsAny.
4. Встроенный::kCall_ReceiverIsAny
В приведенном выше коде, строка 13, rdi — это выполняемая функция JSF, а rcx — ее карта. Как правило, CmpObjectType имеет значение true и переходит к строке 14 и в конечном итоге вызывает kCallFunction_ReceiverIsAny.
5. Встроенный::kCallFunction_ReceiverIsAny
В приведенном выше коде строки 7–19 помещают параметры в стек, регистр rax имеет решающее значение для обеспечения того, чтобы аргументы JavaScript всегда совпадали, поскольку V8 заполняет Null, если аргумент отсутствует, или V8 отбрасывает лишнее. аргументы. Строки 10–14, rdi — это JSFuncion, а rdx — его SharedFunction. Завершите выполнение строки 20.
6. InvokeFunctionCode
В приведенном выше коде строка 23 вызывает rcx, rcx — это просто Builtins::kInterpreterEntryTrampoline, который является прологом нашего JavaScript. Другими словами, если вам интересно, как выполняется ваш JavaScript, отладка отсюда — самый простой способ.
Следующее описание взято из v8.dev.
«Когда функция вызывается во время выполнения, вводится заглушка InterpreterEntryTrampoline. Эта заглушка устанавливает соответствующий кадр стека, а затем отправляет обработчику байт-кода интерпретатора первый байт-код функции, чтобы начать выполнение функции в интерпретаторе. Конец каждого обработчика байт-кода напрямую отправляет следующему обработчику через индекс в глобальной таблице интерпретатора на основе байт-кода».
Хорошо, на этом мы закончили. Увидимся в следующий раз, берегите себя!
Пожалуйста, свяжитесь со мной, если у вас есть какие-либо проблемы. WeChat: qq9123013 Электронная почта: [email protected]
Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord . Заинтересованы в хакинге роста? Ознакомьтесь с разделом Схема.