Глава 29. Встроенное соглашение о вызовах

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

В V8, если вы изучите файл Integration.cc, вы обнаружите, что обработчики байт-кода используют встроенные вызовы CallBuitlin, что очень распространено. CallBuiltin используется только для вызова других встроенных функций во встроенных функциях, таких как обработчики байт-кода или функции CSA. Другими словами, если вы хотите вызвать встроенную функциональность в buitlin, обычно используется CallBuiltin. Точно так же, если вы вызываете функциональность времени выполнения во встроенной функции, для вас уже есть способ, о котором я расскажу в будущем.

В процессе CallBuiltin есть две важные части, одна из которых заключается в поиске адреса вызываемого объекта, а другая — в вычислении аргументов для вызываемого объекта.

1. CallBuiltin

Давайте рассмотрим, как он ищет адрес.

(1) Имя вызываемого объекта — это переменная перечисления, которую можно использовать для поиска во встроенной таблице.

Ниже приведена расширенная переменная перечисления.

(2) Переменная enum хранится в файле isoate-›isolate_data_-›builtins_.

В приведенном выше коде builtins_ представляет собой массив указателей Address, работая с enum Name:int32_t{} для получения определенного встроенного адреса.

(3) CallInterfaceDescriptor вычисляет аргументы, необходимые вызываемому объекту. Здесь мы должны быть знакомы с тем, как организовать список аргументов, так как вы, вероятно, напишете несколько новых встроенных функций.

В приведенном выше коде строки 5 и 6 дают возвращаемое значение вызываемого объекта. В строках 7, 8 и 9 указаны параметры вызываемого объекта. Параметр stackParameter означает, что если количество параметров слишком велико, чтобы превысить количество регистров, превышенные параметры передаются вызываемому объекту стеком. Все эти вещи, такие как возвращаемое значение и параметры регистра, управляются с помощью следующего CallInterfaceDescriptorData.

2. CallBuiltin с регистром

Давайте посмотрим на следующие сцены, которые являются обработчиком байт-кода LdaNamedProperty.

LdaNamedPropertyNoFeedback загружает свойство имени в накопитель регистров. Вы можете представить себе использование String.substring, в котором первым делом нужно получить подстроку функции объекта String, за которую отвечает LdaNamedProperty. Давайте посмотрим на CallBuiltin.

В приведенном выше коде идентификатор перечисления — это то, что я упомянул заранее. Аргументы имеют длину 2, в которых args[0] — это объект (в нашем случае это строка объекта), а args[1] — это имя (это наша подстрока). Отладьте его немного глубже, вы встретите следующий код.

В приведенном выше примере строка 7 возвращает узел, представляющий вызываемого объекта, которого мы вызываем. Если вы блуждаете по узлу, см. море узлов для получения дополнительной информации. Но для понимания CallBuiltin вышеизложенного достаточно.

На рис. 1 показан стек вызовов.

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

Пожалуйста, свяжитесь со мной, если у вас есть какие-либо проблемы. WeChat: qq9123013 Электронная почта: [email protected]

Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord . Заинтересованы в хакинге роста? Ознакомьтесь с разделом Схема.