Objective-C ã® __block ã®åç §ã«ã¦ã³ã¿ã調æ»ä¸â¦
ãã¨ãã¹ãã¼ãObjective-Cããã°ã©ãã³ã°ããBlocksã¾ã§èªç ´ããããã¯ãcopyå¾ã¯ã__blockå¤æ°ã®__forwardingå ãç¾å¨ã®ã¹ã³ã¼ã(?)ãææãã¹ã³ã¼ãããæããæã«éæ¾ããããã«ããªãã¨ãå¤æ°ã®å¯¿å½ããcopyå¾ãããã¯ãçãå ´åã«å°ãã®ã§ã¯
2011-11-24 17:58:17 via web
ãªããã¨ããã®ãããªè¨è¿°ãæ¢ãã¦ã¿ããããããããªãã£ãã-rewrite-objcã¯ãããã¯é¨åã ãã©C++ã¸å±éãããã©ããã以å¤ã¯objcã®ãããªã®ã§ããã¾ãæãããã«ãªããªãããã¢ã»ã³ããªãè¦ããããªã?
2011-11-24 18:00:24 via web
@ganaware copyããblockã®æ¹ãã¹ã¿ãã¯ããã寿å½ãçãã±ã¼ã¹ã¯å®è£ ä¸æ³å®ããã¦ãªãã®ã§ã¯ãªããã¨èãã¦ãã¾ãããã®ã¸ãã«åä½ãã¾ã¨ãã¦ãã¾ãã®ã§åèã«ãªããã¨æãã¾ãã URL URL
2011-11-24 21:49:58 via web to @ganaware
- Xcode 4.2.1
- Apple LLVM Compiler 3.0
- ARC ãªã
- 32-bit Intel, Mac OS X 10.7
- Enable C++ Exceptions => No
ã¨ããè¨å®ã§ä¸è¨ã® @splhack ããã®è¨äºã®ã³ã¼ã(以ä¸ã«åæ²)ããã«ããã
#import <Foundation/Foundation.h> #import <stdio.h> extern const char *_Block_byref_dump(void *); void dump(int line, int *p) { p -= 4; printf("\ndump line:%d\n", line); puts(_Block_byref_dump(p)); } int *test() { __block int total = 11; dump(__LINE__, &total); void (^block_on_stack)() = ^{ ++total; dump(__LINE__, &total); }; block_on_stack(); printf("\n___ Block_copy ___\n"); void (^block_on_heap)() = Block_copy(block_on_stack); dump(__LINE__, &total); block_on_stack(); block_on_heap(); printf("\n___ Block_release ___\n"); Block_release(block_on_heap); dump(__LINE__, &total); block_on_stack(); return &total; } int main() { dump(__LINE__, test()); }
Assembly ãè¦ãã¨ãtest() ã®æå¾ã§ä»¥ä¸ã®ãããªã³ã¼ããå®è¡ããã¦ããã®ãè¦ã¤ããã¾ãã
.loc 1 45 1 ## (ç¥)/main.m:45:1 movl -112(%ebp), %eax ## 4-byte Reload movl %eax, (%esp) movl $8, 4(%esp) calll __Block_object_dispose
ã©ããã __block å¤æ°ã® __forwarding å ã®åç §ã«ã¦ã³ãã¯ãBlock_copy() ããæã«ã¹ã¿ãã¯ããã®åç §åã¨ãã¼ãããåç §åã ãã«ã¦ã³ã¿ãå¢ããã¦ããã¦ãBlock_release() æã¨ã¹ã³ã¼ãã®çµããã«æ¿å ¥ããã _Block_object_dispose() æã«æ¸ããã¦ããããã§ããã
https://llvm.org/svn/llvm-project/compiler-rt/trunk/BlocksRuntime/runtime.c
void _Block_object_dispose(const void *object, const int flags) { // (ç¥) if (flags & BLOCK_FIELD_IS_BYREF) { // get rid of the __block data structure held in a Block _Block_byref_release(object); } // (ç¥) }
ã¨ããããã§
ãã¨ãã¹ãã¼ãObjective-Cããã°ã©ãã³ã°ããBlocksã¾ã§èªç ´ããããã¯ãcopyå¾ã¯ã__blockå¤æ°ã®__forwardingå ãç¾å¨ã®ã¹ã³ã¼ã(?)ãææãã¹ã³ã¼ãããæããæã«éæ¾ããããã«ããªãã¨ãå¤æ°ã®å¯¿å½ããcopyå¾ãããã¯ãçãå ´åã«å°ãã®ã§ã¯
2011-11-24 17:58:17 via web
ã¨ããã§ãå®è¡ãã¦ã¿ãã¨ãã次ã®ãããªåºåãå¾ã¾ããã
dump line:17 byref data block 0xbffff9c0 contents: forwarding: 0xbffff9c0 flags: 0x0 size: 20 dump line:23 byref data block 0xbffff9c0 contents: forwarding: 0xbffff9c0 flags: 0x0 size: 20 ___ Block_copy ___ dump line:31 byref data block 0x13e450 contents: forwarding: 0x13e450 flags: 0x1000004 size: 20 dump line:23 byref data block 0x13e450 contents: forwarding: 0x13e450 flags: 0x1000004 size: 20 dump line:23 byref data block 0x13e450 contents: forwarding: 0x13e450 flags: 0x1000004 size: 20 ___ Block_release ___ dump line:40 byref data block 0x13e450 contents: forwarding: 0x13e450 flags: 0x1000002 size: 20 dump line:23 byref data block 0x13e450 contents: forwarding: 0x13e450 flags: 0x1000002 size: 20 dump line:49 byref data block 0x13e450 contents: forwarding: 0x13e450 flags: 0x1000001 size: 20
@splhack ããã®è¨äºã®çµæã¨ã¯ä»¥ä¸ã®ç¹ãè¥å¹²ç°ãªã£ã¦ãã¾ãã
- è¬1: flags ã®ä¸ä½ 16bit ã®åç
§ã«ã¦ã³ãããBlock_copy() 㧠4 å¢ããBlock_release() 㧠2 æ¸ã
- _Block_object_dispose() å ã§ã¯ flags ã 1 ããæ¸ããã¦ããªãããã«è¦ããã®ã§ããâ¦
- è¬2: æå¾ã® dump line:49 ã§ã¯åç
§ã«ã¦ã³ãã 1 ã®ã¾ã¾
- åç §ã«ã¦ã³ã㯠OSAtomicCompareAndSwapInt() ã§æ¸ããããã®ã§ãæå¾ã¯ã¡ãã㨠0 ã«ãªãã¹ãã§ããã¯ã
@ganaware ããããç§ã調ã¹ãæã¨ã©ã³ã¿ã¤ã ãç°ãªãããã ã¨æãã¾ããç¾å¨ã¯libclosure URL ã使ããã¦ããã®ã§ã¯ãªããã¨ã
2011-11-25 04:01:40 via YoruFukurou to @ganaware
ã¨ãããè¿äºãããã ããã®ã§ libclosure-53 ãè¦ãã¦ã¿ãã¨ã
http://www.opensource.apple.com/source/libclosure/libclosure-53/Block_private.h
enum { BLOCK_DEALLOCATING = (0x0001), BLOCK_REFCOUNT_MASK = (0xfffe), BLOCK_NEEDS_FREE = (1 << 24), (ç¥) };
ã¨ãªã£ã¦ãããåç §ã«ã¦ã³ãã¯1bitå·¦ã¸ã·ããããã¦ãã¾ãããä¸è¨ã®çµæã«ãªãã®ãç´å¾ã§ãã