Index: .github/ISSUE_TEMPLATE/config.yml ================================================================== --- .github/ISSUE_TEMPLATE/config.yml +++ .github/ISSUE_TEMPLATE/config.yml @@ -13,9 +13,24 @@ about: Please use this if you have questions or want support. - name: ObjFW Matrix Room url: https://matrix.to/#/%23objfw:nil.im about: Please use this for interactive questions and support. - name: ObjFW IRC Channel - url: https://webchat.freenode.net/?channels=objfw + url: https://webchat.oftc.net/?channels=%23objfw + about: + Please use this for interactive questions and support - it is bridged to + the Matrix room above. + - name: ObjFW Slack Channel + url: https://objfw.nil.im/slack + about: + Please use this for interactive questions and support - it is bridged to + the Matrix room above. + - name: ObjFW Discord Channel + url: https://objfw.nil.im/discord + about: + Please use this for interactive questions and support - it is bridged to + the Matrix room above. + - name: ObjFW Telegram Room + url: https://t.me/objfw about: Please use this for interactive questions and support - it is bridged to the Matrix room above. Index: PLATFORMS.md ================================================================== --- PLATFORMS.md +++ PLATFORMS.md @@ -96,15 +96,14 @@ MorphOS ------- - * OS Versions: 3.9-3.11 + * OS Versions: 3.14 * Architectures: PowerPC - * Compilers: GCC 5.3.0, GCC 5.4.0 + * Compilers: GCC 9.3.0 * Runtimes: ObjFW - * Notes: libnix and ixemul are both supported NetBSD ------ Index: README.md ================================================================== --- README.md +++ README.md @@ -336,11 +336,11 @@ In order to build the documentation yourself (necessary to have documentation for trunk / master), you need to have [Doxygen](https://www.doxygen.nl) installed. Once installed, you can build the documentation from the root directory of the repository: - $ doxygen >/dev/null + $ make docs

Bugs and feature requests

If you find any bugs or have feature requests, please @@ -354,14 +354,19 @@ If you have any questions about ObjFW or would like to talk to other ObjFW users, the following venues are available: * The [forum](https://objfw.nil.im/forum) - * A [Matrix](https://matrix.to/#/%23objfw:nil.im) room - * An [IRC channel](irc://chat.freenode.net/#objfw) on Freenode (`#objfw`, - [web chat](https://webchat.freenode.net/?channels=objfw)), bridged to the + * A [Matrix room](https://matrix.to/#/%23objfw:nil.im) + * An IRC channel named `#objfw` on `irc.oftc.net` + ([Web chat](https://webchat.oftc.net/?channels=%23objfw)), bridged to the Matrix room above + * A [Slack channel](https://objfw.nil.im/slack), bridged to the Matrix room + above + * A [Discord channel](https://objfw.nil.im/discord), bridged to the Matrix + room above + * A [Telegram room](https://t.me/objfw), bridged to the Matrix room above Please don't hesitate to join any or all of those!

Commercial use

Index: build-aux/m4/buildsys.m4 ================================================================== --- build-aux/m4/buildsys.m4 +++ build-aux/m4/buildsys.m4 @@ -47,11 +47,22 @@ [AC_SUBST(DEP_OBJCXXFLAGS, '-MD -MF $${out%.o}.dep')]) AC_SUBST(AMIGA_LIB_CFLAGS) AC_SUBST(AMIGA_LIB_LDFLAGS) - AC_PATH_PROG(TPUT, tput) + case "$build_os" in + morphos*) + dnl Don't use tput on MorphOS: The colored + dnl output is quite unreadable and in some + dnl MorphOS versions, the output from tput is + dnl not 8-bit safe, with awk (for AC_SUBST) + dnl failing as a result. + ;; + *) + AC_PATH_PROG(TPUT, tput) + ;; + esac AS_IF([test x"$TPUT" != x""], [ if x=$($TPUT el 2>/dev/null); then AC_SUBST(TERM_EL, "$x") else @@ -307,10 +318,11 @@ FRAMEWORK_LDFLAGS_INSTALL_NAME='-Wl,-install_name,@executable_path/../Frameworks/$$out/$${out%.framework}' ]) AC_SUBST(FRAMEWORK_LDFLAGS) AC_SUBST(FRAMEWORK_LDFLAGS_INSTALL_NAME) + AC_SUBST(FRAMEWORK_LIBS) $1 ;; esac ]) Index: buildsys.mk.in ================================================================== --- buildsys.mk.in +++ buildsys.mk.in @@ -61,10 +61,11 @@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PLUGIN_SUFFIX = @PLUGIN_SUFFIX@ FRAMEWORK_LDFLAGS = @FRAMEWORK_LDFLAGS@ FRAMEWORK_LDFLAGS_INSTALL_NAME = @FRAMEWORK_LDFLAGS_INSTALL_NAME@ +FRAMEWORK_LIBS = @FRAMEWORK_LIBS@ CODESIGN = @CODESIGN@ CODESIGN_IDENTITY ?= - CLEAN_LIB = @CLEAN_LIB@ DEP_ASFLAGS = @DEP_ASFLAGS@ DEP_CFLAGS = @DEP_CFLAGS@ Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -103,11 +103,10 @@ AC_SUBST(LIBBASES_M, libbases.m) ]) enable_shared="no" - enable_threads="no" ;; *-msdosdjgpp*) enable_shared="no" enable_threads="no" enable_sockets="no" @@ -150,11 +149,21 @@ : ${GREP:=grep.exe} : ${RANLIB:=ranlib.exe} ]) AC_LANG([Objective C]) -AC_PROG_OBJC([clang egcc gcc]) +case "$host_os" in + morphos*) + dnl Don't use clang on MorphOS - it does not support baserel, + dnl which is required for the .library. + potential_compilers="gcc" + ;; + *) + potential_compilers="clang egcc gcc" + ;; +esac +AC_PROG_OBJC($potential_compilers) AC_PROG_OBJCPP AC_PROG_LN_S AC_PROG_INSTALL AC_PROG_EGREP @@ -365,17 +374,13 @@ AS_HELP_STRING([--disable-shared], [do not build shared library])) AS_IF([test x"$enable_shared" != x"no"], [ BUILDSYS_SHARED_LIB AC_SUBST(OBJFW_SHARED_LIB, "${LIB_PREFIX}objfw${LIB_SUFFIX}") AC_SUBST(EXCEPTIONS_LIB_A, "exceptions.lib.a") - AC_SUBST(EXCEPTIONS_EXCEPTIONS_LIB_A, "exceptions/exceptions.lib.a") AC_SUBST(FORWARDING_LIB_A, "forwarding.lib.a") - AC_SUBST(FORWARDING_FORWARDING_LIB_A, "forwarding/forwarding.lib.a") AC_SUBST(INVOCATION_LIB_A, "invocation.lib.a") - AC_SUBST(INVOCATION_INVOCATION_LIB_A, "invocation/invocation.lib.a") AC_SUBST(LOOKUP_ASM_LIB_A, "lookup-asm.lib.a") - AC_SUBST(LOOKUP_ASM_LOOKUP_ASM_LIB_A, "lookup-asm/lookup-asm.lib.a") BUILDSYS_FRAMEWORK([ AC_SUBST(OBJFW_FRAMEWORK, "ObjFW.framework") build_framework="yes" ]) @@ -403,25 +408,31 @@ TESTS_LIBS="\${OBJFW_LIBS} \${RUNTIME_LIBS} $TESTS_LIBS" TESTS_LIBS="-L../src/runtime -L../src/runtime/linklib $TESTS_LIBS" TESTS_LIBS="-L../src -L../src/linklib $TESTS_LIBS" ]) -AS_IF([test x"$enable_shared" = x"no" -a x"$enable_amiga_lib" = x"no"], [ - enable_static="yes" +AC_ARG_ENABLE(amiga-lib, + AS_HELP_STRING([--disable-amiga-lib], [do not build Amiga library])) +AS_IF([test x"$supports_amiga_lib" != x"yes"], [enable_amiga_lib="no"]) +AS_IF([test x"$enable_amiga_lib" != x"no"], [ + AC_SUBST(OBJFW_STATIC_LIB, "libobjfw.a") + AC_SUBST(EXCEPTIONS_A, "exceptions.a") + AC_SUBST(FORWARDING_A, "forwarding.a") + AC_SUBST(INVOCATION_A, "invocation.a") + AC_SUBST(LOOKUP_ASM_AMIGALIB_A, "lookup-asm.amigalib.a") ]) AC_ARG_ENABLE(static, AS_HELP_STRING([--enable-static], [build static library])) -AS_IF([test x"$enable_static" = x"yes" -o x"$enable_amiga_lib" != x"no"], [ +AS_IF([test x"$enable_shared" = x"no" -a x"$enable_amiga_lib" = x"no"], [ + enable_static="yes" +]) +AS_IF([test x"$enable_static" = x"yes"], [ AC_SUBST(OBJFW_STATIC_LIB, "libobjfw.a") AC_SUBST(EXCEPTIONS_A, "exceptions.a") - AC_SUBST(EXCEPTIONS_EXCEPTIONS_A, "exceptions/exceptions.a") AC_SUBST(FORWARDING_A, "forwarding.a") - AC_SUBST(FORWARDING_FORWARDING_A, "forwarding/forwarding.a") AC_SUBST(INVOCATION_A, "invocation.a") - AC_SUBST(INVOCATION_INVOCATION_A, "invocation/invocation.a") AC_SUBST(LOOKUP_ASM_A, "lookup-asm.a") - AC_SUBST(LOOKUP_ASM_LOOKUP_ASM_A, "lookup-asm/lookup-asm.a") ]) AS_IF([test x"$enable_amiga_lib" != x"no"], [ AC_SUBST(EXCEPTIONS_AMIGALIB_A, "exceptions.amigalib.a") AC_SUBST(EXCEPTIONS_EXCEPTIONS_AMIGALIB_A, @@ -1079,14 +1090,18 @@ case "$host" in aarch64*-*-android*) # Compiler TLS is broken on AArch64 Android with Clang enable_compiler_tls="no" ;; - m68k-*-amigaos | powerpc-*-amigaos) + m68k-*-amigaos* | powerpc-*-amigaos*) # Compiler TLS is broken on AmigaOS enable_compiler_tls="no" ;; + *-*-morphos*) + # Compiler TLS needs helpers that we don't want in the + # .library + enable_compiler_tls="no" esac AS_IF([test x"$enable_compiler_tls" != x"no"], [ AC_CHECK_HEADER(threads.h, [ AC_DEFINE(OF_HAVE_THREADS_H, 1, @@ -1349,19 +1364,13 @@ ]) AC_CHECK_HEADERS(sys/utsname.h) AC_CHECK_FUNCS(uname) -case "$host_os" in - amigaos*) - ;; - *) - AC_CHECK_FUNC(pipe, [ - AC_DEFINE(OF_HAVE_PIPE, 1, [Whether we have pipe()]) - ]) - ;; -esac +AC_CHECK_FUNC(pipe, [ + AC_DEFINE(OF_HAVE_PIPE, 1, [Whether we have pipe()]) +]) AC_ARG_ENABLE(sockets, AS_HELP_STRING([--disable-sockets], [disable socket support])) AS_IF([test x"$enable_sockets" != x"no"], [ AC_DEFINE(OF_HAVE_SOCKETS, 1, [Whether we have sockets]) @@ -1602,18 +1611,34 @@ ]) CHECK_BUILTIN_BSWAP(16) CHECK_BUILTIN_BSWAP(32) CHECK_BUILTIN_BSWAP(64) -case "$host" in - arm*-apple-darwin*) - have_processes="no" +case "$host_os" in + darwin*) + AC_MSG_CHECKING(whether we are compiling for macOS) + AC_EGREP_CPP(egrep_cpp_yes, [ + #include + + #if (!defined(TARGET_OS_IPHONE) || \ + !TARGET_OS_IPHONE) && \ + (!defined(TARGET_OS_SIMULATOR) || \ + !TARGET_OS_SIMULATOR) + egrep_cpp_yes + #endif + ], [ + AC_MSG_RESULT(yes) + have_processes="yes" + ], [ + AC_MSG_RESULT(no) + have_processes="no" + ]) ;; - *-*-mingw*) + mingw*) have_processes="yes" ;; - *-*-msdosdjgpp*) + msdosdjgpp*) have_processes="no" ;; *) AC_HEADER_SYS_WAIT AC_CHECK_FUNCS(kill) Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -29,26 +29,17 @@ ENCODINGS_ENCODINGS_LIB_A = @ENCODINGS_ENCODINGS_LIB_A@ ENCODINGS_LIB_A = @ENCODINGS_LIB_A@ ENCODINGS_SRCS = @ENCODINGS_SRCS@ EXCEPTIONS_A = @EXCEPTIONS_A@ EXCEPTIONS_AMIGALIB_A = @EXCEPTIONS_AMIGALIB_A@ -EXCEPTIONS_EXCEPTIONS_A = @EXCEPTIONS_EXCEPTIONS_A@ -EXCEPTIONS_EXCEPTIONS_AMIGALIB_A = @EXCEPTIONS_EXCEPTIONS_AMIGALIB_A@ -EXCEPTIONS_EXCEPTIONS_LIB_A = @EXCEPTIONS_EXCEPTIONS_LIB_A@ EXCEPTIONS_LIB_A = @EXCEPTIONS_LIB_A@ FISH_COMPLETIONS = @FISH_COMPLETIONS@ FORWARDING_A = @FORWARDING_A@ FORWARDING_AMIGALIB_A = @FORWARDING_AMIGALIB_A@ -FORWARDING_FORWARDING_A = @FORWARDING_FORWARDING_A@ -FORWARDING_FORWARDING_AMIGALIB_A = @FORWARDING_FORWARDING_AMIGALIB_A@ -FORWARDING_FORWARDING_LIB_A = @FORWARDING_FORWARDING_LIB_A@ FORWARDING_LIB_A = @FORWARDING_LIB_A@ INVOCATION_A = @INVOCATION_A@ INVOCATION_AMIGALIB_A = @INVOCATION_AMIGALIB_A@ -INVOCATION_INVOCATION_A = @INVOCATION_INVOCATION_A@ -INVOCATION_INVOCATION_AMIGALIB_A = @INVOCATION_INVOCATION_AMIGALIB_A@ -INVOCATION_INVOCATION_LIB_A = @INVOCATION_INVOCATION_LIB_A@ INVOCATION_LIB_A = @INVOCATION_LIB_A@ LIBBASES_M = @LIBBASES_M@ LIBOBJFWRT_DEP = @LIBOBJFWRT_DEP@ LIBOBJFWRT_DEP_LVL2 = @LIBOBJFWRT_DEP_LVL2@ LIBOBJFW_DEP = @LIBOBJFW_DEP@ @@ -55,13 +46,10 @@ LIBOBJFW_DEP_LVL2 = @LIBOBJFW_DEP_LVL2@ LINKLIB = @LINKLIB@ LOOKUP_ASM_A = @LOOKUP_ASM_A@ LOOKUP_ASM_AMIGALIB_A = @LOOKUP_ASM_AMIGALIB_A@ LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@ -LOOKUP_ASM_LOOKUP_ASM_A = @LOOKUP_ASM_LOOKUP_ASM_A@ -LOOKUP_ASM_LOOKUP_ASM_AMIGALIB_A = @LOOKUP_ASM_LOOKUP_ASM_AMIGALIB_A@ -LOOKUP_ASM_LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LOOKUP_ASM_LIB_A@ MAP_LDFLAGS = @MAP_LDFLAGS@ OBJFW_LIBS = @OBJFW_LIBS@ OFARC = @OFARC@ OFDNS = @OFDNS@ OFHASH = @OFHASH@ Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -237,26 +237,24 @@ ${OF_KQUEUE_KERNEL_EVENT_OBSERVER_M} \ ${OF_POLL_KERNEL_EVENT_OBSERVER_M} \ ${OF_SELECT_KERNEL_EVENT_OBSERVER_M} \ OFTCPSocketSOCKS5Connector.m -OBJS_EXTRA = ${RUNTIME_RUNTIME_A} \ - ${EXCEPTIONS_EXCEPTIONS_A} \ - ${ENCODINGS_ENCODINGS_A} \ - ${FORWARDING_FORWARDING_A} \ - ${INVOCATION_INVOCATION_A} -LIB_OBJS_EXTRA = ${RUNTIME_RUNTIME_LIB_A} \ - ${EXCEPTIONS_EXCEPTIONS_LIB_A} \ - ${ENCODINGS_ENCODINGS_LIB_A} \ - ${FORWARDING_FORWARDING_LIB_A} \ - ${INVOCATION_INVOCATION_LIB_A} +OBJS_EXTRA = exceptions/exceptions.a \ + encodings/encodings.a \ + forwarding/forwarding.a \ + invocation/invocation.a +LIB_OBJS_EXTRA = exceptions/exceptions.lib.a \ + encodings/encodings.lib.a \ + forwarding/forwarding.lib.a \ + invocation/invocation.lib.a AMIGA_LIB_OBJS_START = amiga-library.amigalib.o -AMIGA_LIB_OBJS_EXTRA = amiga-glue.amigalib.o \ - ${EXCEPTIONS_EXCEPTIONS_AMIGALIB_A} \ - ${ENCODINGS_ENCODINGS_AMIGALIB_A} \ - ${FORWARDING_FORWARDING_AMIGALIB_A} \ - ${INVOCATION_INVOCATION_AMIGALIB_A} \ +AMIGA_LIB_OBJS_EXTRA = amiga-glue.amigalib.o \ + exceptions/exceptions.amigalib.a \ + encodings/encodings.amigalib.a \ + forwarding/forwarding.amigalib.a \ + invocation/invocation.amigalib.a \ amiga-end.amigalib.o include ../buildsys.mk ${OBJFW_AMIGA_LIB}: inline.h Index: src/OFApplication.m ================================================================== --- src/OFApplication.m +++ src/OFApplication.m @@ -94,11 +94,12 @@ if ([delegate respondsToSelector: @selector(applicationWillTerminate)]) [delegate applicationWillTerminate]; [delegate release]; -#if defined(OF_HAVE_THREADS) && defined(OF_HAVE_SOCKETS) && defined(OF_AMIGAOS) +#if defined(OF_HAVE_THREADS) && defined(OF_HAVE_SOCKETS) && \ + defined(OF_AMIGAOS) && !defined(OF_MORPHOS) of_socket_deinit(); #endif } int @@ -258,11 +259,11 @@ "variable: %s\n", tmp.UTF8String); continue; } key = [tmp substringToIndex: pos]; - value = [tmp substringFromRange: pos + 1]; + value = [tmp substringFromIndex: pos + 1]; [_environment setObject: value forKey: key]; objc_autoreleasePoolPop(pool); Index: src/OFBitSetCharacterSet.m ================================================================== --- src/OFBitSetCharacterSet.m +++ src/OFBitSetCharacterSet.m @@ -38,18 +38,19 @@ size_t length = string.length; for (size_t i = 0; i < length; i++) { of_unichar_t c = characters[i]; - if (c / 8 >= _size) { + if (c / CHAR_BIT >= _size) { size_t newSize; if (UINT32_MAX - c < 1) @throw [OFOutOfRangeException exception]; - newSize = OF_ROUND_UP_POW2(8, c + 1) / 8; + newSize = OF_ROUND_UP_POW2(CHAR_BIT, c + 1) / + CHAR_BIT; _bitset = of_realloc(_bitset, newSize, 1); memset(_bitset + _size, '\0', newSize - _size); _size = newSize; @@ -74,11 +75,11 @@ [super dealloc]; } - (bool)characterIsMember: (of_unichar_t)character { - if (character / 8 >= _size) + if (character / CHAR_BIT >= _size) return false; return of_bitset_isset(_bitset, character); } @end Index: src/OFFileURLHandler.m ================================================================== --- src/OFFileURLHandler.m +++ src/OFFileURLHandler.m @@ -735,16 +735,16 @@ modificationDate.timeIntervalSince1970; struct timeval times[2] = { { .tv_sec = (time_t)lastAccessTime, .tv_usec = - (int)((lastAccessTime - times[0].tv_sec) * 1000) + (int)((lastAccessTime - times[0].tv_sec) * 1000000) }, { .tv_sec = (time_t)modificationTime, - .tv_usec = - (int)((modificationTime - times[1].tv_sec) * 1000) + .tv_usec = (int)((modificationTime - times[1].tv_sec) * + 1000000) }, }; if (utimes([path cStringWithEncoding: [OFLocale encoding]], times) != 0) @throw [OFSetItemAttributesFailedException Index: src/OFKernelEventObserver.h ================================================================== --- src/OFKernelEventObserver.h +++ src/OFKernelEventObserver.h @@ -122,15 +122,15 @@ OFMutableArray OF_GENERIC(id ) *_readObjects; OFMutableArray OF_GENERIC(id ) *_writeObjects; id _Nullable _delegate; -#if defined(OF_HAVE_PIPE) - int _cancelFD[2]; -#elif defined(OF_AMIGAOS) +#if defined(OF_AMIGAOS) struct Task *_waitingTask; ULONG _cancelSignal; +#elif defined(OF_HAVE_PIPE) + int _cancelFD[2]; #else of_socket_t _cancelFD[2]; struct sockaddr_in _cancelAddr; #endif #ifdef OF_AMIGAOS Index: src/OFKernelEventObserver.m ================================================================== --- src/OFKernelEventObserver.m +++ src/OFKernelEventObserver.m @@ -113,11 +113,11 @@ #endif _readObjects = [[OFMutableArray alloc] init]; _writeObjects = [[OFMutableArray alloc] init]; -#if defined(OF_HAVE_PIPE) +#if defined(OF_HAVE_PIPE) && !defined(OF_AMIGAOS) if (pipe(_cancelFD)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; #elif !defined(OF_AMIGAOS) _cancelFD[0] = _cancelFD[1] = socket(AF_INET, SOCK_DGRAM, 0); @@ -174,11 +174,11 @@ return self; } - (void)dealloc { -#if defined(OF_HAVE_PIPE) +#if defined(OF_HAVE_PIPE) && !defined(OF_AMIGAOS) close(_cancelFD[0]); if (_cancelFD[1] != _cancelFD[0]) close(_cancelFD[1]); #elif !defined(OF_AMIGAOS) closesocket(_cancelFD[0]); @@ -257,25 +257,25 @@ [self observeForTimeInterval: date.timeIntervalSinceNow]; } - (void)cancel { -#if defined(OF_HAVE_PIPE) - OF_ENSURE(write(_cancelFD[1], "", 1) > 0); -#elif defined(OF_AMIGAOS) +#if defined(OF_AMIGAOS) Forbid(); if (_waitingTask != NULL) { Signal(_waitingTask, (1ul << _cancelSignal)); _waitingTask = NULL; } Permit(); +#elif defined(OF_HAVE_PIPE) + OF_ENSURE(write(_cancelFD[1], "", 1) > 0); #elif defined(OF_WII) OF_ENSURE(sendto(_cancelFD[1], "", 1, 0, (struct sockaddr *)&_cancelAddr, 8) > 0); #else OF_ENSURE(sendto(_cancelFD[1], (void *)"", 1, 0, (struct sockaddr *)&_cancelAddr, sizeof(_cancelAddr)) > 0); #endif } @end Index: src/OFOptionsParser.m ================================================================== --- src/OFOptionsParser.m +++ src/OFOptionsParser.m @@ -140,21 +140,19 @@ return self; } - (void)dealloc { - of_options_parser_option_t *iter; + if (_options != NULL) + for (of_options_parser_option_t *iter = _options; + iter->shortOption != '\0' || iter->longOption != nil; + iter++) + [iter->longOption release]; free(_options); [_longOptions release]; - if (_options != NULL) - for (iter = _options; - iter->shortOption != '\0' || iter->longOption != nil; - iter++) - [iter->longOption release]; - [_arguments release]; [_argument release]; [super dealloc]; } Index: src/OFSecureData.m ================================================================== --- src/OFSecureData.m +++ src/OFSecureData.m @@ -99,11 +99,12 @@ static struct page * addPage(bool allowPreallocated) { size_t pageSize = [OFSystemInfo pageSize]; - size_t mapSize = OF_ROUND_UP_POW2(8, pageSize / CHUNK_SIZE) / 8; + size_t mapSize = OF_ROUND_UP_POW2(CHAR_BIT, pageSize / CHUNK_SIZE) / + CHAR_BIT; struct page *page; # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) struct page *lastPage; # endif @@ -184,11 +185,12 @@ static void removePageIfEmpty(struct page *page) { unsigned char *map = page->map; size_t pageSize = [OFSystemInfo pageSize]; - size_t mapSize = OF_ROUND_UP_POW2(8, pageSize / CHUNK_SIZE) / 8; + size_t mapSize = OF_ROUND_UP_POW2(CHAR_BIT, pageSize / CHUNK_SIZE) / + CHAR_BIT; for (size_t i = 0; i < mapSize; i++) if (map[i] != 0) return; Index: src/OFSelectKernelEventObserver.m ================================================================== --- src/OFSelectKernelEventObserver.m +++ src/OFSelectKernelEventObserver.m @@ -48,21 +48,22 @@ - (instancetype)init { self = [super init]; @try { + FD_ZERO(&_readFDs); + FD_ZERO(&_writeFDs); + #ifdef OF_AMIGAOS - _maxFD = 0; + _maxFD = -1; #else # ifndef OF_WINDOWS if (_cancelFD[0] >= (int)FD_SETSIZE) @throw [OFInitializationFailedException exceptionWithClass: self.class]; # endif - FD_ZERO(&_readFDs); - FD_ZERO(&_writeFDs); FD_SET(_cancelFD[0], &_readFDs); if (_cancelFD[0] > INT_MAX) @throw [OFOutOfRangeException exception]; @@ -170,11 +171,12 @@ fd_set readFDs; fd_set writeFDs; struct timeval timeout; int events; #ifdef OF_AMIGAOS - ULONG execSignalMask, cancelSignal; + BYTE cancelSignal; + ULONG execSignalMask; #endif void *pool; if ([self of_processReadBuffers]) return; @@ -196,14 +198,14 @@ #ifndef OF_WINDOWS timeout.tv_sec = (time_t)timeInterval; #else timeout.tv_sec = (long)timeInterval; #endif - timeout.tv_usec = (int)((timeInterval - timeout.tv_sec) * 1000); + timeout.tv_usec = (int)((timeInterval - timeout.tv_sec) * 1000000); #ifdef OF_AMIGAOS - if ((cancelSignal = AllocSignal(-1)) == (ULONG)-1) + if ((cancelSignal = AllocSignal(-1)) == (BYTE)-1) @throw [OFObserveFailedException exceptionWithObserver: self errNo: EAGAIN]; execSignalMask = _execSignalMask | (1ul << cancelSignal); Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -144,11 +144,11 @@ objc_autoreleasePoolPop((void *)(uintptr_t)-1); #else objc_autoreleasePoolPop(thread->_pool); #endif -#if defined(OF_AMIGAOS) && defined(OF_HAVE_SOCKETS) +#if defined(OF_AMIGAOS) && !defined(OF_MORPHOS) && defined(OF_HAVE_SOCKETS) if (thread.supportsSockets) of_socket_deinit(); #endif thread->_running = OF_THREAD_WAITING_FOR_JOIN; Index: src/OFWindowsRegistryKey.m ================================================================== --- src/OFWindowsRegistryKey.m +++ src/OFWindowsRegistryKey.m @@ -359,12 +359,12 @@ void *pool = objc_autoreleasePoolPush(); OFData *data; if ([OFSystemInfo isWindowsNT]) data = [OFData dataWithItems: string.UTF16String - itemSize: sizeof(of_char16_t) - count: string.UTF16StringLength + 1]; + count: string.UTF16StringLength + 1 + itemSize: sizeof(of_char16_t)]; else { of_string_encoding_t encoding = [OFLocale encoding]; const char *cString = [string cStringWithEncoding: encoding]; size_t length = [string cStringLengthWithEncoding: encoding]; Index: src/forwarding/forwarding-powerpc-elf.S ================================================================== --- src/forwarding/forwarding-powerpc-elf.S +++ src/forwarding/forwarding-powerpc-elf.S @@ -25,17 +25,19 @@ .section .text of_forward: stwu %r1, -112(%r1) mflr %r0 stw %r0, 116(%r1) +#ifdef OF_PIC stw %r30, 104(%r1) bl 0f 0: mflr %r30 addis %r30, %r30, .Lbiased_got2-0b@ha addi %r30, %r30, .Lbiased_got2-0b@l +#endif /* Save all arguments */ stw %r3, 8(%r1) stw %r4, 12(%r1) stw %r5, 16(%r1) @@ -53,25 +55,44 @@ stfd %f5, 72(%r1) stfd %f6, 80(%r1) stfd %f7, 88(%r1) stfd %f8, 96(%r1) +#ifdef OF_PIC bl object_getClass+0x8000@plt lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) bl class_respondsToSelector+0x8000@plt +#else + bl object_getClass + + lis %r4, sel_forwardingTargetForSelector_@ha + addi %r4, %r4, sel_forwardingTargetForSelector_@l + bl class_respondsToSelector +#endif cmpwi %r3, 0 beq- 0f lwz %r3, 8(%r1) +#ifdef OF_PIC lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) bl objc_msg_lookup+0x8000@plt +#else + lis %r4, sel_forwardingTargetForSelector_@ha + addi %r4, %r4, sel_forwardingTargetForSelector_@l + bl objc_msg_lookup +#endif mtctr %r3 lwz %r3, 8(%r1) +#ifdef OF_PIC lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) +#else + lis %r4, sel_forwardingTargetForSelector_@ha + addi %r4, %r4, sel_forwardingTargetForSelector_@l +#endif lwz %r5, 12(%r1) bctrl cmpwi %r3, 0 beq- 0f @@ -80,11 +101,15 @@ beq- 0f stw %r3, 8(%r1) lwz %r4, 12(%r1) +#ifdef OF_PIC bl objc_msg_lookup+0x8000@plt +#else + bl objc_msg_lookup +#endif mtctr %r3 /* Restore all arguments */ lwz %r3, 8(%r1) lwz %r4, 12(%r1) @@ -103,42 +128,53 @@ lfd %f5, 72(%r1) lfd %f6, 80(%r1) lfd %f7, 88(%r1) lfd %f8, 96(%r1) +#ifdef OF_PIC lwz %r30, 104(%r1) +#endif lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 bctr 0: lwz %r3, 8(%r1) lwz %r4, 12(%r1) + +#ifdef OF_PIC lwz %r0, .Lgot_of_method_not_found-.Lbiased_got2(%r30) mtctr %r0 - lwz %r30, 104(%r1) +#endif + lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 +#ifdef OF_PIC bctr +#else + b of_method_not_found +#endif .type of_forward, @function .size of_forward, .-of_forward of_forward_stret: stwu %r1, -112(%r1) mflr %r0 stw %r0, 116(%r1) +#ifdef OF_PIC stw %r30, 104(%r1) bl 0f 0: mflr %r30 addis %r30, %r30, .Lbiased_got2-0b@ha addi %r30, %r30, .Lbiased_got2-0b@l +#endif /* Save all arguments */ stw %r3, 8(%r1) stw %r4, 12(%r1) stw %r5, 16(%r1) @@ -157,25 +193,44 @@ stfd %f6, 80(%r1) stfd %f7, 88(%r1) stfd %f8, 96(%r1) mr %r3, %r4 +#ifdef OF_PIC bl object_getClass+0x800@plt lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) bl class_respondsToSelector+0x8000@plt +#else + bl object_getClass + + lis %r4, sel_forwardingTargetForSelector_@ha + addi %r4, %r4, sel_forwardingTargetForSelector_@l + bl class_respondsToSelector +#endif cmpwi %r3, 0 beq- 0f lwz %r3, 12(%r1) +#ifdef OF_PIC lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) bl objc_msg_lookup+0x8000@plt +#else + lis %r4, sel_forwardingTargetForSelector_@ha + addi %r4, %r4, sel_forwardingTargetForSelector_@l + bl objc_msg_lookup +#endif mtctr %r3 lwz %r3, 12(%r1) +#ifdef OF_PIC lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) +#else + lis %r4, sel_forwardingTargetForSelector_@ha + addi %r4, %r4, sel_forwardingTargetForSelector_@l +#endif lwz %r5, 16(%r1) bctrl cmpwi %r3, 0 beq- 0f @@ -184,11 +239,15 @@ beq- 0f stw %r3, 12(%r1) lwz %r4, 16(%r1) +#ifdef OF_PIC bl objc_msg_lookup_stret+0x8000@plt +#else + bl objc_msg_lookup_stret +#endif mtctr %r3 /* Restore all arguments */ lwz %r3, 8(%r1) lwz %r4, 12(%r1) @@ -207,35 +266,46 @@ lfd %f5, 72(%r1) lfd %f6, 80(%r1) lfd %f7, 88(%r1) lfd %f8, 96(%r1) +#ifdef OF_PIC + lwz %r30, 104(%r1) +#endif lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 bctr 0: lwz %r3, 8(%r1) lwz %r4, 12(%r1) lwz %r5, 16(%r1) + +#ifdef OF_PIC lwz %r0, .Lgot_of_method_not_found_stret-.Lbiased_got2(%r30) mtctr %r0 - lwz %r30, 104(%r1) +#endif + lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 +#ifdef OF_PIC bctr +#else + b of_method_not_found_stret +#endif .type of_forward_stret, @function .size of_forward_stret, .-of_forward_stret init: stwu %r1, -16(%r1) mflr %r0 stw %r0, 20(%r1) +#ifdef OF_PIC stw %r30, 8(%r1) bl 0f 0: mflr %r30 @@ -244,10 +314,16 @@ lwz %r3, .Lgot_module-.Lbiased_got2(%r30) bl __objc_exec_class+0x8000@plt lwz %r30, 8(%r1) +#else + lis %r3, module@ha + addi %r3, %r3, module@l + bl __objc_exec_class +#endif + lwz %r0, 20(%r1) addi %r1, %r1, 16 mtlr %r0 blr @@ -268,10 +344,11 @@ .long 0 .long 0 module: .long 8, 16, 0, symtab +#ifdef OF_PIC .section .got2, "aw" .Lbiased_got2 = .+0x8000 .Lgot_module: .long module .Lgot_sel_forwardingTargetForSelector_: @@ -278,9 +355,10 @@ .long sel_forwardingTargetForSelector_ .Lgot_of_method_not_found: .long of_method_not_found .Lgot_of_method_not_found_stret: .long of_method_not_found_stret +#endif #ifdef OF_LINUX .section .note.GNU-stack, "", @progbits #endif Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -25,10 +25,11 @@ #endif #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif +#include #include #include #include #include #include @@ -822,23 +823,23 @@ } static OF_INLINE bool of_bitset_isset(unsigned char *_Nonnull storage, size_t idx) { - return storage[idx / 8] & (1u << (idx % 8)); + return storage[idx / CHAR_BIT] & (1u << (idx % CHAR_BIT)); } static OF_INLINE void of_bitset_set(unsigned char *_Nonnull storage, size_t idx) { - storage[idx / 8] |= (1u << (idx % 8)); + storage[idx / CHAR_BIT] |= (1u << (idx % CHAR_BIT)); } static OF_INLINE void of_bitset_clear(unsigned char *_Nonnull storage, size_t idx) { - storage[idx / 8] &= ~(1u << (idx % 8)); + storage[idx / CHAR_BIT] &= ~(1u << (idx % CHAR_BIT)); } static OF_INLINE char *_Nullable of_strdup(const char *_Nonnull string) { Index: src/platform/amiga/thread.m ================================================================== --- src/platform/amiga/thread.m +++ src/platform/amiga/thread.m @@ -27,11 +27,13 @@ #include #include #include +#ifndef OF_MORPHOS extern void of_tlskey_thread_exited(void); +#endif static of_tlskey_t threadKey; OF_CONSTRUCTOR() { OF_ENSURE(of_tlskey_new(&threadKey)); @@ -49,11 +51,13 @@ ObtainSemaphore(&thread->semaphore); @try { thread->done = true; +#ifndef OF_MORPHOS of_tlskey_thread_exited(); +#endif if (thread->detached) detached = true; else if (thread->joinTask != NULL) Signal(thread->joinTask, (1ul << thread->joinSigBit)); ADDED src/platform/morphos/tlskey.m Index: src/platform/morphos/tlskey.m ================================================================== --- src/platform/morphos/tlskey.m +++ src/platform/morphos/tlskey.m @@ -0,0 +1,32 @@ +/* + * 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" + +#import "tlskey.h" + +bool +of_tlskey_new(of_tlskey_t *key) +{ + return ((*key = TLSAllocA(NULL)) != TLS_INVALID_INDEX); +} + +bool +of_tlskey_free(of_tlskey_t key) +{ + return TLSFree(key); +} Index: src/runtime/Makefile ================================================================== --- src/runtime/Makefile +++ src/runtime/Makefile @@ -38,22 +38,22 @@ sparsearray.m \ static-instances.m \ synchronized.m \ tagged-pointer.m \ ${USE_SRCS_THREADS} -SRCS_THREADS = threading.m \ - ../mutex.m \ - ../once.m \ - ../tlskey.m +SRCS_THREADS = mutex.m \ + once.m \ + threading.m \ + tlskey.m INCLUDES = ObjFWRT.h includesubdir = ObjFWRT -OBJS_EXTRA = ${LOOKUP_ASM_LOOKUP_ASM_A} -LIB_OBJS_EXTRA = ${LOOKUP_ASM_LOOKUP_ASM_LIB_A} +OBJS_EXTRA = lookup-asm/lookup-asm.a +LIB_OBJS_EXTRA = lookup-asm/lookup-asm.lib.a AMIGA_LIB_OBJS_START = amiga-library.amigalib.o -AMIGA_LIB_OBJS_EXTRA = amiga-glue.amigalib.o \ - ${LOOKUP_ASM_LOOKUP_ASM_AMIGALIB_A} \ +AMIGA_LIB_OBJS_EXTRA = amiga-glue.amigalib.o \ + lookup-asm/lookup-asm.amigalib.a \ amiga-end.amigalib.o include ../../buildsys.mk ${OBJFWRT_AMIGA_LIB}: inline.h Index: src/runtime/amiga-end.m ================================================================== --- src/runtime/amiga-end.m +++ src/runtime/amiga-end.m @@ -19,13 +19,15 @@ #import "platform.h" #ifdef OF_MORPHOS __asm__ ( - ".section .ctors, \"aw\", @progbits\n" + ".section .eh_frame, \"aw\"\n" " .long 0\n" + ".section .ctors, \"aw\"\n" + " .long 0" ); #else __asm__ ( "" ); #endif Index: src/runtime/amiga-glue.m ================================================================== --- src/runtime/amiga-glue.m +++ src/runtime/amiga-glue.m @@ -820,18 +820,10 @@ M68K_ARG(id, object, a0) return object_isTaggedPointer(object); } -Class __saveds -glue_object_getTaggedPointerClass PPC_PARAMS(id object) -{ - M68K_ARG(id, object, a0) - - return object_getTaggedPointerClass(object); -} - uintptr_t __saveds glue_object_getTaggedPointerValue PPC_PARAMS(id object) { M68K_ARG(id, object, a0) Index: src/runtime/amiga-library.h ================================================================== --- src/runtime/amiga-library.h +++ src/runtime/amiga-library.h @@ -29,19 +29,18 @@ struct objc_libc { void *_Nullable (*_Nonnull malloc)(size_t); void *_Nullable (*_Nonnull calloc)(size_t, size_t); void *_Nullable (*_Nonnull realloc)(void *_Nullable, size_t); void (*_Nonnull free)(void *_Nullable); - int (*_Nonnull vfprintf)(FILE *_Nonnull restrict, - const char *_Nonnull restrict, va_list); + int (*_Nonnull vfprintf)(FILE *_Nonnull, const char *_Nonnull, va_list); int (*_Nonnull fflush)(FILE *_Nonnull); void (*_Nonnull abort)(void); -#ifdef HAVE_SJLJ_EXCEPTIONS +# ifdef HAVE_SJLJ_EXCEPTIONS int (*_Nonnull _Unwind_SjLj_RaiseException)(void *_Nonnull); -#else +# else int (*_Nonnull _Unwind_RaiseException)(void *_Nonnull); -#endif +# endif void (*_Nonnull _Unwind_DeleteException)(void *_Nonnull); void *_Nullable (*_Nonnull _Unwind_GetLanguageSpecificData)( void *_Nonnull); uintptr_t (*_Nonnull _Unwind_GetRegionStart)(void *_Nonnull); uintptr_t (*_Nonnull _Unwind_GetDataRelBase)(void *_Nonnull); @@ -48,20 +47,24 @@ uintptr_t (*_Nonnull _Unwind_GetTextRelBase)(void *_Nonnull); uintptr_t (*_Nonnull _Unwind_GetIP)(void *_Nonnull); uintptr_t (*_Nonnull _Unwind_GetGR)(void *_Nonnull, int); void (*_Nonnull _Unwind_SetIP)(void *_Nonnull, uintptr_t); void (*_Nonnull _Unwind_SetGR)(void *_Nonnull, int, uintptr_t); -#ifdef HAVE_SJLJ_EXCEPTIONS +# ifdef HAVE_SJLJ_EXCEPTIONS void (*_Nonnull _Unwind_SjLj_Resume)(void *_Nonnull); -#else +# else void (*_Nonnull _Unwind_Resume)(void *_Nonnull); -#endif -#ifdef OF_AMIGAOS_M68K +# endif +# ifdef OF_AMIGAOS_M68K void (*_Nonnull __register_frame_info)(const void *_Nonnull, void *_Nonnull); - void *_Nullable (*_Nonnull __deregister_frame_info)( - const void *_Nonnull); -#endif + void *(*_Nonnull __deregister_frame_info)(const void *_Nonnull); +# endif +# ifdef OF_MORPHOS + void (*_Nonnull __register_frame)(void *_Nonnull); + void (*_Nonnull __deregister_frame)(void *_Nonnull); +# endif + int *_Nonnull (*_Nonnull get_errno)(void); }; extern bool objc_init(unsigned int, struct objc_libc *_Nonnull, FILE *_Nonnull *_Nonnull); Index: src/runtime/amiga-library.m ================================================================== --- src/runtime/amiga-library.m +++ src/runtime/amiga-library.m @@ -149,11 +149,10 @@ extern void glue_objc_hashtable_delete(void); extern void glue_objc_hashtable_free(void); extern void glue_objc_setTaggedPointerSecret(void); extern int glue_objc_registerTaggedPointerClass(void); extern bool glue_object_isTaggedPointer(void); -extern Class glue_object_getTaggedPointerClass(void); extern uintptr_t glue_object_getTaggedPointerValue(void); extern id glue_objc_createTaggedPointer(void); #ifdef OF_MORPHOS const ULONG __abox__ = 1; @@ -415,10 +414,13 @@ #ifdef OF_AMIGAOS_M68K OBJC_M68K_ARG(struct ObjFWRTBase *, base, a6) #else register struct ObjFWRTBase *r12 __asm__("r12"); struct ObjFWRTBase *base = r12; +#endif +#ifdef OF_MORPHOS + void *frame; #endif uintptr_t *iter, *iter0; if (version > 1) return false; @@ -438,14 +440,18 @@ (&_EH_FRAME_OBJECTS__)[i]); iter0 = &__CTOR_LIST__[1]; #elif defined(OF_MORPHOS) __asm__ ( - "lis %0, ctors+4@ha\n\t" - "la %0, ctors+4@l(%0)\n\t" - : "=r"(iter0) + "lis %0, __EH_FRAME_BEGIN__@ha\n\t" + "la %0, __EH_FRAME_BEGIN__@l(%0)\n\t" + "lis %1, __CTOR_LIST__@ha\n\t" + "la %1, __CTOR_LIST__@l(%1)\n\t" + : "=r"(frame), "=r"(iter0) ); + + libc.__register_frame(frame); #endif for (iter = iter0; *iter != 0; iter++); while (iter > iter0) { @@ -588,10 +594,16 @@ _Unwind_Resume(void *ex) { libc._Unwind_Resume(ex); } #endif + +int * +objc_get_errno(void) +{ + return libc.get_errno(); +} #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" static CONST_APTR functionTable[] = { #ifdef OF_MORPHOS @@ -691,11 +703,10 @@ (CONST_APTR)glue_objc_hashtable_delete, (CONST_APTR)glue_objc_hashtable_free, (CONST_APTR)glue_objc_setTaggedPointerSecret, (CONST_APTR)glue_objc_registerTaggedPointerClass, (CONST_APTR)glue_object_isTaggedPointer, - (CONST_APTR)glue_object_getTaggedPointerClass, (CONST_APTR)glue_object_getTaggedPointerValue, (CONST_APTR)glue_objc_createTaggedPointer, (CONST_APTR)-1, #ifdef OF_MORPHOS (CONST_APTR)FUNCARRAY_END @@ -740,11 +751,16 @@ #endif }; #ifdef OF_MORPHOS __asm__ ( - ".section .ctors, \"aw\", @progbits\n" - "ctors:\n" - " .long -1\n" + ".section .eh_frame, \"aw\"\n" + ".globl __EH_FRAME_BEGIN__\n" + ".type __EH_FRAME_BEGIN__, @object\n" + "__EH_FRAME_BEGIN__:\n" + ".section .ctors, \"aw\"\n" + ".globl __CTOR_LIST__\n" + ".type __CTOR_LIST__, @object\n" + "__CTOR_LIST__:\n" ".section .text" ); #endif Index: src/runtime/amigaos3.sfd ================================================================== --- src/runtime/amigaos3.sfd +++ src/runtime/amigaos3.sfd @@ -91,9 +91,8 @@ void glue_objc_hashtable_free(struct objc_hashtable *_Nonnull table)(a0) * Public functions again void glue_objc_setTaggedPointerSecret(uintptr_t secret)(d0) int glue_objc_registerTaggedPointerClass(Class _Nonnull class_)(a0) bool glue_object_isTaggedPointer(id _Nullable object)(a0) -Class _Nullable glue_object_getTaggedPointerClass(id _Nonnull object)(a0) uintptr_t glue_object_getTaggedPointerValue(id _Nonnull object)(a0) id _Nullable glue_objc_createTaggedPointer(int class_, uintptr_t value)(d0,d1) ==end Index: src/runtime/linklib/linklib.m ================================================================== --- src/runtime/linklib/linklib.m +++ src/runtime/linklib/linklib.m @@ -26,10 +26,11 @@ struct ObjFWRTBase; #import "inline.h" +#include #include #include #if defined(OF_AMIGAOS_M68K) # include @@ -60,13 +61,23 @@ #endif #ifdef OF_AMIGAOS_M68K extern void __register_frame_info(const void *, void *); extern void *__deregister_frame_info(const void *); #endif +#ifdef OF_MORPHOS +extern void __register_frame(void *); +extern void __deregister_frame(void *); +#endif struct Library *ObjFWRTBase; void *__objc_class_name_Protocol; + +static int * +get_errno(void) +{ + return &errno; +} static void __attribute__((__used__)) ctor(void) { static bool initialized = false; @@ -100,10 +111,15 @@ #endif #ifdef OF_AMIGAOS_M68K .__register_frame_info = __register_frame_info, .__deregister_frame_info = __deregister_frame_info, #endif +#ifdef OF_MORPHOS + .__register_frame = __register_frame, + .__deregister_frame = __deregister_frame, +#endif + .get_errno = get_errno, }; if (initialized) return; @@ -740,16 +756,10 @@ object_isTaggedPointer(id object) { return glue_object_isTaggedPointer(object); } -Class -object_getTaggedPointerClass(id object) -{ - return glue_object_getTaggedPointerClass(object); -} - uintptr_t object_getTaggedPointerValue(id object) { return glue_object_getTaggedPointerValue(object); } Index: src/runtime/lookup-asm/Makefile ================================================================== --- src/runtime/lookup-asm/Makefile +++ src/runtime/lookup-asm/Makefile @@ -1,11 +1,13 @@ include ../../../extra.mk STATIC_PIC_LIB_NOINST = ${LOOKUP_ASM_LIB_A} +STATIC_AMIGA_LIB_NOINST = ${LOOKUP_ASM_AMIGALIB_A} STATIC_LIB_NOINST = ${LOOKUP_ASM_A} STATIC_AMIGA_LIB_NOINST = ${LOOKUP_ASM_AMIGALIB_A} SRCS = lookup-asm.S include ../../../buildsys.mk ASFLAGS += -I../../.. -I../.. +ASFLAGS_lookup-asm.amigalib.o += -DOF_BASEREL Index: src/runtime/lookup-asm/lookup-asm-powerpc-elf.S ================================================================== --- src/runtime/lookup-asm/lookup-asm-powerpc-elf.S +++ src/runtime/lookup-asm/lookup-asm-powerpc-elf.S @@ -55,10 +55,11 @@ mr %r3, %r5 blr 0: +#ifdef OF_PIC stwu %r1, -16(%r1) mflr %r0 stw %r0, 20(%r1) stw %r30, 8(%r1) @@ -75,12 +76,16 @@ lwz %r0, 20(%r1) addi %r1, %r1, 16 mtlr %r0 bctr +#else + b \not_found +#endif .Ltagged_pointer_\name: +#if defined(OF_PIC) mflr %r7 bl 0f 0: mflr %r6 mtlr %r7 @@ -87,14 +92,29 @@ addis %r6, %r6, .Lbiased_got2-0b@ha addi %r6, %r6, .Lbiased_got2-0b@l lwz %r5, .Lgot_objc_tagged_pointer_secret-.Lbiased_got2(%r6) lwz %r5, 0(%r5) +#elif defined(OF_BASEREL) + addis %r5, %r13, objc_tagged_pointer_secret@drel@ha + lwz %r5, objc_tagged_pointer_secret@drel@l(%r5) +#else + lis %r5, objc_tagged_pointer_secret@ha + lwz %r5, objc_tagged_pointer_secret@l(%r5) +#endif xor %r5, %r3, %r5 rlwinm %r5, %r5, 1, 0x1C +#if defined(OF_PIC) lwz %r6, .Lgot_objc_tagged_pointer_classes-.Lbiased_got2(%r6) +#elif defined(OF_BASEREL) + addis %r6, %r13, objc_tagged_pointer_classes@drel@ha + addi %r6, %r6, objc_tagged_pointer_classes@drel@l +#else + lis %r6, objc_tagged_pointer_classes@ha + addi %r6, %r6, objc_tagged_pointer_classes@l +#endif lwzx %r5, %r6, %r5 lwz %r5, 32(%r5) b .Lmain_\name .type \name, @function @@ -135,10 +155,11 @@ get_pc: mflr %r3 blr +#ifdef OF_PIC .section .got2, "aw" .Lbiased_got2 = .+0x8000 .Lgot_objc_method_not_found: .long objc_method_not_found .Lgot_objc_method_not_found_stret: @@ -145,9 +166,10 @@ .long objc_method_not_found_stret .Lgot_objc_tagged_pointer_secret: .long objc_tagged_pointer_secret .Lgot_objc_tagged_pointer_classes: .long objc_tagged_pointer_classes +#endif #ifdef OF_LINUX .section .note.GNU-stack, "", @progbits #endif Index: src/runtime/morphos-clib.h ================================================================== --- src/runtime/morphos-clib.h +++ src/runtime/morphos-clib.h @@ -86,8 +86,7 @@ void glue_objc_hashtable_free(struct objc_hashtable *); /* Public functions again */ void glue_objc_setTaggedPointerSecret(uintptr_t); int glue_objc_registerTaggedPointerClass(Class); bool glue_object_isTaggedPointer(id); -Class _Nullable glue_object_getTaggedPointerClass(id); uintptr_t glue_object_getTaggedPointerValue(id); id glue_objc_createTaggedPointer(int, uintptr_t); Index: src/runtime/morphos.fd ================================================================== --- src/runtime/morphos.fd +++ src/runtime/morphos.fd @@ -89,9 +89,8 @@ glue_objc_hashtable_free(table)(sysv,r12base) * Public functions again glue_objc_setTaggedPointerSecret(secret)(sysv,r12base) glue_objc_registerTaggedPointerClass(class_)(sysv,r12base) glue_object_isTaggedPointer(object)(sysv,r12base) -glue_object_getTaggedPointerClass(object)(sysv,r12base) glue_object_getTaggedPointerValue(object)(sysv,r12base) glue_objc_createTaggedPointer(class_,value)(sysv,r12base) ##end ADDED src/runtime/mutex.m Index: src/runtime/mutex.m ================================================================== --- src/runtime/mutex.m +++ src/runtime/mutex.m @@ -0,0 +1,23 @@ +/* + * 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" + +#import "ObjFWRT.h" +#import "private.h" + +#include "../mutex.m" ADDED src/runtime/once.m Index: src/runtime/once.m ================================================================== --- src/runtime/once.m +++ src/runtime/once.m @@ -0,0 +1,23 @@ +/* + * 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" + +#import "ObjFWRT.h" +#import "private.h" + +#include "../once.m" Index: src/runtime/private.h ================================================================== --- src/runtime/private.h +++ src/runtime/private.h @@ -213,10 +213,16 @@ #else IMP _Nullable buckets[256]; #endif } *_Nonnull buckets[256]; }; + +#ifdef OBJC_COMPILING_AMIGA_LIBRARY +# undef errno +extern int *_Nonnull objc_get_errno(void); +# define errno (*objc_get_errno()) +#endif extern void objc_register_all_categories(struct objc_symtab *_Nonnull); extern struct objc_category *_Nullable *_Nullable objc_categories_for_class(Class _Nonnull); extern void objc_unregister_all_categories(void); ADDED src/runtime/tlskey.m Index: src/runtime/tlskey.m ================================================================== --- src/runtime/tlskey.m +++ src/runtime/tlskey.m @@ -0,0 +1,23 @@ +/* + * 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" + +#import "ObjFWRT.h" +#import "private.h" + +#include "../tlskey.m" Index: src/socket.h ================================================================== --- src/socket.h +++ src/socket.h @@ -290,20 +290,20 @@ extern void of_socket_address_get_ipx_node( const of_socket_address_t *_Nonnull address, unsigned char node[_Nonnull IPX_NODE_LEN]); extern bool of_socket_init(void); -#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) +#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS) extern void of_socket_deinit(void); #endif extern int of_socket_errno(void); #if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) extern int of_getsockname(of_socket_t sock, struct sockaddr *restrict addr, socklen_t *restrict addrLen); #endif -#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) +#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS) extern of_tlskey_t of_socket_base_key; # ifdef OF_AMIGAOS4 extern of_tlskey_t of_socket_interface_key; # endif #endif Index: src/socket.m ================================================================== --- src/socket.m +++ src/socket.m @@ -36,11 +36,11 @@ #import "OFUnlockFailedException.h" #import "socket.h" #import "socket_helpers.h" #ifdef OF_HAVE_THREADS -# ifndef OF_AMIGAOS +# if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) # import "mutex.h" # else # import "tlskey.h" # endif #endif @@ -53,17 +53,19 @@ #ifdef OF_NINTENDO_3DS # include <3ds/types.h> # include <3ds/services/soc.h> #endif -#if defined(OF_HAVE_THREADS) && !defined(OF_AMIGAOS) +#if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS)) static of_mutex_t mutex; #endif -#if !defined(OF_AMIGAOS) || !defined(OF_HAVE_THREADS) +#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS) static bool initSuccessful = false; -#else -# ifdef OF_HAVE_THREADS +#endif + +#ifdef OF_AMIGAOS +# if defined(OF_HAVE_THREADS) && !defined(OF_MORPHOS) of_tlskey_t of_socket_base_key; # ifdef OF_AMIGAOS4 of_tlskey_t of_socket_interface_key; # endif # else @@ -72,11 +74,11 @@ struct SocketIFace *ISocket = NULL; # endif # endif #endif -#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) +#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS) OF_CONSTRUCTOR() { if (!of_tlskey_new(&of_socket_base_key)) @throw [OFInitializationFailedException exception]; @@ -85,11 +87,11 @@ @throw [OFInitializationFailedException exception]; # endif } #endif -#if !defined(OF_AMIGAOS) || !defined(OF_HAVE_THREADS) +#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS) static void init(void) { # if defined(OF_WINDOWS) WSADATA wsa; @@ -120,11 +122,11 @@ return; atexit((void (*)(void))socExit); # endif -# if defined(OF_HAVE_THREADS) && !defined(OF_AMIGAOS) +# if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS)) if (!of_mutex_new(&mutex)) return; # ifdef OF_WII if (!of_spinlock_new(&spinlock)) @@ -150,11 +152,11 @@ #endif bool of_socket_init(void) { -#if !defined(OF_AMIGAOS) || !defined(OF_HAVE_THREADS) +#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS) static of_once_t onceControl = OF_ONCE_INIT; of_once(&onceControl, init); return initSuccessful; #else @@ -199,11 +201,11 @@ return true; #endif } -#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) +#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS) void of_socket_deinit(void) { struct Library *socketBase = of_tlskey_get(of_socket_base_key); # ifdef OF_AMIGAOS4 @@ -324,19 +326,19 @@ of_getsockname(of_socket_t sock, struct sockaddr *restrict addr, socklen_t *restrict addrLen) { int ret; -# if defined(OF_HAVE_THREADS) && !defined(OF_AMIGAOS) +# if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS)) if (!of_mutex_lock(&mutex)) @throw [OFLockFailedException exception]; # endif ret = getsockname(sock, addr, addrLen); -# if defined(OF_HAVE_THREADS) && !defined(OF_AMIGAOS) +# if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS)) if (!of_mutex_unlock(&mutex)) @throw [OFUnlockFailedException exception]; # endif return ret; Index: src/socket_helpers.h ================================================================== --- src/socket_helpers.h +++ src/socket_helpers.h @@ -57,11 +57,11 @@ # include # define closesocket(sock) CloseSocket(sock) # define ioctlsocket(fd, req, arg) IoctlSocket(fd, req, arg) # define hstrerror(err) "unknown (no hstrerror)" # define SOCKET_ERROR -1 -# ifdef OF_HAVE_THREADS +# if defined(OF_HAVE_THREADS) && !defined(OF_MORPHOS) # define SocketBase ((struct Library *)of_tlskey_get(of_socket_base_key)) # ifdef OF_AMIGAOS4 # define ISocket \ ((struct SocketIFace *)of_tlskey_get(of_socket_interface_key)) # endif Index: src/tlskey.h ================================================================== --- src/tlskey.h +++ src/tlskey.h @@ -30,10 +30,13 @@ # include typedef pthread_key_t of_tlskey_t; #elif defined(OF_WINDOWS) # include typedef DWORD of_tlskey_t; +#elif defined(OF_MORPHOS) +# include +typedef ULONG of_tlskey_t; #elif defined(OF_AMIGAOS) typedef struct of_tlskey { struct objc_hashtable *table; struct of_tlskey *next, *previous; } *of_tlskey_t; @@ -72,10 +75,22 @@ static OF_INLINE bool of_tlskey_set(of_tlskey_t key, void *ptr) { return TlsSetValue(key, ptr); } +#elif defined(OF_MORPHOS) +static OF_INLINE void * +of_tlskey_get(of_tlskey_t key) +{ + return (void *)TLSGetValue(key); +} + +static OF_INLINE bool +of_tlskey_set(of_tlskey_t key, void *ptr) +{ + return TLSSetValue(key, (APTR)ptr); +} #elif defined(OF_AMIGAOS) /* Those are too big too inline. */ # ifdef __cplusplus extern "C" { # endif Index: src/tlskey.m ================================================================== --- src/tlskey.m +++ src/tlskey.m @@ -21,8 +21,10 @@ #if defined(OF_HAVE_PTHREADS) # include "platform/posix/tlskey.m" #elif defined(OF_WINDOWS) # include "platform/windows/tlskey.m" +#elif defined(OF_MORPHOS) +# include "platform/morphos/tlskey.m" #elif defined(OF_AMIGAOS) # include "platform/amiga/tlskey.m" #endif