development

런타임에 결정된 대형 구조체 유형을 반환하는 IMP 함수를 구현하는 방법은 무엇입니까?

big-blog 2020. 12. 9. 21:10
반응형

런타임에 결정된 대형 구조체 유형을 반환하는 IMP 함수를 구현하는 방법은 무엇입니까?


배경 : CamelBones는 Objective-C 런타임에 Perl 클래스를 등록합니다. 이를 위해 모든 Perl 메서드는 동일한 IMP 함수로 등록됩니다. 이 함수는 self& _cmd인수를 검사 하여 호출 할 Perl 메서드를 찾습니다.

이 방법은로 발송 된 메시지에 대해 몇 년 동안 충분히 잘 작동했습니다 objc_msgSend. 하지만 이제는 Perl 메서드에서 부동 소수점 및 대형 구조체 유형을 반환하는 지원을 추가하고 싶습니다. 부동 소수점은 어렵지 않습니다. 나는 단순히 double을 반환하는 또 다른 IMP를 작성하여 objc_msgSend_fpret.

문제는에 대해 무엇을해야 하는가 objc_msgSend_stret입니다. IMP가능한 모든 구조체 반환 유형에 대해 개별적으로 작성하는 것은 두 가지 이유로 비실용적입니다. 첫째, 컴파일 타임에 알려진 구조체 유형에 대해서만 그렇게하더라도 함수의 수가 터무니 없기 때문입니다. 둘째, 임의의 Objective-C 및 Perl 코드와 연결할 수있는 프레임 워크에 대해 이야기하고 있기 때문에 프레임 워크가 컴파일 될 때 모든 잠재적 인 구조체 유형을 알 수 없습니다 .

내가하고자하는 IMP것은를 통해 전달되는 모든 반환 유형을 처리 할 수 있는 단일 작성하는 것 objc_msgSend_stret입니다. 나는 그것을 returning으로 쓸 수 void있고, old objc_msgSend_stret가 선언 된 것처럼 반환 버퍼에 대한 포인터 인수를 취할 수 있습니까? 지금 당장은 작동하더라도 앞으로도 계속 작동 할 것이라고 믿을 수 있습니까?

조언을 해주셔서 감사합니다. :-)

최신 정보:

다음은 objc 언어 메일 링리스트에서 Apple의 런타임 엔지니어 중 한 명으로부터받은 조언입니다.

이 경우를 처리하려면 어셈블리 코드를 작성해야합니다.

귀하의 제안은 일부 아키텍처에서 실패합니다. 여기서 "첫 번째 인수로 구조체에 대한 포인터를 사용하여 void를 반환하는 함수"에 대한 ABI가 "구조를 반환하는 함수"와 다릅니다. (i386에서 구조체 주소는 한 경우에는 호출자에 의해, 다른 경우에는 피 호출자에 의해 스택에서 팝됩니다.) 이것이 프로토 타입 objc_msgSend_stret이 변경된 이유 입니다.

어셈블리 코드는 구조체 반환 주소를 캡처하고 나머지 매개 변수를 방해하지 않고 비 구조 반환 C 함수 호출로 밀어 넣은 다음 종료시 올바른 ABI 관련 정리를 수행합니다 ( ret $4i386에서). 또는 어셈블리 코드가 모든 매개 변수를 캡처 할 수 있습니다. 포워딩 기계는 이와 같은 일을합니다. 기술이 어떻게 생겼는지 확인하려면 해당 코드가 오픈 소스 CoreFoundation에있을 수 있습니다.

누군가가 더 나은 아이디어를 브레인 스토밍하는 경우에 대비해이 질문을 열어 두겠습니다.하지만 이것이 Apple의 "런타임 랭글러"에서 직접 나온 것이므로 아마도 제가 얻을 수있는 것만 큼 권위있는 대답이라고 생각합니다. x86 레퍼런스 매뉴얼을 털어 내고 어셈블러-푸에서 녹을 녹일 시간입니다.


Apple 엔지니어가 옳은 것 같습니다. 유일한 방법은 어셈블리 코드입니다. 다음은 시작하는 데 유용한 몇 가지 지침입니다.

  • Objective-C 런타임 코드에서 : 다양한 메시징 방법을위한 i386x86_64 수작업 메신저 어셈블리 스텁.
  • 발송에 대한 개요를 제공 하는 SO 답변 입니다.
  • 어셈블리 코드의 라인 별 분석을 통해 파견 메카니즘에 대한 심층 검토

도움이 되었기를 바랍니다.

참고 URL : https://stackoverflow.com/questions/5476809/how-to-implement-an-imp-function-that-returns-a-large-struct-type-determined-at

반응형