簡體   English   中英

如何計算ObjC方法類型編碼中的數字?

[英]How are the digits in ObjC method type encoding calculated?

是對我上一個問題的后續跟蹤: ObjC方法類型編碼字符串中的數字是什么?

說有一個編碼:

v24@0:4:8@12B16@20

這些數字是如何計算的? B是一個字符,所以它應該只占用1個字節(而不是4個字節)。 它與“對齊”有關嗎? void的大小是多少?

如下計算數字是否正確? 在每個項目上詢問sizeof並將結果四舍五入為4的倍數? 第一個數字成為所有其他數字的總和?

這些數字在m68K天用於表示堆棧布局。 也就是說,您可以逐字解碼方法簽名,對於幾乎所有類型,確切地知道堆棧幀中哪些偏移量可以用來獲取/設置參數。

這是有效的,因為m68K的ABI完全是[IIRC--已經很長時間]基於堆棧的參數/回傳。 跨越呼叫邊界沒有任何東西被塞進寄存器中。

但是,當Objective-C被移植到其他平台時,堆棧中的永遠不再是調用約定。 參數和返回值通常在寄存器中傳遞。

因此,那些抵消現在是無用的。 同樣,編譯器使用的類型編碼也不再完整(因為它從未非常有用),並且會有類型不會被編碼。 沒有提及編碼一些C ++模板化類型會產生方法類型編碼字符串,其大小可以是多千字節(我認為我遇到的記錄大約是30K的類型信息)。

所以,不,使用sizeof()生成數字是不正確的,因為它們對所有事物都毫無意義。 它們仍然存在的唯一原因是二進制兼容性; 這里和那里有一些深奧的代碼仍在解析類型編碼字符串,期望會有隨機數字灑在這里和那里。

請注意,ObjC運行時中存在API的殘余,這仍然使人們相信可以動態編碼/解碼堆棧幀。 實際上並不是因為C ABI不能保證在優化過程中跨越調用邊界保留參數寄存器。 你必須下降到組裝事情變得丑陋真的快(>不寒而栗<)。

完整的編碼字符串由方法ASTContext::getObjCEncodingForMethodDecl構建(在clang中),您可以在lib/AST/ASTContext.cpp找到lib/AST/ASTContext.cpp

執行大小舍入的方法是ASTContext::getObjCEncodingTypeSize ,在同一文件中。 它強制每個大小至少為int的大小。 在Apple的所有當前平台上, int是4個字節。

堆棧幀大小和參數偏移量由編譯器計算。 我本周試圖在Clang來源中追蹤這個問題。 它可能與CodeGenTypes::arrangeObjCMessageSendSignature (看起來Rob讓我的生活變得更輕松!)

第一個數字是其他數字的總和,是 - 它是參數占用的總空間。 要在代碼中獲取由ObjC類型編碼表示的類型的大小,您應該使用NSGetSizeAndAlignment()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM