Shiwen XU created WEEX-88:
-----------------------------

             Summary: BOOL arguments cannot be received correctly by 
component's method in 32-bit iOS devices
                 Key: WEEX-88
                 URL: https://issues.apache.org/jira/browse/WEEX-88
             Project: Weex
          Issue Type: Bug
          Components: iOS
    Affects Versions: 0.15
         Environment: iPhone 4s (iOS 9.1), iPhone 5 simulator (iOS 10.3)
            Reporter: Shiwen XU
            Assignee: Adam Feng
            Priority: Blocker


BOOL arguments cannot be received correctly by component's method in 32-bit iOS 
devices. It appears that the received argument is always some integer value 
other than boolean value.

This problem might be introduced by the macro *WX_ARGUMENTS_SET*.

{code:title=WXUtility.h|borderStyle=solid}
#define WX_ARGUMENTS_SET(_invocation, _sig, idx, _obj, _ppFree) \
do {\
    const char *encode = [_sig getArgumentTypeAtIndex:(idx) + 2];\
    switch(encode[0]){\
        WX_EPCHAR_CASE(_invocation, idx, _C_CHARPTR, _obj, char *, UTF8String, 
_ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_INT, _obj, int, intValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_SHT, _obj, short, shortValue, 
_ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_LNG, _obj, long, longValue, 
_ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_LNG_LNG, _obj, long long, 
longLongValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_UCHR, _obj, unsigned char, 
unsignedCharValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_UINT, _obj, unsigned int, 
unsignedIntValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_USHT, _obj, unsigned short, 
unsignedShortValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_ULNG, _obj, unsigned long, 
unsignedLongValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_ULNG_LNG, _obj,unsigned long long, 
unsignedLongLongValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_FLT, _obj, float, floatValue, 
_ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_DBL, _obj, double, doubleValue, 
_ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_BOOL, _obj, bool, boolValue, 
_ppFree)\
        default: { [_invocation setArgument:&_obj atIndex:(idx) + 2]; *(_ppFree 
+ idx) = 0; break;}\
    }\
}while(0)
{code}

The BOOL value in 32-bit iOS is a typedef of signed char so its *@encode* is 
*_C_CHR* instead of *_C_BOOL*. We can find the typedef in objc.h.

{code:title=objc.h|borderStyle=solid}
#if defined(__OBJC_BOOL_IS_BOOL)
    // Honor __OBJC_BOOL_IS_BOOL when available.
#   if __OBJC_BOOL_IS_BOOL
#       define OBJC_BOOL_IS_BOOL 1
#   else
#       define OBJC_BOOL_IS_BOOL 0
#   endif
#else
    // __OBJC_BOOL_IS_BOOL not set.
#   if TARGET_OS_OSX || (TARGET_OS_IOS && !__LP64__ && !__ARM_ARCH_7K)
#      define OBJC_BOOL_IS_BOOL 0
#   else
#      define OBJC_BOOL_IS_BOOL 1
#   endif
#endif

#if OBJC_BOOL_IS_BOOL
    typedef bool BOOL;
#else
#   define OBJC_BOOL_IS_CHAR 1
    typedef signed char BOOL; 
    // BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
    // even if -funsigned-char is used.
#endif
{code}

But *WX_ARGUMENTS_SET* didn't consider the case of *_C_CHR*. In this case the 
default condition is executed and the *NSNumber pointer* value will be casted 
to a *BOOL* value so the received argument is always wrong.

If I add this line of code and the received argument will become correct.

{code}
WX_ENUMBER_CASE(_invocation, idx, _C_UCHR, _obj, unsigned char, 
unsignedCharValue, _ppFree)\
/* added code */
WX_ENUMBER_CASE(_invocation, idx, _C_CHR, _obj, char, charValue, _ppFree)\
{code}




--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to