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
没有评论:
发表评论