Index: .fossil-settings/clean-glob ================================================================== --- .fossil-settings/clean-glob +++ .fossil-settings/clean-glob @@ -19,20 +19,20 @@ config.h config.h.in config.log config.status configure -DerivedData docs extra.mk generators/gen_tables src/Info.plist src/bridge/Info.plist src/inline.h src/objfw-defs.h src/runtime/amiga-library-functable.inc src/runtime/inline.h +tests/DerivedData tests/EBOOT.PBP tests/Info.plist tests/PARAM.SFO tests/objc_sync/objc_sync tests/plugin/Info.plist Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -21,20 +21,20 @@ config.h config.h.in config.log config.status configure -DerivedData docs extra.mk generators/gen_tables src/Info.plist src/bridge/Info.plist src/inline.h src/objfw-defs.h src/runtime/amiga-library-functable.inc src/runtime/inline.h +tests/DerivedData tests/EBOOT.PBP tests/Info.plist tests/PARAM.SFO tests/iOS.xcodeproj/*.pbxuser tests/iOS.xcodeproj/project.xcworkspace Index: .gitignore ================================================================== --- .gitignore +++ .gitignore @@ -21,20 +21,20 @@ config.h config.h.in config.log config.status configure -DerivedData docs extra.mk generators/gen_tables src/Info.plist src/bridge/Info.plist src/inline.h src/objfw-defs.h src/runtime/amiga-library-functable.inc src/runtime/inline.h +tests/DerivedData tests/EBOOT.PBP tests/Info.plist tests/PARAM.SFO tests/iOS.xcodeproj/*.pbxuser tests/iOS.xcodeproj/project.xcworkspace Index: .travis.yml ================================================================== --- .travis.yml +++ .travis.yml @@ -223,23 +223,23 @@ env: - config=amigaos # Nintendo 3DS - os: linux - dist: trusty + dist: bionic env: - config=nintendo_3ds # Nintendo DS - os: linux - dist: trusty + dist: bionic env: - config=nintendo_ds # Nintendo Wii - os: linux - dist: trusty + dist: bionic env: - config=wii before_install: - if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then @@ -268,12 +268,14 @@ fi; fi - if [ "$config" = "nintendo_3ds" -o "$config" = "nintendo_ds" -o "$config" = "wii" ]; then - wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb; - sudo dpkg -i devkitpro-pacman.deb; + deb=devkitpro-pacman.amd64.deb; + wget https://github.com/devkitPro/pacman/releases/download/v1.0.2/$deb; + sudo apt install gdebi; + sudo gdebi -n $deb; fi - if [ "$config" = "nintendo_3ds" ]; then sudo dkp-pacman --noconfirm -Syu 3ds-dev; fi Index: PLATFORMS.md ================================================================== --- PLATFORMS.md +++ PLATFORMS.md @@ -77,22 +77,23 @@ Linux ----- - * Architectures: Alpha, ARMv6, ARM64, Itanium, m68k, MIPS (O32), RISC-V 64, - PowerPC, S390x, SH4, x86, x86_64 - * Compilers: Clang 3.0-9.0, GCC 4.6-8.2 + * Architectures: Alpha, ARMv6, ARMv7, ARM64, Itanium, m68k, MIPS (O32), + MIPS64 (N64), RISC-V 64, PowerPC, S390x, SuperH-4, x86, + x86_64 + * Compilers: Clang 3.0-10.0, GCC 4.6-10.0 * Runtimes: ObjFW macOS ----- * OS Versions: 10.5, 10.7-10.14, Darling - * Architectures: PowerPC, PowerPC 64, x86, x86_64 - * Compilers: Clang 3.1-7.0, GCC 4.2.1 + * Architectures: PowerPC, PowerPC64, x86, x86_64 + * Compilers: Clang 3.1-10.0, GCC 4.2.1 * Runtimes: Apple, ObjFW MorphOS ------- @@ -105,12 +106,13 @@ NetBSD ------ - * OS Versions: 5.1-7.99 - * Architectures: ARM, ARM (big endian, BE8 mode), SPARC, SPARC64, x86, x86_64 + * OS Versions: 5.1-9.0 + * Architectures: ARM, ARM (big endian, BE8 mode), MIPS (O32), SPARC, SPARC64, + x86, x86_64 * Compilers: Clang 3.0-3.2, GCC 4.1.3 & 4.5.3 * Runtimes: ObjFW Nintendo 3DS @@ -134,11 +136,11 @@ OpenBSD ------- - * OS Versions: 5.2-6.5 + * OS Versions: 5.2-6.7 * Architectures: MIPS64, PA-RISC, PowerPC, SPARC64, x86_64 * Compilers: GCC 6.3.0, Clang 4.0 * Runtimes: ObjFW @@ -184,12 +186,13 @@ ------- * OS Versions: 98 SE, NT 4.0, XP (x86), 7 (x64), 8 (x64), 8.1 (x64), 10, Wine (x86 & x64) * Architectures: x86, x86_64 - * Compilers: GCC 5.3.0 & 6.2.0 from msys2 (x86 and x64), - Clang 3.9.0 from msys2 (x86) + * Compilers: GCC 5.3.0 & 6.2.0 from msys2 (x86 & x64), + Clang 3.9.0 from msys2 (x86), + Clang 10.0 from msys2 (x86 & x86_64) * Runtimes: ObjFW Others ------ @@ -213,11 +216,12 @@ * ARM (EABI/ELF, Apple/Mach-O) * ARM64 (ARM64/ELF, Apple/Mach-O) * MIPS (O32/ELF, EABI/ELF) * PowerPC (SysV/ELF, EABI/ELF, Apple/Mach-O) + * SPARC (SysV/ELF) * SPARC64 (SysV/ELF) * x86 (SysV/ELF, Apple/Mach-O, Win32/PE) * x86_64 (SysV/ELF, Apple/Mach-O, Mach-O, Win64/PE) Apple/Mach-O means both, the Apple ABI and runtime, while Mach-O means the ObjFW runtime on Mach-O. Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -252,10 +252,18 @@ dnl files, but not for assembly files. mips*-*-*) flag="-integrated-as" OBJCFLAGS="$OBJCFLAGS $flag" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flag" + ;; + dnl Don't use -no-integrated-as on Darwin. It breaks + dnl building for the iOS simulator. + i?86-*-darwin* | x86_64-*-darwin*) + ;; + dnl Many older Clang versions don't support jmp short. + i?86-*-* | x86_64-*-*) + ASFLAGS="$ASFLAGS -no-integrated-as" ;; dnl Clang's assembler on Windows is not complete yet dnl and cannot compile all .S files. *-*-mingw*) ASFLAGS="$ASFLAGS -no-integrated-as" Index: src/OFAdjacentArray.m ================================================================== --- src/OFAdjacentArray.m +++ src/OFAdjacentArray.m @@ -341,11 +341,11 @@ if (state->state >= count) return 0; state->state = (unsigned long)count; - state->itemsPtr = _array.items; + state->itemsPtr = (id *)_array.items; state->mutationsPtr = (unsigned long *)self; return (int)count; } Index: src/OFApplication.m ================================================================== --- src/OFApplication.m +++ src/OFApplication.m @@ -70,10 +70,11 @@ # define asm __asm__ # include # undef asm #endif +OF_DIRECT_MEMBERS @interface OFApplication () - (instancetype)of_init OF_METHOD_FAMILY(init); - (void)of_setArgumentCount: (int *)argc andArgumentValues: (char **[])argv; #ifdef OF_WINDOWS Index: src/OFArray+Private.h ================================================================== --- src/OFArray+Private.h +++ src/OFArray+Private.h @@ -17,10 +17,11 @@ #import "OFArray.h" OF_ASSUME_NONNULL_BEGIN +OF_DIRECT_MEMBERS @interface OFArrayEnumerator: OFEnumerator { OFArray *_array; size_t _count; unsigned long _mutations; Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -63,10 +63,11 @@ @interface OFDNSResolver () - (void)of_contextTimedOut: (OFDNSResolverContext *)context; @end +OF_DIRECT_MEMBERS @interface OFDNSResolverContext: OFObject { @public OFDNSQuery *_query; OFNumber *_ID; Index: src/OFData+CryptoHashing.m ================================================================== --- src/OFData+CryptoHashing.m +++ src/OFData+CryptoHashing.m @@ -29,11 +29,11 @@ #import "OFSHA512Hash.h" int _OFData_CryptoHashing_reference; @implementation OFData (CryptoHashing) -- (OFString *)of_cryptoHashWithClass: (Class )class +- (OFString *)of_cryptoHashWithClass: (Class )class OF_DIRECT { void *pool = objc_autoreleasePoolPush(); id hash = [class cryptoHashWithAllowsSwappableMemory: true]; size_t digestSize = [class digestSize]; Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -46,19 +46,21 @@ @end @interface OFDictionaryPlaceholder: OFDictionary @end +OF_DIRECT_MEMBERS @interface OFDictionaryObjectEnumerator: OFEnumerator { OFDictionary *_dictionary; OFEnumerator *_keyEnumerator; } - (instancetype)initWithDictionary: (OFDictionary *)dictionary; @end +OF_DIRECT_MEMBERS @interface OFURLQueryPartAllowedCharacterSet: OFCharacterSet + (OFCharacterSet *)URLQueryPartAllowedCharacterSet; @end @implementation OFDictionaryPlaceholder @@ -222,11 +224,12 @@ return [[[self alloc] init] autorelease]; } + (instancetype)dictionaryWithDictionary: (OFDictionary *)dictionary { - return [[[self alloc] initWithDictionary: dictionary] autorelease]; + return [[(OFDictionary *)[self alloc] + initWithDictionary: dictionary] autorelease]; } + (instancetype)dictionaryWithObject: (id)object forKey: (id)key { Index: src/OFEnumerator.h ================================================================== --- src/OFEnumerator.h +++ src/OFEnumerator.h @@ -52,11 +52,11 @@ #ifndef NSINTEGER_DEFINED typedef struct { /*! Arbitrary state information for the enumeration */ unsigned long state; /*! Pointer to a C array of objects to return */ - id const __unsafe_unretained _Nullable *_Nullable itemsPtr; + id __unsafe_unretained _Nullable *_Nullable itemsPtr; /*! Arbitrary state information to detect mutations */ unsigned long *_Nullable mutationsPtr; /*! Additional arbitrary state information */ unsigned long extra[5]; } of_fast_enumeration_state_t; Index: src/OFEpollKernelEventObserver.m ================================================================== --- src/OFEpollKernelEventObserver.m +++ src/OFEpollKernelEventObserver.m @@ -90,11 +90,11 @@ [super dealloc]; } - (void)of_addObject: (id)object fileDescriptor: (int)fd - events: (int)addEvents + events: (int)addEvents OF_DIRECT { struct epoll_event event; intptr_t events; events = (intptr_t)[_FDToEvents @@ -113,11 +113,11 @@ forKey: (void *)((intptr_t)fd + 1)]; } - (void)of_removeObject: (id)object fileDescriptor: (int)fd - events: (int)removeEvents + events: (int)removeEvents OF_DIRECT { intptr_t events; events = (intptr_t)[_FDToEvents objectForKey: (void *)((intptr_t)fd + 1)]; Index: src/OFFileURLHandler.h ================================================================== --- src/OFFileURLHandler.h +++ src/OFFileURLHandler.h @@ -18,9 +18,9 @@ #import "OFURLHandler.h" OF_ASSUME_NONNULL_BEGIN @interface OFFileURLHandler: OFURLHandler -+ (bool)of_directoryExistsAtPath: (OFString *)path; ++ (bool)of_directoryExistsAtPath: (OFString *)path OF_DIRECT; @end OF_ASSUME_NONNULL_END Index: src/OFFileURLHandler.m ================================================================== --- src/OFFileURLHandler.m +++ src/OFFileURLHandler.m @@ -642,11 +642,11 @@ } - (void)of_setLastAccessDate: (OFDate *)lastAccessDate andModificationDate: (OFDate *)modificationDate ofItemAtURL: (OFURL *)URL - attributes: (of_file_attributes_t)attributes + attributes: (of_file_attributes_t)attributes OF_DIRECT { OFString *path = URL.fileSystemRepresentation; of_file_attribute_key_t attributeKey = (modificationDate != nil ? of_file_attribute_key_modification_date : of_file_attribute_key_last_access_date); @@ -755,11 +755,11 @@ #endif } - (void)of_setPOSIXPermissions: (OFNumber *)permissions ofItemAtURL: (OFURL *)URL - attributes: (of_file_attributes_t)attributes + attributes: (of_file_attributes_t)attributes OF_DIRECT { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS uint16_t mode = permissions.uInt16Value & 0777; OFString *path = URL.fileSystemRepresentation; int status; @@ -785,11 +785,11 @@ - (void)of_setOwner: (OFString *)owner andGroup: (OFString *)group ofItemAtURL: (OFURL *)URL attributeKey: (of_file_attribute_key_t)attributeKey - attributes: (of_file_attributes_t)attributes + attributes: (of_file_attributes_t)attributes OF_DIRECT { #ifdef OF_FILE_MANAGER_SUPPORTS_OWNER OFString *path = URL.fileSystemRepresentation; uid_t uid = -1; gid_t gid = -1; Index: src/OFHTTPClient.m ================================================================== --- src/OFHTTPClient.m +++ src/OFHTTPClient.m @@ -51,10 +51,11 @@ #import "socket_helpers.h" #define REDIRECTS_DEFAULT 10 +OF_DIRECT_MEMBERS @interface OFHTTPClientRequestHandler: OFObject { @public OFHTTPClient *_client; OFHTTPRequest *_request; @@ -70,10 +71,11 @@ redirects: (unsigned int)redirects; - (void)start; - (void)closeAndReconnect; @end +OF_DIRECT_MEMBERS @interface OFHTTPClientRequestBodyStream: OFStream { OFHTTPClientRequestHandler *_handler; OFTCPSocket *_socket; bool _chunked; @@ -83,10 +85,11 @@ - (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler socket: (OFTCPSocket *)sock; @end +OF_DIRECT_MEMBERS @interface OFHTTPClientResponse: OFHTTPResponse { OFTCPSocket *_socket; bool _hasContentLength, _chunked, _keepAlive; bool _atEndOfStream, _setAtEndOfStream; @@ -96,10 +99,11 @@ @property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive; - (instancetype)initWithSocket: (OFTCPSocket *)sock; @end +OF_DIRECT_MEMBERS @interface OFHTTPClientSyncPerformer: OFObject { OFHTTPClient *_client; OFObject *_delegate; OFHTTPResponse *_response; Index: src/OFHTTPServer.m ================================================================== --- src/OFHTTPServer.m +++ src/OFHTTPServer.m @@ -55,10 +55,11 @@ */ @interface OFHTTPServer () @end +OF_DIRECT_MEMBERS @interface OFHTTPServerResponse: OFHTTPResponse { OFStreamSocket *_socket; OFHTTPServer *_server; OFHTTPRequest *_request; @@ -68,10 +69,11 @@ - (instancetype)initWithSocket: (OFStreamSocket *)sock server: (OFHTTPServer *)server request: (OFHTTPRequest *)request; @end +OF_DIRECT_MEMBERS @interface OFHTTPServerConnection: OFObject { @public OFStreamSocket *_socket; OFHTTPServer *_server; @@ -96,10 +98,11 @@ - (bool)parseHeaders: (OFString *)line; - (bool)sendErrorAndClose: (short)statusCode; - (void)createResponse; @end +OF_DIRECT_MEMBERS @interface OFHTTPServerRequestBodyStream: OFStream { OFStreamSocket *_socket; bool _chunked; intmax_t _toRead; @@ -110,10 +113,11 @@ chunked: (bool)chunked contentLength: (uintmax_t)contentLength; @end #ifdef OF_HAVE_THREADS +OF_DIRECT_MEMBERS @interface OFHTTPServerThread: OFThread - (void)stop; @end #endif Index: src/OFINICategory+Private.h ================================================================== --- src/OFINICategory+Private.h +++ src/OFINICategory+Private.h @@ -20,14 +20,15 @@ OF_ASSUME_NONNULL_BEGIN @class OFStream; +OF_DIRECT_MEMBERS @interface OFINICategory () - (instancetype)of_initWithName: (OFString *)name OF_METHOD_FAMILY(init); - (void)of_parseLine: (OFString *)line; - (bool)of_writeToStream: (OFStream *)stream encoding: (of_string_encoding_t)encoding first: (bool)first; @end OF_ASSUME_NONNULL_END Index: src/OFINICategory.m ================================================================== --- src/OFINICategory.m +++ src/OFINICategory.m @@ -120,11 +120,11 @@ @end @implementation OFINICategory @synthesize name = _name; -- (instancetype)of_initWithName: (OFString *)name +- (instancetype)of_initWithName: (OFString *)name OF_DIRECT { self = [super init]; @try { _name = [name copy]; Index: src/OFINIFile.m ================================================================== --- src/OFINIFile.m +++ src/OFINIFile.m @@ -27,10 +27,11 @@ #import "OFINICategory+Private.h" #import "OFInvalidFormatException.h" #import "OFOpenItemFailedException.h" +OF_DIRECT_MEMBERS @interface OFINIFile () - (void)of_parseFile: (OFString *)path encoding: (of_string_encoding_t)encoding; @end Index: src/OFINIFileSettings.m ================================================================== --- src/OFINIFileSettings.m +++ src/OFINIFileSettings.m @@ -54,11 +54,11 @@ [super dealloc]; } - (void)of_getCategory: (OFString **)category andKey: (OFString **)key - forPath: (OFString *)path + forPath: (OFString *)path OF_DIRECT { size_t pos = [path rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND) { Index: src/OFKernelEventObserver.m ================================================================== --- src/OFKernelEventObserver.m +++ src/OFKernelEventObserver.m @@ -219,11 +219,11 @@ for (id object in _readObjects) { void *pool = objc_autoreleasePoolPush(); if ([object isKindOfClass: [OFStream class]] && [object hasDataInReadBuffer] && - ![object of_isWaitingForDelimiter]) { + ![(OFStream *)object of_isWaitingForDelimiter]) { if ([_delegate respondsToSelector: @selector(objectIsReadyForReading:)]) [_delegate objectIsReadyForReading: object]; foundInReadBuffer = true; Index: src/OFLHAArchive.m ================================================================== --- src/OFLHAArchive.m +++ src/OFLHAArchive.m @@ -36,10 +36,11 @@ #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" +OF_DIRECT_MEMBERS @interface OFLHAArchiveFileReadStream: OFStream { OFStream *_stream, *_decompressedStream; OFLHAArchiveEntry *_entry; uint32_t _toRead, _bytesConsumed; @@ -50,10 +51,11 @@ - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFLHAArchiveEntry *)entry; - (void)of_skip; @end +OF_DIRECT_MEMBERS @interface OFLHAArchiveFileWriteStream: OFStream { OFMutableLHAArchiveEntry *_entry; of_string_encoding_t _encoding; OFSeekableStream *_stream; Index: src/OFLHAArchiveEntry+Private.h ================================================================== --- src/OFLHAArchiveEntry+Private.h +++ src/OFLHAArchiveEntry+Private.h @@ -17,10 +17,11 @@ #import "OFLHAArchive.h" OF_ASSUME_NONNULL_BEGIN +OF_DIRECT_MEMBERS @interface OFLHAArchiveEntry () - (instancetype)of_initWithHeader: (char [_Nonnull 21])header stream: (OFStream *)stream encoding: (of_string_encoding_t)encoding OF_METHOD_FAMILY(init); Index: src/OFLHADecompressingStream.h ================================================================== --- src/OFLHADecompressingStream.h +++ src/OFLHADecompressingStream.h @@ -19,10 +19,11 @@ OF_ASSUME_NONNULL_BEGIN #define OF_LHA_DECOMPRESSING_STREAM_BUFFER_SIZE 4096 +OF_DIRECT_MEMBERS @interface OFLHADecompressingStream: OFStream { OFStream *_stream; uint8_t _distanceBits, _dictionaryBits; unsigned char _buffer[OF_LHA_DECOMPRESSING_STREAM_BUFFER_SIZE]; Index: src/OFList.m ================================================================== --- src/OFList.m +++ src/OFList.m @@ -26,10 +26,11 @@ #import "OFArray.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" +OF_DIRECT_MEMBERS @interface OFListEnumerator: OFEnumerator { OFList *_list; of_list_object_t *_Nullable _current; unsigned long _mutations; Index: src/OFMD5Hash.m ================================================================== --- src/OFMD5Hash.m +++ src/OFMD5Hash.m @@ -26,10 +26,11 @@ #import "OFOutOfRangeException.h" #define DIGEST_SIZE 16 #define BLOCK_SIZE 64 +OF_DIRECT_MEMBERS @interface OFMD5Hash () - (void)of_resetState; @end #define F(a, b, c) (((a) & (b)) | (~(a) & (c))) Index: src/OFMapTable+Private.h ================================================================== --- src/OFMapTable+Private.h +++ src/OFMapTable+Private.h @@ -17,10 +17,11 @@ #import "OFMapTable.h" OF_ASSUME_NONNULL_BEGIN +OF_DIRECT_MEMBERS @interface OFMapTableEnumeratorWrapper: OFEnumerator { OFMapTableEnumerator *_enumerator; id _object; } Index: src/OFMapTable.m ================================================================== --- src/OFMapTable.m +++ src/OFMapTable.m @@ -59,16 +59,18 @@ defaultEqual(void *object1, void *object2) { return (object1 == object2); } +OF_DIRECT_MEMBERS @interface OFMapTable () - (void)of_setObject: (void *)object forKey: (void *)key hash: (uint32_t)hash; @end +OF_DIRECT_MEMBERS @interface OFMapTableEnumerator () - (instancetype)of_initWithMapTable: (OFMapTable *)mapTable buckets: (struct of_map_table_bucket **)buckets capacity: (uint32_t)capacity mutationsPointer: (unsigned long *)mutationsPtr @@ -291,11 +293,11 @@ } return NULL; } -- (void)of_resizeForCount: (uint32_t)count +- (void)of_resizeForCount: (uint32_t)count OF_DIRECT { uint32_t fullness, capacity; struct of_map_table_bucket **buckets; if (count > UINT32_MAX / sizeof(*_buckets) || count > UINT32_MAX / 8) Index: src/OFMutableAdjacentArray.m ================================================================== --- src/OFMutableAdjacentArray.m +++ src/OFMutableAdjacentArray.m @@ -326,11 +326,11 @@ if (state->state >= count) return 0; state->state = (unsigned long)count; - state->itemsPtr = _array.items; + state->itemsPtr = (id *)_array.items; state->mutationsPtr = &_mutations; return (int)count; } Index: src/OFMutableString.m ================================================================== --- src/OFMutableString.m +++ src/OFMutableString.m @@ -233,11 +233,11 @@ #ifdef OF_HAVE_UNICODE_TABLES - (void)of_convertWithWordStartTable: (const of_unichar_t *const [])startTable wordMiddleTable: (const of_unichar_t *const [])middleTable wordStartTableSize: (size_t)startTableSize - wordMiddleTableSize: (size_t)middleTableSize + wordMiddleTableSize: (size_t)middleTableSize OF_DIRECT { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t length = self.length; bool isStart = true; @@ -265,10 +265,11 @@ objc_autoreleasePoolPop(pool); } #else - (void)of_convertWithWordStartFunction: (char (*)(char))startFunction wordMiddleFunction: (char (*)(char))middleFunction + OF_DIRECT { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t length = self.length; bool isStart = true; Index: src/OFMutableUTF8String.m ================================================================== --- src/OFMutableUTF8String.m +++ src/OFMutableUTF8String.m @@ -71,11 +71,11 @@ } - (void)of_convertWithWordStartTable: (const of_unichar_t *const[])startTable wordMiddleTable: (const of_unichar_t *const[])middleTable wordStartTableSize: (size_t)startTableSize - wordMiddleTableSize: (size_t)middleTableSize + wordMiddleTableSize: (size_t)middleTableSize OF_DIRECT { of_unichar_t *unicodeString; size_t unicodeLen, newCStringLength; size_t i, j; char *newCString; Index: src/OFPollKernelEventObserver.m ================================================================== --- src/OFPollKernelEventObserver.m +++ src/OFPollKernelEventObserver.m @@ -69,11 +69,11 @@ [super dealloc]; } - (void)of_addObject: (id)object fileDescriptor: (int)fd - events: (short)events + events: (short)events OF_DIRECT { struct pollfd *FDs; size_t count; bool found; @@ -108,11 +108,11 @@ } } - (void)of_removeObject: (id)object fileDescriptor: (int)fd - events: (short)events + events: (short)events OF_DIRECT { struct pollfd *FDs; size_t nFDs; if (fd < 0) Index: src/OFRIPEMD160Hash.m ================================================================== --- src/OFRIPEMD160Hash.m +++ src/OFRIPEMD160Hash.m @@ -26,10 +26,11 @@ #import "OFOutOfRangeException.h" #define DIGEST_SIZE 20 #define BLOCK_SIZE 64 +OF_DIRECT_MEMBERS @interface OFRIPEMD160Hash () - (void)of_resetState; @end #define F(a, b, c) ((a) ^ (b) ^ (c)) Index: src/OFRunLoop+Private.h ================================================================== --- src/OFRunLoop+Private.h +++ src/OFRunLoop+Private.h @@ -31,10 +31,11 @@ exception: (nullable id)exception; - (id)of_connectionFailedExceptionForErrNo: (int)errNo; @end #endif +OF_DIRECT_MEMBERS @interface OFRunLoop () + (void)of_setMainRunLoop: (OFRunLoop *)runLoop; #ifdef OF_HAVE_SOCKETS + (void)of_addAsyncReadForStream: (OFStream *) stream Index: src/OFRunLoop.m ================================================================== --- src/OFRunLoop.m +++ src/OFRunLoop.m @@ -76,10 +76,11 @@ # endif #endif } @end +OF_DIRECT_MEMBERS @interface OFRunLoop () - (OFRunLoopState *)of_stateForMode: (of_run_loop_mode_t)mode create: (bool)create; @end Index: src/OFSHA1Hash.m ================================================================== --- src/OFSHA1Hash.m +++ src/OFSHA1Hash.m @@ -26,10 +26,11 @@ #import "OFOutOfRangeException.h" #define DIGEST_SIZE 20 #define BLOCK_SIZE 64 +OF_DIRECT_MEMBERS @interface OFSHA1Hash () - (void)of_resetState; @end #define F(a, b, c, d) ((d) ^ ((b) & ((c) ^ (d)))) Index: src/OFSPXSocket.m ================================================================== --- src/OFSPXSocket.m +++ src/OFSPXSocket.m @@ -43,10 +43,11 @@ - (bool)of_connectSocketToAddress: (const of_socket_address_t *)address errNo: (int *)errNo; - (void)of_closeSocket; @end +OF_DIRECT_MEMBERS @interface OFSPXSocketAsyncConnectDelegate: OFObject { OFSPXSocket *_socket; unsigned char _node[IPX_NODE_LEN]; uint32_t _network; Index: src/OFSPXStreamSocket.m ================================================================== --- src/OFSPXStreamSocket.m +++ src/OFSPXStreamSocket.m @@ -43,10 +43,11 @@ - (bool)of_connectSocketToAddress: (const of_socket_address_t *)address errNo: (int *)errNo; - (void)of_closeSocket; @end +OF_DIRECT_MEMBERS @interface OFSPXStreamSocketAsyncConnectDelegate: OFObject { OFSPXStreamSocket *_socket; unsigned char _node[IPX_NODE_LEN]; Index: src/OFStdIOStream+Private.h ================================================================== --- src/OFStdIOStream+Private.h +++ src/OFStdIOStream+Private.h @@ -17,10 +17,11 @@ #import "OFStdIOStream.h" OF_ASSUME_NONNULL_BEGIN +OF_DIRECT_MEMBERS @interface OFStdIOStream () #ifndef OF_AMIGAOS - (instancetype)of_initWithFileDescriptor: (int)fd OF_METHOD_FAMILY(init); #else - (instancetype)of_initWithHandle: (BPTR)handle Index: src/OFStdIOStream.m ================================================================== --- src/OFStdIOStream.m +++ src/OFStdIOStream.m @@ -41,14 +41,19 @@ #import "OFInvalidArgumentException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" + +#ifdef OF_IOS +# undef HAVE_ISATTY +#endif #ifdef OF_AMIGAOS # include # include +# undef HAVE_ISATTY #endif /* References for static linking */ #ifdef OF_WINDOWS void @@ -129,11 +134,11 @@ date.microsecond / 1000, me, getpid(), msg]; objc_autoreleasePoolPop(pool); } -#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) +#ifdef HAVE_ISATTY static int colorToANSI(OFColor *color) { if ([color isEqual: [OFColor black]]) return 30; @@ -419,11 +424,11 @@ return OF_RETAIN_COUNT_MAX; } - (bool)hasTerminal { -#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) +#ifdef HAVE_ISATTY return isatty(_fd); #else return false; #endif } @@ -456,11 +461,11 @@ #endif } - (void)setForegroundColor: (OFColor *)color { -#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) +#ifdef HAVE_ISATTY int code; if (!isatty(_fd)) return; @@ -471,11 +476,11 @@ #endif } - (void)setBackgroundColor: (OFColor *)color { -#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) +#ifdef HAVE_ISATTY int code; if (!isatty(_fd)) return; @@ -486,41 +491,41 @@ #endif } - (void)reset { -#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) +#ifdef HAVE_ISATTY if (!isatty(_fd)) return; [self writeString: @"\033[0m"]; #endif } - (void)clear { -#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) +#ifdef HAVE_ISATTY if (!isatty(_fd)) return; [self writeString: @"\033[2J"]; #endif } - (void)eraseLine { -#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) +#ifdef HAVE_ISATTY if (!isatty(_fd)) return; [self writeString: @"\033[2K"]; #endif } - (void)setCursorColumn: (unsigned int)column { -#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) +#ifdef HAVE_ISATTY if (!isatty(_fd)) return; [self writeFormat: @"\033[%uG", column + 1]; #endif @@ -529,11 +534,11 @@ - (void)setCursorPosition: (of_point_t)position { if (position.x < 0 || position.y < 0) @throw [OFInvalidArgumentException exception]; -#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) +#ifdef HAVE_ISATTY if (!isatty(_fd)) return; [self writeFormat: @"\033[%u;%uH", (unsigned)position.y + 1, (unsigned)position.x + 1]; @@ -540,11 +545,11 @@ #endif } - (void)setRelativeCursorPosition: (of_point_t)position { -#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS) +#ifdef HAVE_ISATTY if (!isatty(_fd)) return; if (position.x > 0) [self writeFormat: @"\033[%uC", (unsigned)position.x]; Index: src/OFStream+Private.h ================================================================== --- src/OFStream+Private.h +++ src/OFStream+Private.h @@ -17,11 +17,12 @@ #import "OFStream.h" OF_ASSUME_NONNULL_BEGIN +OF_DIRECT_MEMBERS @interface OFStream () @property (readonly, nonatomic, getter=of_isWaitingForDelimiter) bool of_waitingForDelimiter; @end OF_ASSUME_NONNULL_END Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -86,13 +86,13 @@ @interface OFString () - (size_t)of_getCString: (char *)cString maxLength: (size_t)maxLength encoding: (of_string_encoding_t)encoding - lossy: (bool)lossy; + lossy: (bool)lossy OF_DIRECT; - (const char *)of_cStringWithEncoding: (of_string_encoding_t)encoding - lossy: (bool)lossy; + lossy: (bool)lossy OF_DIRECT; - (OFString *)of_JSONRepresentationWithOptions: (int)options depth: (size_t)depth; @end @interface OFStringPlaceholder: OFString @@ -374,11 +374,11 @@ return (id)[[OFUTF8String alloc] init]; } - (instancetype)initWithUTF8String: (const char *)UTF8String { - id string; + OFUTF8String *string; size_t length; void *storage; length = strlen(UTF8String); string = of_alloc_object([OFUTF8String class], length + 1, 1, &storage); @@ -389,11 +389,11 @@ } - (instancetype)initWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength { - id string; + OFUTF8String *string; void *storage; string = of_alloc_object([OFUTF8String class], UTF8StringLength + 1, 1, &storage); @@ -422,11 +422,11 @@ - (instancetype)initWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding { if (encoding == OF_STRING_ENCODING_UTF_8) { - id string; + OFUTF8String *string; size_t length; void *storage; length = strlen(cString); string = of_alloc_object([OFUTF8String class], length + 1, 1, @@ -444,11 +444,11 @@ - (instancetype)initWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength { if (encoding == OF_STRING_ENCODING_UTF_8) { - id string; + OFUTF8String *string; void *storage; string = of_alloc_object([OFUTF8String class], cStringLength + 1, 1, &storage); Index: src/OFTarArchive.m ================================================================== --- src/OFTarArchive.m +++ src/OFTarArchive.m @@ -32,10 +32,11 @@ #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" +OF_DIRECT_MEMBERS @interface OFTarArchiveFileReadStream: OFStream { OFTarArchiveEntry *_entry; OFStream *_stream; uint64_t _toRead; @@ -45,10 +46,11 @@ - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry; - (void)of_skip; @end +OF_DIRECT_MEMBERS @interface OFTarArchiveFileWriteStream: OFStream { OFTarArchiveEntry *_entry; OFStream *_stream; uint64_t _toWrite; Index: src/OFTarArchiveEntry+Private.h ================================================================== --- src/OFTarArchiveEntry+Private.h +++ src/OFTarArchiveEntry+Private.h @@ -20,14 +20,15 @@ OF_ASSUME_NONNULL_BEGIN @class OFStream; +OF_DIRECT_MEMBERS @interface OFTarArchiveEntry () - (instancetype)of_initWithHeader: (unsigned char [_Nonnull 512])header encoding: (of_string_encoding_t)encoding OF_METHOD_FAMILY(init); - (void)of_writeToStream: (OFStream *)stream encoding: (of_string_encoding_t)encoding; @end OF_ASSUME_NONNULL_END Index: src/OFThread+Private.h ================================================================== --- src/OFThread+Private.h +++ src/OFThread+Private.h @@ -18,11 +18,12 @@ #import "OFThread.h" OF_ASSUME_NONNULL_BEGIN #ifdef OF_HAVE_THREADS +OF_DIRECT_MEMBERS @interface OFThread () + (void)of_createMainThread; @end #endif OF_ASSUME_NONNULL_END Index: src/OFThreadPool.m ================================================================== --- src/OFThreadPool.m +++ src/OFThreadPool.m @@ -24,10 +24,11 @@ #import "OFList.h" #import "OFThread.h" #import "OFCondition.h" #import "OFSystemInfo.h" +OF_DIRECT_MEMBERS @interface OFThreadPoolJob: OFObject { id _target; SEL _selector; id _object; @@ -101,10 +102,11 @@ [_target performSelector: _selector withObject: _object]; } @end +OF_DIRECT_MEMBERS @interface OFThreadPoolThread: OFThread { OFList *_queue; OFCondition *_queueCondition, *_countCondition; @public @@ -117,11 +119,12 @@ @end @implementation OFThreadPoolThread + (instancetype)threadWithThreadPool: (OFThreadPool *)threadPool { - return [[[self alloc] initWithThreadPool: threadPool] autorelease]; + return [[(OFThreadPoolThread *)[self alloc] + initWithThreadPool: threadPool] autorelease]; } - (instancetype)initWithThreadPool: (OFThreadPool *)threadPool { self = [super init]; @@ -295,11 +298,11 @@ [_countCondition release]; [super dealloc]; } -- (void)of_dispatchJob: (OFThreadPoolJob *)job +- (void)of_dispatchJob: (OFThreadPoolJob *)job OF_DIRECT { [_countCondition lock]; _count++; [_countCondition unlock]; Index: src/OFTimer+Private.h ================================================================== --- src/OFTimer+Private.h +++ src/OFTimer+Private.h @@ -17,11 +17,12 @@ #import "OFTimer.h" OF_ASSUME_NONNULL_BEGIN +OF_DIRECT_MEMBERS @interface OFTimer () - (void)of_setInRunLoop: (nullable OFRunLoop *)runLoop mode: (nullable of_run_loop_mode_t)mode; @end OF_ASSUME_NONNULL_END Index: src/OFTimer.m ================================================================== --- src/OFTimer.m +++ src/OFTimer.m @@ -327,11 +327,12 @@ object: (id)object1 object: (id)object2 object: (id)object3 object: (id)object4 arguments: (uint8_t)arguments - repeats: (bool)repeats OF_METHOD_FAMILY(init) + repeats: (bool)repeats + OF_METHOD_FAMILY(init) OF_DIRECT { self = [super init]; @try { _fireDate = [fireDate retain]; Index: src/OFUDPSocket+Private.h ================================================================== --- src/OFUDPSocket+Private.h +++ src/OFUDPSocket+Private.h @@ -17,11 +17,12 @@ #import "OFUDPSocket.h" OF_ASSUME_NONNULL_BEGIN +OF_DIRECT_MEMBERS @interface OFUDPSocket () - (uint16_t)of_bindToAddress: (of_socket_address_t *)address extraType: (int)extraType; @end OF_ASSUME_NONNULL_END Index: src/OFUDPSocket.m ================================================================== --- src/OFUDPSocket.m +++ src/OFUDPSocket.m @@ -37,11 +37,11 @@ @implementation OFUDPSocket @dynamic delegate; - (uint16_t)of_bindToAddress: (of_socket_address_t *)address - extraType: (int)extraType + extraType: (int)extraType OF_DIRECT { void *pool = objc_autoreleasePoolPush(); OFString *host; uint16_t port; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) Index: src/OFURL.m ================================================================== --- src/OFURL.m +++ src/OFURL.m @@ -85,10 +85,11 @@ { URLQueryOrFragmentAllowedCharacterSet = [[OFURLQueryOrFragmentAllowedCharacterSet alloc] init]; } +OF_DIRECT_MEMBERS @interface OFInvertedCharacterSetWithoutPercent: OFCharacterSet { OFCharacterSet *_characterSet; bool (*_characterIsMember)(id, SEL, of_unichar_t); } Index: src/OFUTF8String+Private.h ================================================================== --- src/OFUTF8String+Private.h +++ src/OFUTF8String+Private.h @@ -17,12 +17,13 @@ #import "OFUTF8String.h" OF_ASSUME_NONNULL_BEGIN +OF_DIRECT_MEMBERS @interface OFUTF8String () - (instancetype)of_initWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength storage: (char *)storage OF_METHOD_FAMILY(init); @end OF_ASSUME_NONNULL_END Index: src/OFWindowsRegistryKey.m ================================================================== --- src/OFWindowsRegistryKey.m +++ src/OFWindowsRegistryKey.m @@ -32,10 +32,11 @@ #import "OFInvalidFormatException.h" #import "OFOpenWindowsRegistryKeyFailedException.h" #import "OFOutOfRangeException.h" #import "OFSetWindowsRegistryValueFailedException.h" +OF_DIRECT_MEMBERS @interface OFWindowsRegistryKey () - (instancetype)of_initWithHKey: (HKEY)hKey close: (bool)close; @end Index: src/OFXMLElement.m ================================================================== --- src/OFXMLElement.m +++ src/OFXMLElement.m @@ -426,11 +426,11 @@ } - (OFString *)of_XMLStringWithParent: (OFXMLElement *)parent namespaces: (OFDictionary *)allNamespaces indentation: (unsigned int)indentation - level: (unsigned int)level + level: (unsigned int)level OF_DIRECT { void *pool; char *cString; size_t length, i; OFString *prefix, *parentPrefix; Index: src/OFXMLParser.h ================================================================== --- src/OFXMLParser.h +++ src/OFXMLParser.h @@ -151,12 +151,11 @@ OF_XMLPARSER_IN_CDATA_OPENING, OF_XMLPARSER_IN_CDATA, OF_XMLPARSER_IN_COMMENT_OPENING, OF_XMLPARSER_IN_COMMENT_1, OF_XMLPARSER_IN_COMMENT_2, - OF_XMLPARSER_IN_DOCTYPE, - OF_XMLPARSER_NUM_STATES + OF_XMLPARSER_IN_DOCTYPE } _state; size_t _i, _last; const char *_Nullable _data; OFMutableData *_buffer; OFString *_Nullable _name, *_Nullable _prefix; Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -39,36 +39,59 @@ #import "OFInvalidFormatException.h" #import "OFMalformedXMLException.h" #import "OFOutOfRangeException.h" #import "OFUnboundPrefixException.h" -typedef void (*state_function_t)(id, SEL); -static SEL selectors[OF_XMLPARSER_NUM_STATES]; -static state_function_t lookupTable[OF_XMLPARSER_NUM_STATES]; - @interface OFXMLParser () -- (void)of_inByteOrderMarkState; -- (void)of_outsideTagState; -- (void)of_tagOpenedState; -- (void)of_inProcessingInstructionsState; -- (void)of_inTagNameState; -- (void)of_inCloseTagNameState; -- (void)of_inTagState; -- (void)of_inAttributeNameState; -- (void)of_expectAttributeEqualSignState; -- (void)of_expectAttributeDelimiterState; -- (void)of_inAttributeValueState; -- (void)of_expectTagCloseState; -- (void)of_expectSpaceOrTagCloseState; -- (void)of_inExclamationMarkState; -- (void)of_inCDATAOpeningState; -- (void)of_inCDATAState; -- (void)of_inCommentOpeningState; -- (void)of_inCommentState1; -- (void)of_inCommentState2; -- (void)of_inDOCTYPEState; @end + +static void inByteOrderMarkState(OFXMLParser *); +static void outsideTagState(OFXMLParser *); +static void tagOpenedState(OFXMLParser *); +static void inProcessingInstructionsState(OFXMLParser *); +static void inTagNameState(OFXMLParser *); +static void inCloseTagNameState(OFXMLParser *); +static void inTagState(OFXMLParser *); +static void inAttributeNameState(OFXMLParser *); +static void expectAttributeEqualSignState(OFXMLParser *); +static void expectAttributeDelimiterState(OFXMLParser *); +static void inAttributeValueState(OFXMLParser *); +static void expectTagCloseState(OFXMLParser *); +static void expectSpaceOrTagCloseState(OFXMLParser *); +static void inExclamationMarkState(OFXMLParser *); +static void inCDATAOpeningState(OFXMLParser *); +static void inCDATAState(OFXMLParser *); +static void inCommentOpeningState(OFXMLParser *); +static void inCommentState1(OFXMLParser *); +static void inCommentState2(OFXMLParser *); +static void inDOCTYPEState(OFXMLParser *); +typedef void (*state_function_t)(OFXMLParser *); +static state_function_t lookupTable[] = { + [OF_XMLPARSER_IN_BYTE_ORDER_MARK] = inByteOrderMarkState, + [OF_XMLPARSER_OUTSIDE_TAG] = outsideTagState, + [OF_XMLPARSER_TAG_OPENED] = tagOpenedState, + [OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS] = + inProcessingInstructionsState, + [OF_XMLPARSER_IN_TAG_NAME] = inTagNameState, + [OF_XMLPARSER_IN_CLOSE_TAG_NAME] = inCloseTagNameState, + [OF_XMLPARSER_IN_TAG] = inTagState, + [OF_XMLPARSER_IN_ATTRIBUTE_NAME] = inAttributeNameState, + [OF_XMLPARSER_EXPECT_ATTRIBUTE_EQUAL_SIGN] = + expectAttributeEqualSignState, + [OF_XMLPARSER_EXPECT_ATTRIBUTE_DELIMITER] = + expectAttributeDelimiterState, + [OF_XMLPARSER_IN_ATTRIBUTE_VALUE] = inAttributeValueState, + [OF_XMLPARSER_EXPECT_TAG_CLOSE] = expectTagCloseState, + [OF_XMLPARSER_EXPECT_SPACE_OR_TAG_CLOSE] = expectSpaceOrTagCloseState, + [OF_XMLPARSER_IN_EXCLAMATION_MARK] = inExclamationMarkState, + [OF_XMLPARSER_IN_CDATA_OPENING] = inCDATAOpeningState, + [OF_XMLPARSER_IN_CDATA] = inCDATAState, + [OF_XMLPARSER_IN_COMMENT_OPENING] = inCommentOpeningState, + [OF_XMLPARSER_IN_COMMENT_1] = inCommentState1, + [OF_XMLPARSER_IN_COMMENT_2] = inCommentState2, + [OF_XMLPARSER_IN_DOCTYPE] = inDOCTYPEState +}; static OF_INLINE void appendToBuffer(OFMutableData *buffer, const char *string, of_string_encoding_t encoding, size_t length) { @@ -165,46 +188,10 @@ } @implementation OFXMLParser @synthesize delegate = _delegate, depthLimit = _depthLimit; -+ (void)initialize -{ - const SEL selectors_[OF_XMLPARSER_NUM_STATES] = { - @selector(of_inByteOrderMarkState), - @selector(of_outsideTagState), - @selector(of_tagOpenedState), - @selector(of_inProcessingInstructionsState), - @selector(of_inTagNameState), - @selector(of_inCloseTagNameState), - @selector(of_inTagState), - @selector(of_inAttributeNameState), - @selector(of_expectAttributeEqualSignState), - @selector(of_expectAttributeDelimiterState), - @selector(of_inAttributeValueState), - @selector(of_expectTagCloseState), - @selector(of_expectSpaceOrTagCloseState), - @selector(of_inExclamationMarkState), - @selector(of_inCDATAOpeningState), - @selector(of_inCDATAState), - @selector(of_inCommentOpeningState), - @selector(of_inCommentState1), - @selector(of_inCommentState2), - @selector(of_inDOCTYPEState) - }; - memcpy(selectors, selectors_, sizeof(selectors_)); - - for (size_t i = 0; i < OF_XMLPARSER_NUM_STATES; i++) { - if (![self instancesRespondToSelector: selectors[i]]) - @throw [OFInitializationFailedException - exceptionWithClass: self]; - - lookupTable[i] = (state_function_t) - [self instanceMethodForSelector: selectors[i]]; - } -} - + (instancetype)parser { return [[[self alloc] init] autorelease]; } @@ -261,11 +248,11 @@ _data = buffer; for (_i = _last = 0; _i < length; _i++) { size_t j = _i; - lookupTable[_state](self, selectors[_state]); + lookupTable[_state](self); /* Ensure we don't count this character twice */ if (_i != j) continue; @@ -317,116 +304,119 @@ [file release]; } } #endif -/* - * The following methods handle the different states of the parser. They are - * looked up in +[initialize] and put in a lookup table to speed things up. - * One dispatch for every character would be way too slow! - */ - -- (void)of_inByteOrderMarkState -{ - if (_data[_i] != "\xEF\xBB\xBF"[_level]) { - if (_level == 0) { - _state = OF_XMLPARSER_OUTSIDE_TAG; - _i--; +static void +inByteOrderMarkState(OFXMLParser *self) +{ + if (self->_data[self->_i] != "\xEF\xBB\xBF"[self->_level]) { + if (self->_level == 0) { + self->_state = OF_XMLPARSER_OUTSIDE_TAG; + self->_i--; return; } @throw [OFMalformedXMLException exceptionWithParser: self]; } - if (_level++ == 2) - _state = OF_XMLPARSER_OUTSIDE_TAG; + if (self->_level++ == 2) + self->_state = OF_XMLPARSER_OUTSIDE_TAG; - _last = _i + 1; + self->_last = self->_i + 1; } /* Not in a tag */ -- (void)of_outsideTagState +static void +outsideTagState(OFXMLParser *self) { size_t length; - if ((_finishedParsing || _previous.count < 1) && _data[_i] != ' ' && - _data[_i] != '\t' && _data[_i] != '\n' && _data[_i] != '\r' && - _data[_i] != '<') + if ((self->_finishedParsing || self->_previous.count < 1) && + self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' && + self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r' && + self->_data[self->_i] != '<') @throw [OFMalformedXMLException exceptionWithParser: self]; - if (_data[_i] != '<') + if (self->_data[self->_i] != '<') return; - if ((length = _i - _last) > 0) - appendToBuffer(_buffer, _data + _last, _encoding, length); + if ((length = self->_i - self->_last) > 0) + appendToBuffer(self->_buffer, self->_data + self->_last, + self->_encoding, length); - if (_buffer.count > 0) { + if (self->_buffer.count > 0) { void *pool = objc_autoreleasePoolPush(); - OFString *characters = transformString(self, _buffer, 0, true); + OFString *characters = transformString(self, self->_buffer, 0, + true); - if ([_delegate respondsToSelector: + if ([self->_delegate respondsToSelector: @selector(parser:foundCharacters:)]) - [_delegate parser: self - foundCharacters: characters]; + [self->_delegate parser: self + foundCharacters: characters]; objc_autoreleasePoolPop(pool); } - [_buffer removeAllItems]; + [self->_buffer removeAllItems]; - _last = _i + 1; - _state = OF_XMLPARSER_TAG_OPENED; + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_TAG_OPENED; } /* Tag was just opened */ -- (void)of_tagOpenedState +static void +tagOpenedState(OFXMLParser *self) { - if (_finishedParsing && _data[_i] != '!' && _data[_i] != '?') + if (self->_finishedParsing && self->_data[self->_i] != '!' && + self->_data[self->_i] != '?') @throw [OFMalformedXMLException exceptionWithParser: self]; - switch (_data[_i]) { + switch (self->_data[self->_i]) { case '?': - _last = _i + 1; - _state = OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS; - _level = 0; + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS; + self->_level = 0; break; case '/': - _last = _i + 1; - _state = OF_XMLPARSER_IN_CLOSE_TAG_NAME; - _acceptProlog = false; + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_IN_CLOSE_TAG_NAME; + self->_acceptProlog = false; break; case '!': - _last = _i + 1; - _state = OF_XMLPARSER_IN_EXCLAMATION_MARK; - _acceptProlog = false; + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_IN_EXCLAMATION_MARK; + self->_acceptProlog = false; break; default: - if (_depthLimit > 0 && _previous.count >= _depthLimit) + if (self->_depthLimit > 0 && + self->_previous.count >= self->_depthLimit) @throw [OFOutOfRangeException exception]; - _state = OF_XMLPARSER_IN_TAG_NAME; - _acceptProlog = false; - _i--; + self->_state = OF_XMLPARSER_IN_TAG_NAME; + self->_acceptProlog = false; + self->_i--; break; } } /* */ -- (bool)of_parseXMLProcessingInstructions: (OFString *)pi +static bool +parseXMLProcessingInstructions(OFXMLParser *self, OFString *pi) { const char *cString; size_t length, last; int PIState = 0; OFString *attribute = nil; OFMutableString *value = nil; char piDelimiter = 0; bool hasVersion = false; - if (!_acceptProlog) + if (!self->_acceptProlog) return false; - _acceptProlog = false; + self->_acceptProlog = false; pi = [pi substringWithRange: of_range(3, pi.length - 3)]; pi = pi.stringByDeletingEnclosingWhitespaces; cString = pi.UTF8String; @@ -449,11 +439,11 @@ if (cString[i] != '=') continue; attribute = [OFString stringWithCString: cString + last - encoding: _encoding + encoding: self->_encoding length: i - last]; last = i + 1; PIState = 2; break; @@ -470,11 +460,11 @@ if (cString[i] != piDelimiter) continue; value = [OFMutableString stringWithCString: cString + last - encoding: _encoding + encoding: self->_encoding length: i - last]; if ([attribute isEqual: @"version"]) { if (![value hasPrefix: @"1."]) return false; @@ -482,11 +472,11 @@ hasVersion = true; } if ([attribute isEqual: @"encoding"]) { @try { - _encoding = + self->_encoding = of_string_parse_encoding(value); } @catch (OFInvalidArgumentException *e) { @throw [OFInvalidEncodingException exception]; } @@ -504,532 +494,568 @@ return true; } /* Inside processing instructions */ -- (void)of_inProcessingInstructionsState +static void +inProcessingInstructionsState(OFXMLParser *self) { - if (_data[_i] == '?') - _level = 1; - else if (_level == 1 && _data[_i] == '>') { + if (self->_data[self->_i] == '?') + self->_level = 1; + else if (self->_level == 1 && self->_data[self->_i] == '>') { void *pool = objc_autoreleasePoolPush(); OFString *PI; - appendToBuffer(_buffer, _data + _last, _encoding, _i - _last); - PI = transformString(self, _buffer, 1, false); + appendToBuffer(self->_buffer, self->_data + self->_last, + self->_encoding, self->_i - self->_last); + PI = transformString(self, self->_buffer, 1, false); if ([PI isEqual: @"xml"] || [PI hasPrefix: @"xml "] || [PI hasPrefix: @"xml\t"] || [PI hasPrefix: @"xml\r"] || [PI hasPrefix: @"xml\n"]) - if (![self of_parseXMLProcessingInstructions: PI]) + if (!parseXMLProcessingInstructions(self, PI)) @throw [OFMalformedXMLException exceptionWithParser: self]; - if ([_delegate respondsToSelector: + if ([self->_delegate respondsToSelector: @selector(parser:foundProcessingInstructions:)]) - [_delegate parser: self + [self->_delegate parser: self foundProcessingInstructions: PI]; objc_autoreleasePoolPop(pool); - [_buffer removeAllItems]; + [self->_buffer removeAllItems]; - _last = _i + 1; - _state = OF_XMLPARSER_OUTSIDE_TAG; + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_OUTSIDE_TAG; } else - _level = 0; + self->_level = 0; } /* Inside a tag, no name yet */ -- (void)of_inTagNameState +static void +inTagNameState(OFXMLParser *self) { void *pool; const char *bufferCString, *tmp; size_t length, bufferLength; OFString *bufferString; - if (_data[_i] != ' ' && _data[_i] != '\t' && _data[_i] != '\n' && - _data[_i] != '\r' && _data[_i] != '>' && _data[_i] != '/') + if (self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' && + self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r' && + self->_data[self->_i] != '>' && self->_data[self->_i] != '/') return; - if ((length = _i - _last) > 0) - appendToBuffer(_buffer, _data + _last, _encoding, length); + if ((length = self->_i - self->_last) > 0) + appendToBuffer(self->_buffer, self->_data + self->_last, + self->_encoding, length); pool = objc_autoreleasePoolPush(); - bufferCString = _buffer.items; - bufferLength = _buffer.count; + bufferCString = self->_buffer.items; + bufferLength = self->_buffer.count; bufferString = [OFString stringWithUTF8String: bufferCString length: bufferLength]; if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) { - _name = [[OFString alloc] + self->_name = [[OFString alloc] initWithUTF8String: tmp + 1 length: bufferLength - (tmp - bufferCString) - 1]; - _prefix = [[OFString alloc] + self->_prefix = [[OFString alloc] initWithUTF8String: bufferCString length: tmp - bufferCString]; } else { - _name = [bufferString copy]; - _prefix = nil; + self->_name = [bufferString copy]; + self->_prefix = nil; } - if (_data[_i] == '>' || _data[_i] == '/') { + if (self->_data[self->_i] == '>' || self->_data[self->_i] == '/') { OFString *namespace; - namespace = namespaceForPrefix(_prefix, _namespaces); + namespace = namespaceForPrefix(self->_prefix, + self->_namespaces); - if (_prefix != nil && namespace == nil) + if (self->_prefix != nil && namespace == nil) @throw [OFUnboundPrefixException - exceptionWithPrefix: _prefix + exceptionWithPrefix: self->_prefix parser: self]; - if ([_delegate respondsToSelector: @selector(parser: + if ([self->_delegate respondsToSelector: @selector(parser: didStartElement:prefix:namespace:attributes:)]) - [_delegate parser: self - didStartElement: _name - prefix: _prefix - namespace: namespace - attributes: nil]; - - if (_data[_i] == '/') { - if ([_delegate respondsToSelector: + [self->_delegate parser: self + didStartElement: self->_name + prefix: self->_prefix + namespace: namespace + attributes: nil]; + + if (self->_data[self->_i] == '/') { + if ([self->_delegate respondsToSelector: @selector(parser:didEndElement:prefix:namespace:)]) - [_delegate parser: self - didEndElement: _name - prefix: _prefix - namespace: namespace]; + [self->_delegate parser: self + didEndElement: self->_name + prefix: self->_prefix + namespace: namespace]; - if (_previous.count == 0) - _finishedParsing = true; + if (self->_previous.count == 0) + self->_finishedParsing = true; } else - [_previous addObject: bufferString]; + [self->_previous addObject: bufferString]; - [_name release]; - [_prefix release]; - _name = _prefix = nil; + [self->_name release]; + [self->_prefix release]; + self->_name = self->_prefix = nil; - _state = (_data[_i] == '/' + self->_state = (self->_data[self->_i] == '/' ? OF_XMLPARSER_EXPECT_TAG_CLOSE : OF_XMLPARSER_OUTSIDE_TAG); } else - _state = OF_XMLPARSER_IN_TAG; + self->_state = OF_XMLPARSER_IN_TAG; - if (_data[_i] != '/') - [_namespaces addObject: [OFMutableDictionary dictionary]]; + if (self->_data[self->_i] != '/') + [self->_namespaces addObject: [OFMutableDictionary dictionary]]; objc_autoreleasePoolPop(pool); - [_buffer removeAllItems]; - _last = _i + 1; + [self->_buffer removeAllItems]; + self->_last = self->_i + 1; } /* Inside a close tag, no name yet */ -- (void)of_inCloseTagNameState +static void +inCloseTagNameState(OFXMLParser *self) { void *pool; const char *bufferCString, *tmp; size_t length, bufferLength; OFString *bufferString, *namespace; - if (_data[_i] != ' ' && _data[_i] != '\t' && _data[_i] != '\n' && - _data[_i] != '\r' && _data[_i] != '>') + if (self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' && + self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r' && + self->_data[self->_i] != '>') return; - if ((length = _i - _last) > 0) - appendToBuffer(_buffer, _data + _last, _encoding, length); + if ((length = self->_i - self->_last) > 0) + appendToBuffer(self->_buffer, self->_data + self->_last, + self->_encoding, length); pool = objc_autoreleasePoolPush(); - bufferCString = _buffer.items; - bufferLength = _buffer.count; + bufferCString = self->_buffer.items; + bufferLength = self->_buffer.count; bufferString = [OFString stringWithUTF8String: bufferCString length: bufferLength]; if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) { - _name = [[OFString alloc] + self->_name = [[OFString alloc] initWithUTF8String: tmp + 1 length: bufferLength - (tmp - bufferCString) - 1]; - _prefix = [[OFString alloc] + self->_prefix = [[OFString alloc] initWithUTF8String: bufferCString length: tmp - bufferCString]; } else { - _name = [bufferString copy]; - _prefix = nil; - } - - if (![_previous.lastObject isEqual: bufferString]) - @throw [OFMalformedXMLException exceptionWithParser: self]; - - [_previous removeLastObject]; - - [_buffer removeAllItems]; - - namespace = namespaceForPrefix(_prefix, _namespaces); - if (_prefix != nil && namespace == nil) - @throw [OFUnboundPrefixException exceptionWithPrefix: _prefix - parser: self]; - - if ([_delegate respondsToSelector: - @selector(parser:didEndElement:prefix:namespace:)]) - [_delegate parser: self - didEndElement: _name - prefix: _prefix - namespace: namespace]; + self->_name = [bufferString copy]; + self->_prefix = nil; + } + + if (![self->_previous.lastObject isEqual: bufferString]) + @throw [OFMalformedXMLException exceptionWithParser: self]; + + [self->_previous removeLastObject]; + + [self->_buffer removeAllItems]; + + namespace = namespaceForPrefix(self->_prefix, self->_namespaces); + if (self->_prefix != nil && namespace == nil) + @throw [OFUnboundPrefixException + exceptionWithPrefix: self->_prefix + parser: self]; + + if ([self->_delegate respondsToSelector: + @selector(parser:didEndElement:prefix:namespace:)]) + [self->_delegate parser: self + didEndElement: self->_name + prefix: self->_prefix + namespace: namespace]; objc_autoreleasePoolPop(pool); - [_namespaces removeLastObject]; - [_name release]; - [_prefix release]; - _name = _prefix = nil; + [self->_namespaces removeLastObject]; + [self->_name release]; + [self->_prefix release]; + self->_name = self->_prefix = nil; - _last = _i + 1; - _state = (_data[_i] == '>' + self->_last = self->_i + 1; + self->_state = (self->_data[self->_i] == '>' ? OF_XMLPARSER_OUTSIDE_TAG : OF_XMLPARSER_EXPECT_SPACE_OR_TAG_CLOSE); - if (_previous.count == 0) - _finishedParsing = true; + if (self->_previous.count == 0) + self->_finishedParsing = true; } /* Inside a tag, name found */ -- (void)of_inTagState +static void +inTagState(OFXMLParser *self) { void *pool; OFString *namespace; OFXMLAttribute *const *attributesObjects; size_t attributesCount; - if (_data[_i] != '>' && _data[_i] != '/') { - if (_data[_i] != ' ' && _data[_i] != '\t' && - _data[_i] != '\n' && _data[_i] != '\r') { - _last = _i; - _state = OF_XMLPARSER_IN_ATTRIBUTE_NAME; - _i--; + if (self->_data[self->_i] != '>' && self->_data[self->_i] != '/') { + if (self->_data[self->_i] != ' ' && + self->_data[self->_i] != '\t' && + self->_data[self->_i] != '\n' && + self->_data[self->_i] != '\r') { + self->_last = self->_i; + self->_state = OF_XMLPARSER_IN_ATTRIBUTE_NAME; + self->_i--; } return; } - attributesObjects = _attributes.objects; - attributesCount = _attributes.count; - - namespace = namespaceForPrefix(_prefix, _namespaces); - - if (_prefix != nil && namespace == nil) - @throw [OFUnboundPrefixException exceptionWithPrefix: _prefix - parser: self]; + attributesObjects = self->_attributes.objects; + attributesCount = self->_attributes.count; + + namespace = namespaceForPrefix(self->_prefix, self->_namespaces); + + if (self->_prefix != nil && namespace == nil) + @throw [OFUnboundPrefixException + exceptionWithPrefix: self->_prefix + parser: self]; for (size_t j = 0; j < attributesCount; j++) - resolveAttributeNamespace(attributesObjects[j], _namespaces, - self); + resolveAttributeNamespace(attributesObjects[j], + self->_namespaces, self); pool = objc_autoreleasePoolPush(); - if ([_delegate respondsToSelector: + if ([self->_delegate respondsToSelector: @selector(parser:didStartElement:prefix:namespace:attributes:)]) - [_delegate parser: self - didStartElement: _name - prefix: _prefix - namespace: namespace - attributes: _attributes]; - - if (_data[_i] == '/') { - if ([_delegate respondsToSelector: + [self->_delegate parser: self + didStartElement: self->_name + prefix: self->_prefix + namespace: namespace + attributes: self->_attributes]; + + if (self->_data[self->_i] == '/') { + if ([self->_delegate respondsToSelector: @selector(parser:didEndElement:prefix:namespace:)]) - [_delegate parser: self - didEndElement: _name - prefix: _prefix - namespace: namespace]; - - if (_previous.count == 0) - _finishedParsing = true; - - [_namespaces removeLastObject]; - } else if (_prefix != nil) { - OFString *str = [OFString stringWithFormat: @"%@:%@", - _prefix, _name]; - [_previous addObject: str]; + [self->_delegate parser: self + didEndElement: self->_name + prefix: self->_prefix + namespace: namespace]; + + if (self->_previous.count == 0) + self->_finishedParsing = true; + + [self->_namespaces removeLastObject]; + } else if (self->_prefix != nil) { + OFString *str = [OFString stringWithFormat: + @"%@:%@", self->_prefix, self->_name]; + [self->_previous addObject: str]; } else - [_previous addObject: _name]; + [self->_previous addObject: self->_name]; objc_autoreleasePoolPop(pool); - [_name release]; - [_prefix release]; - [_attributes removeAllObjects]; - _name = _prefix = nil; + [self->_name release]; + [self->_prefix release]; + [self->_attributes removeAllObjects]; + self->_name = self->_prefix = nil; - _last = _i + 1; - _state = (_data[_i] == '/' + self->_last = self->_i + 1; + self->_state = (self->_data[self->_i] == '/' ? OF_XMLPARSER_EXPECT_TAG_CLOSE : OF_XMLPARSER_OUTSIDE_TAG); } /* Looking for attribute name */ -- (void)of_inAttributeNameState +static void +inAttributeNameState(OFXMLParser *self) { void *pool; OFString *bufferString; const char *bufferCString, *tmp; size_t length, bufferLength; - if (_data[_i] != '=' && _data[_i] != ' ' && _data[_i] != '\t' && - _data[_i] != '\n' && _data[_i] != '\r') + if (self->_data[self->_i] != '=' && self->_data[self->_i] != ' ' && + self->_data[self->_i] != '\t' && self->_data[self->_i] != '\n' && + self->_data[self->_i] != '\r') return; - if ((length = _i - _last) > 0) - appendToBuffer(_buffer, _data + _last, _encoding, length); + if ((length = self->_i - self->_last) > 0) + appendToBuffer(self->_buffer, self->_data + self->_last, + self->_encoding, length); pool = objc_autoreleasePoolPush(); - bufferString = [OFString stringWithUTF8String: _buffer.items - length: _buffer.count]; + bufferString = [OFString stringWithUTF8String: self->_buffer.items + length: self->_buffer.count]; bufferCString = bufferString.UTF8String; bufferLength = bufferString.UTF8StringLength; if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) { - _attributeName = [[OFString alloc] + self->_attributeName = [[OFString alloc] initWithUTF8String: tmp + 1 length: bufferLength - (tmp - bufferCString) - 1]; - _attributePrefix = [[OFString alloc] + self->_attributePrefix = [[OFString alloc] initWithUTF8String: bufferCString length: tmp - bufferCString]; } else { - _attributeName = [bufferString copy]; - _attributePrefix = nil; + self->_attributeName = [bufferString copy]; + self->_attributePrefix = nil; } objc_autoreleasePoolPop(pool); - [_buffer removeAllItems]; + [self->_buffer removeAllItems]; - _last = _i + 1; - _state = (_data[_i] == '=' + self->_last = self->_i + 1; + self->_state = (self->_data[self->_i] == '=' ? OF_XMLPARSER_EXPECT_ATTRIBUTE_DELIMITER : OF_XMLPARSER_EXPECT_ATTRIBUTE_EQUAL_SIGN); } /* Expecting equal sign of an attribute */ -- (void)of_expectAttributeEqualSignState +static void +expectAttributeEqualSignState(OFXMLParser *self) { - if (_data[_i] == '=') { - _last = _i + 1; - _state = OF_XMLPARSER_EXPECT_ATTRIBUTE_DELIMITER; + if (self->_data[self->_i] == '=') { + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_EXPECT_ATTRIBUTE_DELIMITER; return; } - if (_data[_i] != ' ' && _data[_i] != '\t' && _data[_i] != '\n' && - _data[_i] != '\r') + if (self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' && + self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r') @throw [OFMalformedXMLException exceptionWithParser: self]; } /* Expecting name/value delimiter of an attribute */ -- (void)of_expectAttributeDelimiterState +static void +expectAttributeDelimiterState(OFXMLParser *self) { - _last = _i + 1; + self->_last = self->_i + 1; - if (_data[_i] == ' ' || _data[_i] == '\t' || _data[_i] == '\n' || - _data[_i] == '\r') + if (self->_data[self->_i] == ' ' || self->_data[self->_i] == '\t' || + self->_data[self->_i] == '\n' || self->_data[self->_i] == '\r') return; - if (_data[_i] != '\'' && _data[_i] != '"') + if (self->_data[self->_i] != '\'' && self->_data[self->_i] != '"') @throw [OFMalformedXMLException exceptionWithParser: self]; - _delimiter = _data[_i]; - _state = OF_XMLPARSER_IN_ATTRIBUTE_VALUE; + self->_delimiter = self->_data[self->_i]; + self->_state = OF_XMLPARSER_IN_ATTRIBUTE_VALUE; } /* Looking for attribute value */ -- (void)of_inAttributeValueState +static void +inAttributeValueState(OFXMLParser *self) { void *pool; OFString *attributeValue; size_t length; OFXMLAttribute *attribute; - if (_data[_i] != _delimiter) + if (self->_data[self->_i] != self->_delimiter) return; - if ((length = _i - _last) > 0) - appendToBuffer(_buffer, _data + _last, _encoding, length); + if ((length = self->_i - self->_last) > 0) + appendToBuffer(self->_buffer, self->_data + self->_last, + self->_encoding, length); pool = objc_autoreleasePoolPush(); - attributeValue = transformString(self, _buffer, 0, true); - - if (_attributePrefix == nil && [_attributeName isEqual: @"xmlns"]) - [_namespaces.lastObject setObject: attributeValue - forKey: @""]; - if ([_attributePrefix isEqual: @"xmlns"]) - [_namespaces.lastObject setObject: attributeValue - forKey: _attributeName]; - - attribute = [OFXMLAttribute attributeWithName: _attributeName - namespace: _attributePrefix + attributeValue = transformString(self, self->_buffer, 0, true); + + if (self->_attributePrefix == nil && + [self->_attributeName isEqual: @"xmlns"]) + [self->_namespaces.lastObject setObject: attributeValue + forKey: @""]; + if ([self->_attributePrefix isEqual: @"xmlns"]) + [self->_namespaces.lastObject setObject: attributeValue + forKey: self->_attributeName]; + + attribute = [OFXMLAttribute attributeWithName: self->_attributeName + namespace: self->_attributePrefix stringValue: attributeValue]; - attribute->_useDoubleQuotes = (_delimiter == '"'); - [_attributes addObject: attribute]; + attribute->_useDoubleQuotes = (self->_delimiter == '"'); + [self->_attributes addObject: attribute]; objc_autoreleasePoolPop(pool); - [_buffer removeAllItems]; - [_attributeName release]; - [_attributePrefix release]; - _attributeName = _attributePrefix = nil; + [self->_buffer removeAllItems]; + [self->_attributeName release]; + [self->_attributePrefix release]; + self->_attributeName = self->_attributePrefix = nil; - _last = _i + 1; - _state = OF_XMLPARSER_IN_TAG; + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_IN_TAG; } /* Expecting closing '>' */ -- (void)of_expectTagCloseState +static void +expectTagCloseState(OFXMLParser *self) { - if (_data[_i] == '>') { - _last = _i + 1; - _state = OF_XMLPARSER_OUTSIDE_TAG; + if (self->_data[self->_i] == '>') { + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_OUTSIDE_TAG; } else @throw [OFMalformedXMLException exceptionWithParser: self]; } /* Expecting closing '>' or space */ -- (void)of_expectSpaceOrTagCloseState +static void +expectSpaceOrTagCloseState(OFXMLParser *self) { - if (_data[_i] == '>') { - _last = _i + 1; - _state = OF_XMLPARSER_OUTSIDE_TAG; - } else if (_data[_i] != ' ' && _data[_i] != '\t' && - _data[_i] != '\n' && _data[_i] != '\r') + if (self->_data[self->_i] == '>') { + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_OUTSIDE_TAG; + } else if (self->_data[self->_i] != ' ' && + self->_data[self->_i] != '\t' && self->_data[self->_i] != '\n' && + self->_data[self->_i] != '\r') @throw [OFMalformedXMLException exceptionWithParser: self]; } /* In _finishedParsing && self->_data[self->_i] != '-') @throw [OFMalformedXMLException exceptionWithParser: self]; - if (_data[_i] == '-') - _state = OF_XMLPARSER_IN_COMMENT_OPENING; - else if (_data[_i] == '[') { - _state = OF_XMLPARSER_IN_CDATA_OPENING; - _level = 0; - } else if (_data[_i] == 'D') { - _state = OF_XMLPARSER_IN_DOCTYPE; - _level = 0; + if (self->_data[self->_i] == '-') + self->_state = OF_XMLPARSER_IN_COMMENT_OPENING; + else if (self->_data[self->_i] == '[') { + self->_state = OF_XMLPARSER_IN_CDATA_OPENING; + self->_level = 0; + } else if (self->_data[self->_i] == 'D') { + self->_state = OF_XMLPARSER_IN_DOCTYPE; + self->_level = 0; } else @throw [OFMalformedXMLException exceptionWithParser: self]; - _last = _i + 1; + self->_last = self->_i + 1; } /* CDATA */ -- (void)of_inCDATAOpeningState -{ - if (_data[_i] != "CDATA["[_level]) - @throw [OFMalformedXMLException exceptionWithParser: self]; - - if (++_level == 6) { - _state = OF_XMLPARSER_IN_CDATA; - _level = 0; - } - - _last = _i + 1; -} - -- (void)of_inCDATAState -{ - - if (_data[_i] == ']') - _level++; - else if (_data[_i] == '>' && _level >= 2) { +static void +inCDATAOpeningState(OFXMLParser *self) +{ + if (self->_data[self->_i] != "CDATA["[self->_level]) + @throw [OFMalformedXMLException exceptionWithParser: self]; + + if (++self->_level == 6) { + self->_state = OF_XMLPARSER_IN_CDATA; + self->_level = 0; + } + + self->_last = self->_i + 1; +} + +static void +inCDATAState(OFXMLParser *self) +{ + if (self->_data[self->_i] == ']') + self->_level++; + else if (self->_data[self->_i] == '>' && self->_level >= 2) { void *pool = objc_autoreleasePoolPush(); OFString *CDATA; - appendToBuffer(_buffer, _data + _last, _encoding, _i - _last); - CDATA = transformString(self, _buffer, 2, false); + appendToBuffer(self->_buffer, self->_data + self->_last, + self->_encoding, self->_i - self->_last); + CDATA = transformString(self, self->_buffer, 2, false); - if ([_delegate respondsToSelector: + if ([self->_delegate respondsToSelector: @selector(parser:foundCDATA:)]) - [_delegate parser: self - foundCDATA: CDATA]; + [self->_delegate parser: self + foundCDATA: CDATA]; objc_autoreleasePoolPop(pool); - [_buffer removeAllItems]; + [self->_buffer removeAllItems]; - _last = _i + 1; - _state = OF_XMLPARSER_OUTSIDE_TAG; + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_OUTSIDE_TAG; } else - _level = 0; + self->_level = 0; } /* Comment */ -- (void)of_inCommentOpeningState +static void +inCommentOpeningState(OFXMLParser *self) { - if (_data[_i] != '-') + if (self->_data[self->_i] != '-') @throw [OFMalformedXMLException exceptionWithParser: self]; - _last = _i + 1; - _state = OF_XMLPARSER_IN_COMMENT_1; - _level = 0; -} - -- (void)of_inCommentState1 -{ - if (_data[_i] == '-') - _level++; - else - _level = 0; - - if (_level == 2) - _state = OF_XMLPARSER_IN_COMMENT_2; -} - -- (void)of_inCommentState2 + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_IN_COMMENT_1; + self->_level = 0; +} + +static void +inCommentState1(OFXMLParser *self) +{ + if (self->_data[self->_i] == '-') + self->_level++; + else + self->_level = 0; + + if (self->_level == 2) + self->_state = OF_XMLPARSER_IN_COMMENT_2; +} + +static void +inCommentState2(OFXMLParser *self) { void *pool; OFString *comment; - if (_data[_i] != '>') + if (self->_data[self->_i] != '>') @throw [OFMalformedXMLException exceptionWithParser: self]; pool = objc_autoreleasePoolPush(); - appendToBuffer(_buffer, _data + _last, _encoding, _i - _last); - comment = transformString(self, _buffer, 2, false); + appendToBuffer(self->_buffer, self->_data + self->_last, + self->_encoding, self->_i - self->_last); + comment = transformString(self, self->_buffer, 2, false); - if ([_delegate respondsToSelector: @selector(parser:foundComment:)]) - [_delegate parser: self - foundComment: comment]; + if ([self->_delegate respondsToSelector: + @selector(parser:foundComment:)]) + [self->_delegate parser: self + foundComment: comment]; objc_autoreleasePoolPop(pool); - [_buffer removeAllItems]; + [self->_buffer removeAllItems]; - _last = _i + 1; - _state = OF_XMLPARSER_OUTSIDE_TAG; + self->_last = self->_i + 1; + self->_state = OF_XMLPARSER_OUTSIDE_TAG; } /* In */ -- (void)of_inDOCTYPEState +static void +inDOCTYPEState(OFXMLParser *self) { - if ((_level < 6 && _data[_i] != "OCTYPE"[_level]) || - (_level == 6 && _data[_i] != ' ' && _data[_i] != '\t' && - _data[_i] != '\n' && _data[_i] != '\r')) + if ((self->_level < 6 && + self->_data[self->_i] != "OCTYPE"[self->_level]) || + (self->_level == 6 && self->_data[self->_i] != ' ' && + self->_data[self->_i] != '\t' && self->_data[self->_i] != '\n' && + self->_data[self->_i] != '\r')) @throw [OFMalformedXMLException exceptionWithParser: self]; - _level++; + self->_level++; - if (_level > 6 && _data[_i] == '>') - _state = OF_XMLPARSER_OUTSIDE_TAG; + if (self->_level > 6 && self->_data[self->_i] == '>') + self->_state = OF_XMLPARSER_OUTSIDE_TAG; - _last = _i + 1; + self->_last = self->_i + 1; } - (size_t)lineNumber { return _lineNumber; Index: src/OFZIPArchive.m ================================================================== --- src/OFZIPArchive.m +++ src/OFZIPArchive.m @@ -50,17 +50,19 @@ * FIXME: Current limitations: * - Split archives are not supported. * - Encrypted files cannot be read. */ +OF_DIRECT_MEMBERS @interface OFZIPArchive () - (void)of_readZIPInfo; - (void)of_readEntries; - (void)of_closeLastReturnedStream; - (void)of_writeCentralDirectory; @end +OF_DIRECT_MEMBERS @interface OFZIPArchiveLocalFileHeader: OFObject { @public uint16_t _minVersionNeeded, _generalPurposeBitFlag, _compressionMethod; uint16_t _lastModifiedFileTime, _lastModifiedFileDate; @@ -72,10 +74,11 @@ - (instancetype)initWithStream: (OFStream *)stream; - (bool)matchesEntry: (OFZIPArchiveEntry *)entry; @end +OF_DIRECT_MEMBERS @interface OFZIPArchiveFileReadStream: OFStream { OFStream *_stream, *_decompressedStream; OFZIPArchiveEntry *_entry; uint64_t _toRead; @@ -85,10 +88,11 @@ - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFZIPArchiveEntry *)entry; @end +OF_DIRECT_MEMBERS @interface OFZIPArchiveFileWriteStream: OFStream { OFStream *_stream; uint32_t _CRC32; @public Index: src/OFZIPArchiveEntry+Private.h ================================================================== --- src/OFZIPArchiveEntry+Private.h +++ src/OFZIPArchiveEntry+Private.h @@ -22,15 +22,16 @@ @interface OFZIPArchiveEntry () @property (readonly, nonatomic) uint16_t of_lastModifiedFileTime, of_lastModifiedFileDate; @property (readonly, nonatomic) int64_t of_localFileHeaderOffset; -- (instancetype)of_initWithStream: (OFStream *)stream OF_METHOD_FAMILY(init); -- (uint64_t)of_writeToStream: (OFStream *)stream; +- (instancetype)of_initWithStream: (OFStream *)stream + OF_METHOD_FAMILY(init) OF_DIRECT; +- (uint64_t)of_writeToStream: (OFStream *)stream OF_DIRECT; @end @interface OFMutableZIPArchiveEntry () @property (readwrite, nonatomic, setter=of_setLocalFileHeaderOffset:) int64_t of_localFileHeaderOffset; @end OF_ASSUME_NONNULL_END Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -68,10 +68,12 @@ # import "OFINIFile.h" # import "OFSettings.h" #endif #ifdef OF_HAVE_SOCKETS # import "OFStreamSocket.h" +# import "OFDatagramSocket.h" +# import "OFSequencedPacketSocket.h" # import "OFTCPSocket.h" # import "OFUDPSocket.h" # import "OFTLSSocket.h" # import "OFKernelEventObserver.h" # import "OFDNSQuery.h" @@ -261,10 +263,11 @@ #import "OFLocking.h" #import "OFThread.h" #import "once.h" #ifdef OF_HAVE_THREADS # import "thread.h" +# import "tlskey.h" # import "mutex.h" # import "condition.h" # import "OFThreadPool.h" # import "OFMutex.h" # import "OFRecursiveMutex.h" Index: src/forwarding/apple-forwarding-i386.S ================================================================== --- src/forwarding/apple-forwarding-i386.S +++ src/forwarding/apple-forwarding-i386.S @@ -15,123 +15,133 @@ * file. */ #include "config.h" +.intel_syntax noprefix + .globl _of_forward .globl _of_forward_stret .section __TEXT, __cstring, cstring_literals -str_forwardingTargetForSelector_: +Lstr_forwardingTargetForSelector_: .asciz "forwardingTargetForSelector:" .section __OBJC, __message_refs, literal_pointers, no_dead_strip -sel_forwardingTargetForSelector_: - .long str_forwardingTargetForSelector_ +Lsel_forwardingTargetForSelector_: + .long Lstr_forwardingTargetForSelector_ .section __OBJC, __image_info .long 0, 0 .section __TEXT, __text, regular, pure_instructions _of_forward: - pushl %ebp - movl %esp, %ebp + push ebp + mov ebp, esp - pushl %ebx - subl $20, %esp + push ebx + sub esp, 20 call get_eip 0: - movl 8(%ebp), %eax - movl %eax, (%esp) + mov eax, [ebp+8] + mov [esp], eax call _object_getClass - movl %eax, (%esp) - movl sel_forwardingTargetForSelector_-0b(%ebx), %eax - movl %eax, 4(%esp) + mov [esp], eax + .att_syntax /* Next line is broken in Intel syntax */ + movl Lsel_forwardingTargetForSelector_-0b(%ebx), %eax + .intel_syntax noprefix + mov [esp+4], eax call _class_respondsToSelector - testl %eax, %eax + test eax, eax jz 0f - movl 8(%ebp), %eax - movl %eax, (%esp) - movl sel_forwardingTargetForSelector_-0b(%ebx), %eax - movl %eax, 4(%esp) - movl 12(%ebp), %eax - movl %eax, 8(%esp) + mov eax, [ebp+8] + mov [esp], eax + .att_syntax /* Next line is broken in Intel syntax */ + movl Lsel_forwardingTargetForSelector_-0b(%ebx), %eax + .intel_syntax noprefix + mov [esp+4], eax + mov eax, [ebp+12] + mov [esp+8], eax call _objc_msgSend - testl %eax, %eax + test eax, eax jz 0f - cmpl 8(%ebp), %eax + cmp eax, [ebp+8] je 0f - movl %eax, 8(%ebp) + mov [ebp+8], eax - addl $20, %esp - popl %ebx - popl %ebp + add esp, 20 + pop ebx + pop ebp jmp _objc_msgSend 0: - addl $20, %esp - popl %ebx - popl %ebp + add esp, 20 + pop ebx + pop ebp jmp _of_method_not_found _of_forward_stret: - pushl %ebp - movl %esp, %ebp + push ebp + mov ebp, esp - pushl %ebx - subl $20, %esp + push ebx + sub esp, 20 call get_eip 0: - movl 12(%ebp), %eax - movl %eax, (%esp) + mov eax, [ebp+12] + mov [esp], eax call _object_getClass - movl %eax, (%esp) - movl sel_forwardingTargetForSelector_-0b(%ebx), %eax - movl %eax, 4(%esp) + mov [esp], eax + .att_syntax /* Next line is broken in Intel syntax */ + movl Lsel_forwardingTargetForSelector_-0b(%ebx), %eax + .intel_syntax noprefix + mov [esp+4], eax call _class_respondsToSelector - testl %eax, %eax + test eax, eax jz 0f - movl 12(%ebp), %eax - movl %eax, (%esp) - movl sel_forwardingTargetForSelector_-0b(%ebx), %eax - movl %eax, 4(%esp) - movl 16(%ebp), %eax - movl %eax, 8(%esp) + mov eax, [ebp+12] + mov [esp], eax + .att_syntax /* Next line is broken in Intel syntax */ + movl Lsel_forwardingTargetForSelector_-0b(%ebx), %eax + .intel_syntax noprefix + mov [esp+4], eax + mov eax, [ebp+16] + mov [esp+8], eax call _objc_msgSend - testl %eax, %eax + test eax, eax jz 0f - cmpl 12(%ebp), %eax + cmp eax, [ebp+12] je 0f - movl %eax, 12(%ebp) + mov [ebp+12], eax - addl $20, %esp - popl %ebx - popl %ebp + add esp, 20 + pop ebx + pop ebp jmp _objc_msgSend_stret 0: - addl $20, %esp - popl %ebx - popl %ebp + add esp, 20 + pop ebx + pop ebp jmp _of_method_not_found_stret get_eip: - movl (%esp), %ebx + mov ebx, [esp] ret Index: src/forwarding/apple-forwarding-x86_64.S ================================================================== --- src/forwarding/apple-forwarding-x86_64.S +++ src/forwarding/apple-forwarding-x86_64.S @@ -15,10 +15,12 @@ * file. */ #include "config.h" +.intel_syntax noprefix + .globl _of_forward .globl _of_forward_stret .section __TEXT, __objc_methname, cstring_literals str_forwardingTargetForSelector_: @@ -31,150 +33,150 @@ .section __DATA, __objc_imageinfo, regular, no_dead_strip .long 0, 0 .section __TEXT, __text, regular, pure_instructions _of_forward: - pushq %rbp - movq %rsp, %rbp + push rbp + mov rbp, rsp /* Save all arguments */ - subq $0xC0, %rsp /* 16-byte alignment */ - movq %rax, -0x8(%rbp) - movq %rdi, -0x10(%rbp) - movq %rsi, -0x18(%rbp) - movq %rdx, -0x20(%rbp) - movq %rcx, -0x28(%rbp) - movq %r8, -0x30(%rbp) - movq %r9, -0x38(%rbp) - movaps %xmm0, -0x50(%rbp) - movaps %xmm1, -0x60(%rbp) - movaps %xmm2, -0x70(%rbp) - movaps %xmm3, -0x80(%rbp) - movaps %xmm4, -0x90(%rbp) - movaps %xmm5, -0xA0(%rbp) - movaps %xmm6, -0xB0(%rbp) - movaps %xmm7, -0xC0(%rbp) + sub rsp, 0xC0 /* 16-byte alignment */ + mov [rbp-0x08], rax + mov [rbp-0x10], rdi + mov [rbp-0x18], rsi + mov [rbp-0x20], rdx + mov [rbp-0x28], rcx + mov [rbp-0x30], r8 + mov [rbp-0x38], r9 + movaps [rbp-0x50], xmm0 + movaps [rbp-0x60], xmm1 + movaps [rbp-0x70], xmm2 + movaps [rbp-0x80], xmm3 + movaps [rbp-0x90], xmm4 + movaps [rbp-0xA0], xmm5 + movaps [rbp-0xB0], xmm6 + movaps [rbp-0xC0], xmm7 call _object_getClass - movq %rax, %rdi - movq sel_forwardingTargetForSelector_(%rip), %rsi + mov rdi, rax + mov rsi, [rip+sel_forwardingTargetForSelector_] call _class_respondsToSelector - testq %rax, %rax + test rax, rax jz 0f - movq -0x10(%rbp), %rdi - movq sel_forwardingTargetForSelector_(%rip), %rsi - movq -0x18(%rbp), %rdx + mov rdi, [rbp-0x10] + mov rsi, [rip+sel_forwardingTargetForSelector_] + mov rdx, [rbp-0x18] call _objc_msgSend - testq %rax, %rax + test rax, rax jz 0f - cmpq -0x10(%rbp), %rax + cmp rax, [rbp-0x10] je 0f - movq %rax, %rdi + mov rdi, rax /* Restore all arguments, except %rdi */ - movaps -0xC0(%rbp), %xmm7 - movaps -0xB0(%rbp), %xmm6 - movaps -0xA0(%rbp), %xmm5 - movaps -0x90(%rbp), %xmm4 - movaps -0x80(%rbp), %xmm3 - movaps -0x70(%rbp), %xmm2 - movaps -0x60(%rbp), %xmm1 - movaps -0x50(%rbp), %xmm0 - movq -0x38(%rbp), %r9 - movq -0x30(%rbp), %r8 - movq -0x28(%rbp), %rcx - movq -0x20(%rbp), %rdx - movq -0x18(%rbp), %rsi - movq -0x8(%rbp), %rax - - movq %rbp, %rsp - popq %rbp + movaps xmm7, [rbp-0xC0] + movaps xmm6, [rbp-0xB0] + movaps xmm5, [rbp-0xA0] + movaps xmm4, [rbp-0x90] + movaps xmm3, [rbp-0x80] + movaps xmm2, [rbp-0x70] + movaps xmm1, [rbp-0x60] + movaps xmm0, [rbp-0x50] + mov r9, [rbp-0x38] + mov r8, [rbp-0x30] + mov rcx, [rbp-0x28] + mov rdx, [rbp-0x20] + mov rsi, [rbp-0x18] + mov rax, [rbp-0x08] + + mov rsp, rbp + pop rbp jmp _objc_msgSend 0: - movq -0x10(%rbp), %rdi - movq -0x18(%rbp), %rsi + mov rdi, [rbp-0x10] + mov rsi, [rbp-0x18] - movq %rbp, %rsp - popq %rbp + mov rsp, rbp + pop rbp jmp _of_method_not_found _of_forward_stret: - pushq %rbp - movq %rsp, %rbp + push rbp + mov rbp, rsp /* Save all arguments */ - subq $0xC0, %rsp /* 16-byte alignment */ - movq %rax, -0x8(%rbp) - movq %rdi, -0x10(%rbp) - movq %rsi, -0x18(%rbp) - movq %rdx, -0x20(%rbp) - movq %rcx, -0x28(%rbp) - movq %r8, -0x30(%rbp) - movq %r9, -0x38(%rbp) - movaps %xmm0, -0x50(%rbp) - movaps %xmm1, -0x60(%rbp) - movaps %xmm2, -0x70(%rbp) - movaps %xmm3, -0x80(%rbp) - movaps %xmm4, -0x90(%rbp) - movaps %xmm5, -0xA0(%rbp) - movaps %xmm6, -0xB0(%rbp) - movaps %xmm7, -0xC0(%rbp) - - movq %rsi, %rdi + sub rsp, 0xC0 /* 16-byte alignment */ + mov [rbp-0x08], rax + mov [rbp-0x10], rdi + mov [rbp-0x18], rsi + mov [rbp-0x20], rdx + mov [rbp-0x28], rcx + mov [rbp-0x30], r8 + mov [rbp-0x38], r9 + movaps [rbp-0x50], xmm0 + movaps [rbp-0x60], xmm1 + movaps [rbp-0x70], xmm2 + movaps [rbp-0x80], xmm3 + movaps [rbp-0x90], xmm4 + movaps [rbp-0xA0], xmm5 + movaps [rbp-0xB0], xmm6 + movaps [rbp-0xC0], xmm7 + + mov rdi, rsi call _object_getClass - movq %rax, %rdi - movq sel_forwardingTargetForSelector_(%rip), %rsi + mov rdi, rax + mov rsi, [rip+sel_forwardingTargetForSelector_] call _class_respondsToSelector - testq %rax, %rax + test rax, rax jz 0f - movq -0x18(%rbp), %rdi - movq sel_forwardingTargetForSelector_(%rip), %rsi - movq -0x20(%rbp), %rdx + mov rdi, [rbp-0x18] + mov rsi, [rip+sel_forwardingTargetForSelector_] + mov rdx, [rbp-0x20] call _objc_msgSend - testq %rax, %rax + test rax, rax jz 0f - cmpq -0x18(%rbp), %rax + cmp rax, [rbp-0x18] je 0f - movq %rax, %rsi + mov rsi, rax /* Restore all arguments, except %rsi */ - movaps -0xC0(%rbp), %xmm7 - movaps -0xB0(%rbp), %xmm6 - movaps -0xA0(%rbp), %xmm5 - movaps -0x90(%rbp), %xmm4 - movaps -0x80(%rbp), %xmm3 - movaps -0x70(%rbp), %xmm2 - movaps -0x60(%rbp), %xmm1 - movaps -0x50(%rbp), %xmm0 - movq -0x38(%rbp), %r9 - movq -0x30(%rbp), %r8 - movq -0x28(%rbp), %rcx - movq -0x20(%rbp), %rdx - movq -0x10(%rbp), %rdi - movq -0x8(%rbp), %rax - - movq %rbp, %rsp - popq %rbp + movaps xmm7, [rbp-0xC0] + movaps xmm6, [rbp-0xB0] + movaps xmm5, [rbp-0xA0] + movaps xmm4, [rbp-0x90] + movaps xmm3, [rbp-0x80] + movaps xmm2, [rbp-0x70] + movaps xmm1, [rbp-0x60] + movaps xmm0, [rbp-0x50] + mov r9, [rbp-0x38] + mov r8, [rbp-0x30] + mov rcx, [rbp-0x28] + mov rdx, [rbp-0x20] + mov rdi, [rbp-0x10] + mov rax, [rbp-0x08] + + mov rsp, rbp + pop rbp jmp _objc_msgSend_stret 0: - movq -0x10(%rbp), %rdi - movq -0x18(%rbp), %rsi - movq -0x20(%rbp), %rdx + mov rdi, [rbp-0x10] + mov rsi, [rbp-0x18] + mov rdx, [rbp-0x20] - movq %rbp, %rsp - popq %rbp + mov rsp, rbp + pop rbp jmp _of_method_not_found_stret ADDED src/forwarding/forwarding-sparc-elf.S Index: src/forwarding/forwarding-sparc-elf.S ================================================================== --- src/forwarding/forwarding-sparc-elf.S +++ src/forwarding/forwarding-sparc-elf.S @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019, 2020 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#include "platform.h" + +.globl of_forward +.globl of_forward_stret + +.section .text +of_forward: + save %sp, -96, %sp + + sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7 + call add_pc + add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7 + + mov %i0, %o0 + call object_getClass + nop + + sethi %hi(sel_forwardingTargetForSelector_), %o1 + or %o1, %lo(sel_forwardingTargetForSelector_), %o1 + ld [%l7 + %o1], %o1 + call class_respondsToSelector + nop + + cmp %o0, 0 + be 0f + + mov %i0, %o0 + sethi %hi(sel_forwardingTargetForSelector_), %o1 + or %o1, %lo(sel_forwardingTargetForSelector_), %o1 + ld [%l7 + %o1], %o1 + call objc_msg_lookup + nop + mov %o0, %l0 + + mov %i0, %o0 + sethi %hi(sel_forwardingTargetForSelector_), %o1 + or %o1, %lo(sel_forwardingTargetForSelector_), %o1 + ld [%l7 + %o1], %o1 + jmpl %l0, %o7 + mov %i1, %o2 + + cmp %o0, 0 + be 0f + cmp %o0, %i0 + be 0f + + mov %o0, %i0 + call objc_msg_lookup + mov %i1, %o1 + + jmpl %o0, %g0 + restore + +0: + call of_method_not_found + restore +.type of_forward, %function +.size of_forward, .-of_forward + +of_forward_stret: + save %sp, -96, %sp + + sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7 + call add_pc + add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7 + + mov %i1, %o0 + call object_getClass + nop + + sethi %hi(sel_forwardingTargetForSelector_), %o1 + or %o1, %lo(sel_forwardingTargetForSelector_), %o1 + ld [%l7 + %o1], %o1 + call class_respondsToSelector + nop + + cmp %o0, 0 + be 0f + + mov %i1, %o0 + sethi %hi(sel_forwardingTargetForSelector_), %o1 + or %o1, %lo(sel_forwardingTargetForSelector_), %o1 + ld [%l7 + %o1], %o1 + call objc_msg_lookup + nop + mov %o0, %l0 + + mov %i1, %o0 + sethi %hi(sel_forwardingTargetForSelector_), %o1 + or %o1, %lo(sel_forwardingTargetForSelector_), %o1 + ld [%l7 + %o1], %o1 + jmpl %l0, %o7 + mov %i2, %o2 + + cmp %o0, 0 + be 0f + cmp %o0, %i1 + be 0f + + mov %o0, %i1 + call objc_msg_lookup + mov %i2, %o1 + + jmpl %o0, %g0 + restore + +0: + call of_method_not_found_stret + restore +.type of_forward_stret, %function +.size of_forward_stret, .-of_forward_stret + +init: + save %sp, -96, %sp + + sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7 + call add_pc + add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7 + + sethi %hi(module), %i0 + or %i0, %lo(module), %i0 + ld [%l7 + %i0], %i0 + + call __objc_exec_class + restore + +add_pc: + jmp %o7 + 8 + add %l7, %o7, %l7 + +#ifdef OF_SOLARIS +.section .init_array, "aw" +#else +.section .ctors, "aw", %progbits +#endif + .word init + +.section .rodata +str_forwardingTargetForSelector_: + .asciz "forwardingTargetForSelector:" + +.section .data +sel_forwardingTargetForSelector_: + .word str_forwardingTargetForSelector_, 0 + .word 0, 0 +symtab: + .word 0, sel_forwardingTargetForSelector_ + .half 0, 0 + .word 0 + .word 0 +module: + .word 8, 16, 0, symtab + +#ifdef OF_LINUX +.section .note.GNU-stack, "", %progbits +#endif Index: src/forwarding/forwarding-sparc64-elf.S ================================================================== --- src/forwarding/forwarding-sparc64-elf.S +++ src/forwarding/forwarding-sparc64-elf.S @@ -61,15 +61,13 @@ or %o1, %lo(sel_forwardingTargetForSelector_), %o1 ldx [%l7 + %o1], %o1 call class_respondsToSelector nop - cmp %o0, 0 - be,pn %xcc, 0f - nop + brz,pn %o0, 0f - mov %i0, %o0 + mov %i0, %o0 sethi %hi(sel_forwardingTargetForSelector_), %o1 or %o1, %lo(sel_forwardingTargetForSelector_), %o1 ldx [%l7 + %o1], %o1 call objc_msg_lookup nop @@ -80,18 +78,15 @@ or %o1, %lo(sel_forwardingTargetForSelector_), %o1 ldx [%l7 + %o1], %o1 jmpl %l0, %o7 mov %i1, %o2 - cmp %o0, 0 - be,pn %xcc, 0f - nop - cmp %o0, %i0 - be,pn %xcc, 0f - nop - - mov %o0, %i0 + brz,pn %o0, 0f + cmp %o0, %i0 + be,pn %xcc, 0f + + mov %o0, %i0 call objc_msg_lookup mov %i1, %o1 /* * Restore all floating point registers as they can be used for @@ -159,15 +154,13 @@ or %o1, %lo(sel_forwardingTargetForSelector_), %o1 ldx [%l7 + %o1], %o1 call class_respondsToSelector nop - cmp %o0, 0 - be,pn %xcc, 0f - nop + brz,pn %o0, 0f - mov %i1, %o0 + mov %i1, %o0 sethi %hi(sel_forwardingTargetForSelector_), %o1 or %o1, %lo(sel_forwardingTargetForSelector_), %o1 ldx [%l7 + %o1], %o1 call objc_msg_lookup nop @@ -178,18 +171,15 @@ or %o1, %lo(sel_forwardingTargetForSelector_), %o1 ldx [%l7 + %o1], %o1 jmpl %l0, %o7 mov %i2, %o2 - cmp %o0, 0 - be,pn %xcc, 0f - nop - cmp %o0, %i1 - be,pn %xcc, 0f - nop - - mov %o0, %i1 + brz,pn %o0, 0f + cmp %o0, %i1 + be,pn %xcc, 0f + + mov %o0, %i1 call objc_msg_lookup mov %i2, %o1 /* * Restore all floating point registers as they can be used for Index: src/forwarding/forwarding-x86-elf.S ================================================================== --- src/forwarding/forwarding-x86-elf.S +++ src/forwarding/forwarding-x86-elf.S @@ -17,175 +17,165 @@ #include "config.h" #include "platform.h" +.intel_syntax noprefix + .globl of_forward .globl of_forward_stret .section .text of_forward: - pushl %ebp - movl %esp, %ebp + push ebp + mov ebp, esp - pushl %ebx - subl $20, %esp + push ebx + sub esp, 20 call get_eip + add ebx, offset _GLOBAL_OFFSET_TABLE_ + + mov eax, [ebp+8] + mov [esp], eax + call object_getClass@PLT + + mov [esp], eax + lea eax, [ebx+sel_forwardingTargetForSelector_@GOTOFF] + mov [esp+4], eax + call class_respondsToSelector@PLT + + test eax, eax + jz short 0f + + mov eax, [ebp+8] + mov [esp], eax + lea eax, [ebx+sel_forwardingTargetForSelector_@GOTOFF] + mov [esp+4], eax + call objc_msg_lookup@PLT + + mov edx, [ebp+8] + mov [esp], edx + lea edx, [ebx+sel_forwardingTargetForSelector_@GOTOFF] + mov [esp+4], edx + mov edx, [ebp+12] + mov [esp+8], edx + call eax + + test eax, eax + jz short 0f + cmp eax, [ebp+8] + je short 0f + + mov [ebp+8], eax + mov [esp], eax + mov eax, [ebp+12] + mov [esp+4], eax + call objc_msg_lookup@PLT + + add esp, 20 + pop ebx + pop ebp + + jmp eax + 0: - addl $_GLOBAL_OFFSET_TABLE_, %ebx - - movl 8(%ebp), %eax - movl %eax, (%esp) - movl object_getClass@GOT(%ebx), %eax - call *%eax - - movl %eax, (%esp) - leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax - movl %eax, 4(%esp) - movl class_respondsToSelector@GOT(%ebx), %eax - call *%eax - - testl %eax, %eax - jz 1f - - movl 8(%ebp), %eax - movl %eax, (%esp) - leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax - movl %eax, 4(%esp) - movl objc_msg_lookup@GOT(%ebx), %eax - call *%eax - - movl 8(%ebp), %edx - movl %edx, (%esp) - leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %edx - movl %edx, 4(%esp) - movl 12(%ebp), %edx - movl %edx, 8(%esp) - call *%eax - - testl %eax, %eax - jz 1f - cmpl 8(%ebp), %eax - je 1f - - movl %eax, 8(%ebp) - movl %eax, (%esp) - movl 12(%ebp), %eax - movl %eax, 4(%esp) - movl objc_msg_lookup@GOT(%ebx), %eax - call *%eax - - addl $20, %esp - popl %ebx - popl %ebp - - jmp *%eax - -1: - movl of_method_not_found@GOT(%ebx), %eax - - addl $20, %esp - popl %ebx - popl %ebp - - jmp *%eax + lea eax, [ebx+of_method_not_found@GOTOFF] + + add esp, 20 + pop ebx + pop ebp + + jmp eax .type of_forward, %function .size of_forward, .-of_forward of_forward_stret: - pushl %ebp - movl %esp, %ebp + push ebp + mov ebp, esp - pushl %ebx - subl $20, %esp + push ebx + sub esp, 20 call get_eip + add ebx, offset _GLOBAL_OFFSET_TABLE_ + + mov eax, [ebp+12] + mov [esp], eax + call object_getClass@PLT + + mov [esp], eax + lea eax, [ebx+sel_forwardingTargetForSelector_@GOTOFF] + mov [esp+4], eax + call class_respondsToSelector@PLT + + test eax, eax + jz short 0f + + mov eax, [ebp+12] + mov [esp], eax + lea eax, [ebx+sel_forwardingTargetForSelector_@GOTOFF] + mov [esp+4], eax + call objc_msg_lookup@PLT + + mov edx, [ebp+12] + mov [esp], edx + lea edx, [ebx+sel_forwardingTargetForSelector_@GOTOFF] + mov [esp+4], edx + mov edx, [ebp+16] + mov [esp+8], edx + call eax + + test eax, eax + jz short 0f + cmp eax, [ebp+12] + je short 0f + + mov [ebp+12], eax + mov [esp], eax + mov eax, [ebp+16] + mov [esp+4], eax + call objc_msg_lookup_stret@PLT + + add esp, 20 + pop ebx + pop ebp + + jmp eax + 0: - addl $_GLOBAL_OFFSET_TABLE_, %ebx - - movl 12(%ebp), %eax - movl %eax, (%esp) - movl object_getClass@GOT(%ebx), %eax - call *%eax - - movl %eax, (%esp) - leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax - movl %eax, 4(%esp) - movl class_respondsToSelector@GOT(%ebx), %eax - call *%eax - - testl %eax, %eax - jz 1f - - movl 12(%ebp), %eax - movl %eax, (%esp) - leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax - movl %eax, 4(%esp) - movl objc_msg_lookup@GOT(%ebx), %eax - call *%eax - - movl 12(%ebp), %edx - movl %edx, (%esp) - leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %edx - movl %edx, 4(%esp) - movl 16(%ebp), %edx - movl %edx, 8(%esp) - call *%eax - - testl %eax, %eax - jz 1f - cmpl 12(%ebp), %eax - je 1f - - movl %eax, 12(%ebp) - movl %eax, (%esp) - movl 16(%ebp), %eax - movl %eax, 4(%esp) - movl objc_msg_lookup_stret@GOT(%ebx), %eax - call *%eax - - addl $20, %esp - popl %ebx - popl %ebp - - jmp *%eax - -1: - movl of_method_not_found_stret@GOT(%ebx), %eax - - addl $20, %esp - popl %ebx - popl %ebp - - jmp *%eax + lea eax, [ebx+of_method_not_found_stret@GOTOFF] + + add esp, 20 + pop ebx + pop ebp + + jmp eax .type of_forward_stret, %function .size of_forward_stret, .-of_forward_stret init: - pushl %ebp - movl %esp, %ebp + push ebp + mov ebp, esp - pushl %ebx - subl $4, %esp + push ebx + sub esp, 4 call get_eip -0: - add $_GLOBAL_OFFSET_TABLE_, %ebx - - leal module@GOTOFF(%ebx), %eax - movl %eax, (%esp) - movl __objc_exec_class@GOT(%ebx), %eax - call *%eax - - addl $4, %esp - popl %ebx - popl %ebp + add ebx, offset _GLOBAL_OFFSET_TABLE_ + + lea eax, [ebx+module@GOTOFF] + mov [esp], eax + call __objc_exec_class@PLT + + add esp, 4 + pop ebx + pop ebp ret get_eip: - movl (%esp), %ebx + mov ebx, [esp] ret #ifdef OF_SOLARIS .section .init_array, "aw" #else Index: src/forwarding/forwarding-x86-win32.S ================================================================== --- src/forwarding/forwarding-x86-win32.S +++ src/forwarding/forwarding-x86-win32.S @@ -15,167 +15,144 @@ * file. */ #include "config.h" +.intel_syntax noprefix + .globl _of_forward .globl _of_forward_stret .section .text _of_forward: - pushl %ebp - movl %esp, %ebp + push ebp + mov ebp, esp + + push ebx + sub esp, 20 + + mov eax, [ebp+8] + mov [esp], eax + call _object_getClass + + mov [esp], eax + mov eax, offset sel_forwardingTargetForSelector_ + mov [esp+4], eax + call _class_respondsToSelector + + test eax, eax + jz short 0f + + mov eax, [ebp+8] + mov [esp], eax + mov eax, offset sel_forwardingTargetForSelector_ + mov [esp+4], eax + call _objc_msg_lookup + + mov edx, [ebp+8] + mov [esp], edx + mov edx, offset sel_forwardingTargetForSelector_ + mov [esp+4], edx + mov edx, [ebp+12] + mov [esp+8], edx + call eax + + test eax, eax + jz short 0f + cmp eax, [ebp+8] + je short 0f + + mov [ebp+8], eax + mov [esp], eax + mov eax, [ebp+12] + mov [esp+4], eax + call _objc_msg_lookup - pushl %ebx - subl $20, %esp + add esp, 20 + pop ebx + pop ebp - call get_eip + jmp eax + 0: - - movl 8(%ebp), %eax - movl %eax, (%esp) - leal _object_getClass-0b(%ebx), %eax - call *%eax - - movl %eax, (%esp) - leal sel_forwardingTargetForSelector_-0b(%ebx), %eax - movl %eax, 4(%esp) - leal _class_respondsToSelector-0b(%ebx), %eax - call *%eax - - testl %eax, %eax - jz 1f - - movl 8(%ebp), %eax - movl %eax, (%esp) - leal sel_forwardingTargetForSelector_-0b(%ebx), %eax - movl %eax, 4(%esp) - leal _objc_msg_lookup-0b(%ebx), %eax - call *%eax - - movl 8(%ebp), %edx - movl %edx, (%esp) - leal sel_forwardingTargetForSelector_-0b(%ebx), %edx - movl %edx, 4(%esp) - movl 12(%ebp), %edx - movl %edx, 8(%esp) - call *%eax - - testl %eax, %eax - jz 1f - cmpl 8(%ebp), %eax - je 1f - - movl %eax, 8(%ebp) - movl %eax, (%esp) - movl 12(%ebp), %eax - movl %eax, 4(%esp) - leal _objc_msg_lookup-0b(%ebx), %eax - call *%eax - - addl $20, %esp - popl %ebx - popl %ebp - - jmp *%eax - -1: - leal _of_method_not_found-0b(%ebx), %eax - - addl $20, %esp - popl %ebx - popl %ebp - - jmp *%eax + add esp, 20 + pop ebx + pop ebp + + jmp _of_method_not_found _of_forward_stret: - pushl %ebp - movl %esp, %ebp + push ebp + mov ebp, esp + + push ebx + sub esp, 20 + + mov eax, [ebp+12] + mov [esp], eax + call _object_getClass + + mov [esp], eax + mov eax, offset sel_forwardingTargetForSelector_ + mov [esp+4], eax + call _class_respondsToSelector + + test eax, eax + jz short 0f + + mov eax, [ebp+12] + mov [esp], eax + mov eax, offset sel_forwardingTargetForSelector_ + mov [esp+4], eax + call _objc_msg_lookup + + mov edx, [ebp+12] + mov [esp], edx + mov edx, offset sel_forwardingTargetForSelector_ + mov [esp+4], edx + mov edx, [ebp+16] + mov [esp+8], edx + call eax + + test eax, eax + jz short 0f + cmp eax, [ebp+12] + je short 0f + + mov [ebp+12], eax + mov [esp], eax + mov eax, [ebp+16] + mov [esp+4], eax + call _objc_msg_lookup_stret - pushl %ebx - subl $20, %esp + add esp, 20 + pop ebx + pop ebp - call get_eip + jmp eax + 0: - - movl 12(%ebp), %eax - movl %eax, (%esp) - leal _object_getClass-0b(%ebx), %eax - call *%eax - - movl %eax, (%esp) - leal sel_forwardingTargetForSelector_-0b(%ebx), %eax - movl %eax, 4(%esp) - leal _class_respondsToSelector-0b(%ebx), %eax - call *%eax - - testl %eax, %eax - jz 1f - - movl 12(%ebp), %eax - movl %eax, (%esp) - leal sel_forwardingTargetForSelector_-0b(%ebx), %eax - movl %eax, 4(%esp) - leal _objc_msg_lookup-0b(%ebx), %eax - call *%eax - - movl 12(%ebp), %edx - movl %edx, (%esp) - leal sel_forwardingTargetForSelector_-0b(%ebx), %edx - movl %edx, 4(%esp) - movl 16(%ebp), %edx - movl %edx, 8(%esp) - call *%eax - - testl %eax, %eax - jz 1f - cmpl 12(%ebp), %eax - je 1f - - movl %eax, 12(%ebp) - movl %eax, (%esp) - movl 16(%ebp), %eax - movl %eax, 4(%esp) - leal _objc_msg_lookup_stret-0b(%ebx), %eax - call *%eax - - addl $20, %esp - popl %ebx - popl %ebp - - jmp *%eax - -1: - leal _of_method_not_found_stret-0b(%ebx), %eax - - addl $20, %esp - popl %ebx - popl %ebp - - jmp *%eax + add esp, 20 + pop ebx + pop ebp + + jmp _of_method_not_found_stret init: - pushl %ebp - movl %esp, %ebp - - pushl %ebx - subl $4, %esp - - call get_eip -0: - leal module-0b(%ebx), %eax - movl %eax, (%esp) - leal ___objc_exec_class-0b(%ebx), %eax - call *%eax - - addl $4, %esp - popl %ebx - popl %ebp - ret - -get_eip: - movl (%esp), %ebx + push ebp + mov ebp, esp + + push ebx + sub esp, 4 + + mov eax, offset module + mov [esp], eax + call ___objc_exec_class + + add esp, 4 + pop ebx + pop ebp ret .section .ctors, "aw" .long init Index: src/forwarding/forwarding-x86_64-elf.S ================================================================== --- src/forwarding/forwarding-x86_64-elf.S +++ src/forwarding/forwarding-x86_64-elf.S @@ -17,188 +17,190 @@ #include "config.h" #include "platform.h" +.intel_syntax noprefix + .globl of_forward .globl of_forward_stret .section .text of_forward: - pushq %rbp - movq %rsp, %rbp + push rbp + mov rbp, rsp /* Save all arguments */ - subq $0xC0, %rsp /* 16-byte alignment */ - movq %rax, -0x8(%rbp) - movq %rdi, -0x10(%rbp) - movq %rsi, -0x18(%rbp) - movq %rdx, -0x20(%rbp) - movq %rcx, -0x28(%rbp) - movq %r8, -0x30(%rbp) - movq %r9, -0x38(%rbp) - movaps %xmm0, -0x50(%rbp) - movaps %xmm1, -0x60(%rbp) - movaps %xmm2, -0x70(%rbp) - movaps %xmm3, -0x80(%rbp) - movaps %xmm4, -0x90(%rbp) - movaps %xmm5, -0xA0(%rbp) - movaps %xmm6, -0xB0(%rbp) - movaps %xmm7, -0xC0(%rbp) + sub rsp, 0xC0 /* 16-byte alignment */ + mov [rbp-0x08], rax + mov [rbp-0x10], rdi + mov [rbp-0x18], rsi + mov [rbp-0x20], rdx + mov [rbp-0x28], rcx + mov [rbp-0x30], r8 + mov [rbp-0x38], r9 + movaps [rbp-0x50], xmm0 + movaps [rbp-0x60], xmm1 + movaps [rbp-0x70], xmm2 + movaps [rbp-0x80], xmm3 + movaps [rbp-0x90], xmm4 + movaps [rbp-0xA0], xmm5 + movaps [rbp-0xB0], xmm6 + movaps [rbp-0xC0], xmm7 call object_getClass@PLT - movq %rax, %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi + mov rdi, rax + lea rsi, [rip+sel_forwardingTargetForSelector_] call class_respondsToSelector@PLT - testq %rax, %rax - jz 0f - - movq -0x10(%rbp), %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi - call objc_msg_lookup@PLT - - movq -0x10(%rbp), %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi - movq -0x18(%rbp), %rdx - call *%rax - - testq %rax, %rax - jz 0f - cmpq -0x10(%rbp), %rax - je 0f - - movq %rax, -0x10(%rbp) - - movq %rax, %rdi - movq -0x18(%rbp), %rsi - call objc_msg_lookup@PLT - movq %rax, %r11 + test rax, rax + jz short 0f + + mov rdi, [rbp-0x10] + lea rsi, [rip+sel_forwardingTargetForSelector_] + call objc_msg_lookup@PLT + + mov rdi, [rbp-0x10] + lea rsi, [rip+sel_forwardingTargetForSelector_] + mov rdx, [rbp-0x18] + call rax + + test rax, rax + jz short 0f + cmp rax, [rbp-0x10] + je short 0f + + mov [rbp-0x10], rax + + mov rdi, rax + mov rsi, [rbp-0x18] + call objc_msg_lookup@PLT + mov r11, rax /* Restore all arguments */ - movaps -0xC0(%rbp), %xmm7 - movaps -0xB0(%rbp), %xmm6 - movaps -0xA0(%rbp), %xmm5 - movaps -0x90(%rbp), %xmm4 - movaps -0x80(%rbp), %xmm3 - movaps -0x70(%rbp), %xmm2 - movaps -0x60(%rbp), %xmm1 - movaps -0x50(%rbp), %xmm0 - movq -0x38(%rbp), %r9 - movq -0x30(%rbp), %r8 - movq -0x28(%rbp), %rcx - movq -0x20(%rbp), %rdx - movq -0x18(%rbp), %rsi - movq -0x10(%rbp), %rdi - movq -0x8(%rbp), %rax - - movq %rbp, %rsp - popq %rbp - - jmpq *%r11 + movaps xmm7, [rbp-0xC0] + movaps xmm6, [rbp-0xB0] + movaps xmm5, [rbp-0xA0] + movaps xmm4, [rbp-0x90] + movaps xmm3, [rbp-0x80] + movaps xmm2, [rbp-0x70] + movaps xmm1, [rbp-0x60] + movaps xmm0, [rbp-0x50] + mov r9, [rbp-0x38] + mov r8, [rbp-0x30] + mov rcx, [rbp-0x28] + mov rdx, [rbp-0x20] + mov rsi, [rbp-0x18] + mov rdi, [rbp-0x10] + mov rax, [rbp-0x08] + + mov rsp, rbp + pop rbp + + jmp r11 0: - movq -0x10(%rbp), %rdi - movq -0x18(%rbp), %rsi + mov rdi, [rbp-0x10] + mov rsi, [rbp-0x18] - movq %rbp, %rsp - popq %rbp + mov rsp, rbp + pop rbp jmp of_method_not_found@PLT .type of_forward, %function .size of_forward, .-of_forward of_forward_stret: - pushq %rbp - movq %rsp, %rbp + push rbp + mov rbp, rsp /* Save all arguments */ - subq $0xC0, %rsp /* 16-byte alignment */ - movq %rax, -0x8(%rbp) - movq %rdi, -0x10(%rbp) - movq %rsi, -0x18(%rbp) - movq %rdx, -0x20(%rbp) - movq %rcx, -0x28(%rbp) - movq %r8, -0x30(%rbp) - movq %r9, -0x38(%rbp) - movaps %xmm0, -0x50(%rbp) - movaps %xmm1, -0x60(%rbp) - movaps %xmm2, -0x70(%rbp) - movaps %xmm3, -0x80(%rbp) - movaps %xmm4, -0x90(%rbp) - movaps %xmm5, -0xA0(%rbp) - movaps %xmm6, -0xB0(%rbp) - movaps %xmm7, -0xC0(%rbp) - - movq %rsi, %rdi + sub rsp, 0xC0 /* 16-byte alignment */ + mov [rbp-0x08], rax + mov [rbp-0x10], rdi + mov [rbp-0x18], rsi + mov [rbp-0x20], rdx + mov [rbp-0x28], rcx + mov [rbp-0x30], r8 + mov [rbp-0x38], r9 + movaps [rbp-0x50], xmm0 + movaps [rbp-0x60], xmm1 + movaps [rbp-0x70], xmm2 + movaps [rbp-0x80], xmm3 + movaps [rbp-0x90], xmm4 + movaps [rbp-0xA0], xmm5 + movaps [rbp-0xB0], xmm6 + movaps [rbp-0xC0], xmm7 + + mov rdi, rsi call object_getClass@PLT - movq %rax, %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi + mov rdi, rax + lea rsi, [rip+sel_forwardingTargetForSelector_] call class_respondsToSelector@PLT - testq %rax, %rax - jz 0f + test rax, rax + jz short 0f - movq -0x18(%rbp), %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi + mov rdi, [rbp-0x18] + lea rsi, [rip+sel_forwardingTargetForSelector_] call objc_msg_lookup@PLT - movq -0x18(%rbp), %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi - movq -0x20(%rbp), %rdx - call *%rax - - testq %rax, %rax - jz 0f - cmpq -0x18(%rbp), %rax - je 0f - - movq %rax, -0x18(%rbp) - - movq %rax, %rdi - movq -0x20(%rbp), %rsi + mov rdi, [rbp-0x18] + lea rsi, [rip+sel_forwardingTargetForSelector_] + mov rdx, [rbp-0x20] + call rax + + test rax, rax + jz short 0f + cmp rax, [rbp-0x18] + je short 0f + + mov [rbp-0x18], rax + + mov rdi, rax + mov rsi, [rbp-0x20] call objc_msg_lookup_stret@PLT - movq %rax, %r11 + mov r11, rax /* Restore all arguments */ - movaps -0xC0(%rbp), %xmm7 - movaps -0xB0(%rbp), %xmm6 - movaps -0xA0(%rbp), %xmm5 - movaps -0x90(%rbp), %xmm4 - movaps -0x80(%rbp), %xmm3 - movaps -0x70(%rbp), %xmm2 - movaps -0x60(%rbp), %xmm1 - movaps -0x50(%rbp), %xmm0 - movq -0x38(%rbp), %r9 - movq -0x30(%rbp), %r8 - movq -0x28(%rbp), %rcx - movq -0x20(%rbp), %rdx - movq -0x18(%rbp), %rsi - movq -0x10(%rbp), %rdi - movq -0x8(%rbp), %rax - - movq %rbp, %rsp - popq %rbp - - jmpq *%r11 + movaps xmm7, [rbp-0xC0] + movaps xmm6, [rbp-0xB0] + movaps xmm5, [rbp-0xA0] + movaps xmm4, [rbp-0x90] + movaps xmm3, [rbp-0x80] + movaps xmm2, [rbp-0x70] + movaps xmm1, [rbp-0x60] + movaps xmm0, [rbp-0x50] + mov r9, [rbp-0x38] + mov r8, [rbp-0x30] + mov rcx, [rbp-0x28] + mov rdx, [rbp-0x20] + mov rsi, [rbp-0x18] + mov rdi, [rbp-0x10] + mov rax, [rbp-0x08] + + mov rsp, rbp + pop rbp + + jmp r11 0: - movq -0x10(%rbp), %rdi - movq -0x18(%rbp), %rsi - movq -0x20(%rbp), %rdx + mov rdi, [rbp-0x10] + mov rsi, [rbp-0x18] + mov rdx, [rbp-0x20] - movq %rbp, %rsp - popq %rbp + mov rsp, rbp + pop rbp jmp of_method_not_found_stret@PLT .type of_forward_stret, %function .size of_forward_stret, .-of_forward_stret init: - leaq module(%rip), %rdi + lea rdi, [rip+module] jmp __objc_exec_class@PLT #ifdef OF_SOLARIS .section .init_array, "aw" #else Index: src/forwarding/forwarding-x86_64-macho.S ================================================================== --- src/forwarding/forwarding-x86_64-macho.S +++ src/forwarding/forwarding-x86_64-macho.S @@ -17,184 +17,186 @@ #include "config.h" #include "platform.h" +.intel_syntax noprefix + .globl _of_forward .globl _of_forward_stret .section __TEXT, __text, regular, pure_instructions _of_forward: - pushq %rbp - movq %rsp, %rbp + push rbp + mov rbp, rsp /* Save all arguments */ - subq $0xC0, %rsp /* 16-byte alignment */ - movq %rax, -0x8(%rbp) - movq %rdi, -0x10(%rbp) - movq %rsi, -0x18(%rbp) - movq %rdx, -0x20(%rbp) - movq %rcx, -0x28(%rbp) - movq %r8, -0x30(%rbp) - movq %r9, -0x38(%rbp) - movaps %xmm0, -0x50(%rbp) - movaps %xmm1, -0x60(%rbp) - movaps %xmm2, -0x70(%rbp) - movaps %xmm3, -0x80(%rbp) - movaps %xmm4, -0x90(%rbp) - movaps %xmm5, -0xA0(%rbp) - movaps %xmm6, -0xB0(%rbp) - movaps %xmm7, -0xC0(%rbp) + sub rsp, 0xC0 /* 16-byte alignment */ + mov [rbp-0x08], rax + mov [rbp-0x10], rdi + mov [rbp-0x18], rsi + mov [rbp-0x20], rdx + mov [rbp-0x28], rcx + mov [rbp-0x30], r8 + mov [rbp-0x38], r9 + movaps [rbp-0x50], xmm0 + movaps [rbp-0x60], xmm1 + movaps [rbp-0x70], xmm2 + movaps [rbp-0x80], xmm3 + movaps [rbp-0x90], xmm4 + movaps [rbp-0xA0], xmm5 + movaps [rbp-0xB0], xmm6 + movaps [rbp-0xC0], xmm7 call _object_getClass - movq %rax, %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi + mov rdi, rax + lea rsi, [rip+sel_forwardingTargetForSelector_] call _class_respondsToSelector - testq %rax, %rax + test rax, rax jz 0f - movq -0x10(%rbp), %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi + mov rdi, [rbp-0x10] + lea rsi, [rip+sel_forwardingTargetForSelector_] call _objc_msg_lookup - movq -0x10(%rbp), %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi - movq -0x18(%rbp), %rdx - call *%rax + mov rdi, [rbp-0x10] + lea rsi, [rip+sel_forwardingTargetForSelector_] + mov rdx, [rbp-0x18] + call rax - testq %rax, %rax + test rax, rax jz 0f - cmpq -0x10(%rbp), %rax + cmp rax, [rbp-0x10] je 0f - movq %rax, -0x10(%rbp) + mov [rbp-0x10], rax - movq %rax, %rdi - movq -0x18(%rbp), %rsi + mov rdi, rax + mov rsi, [rbp-0x18] call _objc_msg_lookup - movq %rax, %r11 + mov r11, rax /* Restore all arguments */ - movaps -0xC0(%rbp), %xmm7 - movaps -0xB0(%rbp), %xmm6 - movaps -0xA0(%rbp), %xmm5 - movaps -0x90(%rbp), %xmm4 - movaps -0x80(%rbp), %xmm3 - movaps -0x70(%rbp), %xmm2 - movaps -0x60(%rbp), %xmm1 - movaps -0x50(%rbp), %xmm0 - movq -0x38(%rbp), %r9 - movq -0x30(%rbp), %r8 - movq -0x28(%rbp), %rcx - movq -0x20(%rbp), %rdx - movq -0x18(%rbp), %rsi - movq -0x10(%rbp), %rdi - movq -0x8(%rbp), %rax - - movq %rbp, %rsp - popq %rbp - - jmpq *%r11 + movaps xmm7, [rbp-0xC0] + movaps xmm6, [rbp-0xB0] + movaps xmm5, [rbp-0xA0] + movaps xmm4, [rbp-0x90] + movaps xmm3, [rbp-0x80] + movaps xmm2, [rbp-0x70] + movaps xmm1, [rbp-0x60] + movaps xmm0, [rbp-0x50] + mov r9, [rbp-0x38] + mov r8, [rbp-0x30] + mov rcx, [rbp-0x28] + mov rdx, [rbp-0x20] + mov rsi, [rbp-0x18] + mov rdi, [rbp-0x10] + mov rax, [rbp-0x08] + + mov rsp, rbp + pop rbp + + jmp r11 0: - movq -0x10(%rbp), %rdi - movq -0x18(%rbp), %rsi + mov rdi, [rbp-0x10] + mov rsi, [rbp-0x18] - movq %rbp, %rsp - popq %rbp + mov rsp, rbp + pop rbp jmp _of_method_not_found _of_forward_stret: - pushq %rbp - movq %rsp, %rbp + push rbp + mov rbp, rsp /* Save all arguments */ - subq $0xC0, %rsp /* 16-byte alignment */ - movq %rax, -0x8(%rbp) - movq %rdi, -0x10(%rbp) - movq %rsi, -0x18(%rbp) - movq %rdx, -0x20(%rbp) - movq %rcx, -0x28(%rbp) - movq %r8, -0x30(%rbp) - movq %r9, -0x38(%rbp) - movaps %xmm0, -0x50(%rbp) - movaps %xmm1, -0x60(%rbp) - movaps %xmm2, -0x70(%rbp) - movaps %xmm3, -0x80(%rbp) - movaps %xmm4, -0x90(%rbp) - movaps %xmm5, -0xA0(%rbp) - movaps %xmm6, -0xB0(%rbp) - movaps %xmm7, -0xC0(%rbp) - - movq %rsi, %rdi + sub rsp, 0xC0 /* 16-byte alignment */ + mov [rbp-0x08], rax + mov [rbp-0x10], rdi + mov [rbp-0x18], rsi + mov [rbp-0x20], rdx + mov [rbp-0x28], rcx + mov [rbp-0x30], r8 + mov [rbp-0x38], r9 + movaps [rbp-0x50], xmm0 + movaps [rbp-0x60], xmm1 + movaps [rbp-0x70], xmm2 + movaps [rbp-0x80], xmm3 + movaps [rbp-0x90], xmm4 + movaps [rbp-0xA0], xmm5 + movaps [rbp-0xB0], xmm6 + movaps [rbp-0xC0], xmm7 + + mov rdi, rsi call _object_getClass - movq %rax, %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi + mov rdi, rax + lea rsi, [rip+sel_forwardingTargetForSelector_] call _class_respondsToSelector - testq %rax, %rax + test rax, rax jz 0f - movq -0x18(%rbp), %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi + mov rdi, [rbp-0x18] + lea rsi, [rip+sel_forwardingTargetForSelector_] call _objc_msg_lookup - movq -0x18(%rbp), %rdi - leaq sel_forwardingTargetForSelector_(%rip), %rsi - movq -0x20(%rbp), %rdx - call *%rax + mov rdi, [rbp-0x18] + lea rsi, [rip+sel_forwardingTargetForSelector_] + mov rdx, [rbp-0x20] + call rax - testq %rax, %rax + test rax, rax jz 0f - cmpq -0x18(%rbp), %rax + cmp rax, [rbp-0x18] je 0f - movq %rax, -0x18(%rbp) + mov [rbp-0x18], rax - movq %rax, %rdi - movq -0x20(%rbp), %rsi + mov rdi, rax + mov rsi, [rbp-0x20] call _objc_msg_lookup_stret - movq %rax, %r11 + mov r11, rax /* Restore all arguments */ - movaps -0xC0(%rbp), %xmm7 - movaps -0xB0(%rbp), %xmm6 - movaps -0xA0(%rbp), %xmm5 - movaps -0x90(%rbp), %xmm4 - movaps -0x80(%rbp), %xmm3 - movaps -0x70(%rbp), %xmm2 - movaps -0x60(%rbp), %xmm1 - movaps -0x50(%rbp), %xmm0 - movq -0x38(%rbp), %r9 - movq -0x30(%rbp), %r8 - movq -0x28(%rbp), %rcx - movq -0x20(%rbp), %rdx - movq -0x18(%rbp), %rsi - movq -0x10(%rbp), %rdi - movq -0x8(%rbp), %rax - - movq %rbp, %rsp - popq %rbp - - jmpq *%r11 + movaps xmm7, [rbp-0xC0] + movaps xmm6, [rbp-0xB0] + movaps xmm5, [rbp-0xA0] + movaps xmm4, [rbp-0x90] + movaps xmm3, [rbp-0x80] + movaps xmm2, [rbp-0x70] + movaps xmm1, [rbp-0x60] + movaps xmm0, [rbp-0x50] + mov r9, [rbp-0x38] + mov r8, [rbp-0x30] + mov rcx, [rbp-0x28] + mov rdx, [rbp-0x20] + mov rsi, [rbp-0x18] + mov rdi, [rbp-0x10] + mov rax, [rbp-0x08] + + mov rsp, rbp + pop rbp + + jmp r11 0: - movq -0x10(%rbp), %rdi - movq -0x18(%rbp), %rsi - movq -0x20(%rbp), %rdx + mov rdi, [rbp-0x10] + mov rsi, [rbp-0x18] + mov rdx, [rbp-0x20] - movq %rbp, %rsp - popq %rbp + mov rsp, rbp + pop rbp jmp _of_method_not_found_stret init: - leaq module(%rip), %rdi + lea rdi, [rip+module] jmp ___objc_exec_class .section __DATA, __mod_init_func, mod_init_funcs .quad init Index: src/forwarding/forwarding-x86_64-win64.S ================================================================== --- src/forwarding/forwarding-x86_64-win64.S +++ src/forwarding/forwarding-x86_64-win64.S @@ -15,160 +15,162 @@ * file. */ #include "config.h" +.intel_syntax noprefix + .globl of_forward .globl of_forward_stret .section .text of_forward: - pushq %rbp - movq %rsp, %rbp + push rbp + mov rbp, rsp /* Save all arguments */ - subq $0x90, %rsp /* 16-byte alignment */ - movq %rax, -0x28(%rbp) - movq %rcx, -0x30(%rbp) - movq %rdx, -0x38(%rbp) - movq %r8, -0x40(%rbp) - movq %r9, -0x48(%rbp) - movaps %xmm0, -0x60(%rbp) - movaps %xmm1, -0x70(%rbp) - movaps %xmm2, -0x80(%rbp) - movaps %xmm3, -0x90(%rbp) + sub rsp, 0x90 /* 16-byte alignment */ + mov [rbp-0x28], rax + mov [rbp-0x30], rcx + mov [rbp-0x38], rdx + mov [rbp-0x40], r8 + mov [rbp-0x48], r9 + movaps [rbp-0x60], xmm0 + movaps [rbp-0x70], xmm1 + movaps [rbp-0x80], xmm2 + movaps [rbp-0x90], xmm3 call object_getClass - movq %rax, %rcx - leaq sel_forwardingTargetForSelector_(%rip), %rdx + mov rcx, rax + mov rdx, offset sel_forwardingTargetForSelector_ call class_respondsToSelector - testq %rax, %rax - jz 0f - - movq -0x30(%rbp), %rcx - leaq sel_forwardingTargetForSelector_(%rip), %rdx - call objc_msg_lookup - - movq -0x30(%rbp), %rcx - leaq sel_forwardingTargetForSelector_(%rip), %rdx - movq -0x38(%rbp), %r8 - call *%rax - - testq %rax, %rax - jz 0f - cmpq -0x30(%rbp), %rax - je 0f - - movq %rax, -0x30(%rbp) - - movq %rax, %rcx - movq -0x38(%rbp), %rdx - call objc_msg_lookup - movq %rax, %r11 + test rax, rax + jz short 0f + + mov rcx, [rbp-0x30] + mov rdx, offset sel_forwardingTargetForSelector_ + call objc_msg_lookup + + mov rcx, [rbp-0x30] + mov rdx, offset sel_forwardingTargetForSelector_ + mov r8, [rbp-0x38] + call rax + + test rax, rax + jz short 0f + cmp rax, [rbp-0x30] + je short 0f + + mov [rbp-0x30], rax + + mov rcx, rax + mov rdx, [rbp-0x38] + call objc_msg_lookup + mov r11, rax /* Restore all arguments */ - movaps -0x90(%rbp), %xmm3 - movaps -0x80(%rbp), %xmm2 - movaps -0x70(%rbp), %xmm1 - movaps -0x60(%rbp), %xmm0 - movq -0x48(%rbp), %r9 - movq -0x40(%rbp), %r8 - movq -0x38(%rbp), %rdx - movq -0x30(%rbp), %rcx - movq -0x28(%rbp), %rax - - movq %rbp, %rsp - popq %rbp - - jmpq *%r11 + movaps xmm3, [rbp-0x90] + movaps xmm2, [rbp-0x80] + movaps xmm1, [rbp-0x70] + movaps xmm0, [rbp-0x60] + mov r9, [rbp-0x48] + mov r8, [rbp-0x40] + mov rdx, [rbp-0x38] + mov rcx, [rbp-0x30] + mov rax, [rbp-0x28] + + mov rsp, rbp + pop rbp + + jmp r11 0: - movq -0x30(%rbp), %rcx - movq -0x38(%rbp), %rdx + mov rcx, [rbp-0x30] + mov rdx, [rbp-0x38] - movq %rbp, %rsp - popq %rbp + mov rsp, rbp + pop rbp jmp of_method_not_found of_forward_stret: - pushq %rbp - movq %rsp, %rbp + push rbp + mov rbp, rsp /* Save all arguments */ - subq $0x90, %rsp /* 16-byte alignment */ - movq %rax, -0x28(%rbp) - movq %rcx, -0x30(%rbp) - movq %rdx, -0x38(%rbp) - movq %r8, -0x40(%rbp) - movq %r9, -0x48(%rbp) - movaps %xmm0, -0x60(%rbp) - movaps %xmm1, -0x70(%rbp) - movaps %xmm2, -0x80(%rbp) - movaps %xmm3, -0x90(%rbp) - - movq %rdx, %rcx + sub rsp, 0x90 /* 16-byte alignment */ + mov [rbp-0x28], rax + mov [rbp-0x30], rcx + mov [rbp-0x38], rdx + mov [rbp-0x40], r8 + mov [rbp-0x48], r9 + movaps [rbp-0x60], xmm0 + movaps [rbp-0x70], xmm1 + movaps [rbp-0x80], xmm2 + movaps [rbp-0x90], xmm3 + + mov rcx, rdx call object_getClass - movq %rax, %rcx - leaq sel_forwardingTargetForSelector_(%rip), %rdx + mov rcx, rax + mov rdx, offset sel_forwardingTargetForSelector_ call class_respondsToSelector - testq %rax, %rax - jz 0f + test rax, rax + jz short 0f - movq -0x38(%rbp), %rcx - leaq sel_forwardingTargetForSelector_(%rip), %rdx + mov rcx, [rbp-0x38] + mov rdx, offset sel_forwardingTargetForSelector_ call objc_msg_lookup - movq -0x38(%rbp), %rcx - leaq sel_forwardingTargetForSelector_(%rip), %rdx - movq -0x40(%rbp), %r8 - call *%rax - - testq %rax, %rax - jz 0f - cmpq -0x38(%rbp), %rax - je 0f - - movq %rax, -0x38(%rbp) - - movq %rax, %rcx - movq -0x40(%rbp), %rdx + mov rcx, [rbp-0x38] + mov rdx, offset sel_forwardingTargetForSelector_ + mov r8, [rbp-0x40] + call rax + + test rax, rax + jz short 0f + cmp rax, [rbp-0x38] + je short 0f + + mov [rbp-0x38], rax + + mov rcx, rax + mov rdx, [rbp-0x40] call objc_msg_lookup_stret - movq %rax, %r11 + mov r11, rax /* Restore all arguments */ - movaps -0x90(%rbp), %xmm3 - movaps -0x80(%rbp), %xmm2 - movaps -0x70(%rbp), %xmm1 - movaps -0x60(%rbp), %xmm0 - movq -0x48(%rbp), %r9 - movq -0x40(%rbp), %r8 - movq -0x38(%rbp), %rdx - movq -0x30(%rbp), %rcx - movq -0x28(%rbp), %rax - - movq %rbp, %rsp - popq %rbp - - jmpq *%r11 + movaps xmm3, [rbp-0x90] + movaps xmm2, [rbp-0x80] + movaps xmm1, [rbp-0x70] + movaps xmm0, [rbp-0x60] + mov r9, [rbp-0x48] + mov r8, [rbp-0x40] + mov rdx, [rbp-0x38] + mov rcx, [rbp-0x30] + mov rax, [rbp-0x28] + + mov rsp, rbp + pop rbp + + jmp r11 0: - movq -0x30(%rbp), %rcx - movq -0x38(%rbp), %rdx - movq -0x40(%rbp), %r8 + mov rcx, [rbp-0x30] + mov rdx, [rbp-0x38] + mov r8, [rbp-0x40] - movq %rbp, %rsp - popq %rbp + mov rsp, rbp + pop rbp jmp of_method_not_found_stret init: - leaq module(%rip), %rcx + mov rcx, offset module jmp __objc_exec_class .section .ctors, "aw" .quad init Index: src/forwarding/forwarding.S ================================================================== --- src/forwarding/forwarding.S +++ src/forwarding/forwarding.S @@ -45,10 +45,12 @@ # include "forwarding-powerpc-elf.S" # elif defined(OF_MIPS) # include "forwarding-mips-elf.S" # elif defined(OF_SPARC64) # include "forwarding-sparc64-elf.S" +# elif defined(OF_SPARC) +# include "forwarding-sparc-elf.S" # endif # elif defined(OF_MACH_O) # if defined(OF_X86_64) # include "forwarding-x86_64-macho.S" # endif Index: src/invocation/apple-call-x86_64.S ================================================================== --- src/invocation/apple-call-x86_64.S +++ src/invocation/apple-call-x86_64.S @@ -16,103 +16,105 @@ */ #include "config.h" #include "invoke-x86_64.h" + +.intel_syntax noprefix .globl _of_invocation_call .section __TEXT, __text, regular, pure_instructions _of_invocation_call: - pushq %rbp - movq %rsp, %rbp - - subq $16, %rsp - andq $-16, %rsp - movq %rdi, -8(%rbp) - - leaq OFFSET_STACK(%rdi), %rdx - movq OFFSET_STACK_SIZE(%rdi), %rcx - - testq $1, %rcx + push rbp + mov rbp, rsp + + sub rsp, 16 + and rsp, -16 + mov [rbp-8], rdi + + lea rdx, [rdi+OFFSET_STACK] + mov rcx, [rdi+OFFSET_STACK_SIZE] + + test rcx, 1 jnz Lfix_align Lfill_stack: - testq %rcx, %rcx + test rcx, rcx jz Lstack_filled - decq %rcx - movq (%rdx,%rcx,8), %r11 - pushq %r11 + dec rcx + mov r11, [rdx+rcx*8] + push r11 jmp Lfill_stack Lstack_filled: - movb OFFSET_NUM_SSE_USED(%rdi), %al - - movaps OFFSET_SSE_INOUT+112(%rdi), %xmm7 - movaps OFFSET_SSE_INOUT+96(%rdi), %xmm6 - movaps OFFSET_SSE_INOUT+80(%rdi), %xmm5 - movaps OFFSET_SSE_INOUT+64(%rdi), %xmm4 - movaps OFFSET_SSE_INOUT+48(%rdi), %xmm3 - movaps OFFSET_SSE_INOUT+32(%rdi), %xmm2 - movaps OFFSET_SSE_INOUT+16(%rdi), %xmm1 - movaps OFFSET_SSE_INOUT(%rdi), %xmm0 - - movq OFFSET_GPR_IN+40(%rdi), %r9 - movq OFFSET_GPR_IN+32(%rdi), %r8 - movq OFFSET_GPR_IN+24(%rdi), %rcx - movq OFFSET_GPR_IN+16(%rdi), %rdx - movq OFFSET_GPR_IN+8(%rdi), %rsi - - movb OFFSET_RETURN_TYPE(%rdi), %r11b - movq OFFSET_GPR_IN(%rdi), %rdi - - cmpb $RETURN_TYPE_STRET, %r11b + mov al, [rdi+OFFSET_NUM_SSE_USED] + + movaps xmm7, [rdi+OFFSET_SSE_INOUT+112] + movaps xmm6, [rdi+OFFSET_SSE_INOUT+96] + movaps xmm5, [rdi+OFFSET_SSE_INOUT+80] + movaps xmm4, [rdi+OFFSET_SSE_INOUT+64] + movaps xmm3, [rdi+OFFSET_SSE_INOUT+48] + movaps xmm2, [rdi+OFFSET_SSE_INOUT+32] + movaps xmm1, [rdi+OFFSET_SSE_INOUT+16] + movaps xmm0, [rdi+OFFSET_SSE_INOUT] + + mov r9, [rdi+OFFSET_GPR_IN+40] + mov r8, [rdi+OFFSET_GPR_IN+32] + mov rcx, [rdi+OFFSET_GPR_IN+24] + mov rdx, [rdi+OFFSET_GPR_IN+16] + mov rsi, [rdi+OFFSET_GPR_IN+8] + + mov r11b, [rdi+OFFSET_RETURN_TYPE] + mov rdi, [rdi+OFFSET_GPR_IN] + + cmp r11b, RETURN_TYPE_STRET je Lcall_send_stret - cmpb $RETURN_TYPE_JMP, %r11b + cmp r11b, RETURN_TYPE_JMP je _objc_msgSend - cmpb $RETURN_TYPE_JMP_STRET, %r11b + cmp r11b, RETURN_TYPE_JMP_STRET je _objc_msgSend_stret call _objc_msgSend Lafter_send: - movq -8(%rbp), %rdi - movq %rax, OFFSET_GPR_OUT(%rdi) - movq %rdx, OFFSET_GPR_OUT+8(%rdi) - movaps %xmm0, OFFSET_SSE_INOUT(%rdi) - movaps %xmm1, OFFSET_SSE_INOUT+16(%rdi) - - movb OFFSET_RETURN_TYPE(%rdi), %r11b - - cmpb $RETURN_TYPE_X87, %r11b + mov rdi, [rbp-8] + mov [rdi+OFFSET_GPR_OUT], rax + mov [rdi+OFFSET_GPR_OUT+8], rdx + movaps [rdi+OFFSET_SSE_INOUT], xmm0 + movaps [rdi+OFFSET_SSE_INOUT+16], xmm1 + + mov r11b, [rdi+OFFSET_RETURN_TYPE] + + cmp r11b, RETURN_TYPE_X87 je Lpop_long_double - cmpb $RETURN_TYPE_COMPLEX_X87, %r11b + cmp r11b, RETURN_TYPE_COMPLEX_X87 je Lpop_complex_long_double Lreturn: - movq %rbp, %rsp - popq %rbp + mov rsp, rbp + pop rbp ret Lfix_align: - xorq %r11, %r11 - pushq %r11 + xor r11, r11 + push r11 jmp Lfill_stack Lcall_send_stret: call _objc_msgSend_stret jmp Lafter_send Lpop_long_double: - fstpt OFFSET_X87_OUT(%rdi) + fstp tbyte ptr [rdi+OFFSET_X87_OUT] jmp Lreturn Lpop_complex_long_double: - fstpt OFFSET_X87_OUT(%rdi) - fstpt OFFSET_X87_OUT+16(%rdi) + fstp tbyte ptr [rdi+OFFSET_X87_OUT] + fstp tbyte ptr [rdi+OFFSET_X87_OUT+16] jmp Lreturn Index: src/invocation/call-x86_64-elf.S ================================================================== --- src/invocation/call-x86_64-elf.S +++ src/invocation/call-x86_64-elf.S @@ -16,125 +16,127 @@ */ #include "config.h" #include "invoke-x86_64.h" + +.intel_syntax noprefix .globl of_invocation_call .section .text of_invocation_call: - pushq %rbp - movq %rsp, %rbp - - subq $16, %rsp - andq $-16, %rsp - movq %rdi, -8(%rbp) - - movb OFFSET_RETURN_TYPE(%rdi), %r11b - cmpb $RETURN_TYPE_STRET, %r11b - je .lookup_stret - cmpb $RETURN_TYPE_JMP_STRET, %r11b - je .lookup_stret - - movq OFFSET_GPR_IN+8(%rdi), %rsi - movq OFFSET_GPR_IN+0(%rdi), %rdi + pushq rbp + mov rbp, rsp + + sub rsp, 16 + and rsp, -16 + mov [rbp-8], rdi + + mov r11b, [rdi+OFFSET_RETURN_TYPE] + cmp r11b, RETURN_TYPE_STRET + je short .Llookup_stret + cmp r11b, RETURN_TYPE_JMP_STRET + je short .Llookup_stret + + mov rsi, [rdi+OFFSET_GPR_IN+8] + mov rdi, [rdi+OFFSET_GPR_IN] call objc_msg_lookup@PLT -.after_lookup: - movq %rax, -16(%rbp) - movq -8(%rbp), %rdi - - leaq OFFSET_STACK(%rdi), %rdx - movq OFFSET_STACK_SIZE(%rdi), %rcx - - testq $1, %rcx - jnz .fix_align - -.fill_stack: - testq %rcx, %rcx - jz .stack_filled - - decq %rcx - movq (%rdx,%rcx,8), %r11 - pushq %r11 - - jmp .fill_stack - -.stack_filled: - movb OFFSET_NUM_SSE_USED(%rdi), %al - - movaps OFFSET_SSE_INOUT+112(%rdi), %xmm7 - movaps OFFSET_SSE_INOUT+96(%rdi), %xmm6 - movaps OFFSET_SSE_INOUT+80(%rdi), %xmm5 - movaps OFFSET_SSE_INOUT+64(%rdi), %xmm4 - movaps OFFSET_SSE_INOUT+48(%rdi), %xmm3 - movaps OFFSET_SSE_INOUT+32(%rdi), %xmm2 - movaps OFFSET_SSE_INOUT+16(%rdi), %xmm1 - movaps OFFSET_SSE_INOUT(%rdi), %xmm0 - - movq OFFSET_GPR_IN+40(%rdi), %r9 - movq OFFSET_GPR_IN+32(%rdi), %r8 - movq OFFSET_GPR_IN+24(%rdi), %rcx - movq OFFSET_GPR_IN+16(%rdi), %rdx - movq OFFSET_GPR_IN+8(%rdi), %rsi - - movb OFFSET_RETURN_TYPE(%rdi), %r11b - movq OFFSET_GPR_IN(%rdi), %rdi - - cmpb $RETURN_TYPE_JMP, %r11b - je .jmp_into_method - cmpb $RETURN_TYPE_JMP_STRET, %r11b - je .jmp_into_method - - movq -16(%rbp), %r11 - call *%r11 - -.after_send: - movq -8(%rbp), %rdi - movq %rax, OFFSET_GPR_OUT(%rdi) - movq %rdx, OFFSET_GPR_OUT+8(%rdi) - movaps %xmm0, OFFSET_SSE_INOUT(%rdi) - movaps %xmm1, OFFSET_SSE_INOUT+16(%rdi) - - movb OFFSET_RETURN_TYPE(%rdi), %r11b - - cmpb $RETURN_TYPE_X87, %r11b - je .pop_long_double - - cmpb $RETURN_TYPE_COMPLEX_X87, %r11b - je .pop_complex_long_double - -.return: - movq %rbp, %rsp - popq %rbp +.Lafter_lookup: + mov [rbp-16], rax + mov rdi, [rbp-8] + + lea rdx, [rdi+OFFSET_STACK] + mov rcx, [rdi+OFFSET_STACK_SIZE] + + test rcx, 1 + jnz short .Lfix_align + +.Lfill_stack: + test rcx, rcx + jz short .Lstack_filled + + dec rcx + mov r11, [rdx+rcx*8] + push r11 + + jmp short .Lfill_stack + +.Lstack_filled: + mov al, [rdi+OFFSET_NUM_SSE_USED] + + movaps xmm7, [rdi+OFFSET_SSE_INOUT+112] + movaps xmm6, [rdi+OFFSET_SSE_INOUT+96] + movaps xmm5, [rdi+OFFSET_SSE_INOUT+80] + movaps xmm4, [rdi+OFFSET_SSE_INOUT+64] + movaps xmm3, [rdi+OFFSET_SSE_INOUT+48] + movaps xmm2, [rdi+OFFSET_SSE_INOUT+32] + movaps xmm1, [rdi+OFFSET_SSE_INOUT+16] + movaps xmm0, [rdi+OFFSET_SSE_INOUT] + + mov r9, [rdi+OFFSET_GPR_IN+40] + mov r8, [rdi+OFFSET_GPR_IN+32] + mov rcx, [rdi+OFFSET_GPR_IN+24] + mov rdx, [rdi+OFFSET_GPR_IN+16] + mov rsi, [rdi+OFFSET_GPR_IN+8] + + mov r11b, [rdi+OFFSET_RETURN_TYPE] + mov rdi, [rdi+OFFSET_GPR_IN] + + cmp r11b, RETURN_TYPE_JMP + je short .Ljmp_into_method + cmp r11b, RETURN_TYPE_JMP_STRET + je short .Ljmp_into_method + + mov r11, [rbp-16] + call r11 + +.Lafter_send: + mov rdi, [rbp-8] + mov [rdi+OFFSET_GPR_OUT], rax + mov [rdi+OFFSET_GPR_OUT+8], rdx + movaps [rdi+OFFSET_SSE_INOUT], xmm0 + movaps [rdi+OFFSET_SSE_INOUT+16], xmm1 + + mov r11b, [rdi+OFFSET_RETURN_TYPE] + + cmp r11b, RETURN_TYPE_X87 + je short .Lpop_long_double + + cmp r11b, RETURN_TYPE_COMPLEX_X87 + je short .Lpop_complex_long_double + +.Lreturn: + mov rsp, rbp + pop rbp ret -.fix_align: - xorq %r11, %r11 - pushq %r11 - jmp .fill_stack - -.lookup_stret: - movq OFFSET_GPR_IN+16(%rdi), %rsi - movq OFFSET_GPR_IN+8(%rdi), %rdi +.Lfix_align: + xor r11, r11 + push r11 + jmp short .Lfill_stack + +.Llookup_stret: + mov rsi, [rdi+OFFSET_GPR_IN+16] + mov rdi, [rdi+OFFSET_GPR_IN+8] call objc_msg_lookup_stret@PLT - jmp .after_lookup - -.jmp_into_method: - movq -16(%rbp), %r11 - jmp *%r11 - -.pop_long_double: - fstpt OFFSET_X87_OUT(%rdi) - jmp .return - -.pop_complex_long_double: - fstpt OFFSET_X87_OUT(%rdi) - fstpt OFFSET_X87_OUT+16(%rdi) - jmp .return + jmp short .Lafter_lookup + +.Ljmp_into_method: + mov r11, [rbp-16] + jmp r11 + +.Lpop_long_double: + fstp tbyte ptr [rdi+OFFSET_X87_OUT] + jmp short .Lreturn + +.Lpop_complex_long_double: + fstp tbyte ptr [rdi+OFFSET_X87_OUT] + fstp tbyte ptr [rdi+OFFSET_X87_OUT+16] + jmp short .Lreturn #ifdef OF_LINUX .section .note.GNU-stack, "", %progbits #endif Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -306,10 +306,21 @@ #if __has_attribute(__swift_name__) # define OF_SWIFT_NAME(name) __attribute__((__swift_name__(name))) #else # define OF_SWIFT_NAME(name) #endif + +#if __has_attribute(__objc_direct__) && defined(OF_APPLE_RUNTIME) +# define OF_DIRECT __attribute__((__objc_direct__)) +#else +# define OF_DIRECT +#endif +#if __has_attribute(__objc_direct_members__) && defined(OF_APPLE_RUNTIME) +# define OF_DIRECT_MEMBERS __attribute__((__objc_direct_members__)) +#else +# define OF_DIRECT_MEMBERS +#endif #ifdef __GNUC__ # ifdef OF_X86_64 # define OF_X86_64_ASM # endif @@ -353,11 +364,11 @@ # endif #else # if defined(OF_ELF) # if defined(OF_X86_64) || defined(OF_X86) || \ defined(OF_ARM64) || defined(OF_ARM) || defined(OF_POWERPC) || \ - defined(OF_MIPS) || defined(OF_SPARC64) + defined(OF_MIPS) || defined(OF_SPARC64) || defined(OF_SPARC) # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR # if __OBJFW_RUNTIME_ABI__ >= 800 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET # endif # endif Index: src/runtime/lookup-asm/lookup-asm-sparc-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-sparc-elf.S +++ src/runtime/lookup-asm/lookup-asm-sparc-elf.S @@ -52,15 +52,20 @@ #endif ld [%o2 + %o4], %o2 ld [%o2 + %o5], %o2 cmp %o2, 0 - be \not_found + be 0f nop retl mov %o2, %o0 + +0: + mov %o7, %g1 + call \not_found + mov %g1, %o7 .type \name, %function .size \name, .-\name .endm .macro generate_lookup_super name lookup Index: src/runtime/lookup-asm/lookup-asm-x86-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-x86-elf.S +++ src/runtime/lookup-asm/lookup-asm-x86-elf.S @@ -17,63 +17,64 @@ #include "config.h" #include "platform.h" +.intel_syntax noprefix + .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro generate_lookup name not_found \name: - movl 4(%esp), %edx - testl %edx, %edx - jz ret_nil + mov edx, [esp+4] + test edx, edx + jz short ret_nil - movl (%edx), %edx - movl 32(%edx), %edx + mov edx, [edx] + mov edx, [edx+32] .Lmain_\name: - movl 8(%esp), %eax + mov eax, [esp+8] #ifdef OF_SELUID24 - movzbl 2(%eax), %ecx - movl (%edx,%ecx,4), %edx + movzx ecx, byte ptr [eax+2] + mov edx, [edx+ecx*4] #endif - movzbl 1(%eax), %ecx - movl (%edx,%ecx,4), %edx - movzbl (%eax), %ecx - movl (%edx,%ecx,4), %eax + movzx ecx, byte ptr [eax+1] + mov edx, [edx+ecx*4] + movzx ecx, byte ptr [eax] + mov eax, [edx+ecx*4] - testl %eax, %eax - jz 0f + test eax, eax + jz short 0f ret 0: call get_eip -1: - addl $_GLOBAL_OFFSET_TABLE_, %eax - movl \not_found@GOT(%eax), %eax - jmp *%eax + add eax, offset _GLOBAL_OFFSET_TABLE_ + lea eax, [eax+\not_found@GOTOFF] + jmp eax .type \name, %function .size \name, .-\name .endm .macro generate_lookup_super name lookup \name: - movl 4(%esp), %edx - movl (%edx), %eax - cmpl $0, %eax - je ret_nil - - movl %eax, 4(%esp) - movl 4(%edx), %edx - movl 32(%edx), %edx - jmp .Lmain_\lookup + mov edx, [esp+4] + mov eax, [edx] + test eax, eax + jz short ret_nil + + mov [esp+4], eax + mov edx, [edx+4] + mov edx, [edx+32] + jmp short .Lmain_\lookup .type \name, %function .size \name, .-\name .endm generate_lookup objc_msg_lookup objc_method_not_found @@ -81,20 +82,20 @@ generate_lookup_super objc_msg_lookup_super objc_msg_lookup generate_lookup_super objc_msg_lookup_super_stret objc_msg_lookup_stret ret_nil: call get_eip -0: - addl $nil_method-0b, %eax + add eax, offset _GLOBAL_OFFSET_TABLE_ + lea eax, [eax+nil_method@GOTOFF] ret nil_method: - xorl %eax, %eax + xor eax, eax ret get_eip: - movl (%esp), %eax + mov eax, [esp] ret #ifdef OF_LINUX .section .note.GNU-stack, "", %progbits #endif Index: src/runtime/lookup-asm/lookup-asm-x86-win32.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-x86-win32.S +++ src/runtime/lookup-asm/lookup-asm-x86-win32.S @@ -14,76 +14,69 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" + +.intel_syntax noprefix .globl _objc_msg_lookup .globl _objc_msg_lookup_stret .globl _objc_msg_lookup_super .globl _objc_msg_lookup_super_stret .section .text .macro generate_lookup name not_found \name: - movl 4(%esp), %edx - testl %edx, %edx - jz ret_nil + mov edx, [esp+4] + test edx, edx + jz short ret_nil - movl (%edx), %edx - movl 32(%edx), %edx + mov edx, [edx] + mov edx, [edx+32] .Lmain_\name: - movl 8(%esp), %eax + mov eax, [esp+8] #ifdef OF_SELUID24 - movzbl 2(%eax), %ecx - movl (%edx,%ecx,4), %edx + movzx ecx, byte ptr [eax+2] + mov edx, [edx+ecx*4] #endif - movzbl 1(%eax), %ecx - movl (%edx,%ecx,4), %edx - movzbl (%eax), %ecx - movl (%edx,%ecx,4), %eax + movzx ecx, byte ptr [eax+1] + mov edx, [edx+ecx*4] + movzx ecx, byte ptr [eax] + mov eax, [edx+ecx*4] - testl %eax, %eax - jz 0f + test eax, eax + jz short 0f ret 0: - call get_eip -1: - addl $\not_found-1b, %eax - jmp *%eax + jmp \not_found .endm .macro generate_lookup_super name lookup \name: - movl 4(%esp), %edx - movl (%edx), %eax - cmpl $0, %eax - je ret_nil - - movl %eax, 4(%esp) - movl 4(%edx), %edx - movl 32(%edx), %edx - jmp .Lmain_\lookup + mov edx, [esp+4] + mov eax, [edx] + test eax, eax + jz short ret_nil + + mov [esp+4], eax + mov edx, [edx+4] + mov edx, [edx+32] + jmp short .Lmain_\lookup .endm generate_lookup _objc_msg_lookup _objc_method_not_found generate_lookup _objc_msg_lookup_stret _objc_method_not_found_stret generate_lookup_super _objc_msg_lookup_super _objc_msg_lookup generate_lookup_super _objc_msg_lookup_super_stret _objc_msg_lookup_stret ret_nil: - call get_eip -0: - addl $nil_method-0b, %eax + mov eax, offset nil_method ret nil_method: - xorl %eax, %eax - ret - -get_eip: - movl (%esp), %eax + xor eax, eax ret Index: src/runtime/lookup-asm/lookup-asm-x86_64-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-x86_64-elf.S +++ src/runtime/lookup-asm/lookup-asm-x86_64-elf.S @@ -17,54 +17,56 @@ #include "config.h" #include "platform.h" +.intel_syntax noprefix + .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro generate_lookup name not_found \name: - testq %rdi, %rdi - jz ret_nil + test rdi, rdi + jz short ret_nil - movq (%rdi), %r8 - movq 64(%r8), %r8 + mov r8, [rdi] + mov r8, [r8+64] .Lmain_\name: - movq (%rsi), %rax - movzbl %ah, %ecx - movzbl %al, %edx + mov rax, [rsi] + movzx ecx, ah + movzx edx, al #ifdef OF_SELUID24 - shrl $16, %eax + shr eax, 16 - movq (%r8,%rax,8), %r8 + mov r8, [r8+rax*8] #endif - movq (%r8,%rcx,8), %r8 - movq (%r8,%rdx,8), %rax + mov r8, [r8+rcx*8] + mov rax, [r8+rdx*8] - testq %rax, %rax - jz \not_found@PLT + test rax, rax + jz short \not_found@PLT ret .type \name, %function .size \name, .-\name .endm .macro generate_lookup_super name lookup \name: - movq %rdi, %r8 - movq (%rdi), %rdi - testq %rdi, %rdi - jz ret_nil - - movq 8(%r8), %r8 - movq 64(%r8), %r8 - jmp .Lmain_\lookup + mov r8, rdi + mov rdi, [rdi] + test rdi, rdi + jz short ret_nil + + mov r8, [r8+8] + mov r8, [r8+64] + jmp short .Lmain_\lookup .type \name, %function .size \name, .-\name .endm generate_lookup objc_msg_lookup objc_method_not_found @@ -71,15 +73,15 @@ generate_lookup objc_msg_lookup_stret objc_method_not_found_stret generate_lookup_super objc_msg_lookup_super objc_msg_lookup generate_lookup_super objc_msg_lookup_super_stret objc_msg_lookup_stret ret_nil: - leaq nil_method(%rip), %rax + lea rax, [rip+nil_method] ret nil_method: - xorq %rax, %rax + xor rax, rax ret #ifdef OF_LINUX .section .note.GNU-stack, "", %progbits #endif Index: src/runtime/lookup-asm/lookup-asm-x86_64-macho.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-x86_64-macho.S +++ src/runtime/lookup-asm/lookup-asm-x86_64-macho.S @@ -14,62 +14,64 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" + +.intel_syntax noprefix .globl _objc_msg_lookup .globl _objc_msg_lookup_stret .globl _objc_msg_lookup_super .globl _objc_msg_lookup_super_stret .section __TEXT, __text, regular, pure_instructions .macro generate_lookup $0: - testq %rdi, %rdi + test rdi, rdi jz ret_nil - movq (%rdi), %r8 - movq 64(%r8), %r8 + mov r8, [rdi] + mov r8, [r8+64] Lmain_$0: - movq (%rsi), %rax - movzbl %ah, %ecx - movzbl %al, %edx + mov rax, [rsi] + movzx ecx, ah + movzx edx, al #ifdef OF_SELUID24 - shrl $$16, %eax + shr eax, 16 - movq (%r8,%rax,8), %r8 + mov r8, [r8+rax*8] #endif - movq (%r8,%rcx,8), %r8 - movq (%r8,%rdx,8), %rax + mov r8, [r8+rcx*8] + mov rax, [r8+rdx*8] - testq %rax, %rax + test rax, rax jz $1 ret .endmacro .macro generate_lookup_super $0: - movq %rdi, %r8 - movq (%rdi), %rdi - testq %rdi, %rdi + mov r8, rdi + mov rdi, [rdi] + test rdi, rdi jz ret_nil - movq 8(%r8), %r8 - movq 64(%r8), %r8 + mov r8, [r8+8] + mov r8, [r8+64] jmp Lmain_$1 .endmacro generate_lookup _objc_msg_lookup, _objc_method_not_found generate_lookup _objc_msg_lookup_stret, _objc_method_not_found_stret generate_lookup_super _objc_msg_lookup_super, _objc_msg_lookup generate_lookup_super _objc_msg_lookup_super_stret, _objc_msg_lookup_stret ret_nil: - leaq nil_method(%rip), %rax + lea rax, [rip+nil_method] ret nil_method: - movq %rdi, %rax + mov rax, rdi ret Index: src/runtime/lookup-asm/lookup-asm-x86_64-win64.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-x86_64-win64.S +++ src/runtime/lookup-asm/lookup-asm-x86_64-win64.S @@ -15,69 +15,71 @@ * file. */ #include "config.h" +.intel_syntax noprefix + .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro generate_lookup name not_found \name: - testq %rcx, %rcx - jz ret_nil + test %rcx, %rcx + jz short ret_nil - movq (%rcx), %r8 - movq 56(%r8), %r8 + mov r8, [rcx] + mov r8, [r8+56] .Lmain_\name: - movq %rcx, %r10 - movq %rdx, %r11 + mov r10, rcx + mov r11, rdx - movq (%rdx), %rax - movzbl %ah, %ecx - movzbl %al, %edx + mov rax, [rdx] + movzx ecx, ah + movzx edx, al #ifdef OF_SELUID24 - shrl $16, %eax + shr eax, 16 - movq (%r8,%rax,8), %r8 + mov r8, [r8+rax*8] #endif - movq (%r8,%rcx,8), %r8 - movq (%r8,%rdx,8), %rax + mov r8, [r8+rcx*8] + mov rax, [r8+rdx*8] - testq %rax, %rax - jz 0f + test rax, rax + jz short 0f ret 0: - movq %r10, %rcx - movq %r11, %rdx + mov rcx, r10 + mov rdx, r11 jmp \not_found .endm .macro generate_lookup_super name lookup \name: - movq %rcx, %r8 - movq (%rcx), %rcx - testq %rcx, %rcx - jz ret_nil - - movq 8(%r8), %r8 - movq 56(%r8), %r8 - jmp .Lmain_\lookup + mov r8, rcx + mov rcx, [rcx] + test rcx, rcx + jz short ret_nil + + mov r8, [r8+8] + mov r8, [r8+56] + jmp short .Lmain_\lookup .endm generate_lookup objc_msg_lookup objc_method_not_found generate_lookup objc_msg_lookup_stret objc_method_not_found_stret generate_lookup_super objc_msg_lookup_super objc_msg_lookup generate_lookup_super objc_msg_lookup_super_stret objc_msg_lookup_stret ret_nil: - leaq nil_method(%rip), %rax + mov rax, offset nil_method ret nil_method: - xorq %rax, %rax + xor rax, rax ret Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -213,26 +213,24 @@ - (void)outputSuccess: (OFString *)test inModule: (OFString *)module { if (of_stdout.hasTerminal) { - of_stdout.cursorColumn = 0; of_stdout.foregroundColor = [OFColor lime]; [of_stdout eraseLine]; - [of_stdout writeFormat: @"[%@] %@: ok\n", module, test]; + [of_stdout writeFormat: @"\r[%@] %@: ok\n", module, test]; } else [of_stdout writeLine: @"ok"]; } - (void)outputFailure: (OFString *)test inModule: (OFString *)module { if (of_stdout.hasTerminal) { - of_stdout.cursorColumn = 0; of_stdout.foregroundColor = [OFColor red]; [of_stdout eraseLine]; - [of_stdout writeFormat: @"[%@] %@: failed\n", module, test]; + [of_stdout writeFormat: @"\r[%@] %@: failed\n", module, test]; #ifdef OF_WII [of_stdout reset]; [of_stdout writeLine: @"Press A to continue!"]; @@ -285,11 +283,11 @@ gspWaitForVBlank(); } #endif - of_stdout.cursorColumn = 0; + [of_stdout writeString: @"\r"]; [of_stdout reset]; [of_stdout eraseLine]; } else [of_stdout writeLine: @"failed"]; }