Как реализовать функцию IMP, которая возвращает большой тип структуры, определенный во время выполнения?

Справочная информация. CamelBones регистрирует классы Perl со временем выполнения Objective-C. Для этого каждый метод Perl регистрируется с тем же IMP функция; эта функция проверяет свои аргументы self и _cmd, чтобы найти какой метод Perl вызывать.

Это достаточно хорошо работало в течение нескольких лет для сообщений, которые были отправлен с помощью objc_msgSend. Но теперь я хочу добавить поддержку для возвращающие типы с плавающей точкой и большие структуры из методов Perl. С плавающей точкой нетрудно; Я просто напишу еще один IMP, который возвращает double, для обработки сообщений, отправленных с помощью objc_msgSend_fpret.

Вопрос в том, что делать с objc_msgSend_stret. Написание отдельный IMP для каждого возможного типа возвращаемого типа непрактичен, для две причины: во-первых, потому что даже если бы я сделал это только для типов struct которые известны во время компиляции, это абсурдное количество функций. Во-вторых, поскольку мы говорим о структуре, которая может быть связана с любым произвольным кодом Objective-C и Perl, мы не знаем всех потенциальных типов структуры при компиляции фрейма.

Что я надеюсь сделать, это написать один IMP, который может обрабатывать любой возврат тип, отправленный через objc_msgSend_stret. Могу ли я написать его как возвращая void и принимая аргумент указателя в буфер возврата, например старый objc_msgSend_stret был объявлен? Даже если это случилось с работа на данный момент, могу ли я полагаться на это, продолжая работать в будущем?

Спасибо за любой совет - я уже ломаю голову над этим.: -)

Update:

Вот совет, который я получил от одного из инженеров Apple во время выполнения, в своем списке рассылки на языке objc:

Вы должны написать код сборки для обработки этот случай.

Ваше предложение не работает на некоторых архитектуры, где ABI для функции возвращает пустоту с указателем на struct как первый аргумент "отличается от" функции, возвращающей структуру". (На i386 выведен адрес структуры из стека вызывающим в одном случае и вызываемой в другой случай.) Вот почему прототип для objc_msgSend_stret было изменено.

Код сборки будет захватывать адрес возврата структуры, контрабандой в него вызов функции функции non-struct-return C не нарушая параметров, а затем выполните правильные ABI-специфическая очистка при выходе (ret $4на i386). Альтернативно, сборка код может захватывать все параметры. Транспортное оборудование делает что-то подобное. Этот код может быть в CoreFoundation с открытым исходным кодом если вы хотите посмотреть, какие методы выглядите.

Я оставлю этот вопрос открытым, на случай, если кто-то проведет мозговой штурм лучше, но если это произойдет непосредственно от Apple, "нарушителя времени исполнения", я считаю, что это, вероятно, как авторитетный ответ, как я, скорее всего, получу. Время, пытаясь избавиться от справочных руководств x86 и выбить ржавчину с моего ассемблера-фу, я думаю...

Ответ 1

Кажется, что инженер Apple прав: единственный путь - это код сборки. Вот несколько полезных указаний для начала:

  • Из Objective-C кода времени выполнения: i386 и x86_64 обработанные вручную мессенджеры для различных методов обмена сообщениями.
  • Ответ "Ответ" , в котором представлен обзор диспетчеризации.
  • Углубленный обзор диспетчерского меканизма с поэтапным анализом кода сборки

Надеюсь, что это поможет.