मैं सी/ऑब्जेक्टिव-सी में उच्च स्तरीय कॉलिंग के साथ उपयोग के लिए कुछ ट्रैम्पोलिन फ़ंक्शंस के साथ काम कर रहा हूं, Apple does it के रास्ते पर मामूली मोड़।i386 में स्टैक से तर्कों को हटाने, एआरएम असेंबली
आप पर सभी तरह ऑब्जेक्टिव-सी IMP
काम करता है के साथ परिचित हैं, तो यह मूल रूप से एक समारोह सूचक जहां पहले दो तर्क संदेश का रिसीवर और संदेश चयनकर्ता के नाम हैं, void(*)(id obj, SEL sel, ...)
रूप में इस तरह है। रनटाइम के हाल के संस्करणों में सी ब्लॉक का उपयोग करके रन टाइम पर विधि कार्यान्वयन को संश्लेषित करने की अनुमति मिलती है, जैसे void(^)(id obj, ...)
। इन ब्लॉकों में चयनकर्ता नहीं है; रनटाइम एक ट्रैम्पोलिन बनाता है जो रिसीवर के साथ चयनकर्ता को ओवरराइट करता है, ब्लॉक पॉइंटर के साथ रिसीवर, और उसके बाद इसे निष्पादित करने पर चलता है।
मैं, जो या तो पहले दो तर्कों की नहीं होने शामिल अस्पष्ट समान कुछ करने के लिए इतना है कि इस ब्लॉक के लिए तर्क पारंपरिक विधि भेजने के तर्कों के रूप में ठीक उसी हैं चाहते हैं, के साथ साथ निष्पादन के लिए ब्लॉक सूचक उद्देश्यों, यानी, void(*)(Block *, ...)
। इसके लिए केवल ब्लॉक पॉइंटर में कॉपी करना आवश्यक है, और मुझे लगता है कि एक तर्क से छुटकारा पा रहा है।
__a1a2_tramphead_argonly:
popl %eax
andl $0xFFFFFFF8, %eax
subl $0x1000, %eax
movl 4(%esp), %ecx // self -> ecx
movl %ecx, 8(%esp) // ecx -> _cmd
movl (%eax), %ecx // blockPtr -> ecx
movl %ecx, 4(%esp) // ecx -> self
jmp *12(%ecx) // tail to block->invoke
यहाँ विधानसभा मैं एआरएम पर है:
__a1a2_tramphead_argonly:
// calculate the trampoline's index (512 entries, 8 bytes each)
#ifdef _ARM_ARCH_7
// PC bias is only 4, no need to correct with 8-byte trampolines
ubfx r1, r1, #3, #9
#else
sub r1, r1, #8 // correct PC bias
lsl r1, r1, #20
lsr r1, r1, #23
#endif
// load block pointer from trampoline's data
adr r12, __a1a2_tramphead_argonly // text page
sub r12, r12, #4096 // data page precedes text page
ldr r12, [r12, r1, LSL #3] // load block pointer from data + index*8
// shuffle parameters
mov r1, r0 // _cmd = self
mov r0, r12 // self = block pointer
// tail call block->invoke
ldr pc, [r12, #12]
इसी कोड x86_64 के लिए मौजूद है, ऊपर दिया गया कोड अब तक सीधे ऐप्पल से है। व्यक्तिगत ज्ञान के लिए, मैं सोच रहा हूं कि तर्क को उत्तेजित करने के साथ कहां से शुरू करना है, ताकि पहला तर्क (जो रेसीवर होता था) ब्लॉक शब्दशः है, दूसरा पहला वास्तविक तर्क है, और इसी तरह।
मैं एएसएम में अविश्वसनीय रूप से नोबिश हूं, इसलिए किसी भी मदद की सराहना की जाती है। मैंने जो भी कोशिश की है वह तेजी से दिलचस्प तरीके से उड़ा है। अग्रिम में धन्यवाद।
सावधान रहें, वर्तमान में कई लिनक्स डिस्ट्रोज़ एआरएम हार्ड-फ्लोट एबीआई में जाने की प्रक्रिया में हैं। यह फिर से आपके लिए सबकुछ तोड़ देगा। – ams
यह दिलचस्प है, मैं इसे भविष्य के लिए ध्यान में रखूंगा। हालांकि, यह ज्यादातर डार्विन को लक्षित कर रहा है। धन्यवाद! संपादित करें: इसका मतलब है कि कम से कम समय के लिए एआरएमवी 6 और एआरएमवी 7। – zwaldowski