|
@@ -9,6 +9,7 @@
|
|
|
#import <UIKit/UIKit.h>
|
|
#import <UIKit/UIKit.h>
|
|
|
#import "FLEXRuntimeUtility.h"
|
|
#import "FLEXRuntimeUtility.h"
|
|
|
#import "FLEXObjcInternal.h"
|
|
#import "FLEXObjcInternal.h"
|
|
|
|
|
+#import "FLEXTypeEncodingParser.h"
|
|
|
|
|
|
|
|
// See https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW6
|
|
// See https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW6
|
|
|
NSString *const kFLEXPropertyAttributeKeyTypeEncoding = @"T";
|
|
NSString *const kFLEXPropertyAttributeKeyTypeEncoding = @"T";
|
|
@@ -296,13 +297,12 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
|
|
|
return nil;
|
|
return nil;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Probably an unsupported type encoding, like bitfields
|
|
|
|
|
- // or inline arrays. In the future, we could calculate
|
|
|
|
|
- // the return length on our own. For now, we abort.
|
|
|
|
|
|
|
+ // Probably an unsupported type encoding, like bitfields.
|
|
|
|
|
+ // In the future, we could calculate the return length
|
|
|
|
|
+ // on our own. For now, we abort.
|
|
|
//
|
|
//
|
|
|
// For future reference, the code here will get the true type encoding.
|
|
// For future reference, the code here will get the true type encoding.
|
|
|
// NSMethodSignature will convert {?=b8b4b1b1b18[8S]} to {?}
|
|
// NSMethodSignature will convert {?=b8b4b1b1b18[8S]} to {?}
|
|
|
- // A solution might involve hooking NSGetSizeAndAlignment.
|
|
|
|
|
//
|
|
//
|
|
|
// returnType = method_getTypeEncoding(class_getInstanceMethod([object class], selector));
|
|
// returnType = method_getTypeEncoding(class_getInstanceMethod([object class], selector));
|
|
|
NSMethodSignature *methodSignature = [object methodSignatureForSelector:selector];
|
|
NSMethodSignature *methodSignature = [object methodSignatureForSelector:selector];
|
|
@@ -361,9 +361,7 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
|
|
|
|
|
|
|
|
@try {
|
|
@try {
|
|
|
NSUInteger bufferSize = 0;
|
|
NSUInteger bufferSize = 0;
|
|
|
-
|
|
|
|
|
- // NSGetSizeAndAlignment barfs on type encoding for bitfields.
|
|
|
|
|
- NSGetSizeAndAlignment(typeEncodingCString, &bufferSize, NULL);
|
|
|
|
|
|
|
+ FLEXGetSizeAndAlignment(typeEncodingCString, &bufferSize, NULL);
|
|
|
|
|
|
|
|
if (bufferSize > 0) {
|
|
if (bufferSize > 0) {
|
|
|
void *buffer = alloca(bufferSize);
|
|
void *buffer = alloca(bufferSize);
|
|
@@ -568,30 +566,29 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
|
|
|
substringWithRange:NSMakeRange(nameStart - structEncoding, equals - nameStart)
|
|
substringWithRange:NSMakeRange(nameStart - structEncoding, equals - nameStart)
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
- NSUInteger fieldAlignment = 0;
|
|
|
|
|
- NSUInteger structSize = 0;
|
|
|
|
|
- @try {
|
|
|
|
|
- // NSGetSizeAndAlignment barfs on type encoding for bitfields.
|
|
|
|
|
- NSGetSizeAndAlignment(structEncoding, &structSize, &fieldAlignment);
|
|
|
|
|
- } @catch (NSException *exception) { }
|
|
|
|
|
-
|
|
|
|
|
- if (structSize > 0) {
|
|
|
|
|
|
|
+ NSUInteger fieldAlignment = 0, structSize = 0;
|
|
|
|
|
+ if (FLEXGetSizeAndAlignment(structEncoding, &structSize, &fieldAlignment)) {
|
|
|
NSUInteger runningFieldIndex = 0;
|
|
NSUInteger runningFieldIndex = 0;
|
|
|
NSUInteger runningFieldOffset = 0;
|
|
NSUInteger runningFieldOffset = 0;
|
|
|
const char *typeStart = equals + 1;
|
|
const char *typeStart = equals + 1;
|
|
|
|
|
+
|
|
|
while (*typeStart != FLEXTypeEncodingStructEnd) {
|
|
while (*typeStart != FLEXTypeEncodingStructEnd) {
|
|
|
NSUInteger fieldSize = 0;
|
|
NSUInteger fieldSize = 0;
|
|
|
- // If the struct type encoding was successfully handled by NSGetSizeAndAlignment above, we *should* be ok with the field here.
|
|
|
|
|
|
|
+ // If the struct type encoding was successfully handled by
|
|
|
|
|
+ // FLEXGetSizeAndAlignment above, we *should* be ok with the field here.
|
|
|
const char *nextTypeStart = NSGetSizeAndAlignment(typeStart, &fieldSize, NULL);
|
|
const char *nextTypeStart = NSGetSizeAndAlignment(typeStart, &fieldSize, NULL);
|
|
|
NSString *typeEncoding = [@(structEncoding)
|
|
NSString *typeEncoding = [@(structEncoding)
|
|
|
substringWithRange:NSMakeRange(typeStart - structEncoding, nextTypeStart - typeStart)
|
|
substringWithRange:NSMakeRange(typeStart - structEncoding, nextTypeStart - typeStart)
|
|
|
];
|
|
];
|
|
|
- // Padding to keep proper alignment. __attribute((packed)) structs will break here.
|
|
|
|
|
- // The type encoding is no different for packed structs, so it's not clear there's anything we can do for those.
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // Padding to keep proper alignment. __attribute((packed)) structs
|
|
|
|
|
+ // will break here. The type encoding is no different for packed structs,
|
|
|
|
|
+ // so it's not clear there's anything we can do for those.
|
|
|
const NSUInteger currentSizeSum = runningFieldOffset % fieldAlignment;
|
|
const NSUInteger currentSizeSum = runningFieldOffset % fieldAlignment;
|
|
|
if (currentSizeSum != 0 && currentSizeSum + fieldSize > fieldAlignment) {
|
|
if (currentSizeSum != 0 && currentSizeSum + fieldSize > fieldAlignment) {
|
|
|
runningFieldOffset += fieldAlignment - currentSizeSum;
|
|
runningFieldOffset += fieldAlignment - currentSizeSum;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
typeBlock(
|
|
typeBlock(
|
|
|
structName,
|
|
structName,
|
|
|
typeEncoding.UTF8String,
|
|
typeEncoding.UTF8String,
|