<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">FWIW today dispatch has that code when the objective-C runtime is used os OS X (in src/object.m).<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures" class="">Block_callbacks_RR</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> callbacks = {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre">                </span></span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">sizeof</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(</span><span style="font-variant-ligatures: no-common-ligatures" class="">Block_callbacks_RR</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">),</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">void</span><span style="font-variant-ligatures: no-common-ligatures" class=""> (*)(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">const</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">void</span><span style="font-variant-ligatures: no-common-ligatures" class=""> *))&</span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">objc_retain</span><span style="font-variant-ligatures: no-common-ligatures" class="">,</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">void</span><span style="font-variant-ligatures: no-common-ligatures" class=""> (*)(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">const</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">void</span><span style="font-variant-ligatures: no-common-ligatures" class=""> *))&</span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">objc_release</span><span style="font-variant-ligatures: no-common-ligatures" class="">,</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(49, 89, 93);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">void</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> (*)(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">const</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">void</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> *))&</span><span style="font-variant-ligatures: no-common-ligatures" class="">_os_objc_destructInstance</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>};</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">_Block_use_RR2</span><span style="font-variant-ligatures: no-common-ligatures" class="">(&callbacks);</span></div></div></blockquote><div class=""><br class=""></div><div class="">we may have to set it up with a similar trick for swift and that would solve the retain/release concern IMO.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">but that’s not the only concern, I sent a mail the other day, dispatch needs to:</div><div class="">- get to the function pointer inside the block (so know at which offset it is)</div><div class="">- if we want dispatch_block_create()d blocks to work, get some kind of support for it, to implement this function the right way:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">DISPATCH_ALWAYS_INLINE</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">static</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">inline</span><span style="font-variant-ligatures: no-common-ligatures" class=""> dispatch_block_private_data_t</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">_dispatch_block_get_data(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">const</span><span style="font-variant-ligatures: no-common-ligatures" class=""> dispatch_block_t db)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">{</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">if</span><span style="font-variant-ligatures: no-common-ligatures" class=""> (!_dispatch_block_has_private_data(db)) {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre">                </span></span><span style="font-variant-ligatures: no-common-ligatures" class="">return</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">NULL</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">;</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures" class="">// Keep in sync with _dispatch_block_create implementation</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>uint8_t *x = (uint8_t *)db;</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures" class="">// x points to base of struct Block_layout</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>x += </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">sizeof</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span><span style="font-variant-ligatures: no-common-ligatures" class=""> Block_layout);</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures" class="">// x points to base of captured dispatch_block_private_data_s object</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>dispatch_block_private_data_t dbpd = (dispatch_block_private_data_t)x;</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">if</span><span style="font-variant-ligatures: no-common-ligatures" class=""> (dbpd->dbpd_magic != DISPATCH_BLOCK_PRIVATE_DATA_MAGIC) {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>DISPATCH_CLIENT_CRASH(dbpd->dbpd_magic,</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre">                                </span></span><span style="font-variant-ligatures: no-common-ligatures" class="">"Corruption of dispatch block object"</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">);</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> dbpd;</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div></blockquote><div class="">Though presumably, since dispatch_create_block() are created by the C++ runtime, these are C-like and probably don’t need anything. so the the only two issues should be retain/release of swift issued blocks, and the offset to the invoke function. If that offset could be the same in both worlds then that would be perfect.</div><div class=""><br class=""><div class="">
-Pierre
</div>
<br class=""><div><blockquote type="cite" class=""><div class="">On Jan 22, 2016, at 2:47 PM, Tony Parker via swift-corelibs-dev <<a href="mailto:swift-corelibs-dev@swift.org" class="">swift-corelibs-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Dave,<div class=""><br class=""></div><div class="">What kind of layout does the Swift compiler emit for a Swift closure? If I call into a dispatch function that has a block argument, and that function calls Block_copy (from the blocks library), is everything retained correctly? The closure runtime.c calls out into a function emitted by the compiler to do that work. I would expect C code compiled by clang to follow the existing conventions but I’m not sure about Swift code compiled by swiftc.</div><div class=""><br class=""></div><div class="">- Tony</div><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 22, 2016, at 2:22 PM, David P Grove via swift-corelibs-dev <<a href="mailto:swift-corelibs-dev@swift.org" class="">swift-corelibs-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><p class="">Hi,<br class=""><br class="">Following up on the blocks discussion. I looked at the various Block header files and it looked there was a good chance things would just work. So, I did a quick & dirty hack of copying the .c and .h from foundation/closure into libdispatch/src/closure, building them, and linking with them instead of with libBlocksRuntime. All of the libdispatch tests that were working before, still work (not surprising), so it seems promising.<br class=""><br class="">I speculate we would prefer to not have multiple copies of the blocks runtime used by an application. Therefore we need to get libdispatch and libFoundation to use the same one. The natural path would be to just build a blocks runtime library from the sources in foundation/closure and have foundation and dispatch link against that library and compile against its headers. I'd further guess that it would be preferred to leave the files in foundation/closure (not create some new project) and tweak the foundation build process so that it is possible to invoke it to build just the blocks runtime as a separate step. <br class=""><br class="">Does this sound plausible? If so, I can start working on it. Or is some other approach better?<br class=""><br class="">thanks,<br class=""><br class="">--dave<br class=""><br class=""><br class=""><span id="cid:1__=0ABBF5D1DFE4C5408f9e8a93df938690918c0AB@" class=""><graycol.gif></span><font color="#424282" class="">Pierre Habouzit ---01/14/2016 10:09:28 PM---well dispatch also uses a bit of the blocks runtime because it uncorks the blocks and gets to the ca</font><br class=""><br class=""><font size="2" color="#5F5F5F" class="">From: </font><font size="2" class="">Pierre Habouzit <<a href="mailto:phabouzit@apple.com" class="">phabouzit@apple.com</a>></font><br class=""><font size="2" color="#5F5F5F" class="">To: </font><font size="2" class="">Philippe Hausler <<a href="mailto:phausler@apple.com" class="">phausler@apple.com</a>></font><br class=""><font size="2" color="#5F5F5F" class="">Cc: </font><font size="2" class="">David P Grove/Watson/IBM@IBMUS, Swift Core Libs <<a href="mailto:swift-corelibs-dev@swift.org" class="">swift-corelibs-dev@swift.org</a>></font><br class=""><font size="2" color="#5F5F5F" class="">Date: </font><font size="2" class="">01/14/2016 10:09 PM</font><br class=""><font size="2" color="#5F5F5F" class="">Subject: </font><font size="2" class="">Re: [swift-corelibs-dev] libdispatch prep for integration to the rest of swift-corelibs</font><br class=""><font size="2" color="#5F5F5F" class="">Sent by: </font><font size="2" class=""><a href="mailto:phabouzit@apple.com" class="">phabouzit@apple.com</a></font><br class=""></p><hr width="100%" size="2" align="left" noshade="" style="color:#8091A5; " class=""><br class=""><br class=""><br class=""><font size="4" class="">well dispatch also uses a bit of the blocks runtime because it uncorks the blocks and gets to the captured function pointer.</font><br class=""><br class=""><font size="4" class="">This is used pervasively, through this macro (internal.h):</font><br class=""><br class=""><font size="2" color="#D28F5A" class="">#define _dispatch_Block_invoke(bb) \</font><br class=""><font size="2" color="#D28F5A" class="">((dispatch_function_t)((struct Block_layout *)bb)->invoke)</font><br class=""><br class=""><font size="4" class="">And we need to know the size of the Block_layout for a simple block (abused in _dispatch_block_get_data(), see inline_internal.h).</font><br class=""><br class=""><font size="4" class="">technically speaking dispatch only cares about the offsets/sizes and not about the rest of the layout.</font><br class=""><br class=""><font size="4" class="">-Pierre </font><br class="">
<ul class=""><ul class=""><font size="4" class="">On Jan 14, 2016, at 3:00 PM, Philippe Hausler via swift-corelibs-dev <</font><a href="mailto:swift-corelibs-dev@swift.org" class=""><u class=""><font size="4" color="#0000FF" class="">swift-corelibs-dev@swift.org</font></u></a><font size="4" class="">> wrote:</font><br class=""><br class=""><font size="4" class="">As a note: our closure implementation in Foundation does NOT adhere to this (since it would mean that we would need to alter the c compiler to do so and that was not something that I have gotten to look at beyond a cursory glance.</font><br class=""><br class=""><font size="4" class="">So the change would be effectively something like this:</font><br class=""><br class=""><font size="4" class="">struct Block_layout {<br class=""> void *isa;<br class="">#if DEPLOYMENT_RUNTIME_SWIFT<br class=""> uint32_t refCount;<br class=""> uint32_t weakRefCount;<br class="">#else // not certain this branch can happen or not. we may need both</font><br class=""><font size="4" class=""> volatile int32_t flags; // contains ref count<br class=""> int32_t reserved;</font><br class=""><font size="4" class="">#endif</font><br class=""><font size="4" class=""> void (*invoke)(void *, ...);<br class=""> struct Block_descriptor_1 *descriptor;<br class=""> // imported variables<br class="">};</font><br class=""><br class=""><font size="4" class="">and making the retain and release methods for blocks just call swift_retain and swift_release. But since blocks may be emitted by the compiler we would need to make certain that the compiler had a flag to emit those with the new layout and emit correct values for the refCount fields to give it immortality for things like global static blocks etc.</font><br class=""><br class=""><font size="4" class="">Then we would need to find some way to have the values for:</font><br class=""><br class=""><font size="4" class="">void * _NSConcreteStackBlock[32] = { 0 };<br class="">void * _NSConcreteMallocBlock[32] = { 0 };<br class="">void * _NSConcreteAutoBlock[32] = { 0 };<br class="">void * _NSConcreteFinalizingBlock[32] = { 0 };<br class="">void * _NSConcreteGlobalBlock[32] = { 0 };<br class="">void * _NSConcreteWeakBlockVariable[32] = { 0 };</font><br class=""><br class=""><font size="4" class="">these guys emitted as objects as well so that the isa’s would be treated correctly.</font><br class=""><br class=""><font size="4" class="">I am not certain on how much of this lofty goal is actually needed; perhaps we should loop in one of the compiler team in on this to query what really needs to be done to properly support the @convention(block) syntax on linux. Perhaps I am overthinking this.</font><br class="">
<ul class=""><ul class=""><font size="4" class="">On Jan 14, 2016, at 2:49 PM, David P Grove <</font><a href="mailto:groved@us.ibm.com" class=""><u class=""><font size="4" color="#0000FF" class="">groved@us.ibm.com</font></u></a><font size="4" class="">> wrote:</font><br class=""><p class=""><a href="mailto:phausler@apple.com" class=""><tt class=""><u class=""><font size="4" color="#0000FF" class="">phausler@apple.com</font></u></tt></a><tt class=""><font size="4" class=""> wrote on 01/13/2016 06:04:23 PM:<br class="">> <br class="">> Tony brought up an important point about the prep for integration <br class="">> this morning: the blocks runtime from libblocksruntime-dev will be <br class="">> incompatible with the layout of blocks referenced from swift since <br class="">> the object size there is 2 uint32’s bigger to handle the RR (we <br class="">> don’t have objc). Without modifying clang and the runtime we won’t <br class="">> have a way to properly handoff blocks back and forth w/o objc.</font></tt><font size="4" class=""><br class=""></font><tt class=""><font size="4" class=""><br class="">Hi,</font></tt><font size="4" class=""><br class=""></font><tt class=""><font size="4" class=""><br class="">I'm guessing RR expands to Retain Release?</font></tt><font size="4" class=""><br class=""></font><tt class=""><font size="4" class=""><br class="">I've started exploring the source in swift-corelibs-foundation/closure. Any chance there is a design doc laying out the object model used by the Swift implementation? I'm sure I could figure it out from the source code, but it would be nice to be able to cheat and start with a an overview.</font></tt><font size="4" class=""><br class=""></font><tt class=""><font size="4" class=""><br class="">thanks,</font></tt><font size="4" class=""><br class=""></font><tt class=""><font size="4" class=""><br class="">--dave</font></tt><font size="4" class=""><br class=""></font><tt class=""><font size="4" class=""><br class="">> <br class="">> I am currently taking a look at this to see what we can do to add an<br class="">> option to the clang code-gen to properly emit this structural <br class="">> difference. This isn’t a big issue for Foundation to CF since we <br class="">> don’t have many block APIs but dispatch is mostly blocks and that <br class="">> might pose an issue.<br class="">> </font></tt><font size="4" class=""><br class=""></font></p></ul></ul><font size="4" class=""><br class=""></font><br class=""><font size="4" class="">_______________________________________________<br class="">swift-corelibs-dev mailing list</font><u class=""><font size="4" color="#0000FF" class=""><br class=""></font></u><a href="mailto:swift-corelibs-dev@swift.org" class=""><u class=""><font size="4" color="#0000FF" class="">swift-corelibs-dev@swift.org</font></u></a><font size="4" class=""><br class=""></font><font size="4" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-corelibs-dev" class="">https://lists.swift.org/mailman/listinfo/swift-corelibs-dev</a></font></ul></ul><br class=""><br class=""><br class="">
</div>
_______________________________________________<br class="">swift-corelibs-dev mailing list<br class=""><a href="mailto:swift-corelibs-dev@swift.org" class="">swift-corelibs-dev@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-corelibs-dev" class="">https://lists.swift.org/mailman/listinfo/swift-corelibs-dev</a><br class=""></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">swift-corelibs-dev mailing list<br class=""><a href="mailto:swift-corelibs-dev@swift.org" class="">swift-corelibs-dev@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-corelibs-dev<br class=""></div></blockquote></div><br class=""></div></body></html>