2021年1月2日星期六

The signature of BOOL in a swift closure is wrong in a 32-bit iOS device

The BOOL's signature is "B" normally in objective-c, Reference.

But on a 32-bit device. BOOL's signature is "c". Reference

Interesting finding

The interesting thing is that the BOOL in a swift closure is "B" on a 32-bit device (Should be "c").

For example, this is a swift closure.

let closure = {_ in          } as @convention(block) (Bool) -> Void  

The closure's signature is v8@?0B4 on 32-bit device. By right it should be v8@?0c4.

How to verify it?

sh_blockSignature(c code) is the function to get the signature from a block

test.m

enum {      // Set to true on blocks that have captures (and thus are not true      // global blocks) but are known not to escape for various other      // reasons. For backward compatibility with old runtimes, whenever      // BLOCK_IS_NOESCAPE is set, BLOCK_IS_GLOBAL is set too. Copying a      // non-escaping block returns the original block and releasing such a      // block is a no-op, which is exactly how global blocks are handled.      BLOCK_IS_NOESCAPE      =  (1 << 23),            BLOCK_HAS_COPY_DISPOSE =  (1 << 25),      BLOCK_HAS_CTOR =          (1 << 26), // helpers have C++ code      BLOCK_IS_GLOBAL =         (1 << 28),      BLOCK_HAS_STRET =         (1 << 29), // IFF BLOCK_HAS_SIGNATURE      BLOCK_HAS_SIGNATURE =     (1 << 30),  };    struct Block_literal_1 {      void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock      int flags;      int reserved;      void (*invoke)(void *, ...);      struct Block_descriptor_1 {          unsigned long int reserved;         // NULL          unsigned long int size;         // sizeof(struct Block_literal_1)          // optional helper functions          void (*copy_helper)(void *dst, void *src);     // IFF (1<<25)          void (*dispose_helper)(void *src);             // IFF (1<<25)          // required ABI.2010.3.16          const char *signature;                         // IFF (1<<30)      } *descriptor;      // imported variables  };    const char * _Nullable sh_blockSignature(id block)  {      struct Block_literal_1 *layout = (__bridge void *)block;      if (!(layout->flags & BLOCK_HAS_SIGNATURE))          return nil;            void *descRef = layout->descriptor;      descRef += 2 * sizeof(unsigned long int);            if (layout->flags & BLOCK_HAS_COPY_DISPOSE)          descRef += 2 * sizeof(void *);            if (!descRef) return nil;            const char *signature = (*(const char **)descRef);      return signature;  }  

test2.swift

let closure = {_ in   } as @convention(block) (Bool) -> Void  let p = sh_blockSignature(closure)!  let signature = String.init(cString: p)    print(signature)  // "v8@?0B4"  

Is this a swift bug on 32-bit device?

https://stackoverflow.com/questions/65519942/the-signature-of-bool-in-a-swift-closure-is-wrong-in-a-32-bit-ios-device December 31, 2020 at 06:54PM

没有评论:

发表评论