title: iOS NSInvocation setArgument: atIndex: does not work with struct on ARM builds
body: <p>I have a strange problem with setting the argument of an NSInvocation with a struct that contains a double or any 64 bit type which is not aligned (I offset it with a char at the beginning of the struct). The problem is that some bytes are cleared after the argument is set. This problem occurs on ARM7 but not in the iOS simulator.</p>
  
  <p>I'm using LLVM 3.0 and Xcode 4.2</p>
  
  <p>Here is my code and test results:</p>
  
  <p>NSInvocation+Extension.h</p>
  
  <pre><code>@interface NSInvocation (Extension)
  
  + (NSInvocation*) invocationWithTarget: (id)aTarget
                                selector: (SEL)aSelector
                         retainArguments: (BOOL)aRetainArguments, ...;
  
  - (void) setArguments: (va_list)aArgList;
  - (void) setArguments: (va_list)aArgList atIndex: (NSInteger)aIndex;
  
  @end    // NSInvocation (Extension)
  </code></pre>
  
  <hr>
  
  <p>NSInvocation+Extension.m</p>
  
  <pre><code>#import &lt;objc/runtime.h&gt;
  
  #import "NSInvocation+Extension.h"
  
  
  @implementation NSInvocation (Extension)
  
  + (NSInvocation*) invocationWithTarget: (id)aTarget
                                selector: (SEL)aSelector
                         retainArguments: (BOOL)aRetainArguments, ...
  {
      NSMethodSignature* signature = [aTarget methodSignatureForSelector: aSelector];
      NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: signature];
  
      if (aRetainArguments)
      {
          [invocation retainArguments];
      }
      [invocation setTarget: aTarget];
      [invocation setSelector: aSelector];
  
      va_list argList;
      va_start(argList, aRetainArguments);
      [invocation setArguments: argList];
      va_end(argList);
  
      return invocation;
  }
  
  - (void) setArguments: (va_list)aArgList
  {
      [self setArguments: aArgList atIndex: 0];
  }
  
  - (void) setArguments: (va_list)aArgList atIndex: (NSInteger)aIndex
  {
      // Arguments are aligned on machine word boundaries
      const NSUInteger KOffset = sizeof(size_t) - 1;
  
      UInt8* argPtr = (UInt8*)aArgList;
      NSMethodSignature* signature = [self methodSignature];
  
      // Indices 0 and 1 indicate the hidden arguments self and _cmd respectively.
      for (int index = aIndex + 2; index &lt; [signature numberOfArguments]; ++index)
      {
          const char* type = [signature getArgumentTypeAtIndex: index];
          NSUInteger size = 0;
          NSGetSizeAndAlignment(type, &amp;size, NULL);
          [self setArgument: argPtr atIndex: index];
          argPtr += (size + KOffset) &amp; ~KOffset;
      }
  }
  
  @end  // NSInvocation (Extension)
  </code></pre>
  
  <hr>
  
  <p>Declare method to invoke and a data struct</p>
  
  <pre><code>- (void) arg1: (char)aArg1 arg2: (char)aArg2 arg3: (TEST)aArg3 arg4: (char)aArg4;
  
  typedef struct test {
      char c;
      double s;
      char t;
      void* b;
      char tu;
  } TEST;
  </code></pre>
  
  <hr>
  
  <p>Calling code</p>
  
  <pre><code>TEST df = { 'A', 12345678.0, 'B', (void*)2, 'C' }; 
  
  char buf[100] = {0};
  
  NSInvocation* ik = [NSInvocation invocationWithTarget: self selector: @selector(arg1:arg2:arg3:arg4:) retainArguments: NO, '1', '2', df, '3'];
  [ik getArgument: &amp;buf atIndex: 4];
  </code></pre>
  
  <hr>
  
  <p>Contents of buf on ARM7 (bytes 8, 9, 10 and 11 set to zero which messed up the double value)</p>
  
  <p>41 00 00 00 00 00 00 00 29 8C 67 41 42 00 00 00 02 00 00 00 43 00 00 00</p>
  
  <p>Contents of buf on i386 simulator (as expected)</p>
  
  <p>41 00 00 00 00 00 00 C0 29 8C 67 41 42 00 00 00 02 00 00 00 43 00 00 00</p>
  
  <hr>