Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -44,10 +44,11 @@ ]) OBJCFLAGS="$OBJCFLAGS -noixemul" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -noixemul" CPPFLAGS="$CPPFLAGS -D__NO_NET_API" LDFLAGS="$LDFLAGS -noixemul" + LIBS="$LIBS -ldebug" enable_files="yes" # Required for reading ENV: enable_shared="no" supports_amiga_lib="yes" @@ -59,11 +60,11 @@ dnl For 68000, GCC emits calls to helper functions that dnl do not work properly in a library. t="-mcpu=68020 -fbaserel -noixemul" AC_SUBST(AMIGA_LIB_CFLAGS, "$t -ffreestanding") AC_SUBST(AMIGA_LIB_LDFLAGS, - "$t -resident -nostartfiles") + "$t -resident -nostartfiles -ldebug -lc") ]) AC_SUBST(LIBBASES_M, libbases.m) ;; powerpc-*-amigaos*) @@ -79,10 +80,11 @@ OBJCFLAGS="-O2 -g" ]) OBJCFLAGS="$OBJCFLAGS -noixemul" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -noixemul" LDFLAGS="$LDFLAGS -noixemul" + LIBS="$LIBS -ldebug" enable_files="yes" # Required for reading ENV: enable_shared="no" supports_amiga_lib="yes" check_pedantic="no" # Breaks generated inlines @@ -91,11 +93,11 @@ AC_SUBST(OBJFWRT_AMIGA_LIB, objfwrt.library) AC_SUBST(CVINCLUDE_INLINE_H, inline.h) t="-mresident32 -ffreestanding -noixemul" AC_SUBST(AMIGA_LIB_CFLAGS, $t) t="-mresident32 -nostartfiles -nodefaultlibs" - t="$t -noixemul -lc" + t="$t -noixemul -ldebug -lc" AC_SUBST(AMIGA_LIB_LDFLAGS, $t) ]) AC_SUBST(LIBBASES_M, libbases.m) ;; Index: src/runtime/amiga-library.m ================================================================== --- src/runtime/amiga-library.m +++ src/runtime/amiga-library.m @@ -503,10 +503,32 @@ int fflush(FILE *restrict stream) { return libc.fflush(stream); } + +#ifdef OF_AMIGAOS_M68K +int +snprintf(char *restrict str, size_t size, const char *restrict fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + ret = vsnprintf(str, size, fmt, args); + va_end(args); + + return ret; +} + +int +vsnprintf(char *restrict str, size_t size, const char *restrict fmt, + va_list args) +{ + return libc.vsnprintf(str, size, fmt, args); +} +#endif void abort(void) { libc.abort(); Index: src/runtime/linklib/linklib.m ================================================================== --- src/runtime/linklib/linklib.m +++ src/runtime/linklib/linklib.m @@ -85,10 +85,13 @@ .calloc = calloc, .realloc = realloc, .free = free, .vfprintf = vfprintf, .fflush = fflush, +#ifdef OF_AMIGAOS_M68K + .vsnprintf = vsnprintf, +#endif .abort = abort, #ifdef HAVE_SJLJ_EXCEPTIONS ._Unwind_SjLj_RaiseException = _Unwind_SjLj_RaiseException, #else ._Unwind_RaiseException = _Unwind_RaiseException, Index: src/runtime/misc.m ================================================================== --- src/runtime/misc.m +++ src/runtime/misc.m @@ -20,10 +20,19 @@ #include #include #include "ObjFWRT.h" #include "private.h" + +#ifdef OF_AMIGAOS +# define USE_INLINE_STDARG +# include +# include +# define __NOLIBBASE__ +# include +# undef __NOLIBBASE__ +#endif static objc_enumeration_mutation_handler_t enumerationMutationHandler = NULL; void objc_enumerationMutation(id object) @@ -37,5 +46,60 @@ void objc_setEnumerationMutationHandler(objc_enumeration_mutation_handler_t handler) { enumerationMutationHandler = handler; } + +void +objc_error(const char *file, unsigned int line, const char *format, ...) +{ +#ifdef OF_AMIGAOS +# define BUF_LEN 256 + char title[BUF_LEN]; + char message[BUF_LEN]; + int status; + va_list args; + struct Library *IntuitionBase; + + status = snprintf(title, BUF_LEN, "ObjFWRT @ %s:%u", file, line); + if (status <= 0 || status >= BUF_LEN) + title[0] = '\0'; + + va_start(args, format); + status = vsnprintf(message, BUF_LEN, format, args); + if (status <= 0 || status >= BUF_LEN) + message[0] = '\0'; + va_end(args); + + kprintf("[%s] %s\n", title, message); + + IntuitionBase = OpenLibrary("intuition.library", 0); + if (IntuitionBase != NULL) { + struct EasyStruct easy = { + .es_StructSize = sizeof(easy), + .es_Flags = 0, + .es_Title = (UBYTE *)title, + .es_TextFormat = (UBYTE *)"%s", + (UBYTE *)"OK" + }; + + EasyRequest(NULL, &easy, NULL, (ULONG)message); + + CloseLibrary(IntuitionBase); + } +# undef BUF_LEN +#else + va_list args; + + va_start(args, format); + + vfprintf(stderr, "[ObjFWRT @ %s:%u] ", file, line); + vfprintf(stderr, format, args); + vfprintf(stderr, "\n"); + fflush(stderr); + + va_end(args); +#endif + abort(); + + OF_UNREACHABLE +} Index: src/runtime/private.h ================================================================== --- src/runtime/private.h +++ src/runtime/private.h @@ -225,10 +225,14 @@ 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, const char *_Nonnull, va_list); int (*_Nonnull fflush)(FILE *_Nonnull); +# ifdef OF_AMIGAOS_M68K + int (*_Nonnull vsnprintf)(char *restrict _Nonnull str, size_t size, + const char *_Nonnull restrict fmt, va_list args); +# endif void (*_Nonnull abort)(void); # ifdef HAVE_SJLJ_EXCEPTIONS int (*_Nonnull _Unwind_SjLj_RaiseException)(void *_Nonnull); # else int (*_Nonnull _Unwind_RaiseException)(void *_Nonnull); @@ -345,10 +349,14 @@ return dtable->buckets[i]->buckets[j]; #endif } +extern void OF_NO_RETURN_FUNC objc_error(const char *file, unsigned int line, + const char *format, ...); +#define OBJC_ERROR(...) objc_error(__FILE__, __LINE__, __VA_ARGS__); + #if defined(OF_ELF) # if defined(OF_X86_64) || defined(OF_X86) || defined(OF_POWERPC) || \ defined(OF_ARM64) || defined(OF_ARM) || \ defined(OF_MIPS64_N64) || defined(OF_MIPS) || \ defined(OF_SPARC64) || defined(OF_SPARC) @@ -362,20 +370,10 @@ # if defined(OF_X86_64) || defined(OF_X86) # define OF_ASM_LOOKUP # endif #endif -#define OBJC_ERROR(...) \ - { \ - fprintf(stderr, "[objc @ " __FILE__ ":%d] ", __LINE__); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - fflush(stderr); \ - abort(); \ - OF_UNREACHABLE \ - } - @interface DummyObject { Class _Nonnull isa; }