Index: src/OFMethodSignature.h ================================================================== --- src/OFMethodSignature.h +++ src/OFMethodSignature.h @@ -26,11 +26,11 @@ * @brief A class for parsing type encodings and accessing them. */ @interface OFMethodSignature: OFObject { char *_types; - OFMutableData *_typesPointers; + OFMutableData *_typesPointers, *_offsets; } /*! * The number of arguments of the method. */ @@ -39,10 +39,17 @@ /*! * The return type of the method. */ @property (readonly, nonatomic) const char *methodReturnType; +/*! + * The size of the arguments on the stack frame. + * + * @note This is platform-dependent! + */ +@property (readonly, nonatomic) size_t frameLength; + /*! * @brief Creates a new, autoreleased OFMethodSignature with the specified * ObjC types. * * @param types The ObjC types of the method @@ -60,12 +67,24 @@ - initWithObjCTypes: (const char *)types; /*! * @brief Returns the ObjC type for the argument at the specified index. * - * @param index The index for which to return the ObjC type + * @param index The index of the argument for which to return the ObjC type * @return The ObjC type for the argument at the specified index */ - (const char *)argumentTypeAtIndex: (size_t)index; + +/*! + * @brief Returns the offset on the stack frame of the argument at the + * specified index. + * + * @note This is platform-dependent! + * + * @param index The index of the argument for which to return the offset + * @returns The offset on the stack frame of the argument at the + * specified index + */ +- (size_t)argumentOffsetAtIndex: (size_t)index; @end OF_ASSUME_NONNULL_END Index: src/OFMethodSignature.m ================================================================== --- src/OFMethodSignature.m +++ src/OFMethodSignature.m @@ -49,23 +49,30 @@ _types = [self allocMemoryWithSize: length + 1]; memcpy(_types, types, length); _typesPointers = [[OFMutableData alloc] initWithItemSize: sizeof(char *)]; + _offsets = [[OFMutableData alloc] + initWithItemSize: sizeof(size_t)]; last = _types; for (size_t i = 0; i < length; i++) { if (isdigit(_types[i])) { + size_t offset = _types[i] - '0'; + if (last == _types + i) @throw [OFInvalidFormatException exception]; _types[i] = '\0'; [_typesPointers addItem: &last]; i++; - for (; i < length && isdigit(_types[i]); i++); + for (; i < length && isdigit(_types[i]); i++) + offset = offset * 10 + _types[i] - '0'; + + [_offsets addItem: &offset]; last = _types + i; i--; } else if (_types[i] == '{') { size_t depth = 0; @@ -111,10 +118,11 @@ } - (void)dealloc { [_typesPointers release]; + [_offsets release]; [super dealloc]; } - (size_t)numberOfArguments @@ -124,11 +132,21 @@ - (const char *)methodReturnType { return *(const char **)[_typesPointers firstItem]; } + +- (size_t)frameLength +{ + return *(size_t *)[_offsets firstItem]; +} - (const char *)argumentTypeAtIndex: (size_t)index { return *(const char **)[_typesPointers itemAtIndex: index + 1]; } + +- (size_t)argumentOffsetAtIndex: (size_t)index +{ + return *(size_t *)[_offsets itemAtIndex: index + 1]; +} @end Index: tests/OFMethodSignatureTests.m ================================================================== --- tests/OFMethodSignatureTests.m +++ tests/OFMethodSignatureTests.m @@ -38,11 +38,15 @@ "i28@0:8S16*20"]) && [ms numberOfArguments] == 4 && strcmp([ms methodReturnType], "i") == 0 && strcmp([ms argumentTypeAtIndex: 0], "@") == 0 && strcmp([ms argumentTypeAtIndex: 1], ":") == 0 && strcmp([ms argumentTypeAtIndex: 2], "S") == 0 && - strcmp([ms argumentTypeAtIndex: 3], "*") == 0) + strcmp([ms argumentTypeAtIndex: 3], "*") == 0 && + [ms frameLength] == 28 && [ms argumentOffsetAtIndex: 0] == 0 && + [ms argumentOffsetAtIndex: 1] == 8 && + [ms argumentOffsetAtIndex: 2] == 16 && + [ms argumentOffsetAtIndex: 3] == 20) TEST(@"-[signatureWithObjCTypes:] #2", (ms = [OFMethodSignature signatureWithObjCTypes: "{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}24@0:8" "^{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}16"]) && @@ -50,11 +54,14 @@ strcmp([ms methodReturnType], "{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}") == 0 && strcmp([ms argumentTypeAtIndex: 0], "@") == 0 && strcmp([ms argumentTypeAtIndex: 1], ":") == 0 && strcmp([ms argumentTypeAtIndex: 2], - "^{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}") == 0) + "^{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}") == 0 && + [ms frameLength] == 24 && [ms argumentOffsetAtIndex: 0] == 0 && + [ms argumentOffsetAtIndex: 1] == 8 && + [ms argumentOffsetAtIndex: 2] == 16) EXPECT_EXCEPTION(@"-[signatureWithObjCTypes:] #3", OFInvalidFormatException, [OFMethodSignature signatureWithObjCTypes: "{ii"])