Nat! bio photo

Nat!

Senior Mull

Twitter Github Twitch

NSMethodSignature bug and subsequent NSInvocation failure

You can't use NSInvocation on Mac OS X reliably. Well ain't that great.

The problem is that NSMethodSignature sometimes doesn't calculate the offsets for the parameters of the marg_list properly (see previous entry).

NSMethodSignature <0x3040d0> types(@@:idqf@diiiiiliiid) nargs(18) frameSize(232) retType(@) retSize(4)
{0 : type(@:idqf@diiiiiliiid) size(4) offset(128)}
{1 : type(:idqf@diiiiiliiid) size(4) offset(132)}
{2 : type(idqf@diiiiiliiid) size(4) offset(136)}
{3 : type(dqf@diiiiiliiid) size(8) offset(0)}
{4 : type(qf@diiiiiliiid) size(8) offset(148)}
{5 : type(f@diiiiiliiid) size(8) offset(8)}
{6 : type(@diiiiiliiid) size(4) offset(160)}
{7 : type(diiiiiliiid) size(8) offset(16)}
{8 : type(iiiiiliiid) size(4) offset(180)}
{9 : type(iiiiliiid) size(4) offset(184)}
{10 : type(iiiliiid) size(4) offset(188)}
{11 : type(iiliiid) size(4) offset(192)}
{12 : type(iliiid) size(4) offset(196)}
{13 : type(liiid) size(4) offset(200)}
{14 : type(iiid) size(4) offset(204)}
{15 : type(iid) size(4) offset(208)}
{16 : type(id) size(4) offset(212)}
{17 : type(d) size(8) offset(24)}

For whatever reason the offset for (integer) parameter #8 jumped to 180 from 160. It skipped eight bytes.

Therefore the NSInvocation runs into trouble. NSInvocation obviously uses the same code to compute the argument size and offset as NSMethodSignature or uses a private API of NSMethodSignature. It's curious, why there is no public functionality in Foundation to compute the size of a value given it's @encode ing. Or is there ?

Here's a little test project that shows the lossage. ZNeK portested it onto GNUStep and it runs OK there.

InvocationTest .zip

Output on Mac OS X Tiger 10.4.2

FAILURE
Got      : abcd=1 2.0 3 4.0  efgh=5 6.0 0 0 ijkl=7 8 9 10  mnop=11 12 13 16.0
Expected : abcd=1 2.0 3 4.0  efgh=5 6.0 7 8 ijkl=9 10 11 12  mnop=13 14 15 16.0

Output in GNUStep

SUCCESS
Got      : abcd=1 2.0 3 4.0 efgh=5 6.0 7 8 ijkl=9 10 11 12 mnop=13 14 15 16.0
Expected : abcd=1 2.0 3 4.0 efgh=5 6.0 7 8 ijkl=9 10 11 12 mnop=13 14 15 16.0