Глава 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 . Заинтересованы в хакинге роста? Ознакомьтесь с разделом Схема.