Index: .gitignore ================================================================== --- .gitignore +++ .gitignore @@ -28,12 +28,12 @@ src/ObjFW.framework src/bridge/Info.plist src/bridge/ObjFW_Bridge.framework src/objfw-defs.h src/runtime/ObjFW_RT.framework -src/runtime/ObjFW_RT_inline.h src/runtime/amiga-library-functable.inc +src/runtime/inline.h tests/*.map tests/EBOOT.PBP tests/Info.plist tests/PARAM.SFO tests/iOS.xcodeproj/*.pbxuser Index: build-aux/m4/buildsys.m4 ================================================================== --- build-aux/m4/buildsys.m4 +++ build-aux/m4/buildsys.m4 @@ -40,11 +40,10 @@ AC_SUBST(CC_DEPENDS, $GCC) AC_SUBST(CXX_DEPENDS, $GXX) AC_SUBST(OBJC_DEPENDS, $GOBJC) AC_SUBST(OBJCXX_DEPENDS, $GOBJCXX) - AMIGA_LIB_LDFLAGS="-nostartfiles" AC_SUBST(AMIGA_LIB_CFLAGS) AC_SUBST(AMIGA_LIB_LDFLAGS) AC_PATH_PROG(TPUT, tput) Index: buildsys.mk.in ================================================================== --- buildsys.mk.in +++ buildsys.mk.in @@ -278,13 +278,13 @@ ${MKDIR_P} ${COPY_HEADERS_DESTINATION} || exit $$?; \ ${INSTALL} -m 644 $$i ${COPY_HEADERS_DESTINATION}/$$i || exit $$?; \ done \ fi -${AMIGA_LIB} ${AMIGA_LIB_NOINST}: ${EXT_DEPS} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} +${AMIGA_LIB} ${AMIGA_LIB_NOINST}: ${EXT_DEPS} ${AMIGA_LIB_OBJS_START} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} ${LINK_STATUS} - if ${LD} -o $@ ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} ${AMIGA_LIB_LDFLAGS} ${LDFLAGS} ${LIBS}; then \ + if ${LD} -o $@ ${AMIGA_LIB_OBJS_START} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} ${AMIGA_LIB_LDFLAGS} ${LDFLAGS} ${LIBS}; then \ ${LINK_OK}; \ else \ ${LINK_FAILED}; \ fi Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -48,12 +48,16 @@ AC_DEFINE(__have_longlong64, 1, [Required for AmigaOS to correctly define PRI?64]) AC_SUBST(NOIXEMUL, -noixemul) AC_SUBST(OBJFW_RT_AMIGA_LIB, objfw_rt.library) - AC_SUBST(OBJFW_RT_INLINE_H, ObjFW_RT_inline.h) AC_SUBST(SFDC_TARGET, m68k-amigaos) + dnl For 68000, GCC emits calls to helper functions that + dnl do not work properly in a library. + AC_SUBST(AMIGA_LIB_CFLAGS, "-mcpu=68020 -fbaserel") + AC_SUBST(AMIGA_LIB_LDFLAGS, + "-mcpu=68020 -fbaserel -resident -nostartfiles") AC_SUBST(LINKLIB, linklib) ;; powerpc-*-amigaos*) enable_shared="no" enable_threads="no" @@ -68,12 +72,14 @@ LDFLAGS="$LDFLAGS -noixemul" enable_files="yes" # Required for reading ENV: AC_SUBST(NOIXEMUL, -noixemul) AC_SUBST(OBJFW_RT_AMIGA_LIB, objfw_rt.library) - AC_SUBST(OBJFW_RT_INLINE_H, ObjFW_RT_inline.h) AC_SUBST(SFDC_TARGET, ppc-morphos) + AC_SUBST(AMIGA_LIB_CFLAGS, "-mresident32 -fno-builtin") + AC_SUBST(AMIGA_LIB_LDFLAGS, + "-mresident32 -nostartfiles -nodefaultlibs -lc") AC_SUBST(LINKLIB, linklib) ]) enable_shared="no" enable_threads="no" @@ -839,11 +845,13 @@ ]) ]) AC_CHECK_FUNCS(arc4random random, break) -AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl") +AS_IF([test x"$host_os" != x"morphos"], [ + AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl") +]) AC_CHECK_HEADERS_ONCE(dlfcn.h) case "$host_os" in netbsd*) dnl dladdr exists on NetBSD, but it is completely broken. dnl When using it with code that uses __thread, it freezes the Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -49,11 +49,10 @@ LOOKUP_ASM_A = @LOOKUP_ASM_A@ LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@ LOOKUP_ASM_LOOKUP_ASM_A = @LOOKUP_ASM_LOOKUP_ASM_A@ LOOKUP_ASM_LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LOOKUP_ASM_LIB_A@ MAP_LDFLAGS = @MAP_LDFLAGS@ -OBJFW_RT_INLINE_H = @OBJFW_RT_INLINE_H@ OFBLOCKTESTS_M = @OFBLOCKTESTS_M@ OFHASH = @OFHASH@ OFHTTP = @OFHTTP@ OFHTTPCLIENTTESTS_M = @OFHTTPCLIENTTESTS_M@ OFHTTPCLIENT_M = @OFHTTPCLIENT_M@ Index: src/runtime/Makefile ================================================================== --- src/runtime/Makefile +++ src/runtime/Makefile @@ -1,10 +1,10 @@ include ../../extra.mk SUBDIRS = lookup-asm SUBDIRS_AFTER = ${LINKLIB} -CLEAN = ${OBJFW_RT_INLINE_H} +CLEAN = amiga-library-functable.inc inline.h SHARED_LIB = ${OBJFW_RT_SHARED_LIB} STATIC_LIB = ${OBJFW_RT_STATIC_LIB} FRAMEWORK = ${OBJFW_RT_FRAMEWORK} AMIGA_LIB = ${OBJFW_RT_AMIGA_LIB} @@ -27,38 +27,34 @@ static-instances.m \ synchronized.m \ ${USE_SRCS_THREADS} SRCS_THREADS = threading.m \ ../threading.m -INCLUDES = ObjFW_RT.h ${OBJFW_RT_INLINE_H} +INCLUDES = ObjFW_RT.h includesubdir = ObjFW_RT 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 \ - amiga-library.amigalib.o \ - ${LOOKUP_ASM_LOOKUP_ASM_A} + ${LOOKUP_ASM_LOOKUP_ASM_A} \ + amiga-end.amigalib.o include ../../buildsys.mk -${OBJFW_RT_AMIGA_LIB}: ${OBJFW_RT_INLINE_H} +${OBJFW_RT_AMIGA_LIB}: inline.h amiga-library.m: amiga-library-functable.inc amiga-library-functable.inc: ObjFW_RT.sfd sfdc -q --target=${SFDC_TARGET} --mode=functable -o $@ $< -${OBJFW_RT_INLINE_H}: ObjFW_RT.sfd +inline.h: ObjFW_RT.sfd sfdc -q --target=${SFDC_TARGET} --mode=macros -o $@ $< CPPFLAGS += -I. -I.. -I../.. \ -DOF_COMPILING_OBJFW_RT \ -DOBJFW_RT_LIB_MAJOR=${OBJFW_RT_LIB_MAJOR} \ -DOBJFW_RT_LIB_MINOR=${OBJFW_RT_LIB_MINOR} AMIGA_LIB_CFLAGS += -DOBJC_COMPILING_AMIGA_LIBRARY LD = ${OBJC} FRAMEWORK_LIBS = ${LIBS} - -# For 68000, GCC emits calls to helper functions that expect a4 to be set. -# Remove this once the library is using -fbaserel. -AMIGA_LIB_CFLAGS += -mcpu=68020 -fbaserel -AMIGA_LIB_LDFLAGS += -mcpu=68020 -fbaserel -resident Index: src/runtime/ObjFW_RT.h ================================================================== --- src/runtime/ObjFW_RT.h +++ src/runtime/ObjFW_RT.h @@ -56,23 +56,10 @@ #define Nil (Class _Null_unspecified)0 #define nil (id _Null_unspecified)0 #define YES true #define NO false -#if defined(__amigaos__) && !defined(__MORPHOS__) && !defined(__amigaos4__) -# define OBJC_M68K_REG(reg) __asm__(reg) -#else -# define OBJC_M68K_REG(reg) -#endif -#if defined(__MORPHOS__) && defined(OBJC_COMPILING_AMIGA_LIBRARY) -# define OBJC_M68K_FUNC(name, ...) name(void) -# define OBJC_M68K_ARG(type, name, reg) type name = (type)reg; -#else -# define OBJC_M68K_FUNC(name, ...) name(__VA_ARGS__) -# define OBJC_M68K_ARG(type, name, reg) -#endif - typedef struct objc_class *Class; typedef struct objc_object *id; typedef const struct objc_selector *SEL; #if !defined(__wii__) && !defined(__amigaos__) typedef bool BOOL; @@ -219,85 +206,51 @@ }; #ifdef __cplusplus extern "C" { #endif -# if defined(OBJC_AMIGA_LIBRARY) || defined(OBJC_COMPILING_AMIGA_LINKLIB) -# if defined(__amigaos__) && !defined(__MORPHOS__) && !defined(__amigaos4__) -# define INTUITION_CLASSES_H -# endif -# include -# include "ObjFW_RT_inline.h" -# if defined(__amigaos__) && !defined(__MORPHOS__) && !defined(__amigaos4__) -# undef INTUITION_CLASSES_H -# endif -extern struct Library *ObjFWRTBase; -# else -extern SEL _Nonnull sel_registerName( - const char *_Nonnull name OBJC_M68K_REG("a0")); -extern const char *_Nonnull sel_getName(SEL _Nonnull sel OBJC_M68K_REG("a0")); -extern bool sel_isEqual(SEL _Nonnull sel1 OBJC_M68K_REG("a0"), - SEL _Nonnull sel2 OBJC_M68K_REG("a1")); -extern Class _Nonnull objc_allocateClassPair( - Class _Nullable superclass OBJC_M68K_REG("a0"), - const char *_Nonnull name OBJC_M68K_REG("a1"), - size_t extra_bytes OBJC_M68K_REG("d0")); -extern void objc_registerClassPair(Class _Nonnull cls OBJC_M68K_REG("a0")); -extern unsigned int objc_getClassList( - Class _Nonnull *_Nullable buf OBJC_M68K_REG("a0"), - unsigned int count OBJC_M68K_REG("d0")); -extern Class _Nonnull *_Nonnull objc_copyClassList( - unsigned int *_Nullable OBJC_M68K_REG("a0")); -extern bool class_isMetaClass(Class _Nullable cls OBJC_M68K_REG("a0")); -extern const char *_Nullable class_getName( - Class _Nullable cls OBJC_M68K_REG("a0")); -extern Class _Nullable class_getSuperclass( - Class _Nullable cls OBJC_M68K_REG("a0")); -extern unsigned long class_getInstanceSize( - Class _Nullable cls OBJC_M68K_REG("a0")); -extern bool class_respondsToSelector(Class _Nullable cls OBJC_M68K_REG("a0"), - SEL _Nonnull sel OBJC_M68K_REG("a1")); -extern bool class_conformsToProtocol(Class _Nullable cls OBJC_M68K_REG("a0"), - Protocol *_Nonnull p OBJC_M68K_REG("a1")); -extern IMP _Nullable class_getMethodImplementation( - Class _Nullable cls OBJC_M68K_REG("a0"), - SEL _Nonnull sel OBJC_M68K_REG("a1")); -extern IMP _Nullable class_getMethodImplementation_stret( - Class _Nullable cls OBJC_M68K_REG("a0"), - SEL _Nonnull sel OBJC_M68K_REG("a1")); -extern const char *_Nullable class_getMethodTypeEncoding( - Class _Nullable cls OBJC_M68K_REG("a0"), - SEL _Nonnull sel OBJC_M68K_REG("a1")); -extern bool class_addMethod(Class _Nonnull cls OBJC_M68K_REG("a0"), - SEL _Nonnull sel OBJC_M68K_REG("a1"), IMP _Nonnull imp OBJC_M68K_REG("a2"), - const char *_Nullable types OBJC_M68K_REG("a3")); -extern IMP _Nullable class_replaceMethod(Class _Nonnull cls OBJC_M68K_REG("a0"), - SEL _Nonnull sel OBJC_M68K_REG("a1"), - IMP _Nonnull imp OBJC_M68K_REG("a2"), - const char *_Nullable types OBJC_M68K_REG("a3")); -extern Class _Nullable object_getClass(id _Nullable object OBJC_M68K_REG("a0")); -extern Class _Nullable object_setClass(id _Nullable object OBJC_M68K_REG("a0"), - Class _Nonnull OBJC_M68K_REG("a1")); -extern const char *_Nullable object_getClassName( - id _Nullable object OBJC_M68K_REG("a0")); -extern const char *_Nonnull protocol_getName( - Protocol *_Nonnull p OBJC_M68K_REG("a0")); -extern bool protocol_isEqual(Protocol *_Nonnull a OBJC_M68K_REG("a0"), - Protocol *_Nonnull b OBJC_M68K_REG("a1")); -extern bool protocol_conformsToProtocol( - Protocol *_Nonnull a OBJC_M68K_REG("a0"), - Protocol *_Nonnull b OBJC_M68K_REG("a1")); +extern SEL _Nonnull sel_registerName(const char *_Nonnull name); +extern const char *_Nonnull sel_getName(SEL _Nonnull sel); +extern bool sel_isEqual(SEL _Nonnull sel1, SEL _Nonnull sel2); +extern Class _Nonnull objc_allocateClassPair(Class _Nullable superclass, + const char *_Nonnull name, size_t extra_bytes); +extern void objc_registerClassPair(Class _Nonnull cls); +extern unsigned int objc_getClassList(Class _Nonnull *_Nullable buf, + unsigned int count); +extern Class _Nonnull *_Nonnull objc_copyClassList(unsigned int *_Nullable len); +extern bool class_isMetaClass(Class _Nullable cls); +extern const char *_Nullable class_getName(Class _Nullable cls); +extern Class _Nullable class_getSuperclass(Class _Nullable cls); +extern unsigned long class_getInstanceSize(Class _Nullable cls); +extern bool class_respondsToSelector(Class _Nullable cls, SEL _Nonnull sel); +extern bool class_conformsToProtocol(Class _Nullable cls, Protocol *_Nonnull p); +extern IMP _Nullable class_getMethodImplementation(Class _Nullable cls, + SEL _Nonnull sel); +extern IMP _Nullable class_getMethodImplementation_stret(Class _Nullable cls, + SEL _Nonnull sel); +extern const char *_Nullable class_getMethodTypeEncoding(Class _Nullable cls, + SEL _Nonnull sel); +extern bool class_addMethod(Class _Nonnull cls, SEL _Nonnull sel, + IMP _Nonnull imp, const char *_Nullable types); +extern IMP _Nullable class_replaceMethod(Class _Nonnull cls, SEL _Nonnull sel, + IMP _Nonnull imp, const char *_Nullable types); +extern Class _Nullable object_getClass(id _Nullable object); +extern Class _Nullable object_setClass(id _Nullable object, Class _Nonnull cls); +extern const char *_Nullable object_getClassName(id _Nullable object); +extern const char *_Nonnull protocol_getName(Protocol *_Nonnull p); +extern bool protocol_isEqual(Protocol *_Nonnull a, Protocol *_Nonnull b); +extern bool protocol_conformsToProtocol(Protocol *_Nonnull a, + Protocol *_Nonnull b); extern void objc_exit(void); extern _Nullable objc_uncaught_exception_handler objc_setUncaughtExceptionHandler( - objc_uncaught_exception_handler _Nullable handler OBJC_M68K_REG("a0")); -extern void objc_setForwardHandler(IMP _Nullable forward OBJC_M68K_REG("a0"), - IMP _Nullable forward_stret OBJC_M68K_REG("a1")); + objc_uncaught_exception_handler _Nullable handler); +extern void objc_setForwardHandler(IMP _Nullable forward, + IMP _Nullable forward_stret); extern void objc_setEnumerationMutationHandler( - objc_enumeration_mutation_handler _Nullable handler OBJC_M68K_REG("a0")); -extern void objc_zero_weak_references(id _Nonnull value OBJC_M68K_REG("a0")); -# endif + objc_enumeration_mutation_handler _Nullable handler); +extern void objc_zero_weak_references(id _Nonnull value); /* * Used by the compiler, but can also be called manually. * * These declarations are also required to prevent Clang's implicit @@ -326,14 +279,20 @@ extern void objc_getPropertyStruct(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong); extern void objc_setPropertyStruct(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong); extern void objc_enumerationMutation(id _Nonnull object); -# ifndef OBJC_NO_PERSONALITY_DECLARATION +#ifndef OBJC_NO_PERSONALITY_DECLARATION +/* + * No objfw-defs.h or config.h is available for the installed runtime headers, + * so we don't know which exceptions we have. + */ extern int __gnu_objc_personality_v0(int version, int actions, uint64_t ex_class, void *_Nonnull ex, void *_Nonnull ctx); -# endif +extern int __gnu_objc_personality_sj0(int version, int actions, + uint64_t ex_class, void *_Nonnull ex, void *_Nonnull ctx); +#endif extern id _Nullable objc_retain(id _Nullable object); extern id _Nullable objc_retainBlock(id _Nullable block); extern id _Nullable objc_retainAutorelease(id _Nullable object); extern void objc_release(id _Nullable object); extern id _Nullable objc_autorelease(id _Nullable object); Index: src/runtime/ObjFW_RT.sfd ================================================================== --- src/runtime/ObjFW_RT.sfd +++ src/runtime/ObjFW_RT.sfd @@ -1,74 +1,81 @@ ==base _ObjFWRTBase ==basetype struct Library * ==libname objfw_rt.library ==bias 30 ==public -* Functions for the linklib -bool objc_init(unsigned int version, struct objc_libc *libc, FILE *stdout, FILE *stdin)(d0,a0,a1,a2) -* Used by the compiler - these need glue code -void glue___objc_exec_class(void *_Nonnull module)(a0) -IMP _Nonnull glue_objc_msg_lookup(id _Nullable obj, SEL _Nonnull sel)(a0,a1) -IMP _Nonnull glue_objc_msg_lookup_stret(id _Nullable obj, SEL _Nonnull sel)(a0,a1) -IMP _Nonnull glue_objc_msg_lookup_super(struct objc_super *_Nonnull super, SEL _Nonnull sel)(a0,a1) -IMP _Nonnull glue_objc_msg_lookup_super_stret(struct objc_super *_Nonnull super, SEL _Nonnull sel)(a0,a1) -Class _Nullable glue_objc_lookUpClass(const char *_Nonnull name)(a0) -Class _Nullable glue_objc_getClass(const char *_Nonnull name)(a0) -Class _Nonnull glue_objc_getRequiredClass(const char *_Nonnull name)(a0) -Class _Nullable glue_objc_lookup_class(const char *_Nonnull name)(a0) -Class _Nonnull glue_objc_get_class(const char *_Nonnull name)(a0) -void glue_objc_exception_throw(id _Nonnull object)(a0) -int glue_objc_sync_enter(id _Nullable object)(a0) -int glue_objc_sync_exit(id _Nullable object)(a0) -id glue_objc_getProperty(id _Nonnull self, SEL _Nonnull _cmd, ptrdiff_t offset, bool atomic)(a0,a1,d0,d1) -void glue_objc_setProperty(id _Nonnull self, SEL _Nonnull _cmd, ptrdiff_t offset, id value, bool atomic, signed char copy)(a0,a1,d0,a2,d1,d2) -void glue_objc_getPropertyStruct(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong)(a0,a1,d0,d1,d2) -void glue_objc_setPropertyStruct(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong)(a0,a1,d0,d1,d2) -void glue_objc_enumerationMutation(id _Nonnull obj)(a0) -int glue___gnu_objc_personality_v0(int version, int actions, uint64_t *_Nonnull ex_class, void *_Nonnull ex, void *_Nonnull ctx)(d0,d1,d2,a0,a1) -id _Nullable glue_objc_retain(id _Nullable object)(a0) -id _Nullable glue_objc_retainBlock(id _Nullable block)(a0) -id _Nullable glue_objc_retainAutorelease(id _Nullable object)(a0) -void glue_objc_release(id _Nullable object)(a0) -id _Nullable glue_objc_autorelease(id _Nullable object)(a0) -id _Nullable glue_objc_autoreleaseReturnValue(id _Nullable object)(a0) -id _Nullable glue_objc_retainAutoreleaseReturnValue(id _Nullable object)(a0) -id _Nullable glue_objc_retainAutoreleasedReturnValue(id _Nullable object)(a0) -id _Nullable glue_objc_storeStrong(id _Nullable *_Nonnull object, id _Nullable value)(a0/a1) -id _Nullable glue_objc_storeWeak(id _Nullable *_Nonnull object, id _Nullable value)(a0,a1) -id _Nullable glue_objc_loadWeakRetained(id _Nullable *_Nonnull object)(a0) -id _Nullable glue_objc_initWeak(id _Nullable *_Nonnull object, id _Nullable value)(a0,a1) -void glue_objc_destroyWeak(id _Nullable *_Nonnull object)(a0) -id _Nullable glue_objc_loadWeak(id _Nullable *_Nonnull object)(a0) -void glue_objc_copyWeak(id _Nullable *_Nonnull dest, id _Nullable *_Nonnull src)(a0,a1) -void glue_objc_moveWeak(id _Nullable *_Nonnull dest, id _Nullable *_Nonnull src)(a0,a1) -* Functions declared in ObjFW_RT.h -SEL _Nonnull sel_registerName(const char *_Nonnull name)(a0) -const char *_Nonnull sel_getName(SEL _Nonnull sel)(a0) -bool sel_isEqual(SEL _Nonnull sel1, SEL _Nonnull sel2)(a0,a1) -Class _Nonnull objc_allocateClassPair(Class _Nullable superclass, const char *_Nonnull name, size_t extra_bytes)(a0,a1,d0) -void objc_registerClassPair(Class _Nonnull cls)(a0) -unsigned int objc_getClassList(Class _Nonnull *_Nullable buf, unsigned int count)(a0,d0) -Class _Nonnull *_Nonnull objc_copyClassList(unsigned int *_Nullable)(a0) -bool class_isMetaClass(Class _Nullable cls)(a0) -const char *_Nullable class_getName(Class _Nullable cls)(a0) -Class _Nullable class_getSuperclass(Class _Nullable cls)(a0) -unsigned long class_getInstanceSize(Class _Nullable cls)(a0) -bool class_respondsToSelector(Class _Nullable cls, SEL _Nonnull sel)(a0,a1) -bool class_conformsToProtocol(Class _Nullable cls, Protocol *_Nonnull p)(a0,a1) -IMP _Nullable class_getMethodImplementation(Class _Nullable cls, SEL _Nonnull sel)(a0,a1) -IMP _Nullable class_getMethodImplementation_stret(Class _Nullable cls, SEL _Nonnull sel)(a0,a1) -const char *_Nullable class_getMethodTypeEncoding(Class _Nullable cls, SEL _Nonnull sel)(a0,a1) -bool class_addMethod(Class _Nonnull cls, SEL _Nonnull sel, IMP _Nonnull imp, const char *_Nullable types)(a0,a1,a2,a3) -IMP _Nullable class_replaceMethod(Class _Nonnull cls, SEL _Nonnull sel, IMP _Nonnull imp, const char *_Nullable types)(a0,a1,a2,a3) -Class _Nullable object_getClass(id _Nullable obj)(a0) -Class _Nullable object_setClass(id _Nullable obj, Class _Nonnull)(a0,a1) -const char *_Nullable object_getClassName(id _Nullable obj)(a0) -const char *_Nonnull protocol_getName(Protocol *_Nonnull p)(a0) -bool protocol_isEqual(Protocol *_Nonnull a, Protocol *_Nonnull b)(a0,a1) -bool protocol_conformsToProtocol(Protocol *_Nonnull a, Protocol *_Nonnull b)(a0,a1) -void objc_exit(void)() -_Nullable objc_uncaught_exception_handler objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler _Nullable handler)(a0) -void objc_setForwardHandler(IMP _Nullable forward, IMP _Nullable forward_stret)(a0,a1) -void objc_setEnumerationMutationHandler(objc_enumeration_mutation_handler _Nullable handler)(a0) -void objc_zero_weak_references(id _Nonnull value)(a0) +* Functions that are only for the linklib. +bool objc_init_m68k(unsigned int version, struct objc_libc *libc, FILE *stdout, FILE *stdin)(d0,a0,a1,a2) +* These have a built-in declaration in the compiler that does not use the +* registers and thus always need glue. +void __objc_exec_class_m68k(void *_Nonnull module)(a0) +IMP _Nonnull objc_msg_lookup_m68k(id _Nullable obj, SEL _Nonnull sel)(a0,a1) +IMP _Nonnull objc_msg_lookup_stret_m68k(id _Nullable obj, SEL _Nonnull sel)(a0,a1) +IMP _Nonnull objc_msg_lookup_super_m68k(struct objc_super *_Nonnull super, SEL _Nonnull sel)(a0,a1) +IMP _Nonnull objc_msg_lookup_super_stret_m68k(struct objc_super *_Nonnull super, SEL _Nonnull sel)(a0,a1) +Class _Nullable objc_lookUpClass_m68k(const char *_Nonnull name)(a0) +Class _Nullable objc_getClass_m68k(const char *_Nonnull name)(a0) +Class _Nonnull objc_getRequiredClass_m68k(const char *_Nonnull name)(a0) +Class _Nullable objc_lookup_class_m68k(const char *_Nonnull name)(a0) +Class _Nonnull objc_get_class_m68k(const char *_Nonnull name)(a0) +void objc_exception_throw_m68k(id _Nonnull object)(a0) +int objc_sync_enter_m68k(id _Nullable object)(a0) +int objc_sync_exit_m68k(id _Nullable object)(a0) +id objc_getProperty_m68k(id _Nonnull self, SEL _Nonnull _cmd, ptrdiff_t offset, bool atomic)(a0,a1,d0,d1) +void objc_setProperty_m68k(id _Nonnull self, SEL _Nonnull _cmd, ptrdiff_t offset, id value, bool atomic, signed char copy)(a0,a1,d0,a2,d1,d2) +void objc_getPropertyStruct_m68k(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong)(a0,a1,d0,d1,d2) +void objc_setPropertyStruct_m68k(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong)(a0,a1,d0,d1,d2) +void objc_enumerationMutation_m68k(id _Nonnull obj)(a0) +int __gnu_objc_personality_v0_m68k(int version, int actions, uint64_t *_Nonnull ex_class, void *_Nonnull ex, void *_Nonnull ctx)(d0,d1,d2,a0,a1) +int __gnu_objc_personality_sj0_m68k(int version, int actions, uint64_t *_Nonnull ex_class, void *_Nonnull ex, void *_Nonnull ctx)(d0,d1,d2,a0,a1) +id _Nullable objc_retain_m68k(id _Nullable object)(a0) +id _Nullable objc_retainBlock_m68k(id _Nullable block)(a0) +id _Nullable objc_retainAutorelease_m68k(id _Nullable object)(a0) +void objc_release_m68k(id _Nullable object)(a0) +id _Nullable objc_autorelease_m68k(id _Nullable object)(a0) +id _Nullable objc_autoreleaseReturnValue_m68k(id _Nullable object)(a0) +id _Nullable objc_retainAutoreleaseReturnValue_m68k(id _Nullable object)(a0) +id _Nullable objc_retainAutoreleasedReturnValue_m68k(id _Nullable object)(a0) +id _Nullable objc_storeStrong_m68k(id _Nullable *_Nonnull object, id _Nullable value)(a0/a1) +id _Nullable objc_storeWeak_m68k(id _Nullable *_Nonnull object, id _Nullable value)(a0,a1) +id _Nullable objc_loadWeakRetained_m68k(id _Nullable *_Nonnull object)(a0) +id _Nullable objc_initWeak_m68k(id _Nullable *_Nonnull object, id _Nullable value)(a0,a1) +void objc_destroyWeak_m68k(id _Nullable *_Nonnull object)(a0) +id _Nullable objc_loadWeak_m68k(id _Nullable *_Nonnull object)(a0) +void objc_copyWeak_m68k(id _Nullable *_Nonnull dest, id _Nullable *_Nonnull src)(a0,a1) +void objc_moveWeak_m68k(id _Nullable *_Nonnull dest, id _Nullable *_Nonnull src)(a0,a1) +* These only need glue on MorphOS. As none of them are functions that are used +* in hot paths, it's easier to also use the glue on AmigaOS 3, which also has +* the benefit of having all __saveds in a single place. +SEL _Nonnull sel_registerName_m68k(const char *_Nonnull name)(a0) +const char *_Nonnull sel_getName_m68k(SEL _Nonnull sel)(a0) +bool sel_isEqual_m68k(SEL _Nonnull sel1, SEL _Nonnull sel2)(a0,a1) +Class _Nonnull objc_allocateClassPair_m68k(Class _Nullable superclass, const char *_Nonnull name, size_t extra_bytes)(a0,a1,d0) +void objc_registerClassPair_m68k(Class _Nonnull cls)(a0) +unsigned int objc_getClassList_m68k(Class _Nonnull *_Nullable buf, unsigned int count)(a0,d0) +Class _Nonnull *_Nonnull objc_copyClassList_m68k(unsigned int *_Nullable len)(a0) +bool class_isMetaClass_m68k(Class _Nullable cls)(a0) +const char *_Nullable class_getName_m68k(Class _Nullable cls)(a0) +Class _Nullable class_getSuperclass_m68k(Class _Nullable cls)(a0) +unsigned long class_getInstanceSize_m68k(Class _Nullable cls)(a0) +bool class_respondsToSelector_m68k(Class _Nullable cls, SEL _Nonnull sel)(a0,a1) +bool class_conformsToProtocol_m68k(Class _Nullable cls, Protocol *_Nonnull p)(a0,a1) +IMP _Nullable class_getMethodImplementation_m68k(Class _Nullable cls, SEL _Nonnull sel)(a0,a1) +IMP _Nullable class_getMethodImplementation_stret_m68k(Class _Nullable cls, SEL _Nonnull sel)(a0,a1) +const char *_Nullable class_getMethodTypeEncoding_m68k(Class _Nullable cls, SEL _Nonnull sel)(a0,a1) +bool class_addMethod_m68k(Class _Nonnull cls, SEL _Nonnull sel, IMP _Nonnull imp, const char *_Nullable types)(a0,a1,a2,a3) +IMP _Nullable class_replaceMethod_m68k(Class _Nonnull cls, SEL _Nonnull sel, IMP _Nonnull imp, const char *_Nullable types)(a0,a1,a2,a3) +Class _Nullable object_getClass_m68k(id _Nullable obj)(a0) +Class _Nullable object_setClass_m68k(id _Nullable obj, Class _Nonnull cls)(a0,a1) +const char *_Nullable object_getClassName_m68k(id _Nullable obj)(a0) +const char *_Nonnull protocol_getName_m68k(Protocol *_Nonnull p)(a0) +bool protocol_isEqual_m68k(Protocol *_Nonnull a, Protocol *_Nonnull b)(a0,a1) +bool protocol_conformsToProtocol_m68k(Protocol *_Nonnull a, Protocol *_Nonnull b)(a0,a1) +void objc_exit_m68k(void)() +_Nullable objc_uncaught_exception_handler objc_setUncaughtExceptionHandler_m68k(objc_uncaught_exception_handler _Nullable handler)(a0) +void objc_setForwardHandler_m68k(IMP _Nullable forward, IMP _Nullable forward_stret)(a0,a1) +void objc_setEnumerationMutationHandler_m68k(objc_enumeration_mutation_handler _Nullable handler)(a0) +void objc_zero_weak_references_m68k(id _Nonnull value)(a0) +* SysV functions for MorphOS could be added here for performance. Having them +* in addition to the m68k functions allows m68k applications to call into the +* PPC library, while native code can use the SysV functions. ==end ADDED src/runtime/amiga-end.m Index: src/runtime/amiga-end.m ================================================================== --- src/runtime/amiga-end.m +++ src/runtime/amiga-end.m @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018 + * 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 "platform.h" + +#ifdef OF_MORPHOS +__asm__ ( + ".section .ctors, \"aw\", @progbits\n" + " .long 0\n" +); +#else +__asm__ ( + "" +); +#endif Index: src/runtime/amiga-glue.m ================================================================== --- src/runtime/amiga-glue.m +++ src/runtime/amiga-glue.m @@ -20,229 +20,587 @@ #import "ObjFW_RT.h" #import "private.h" #import "macros.h" void __saveds -glue___objc_exec_class(void *module OBJC_M68K_REG("a0")) +__objc_exec_class_m68k(void) { + OBJC_M68K_ARG(void *, module, a0) + __objc_exec_class(module); } IMP __saveds -glue_objc_msg_lookup(id obj OBJC_M68K_REG("a0"), SEL sel OBJC_M68K_REG("a1")) +objc_msg_lookup_m68k(void) { + OBJC_M68K_ARG(id, obj, a0) + OBJC_M68K_ARG(SEL, sel, a1) + return objc_msg_lookup(obj, sel); } IMP __saveds -glue_objc_msg_lookup_stret(id obj OBJC_M68K_REG("a0"), - SEL sel OBJC_M68K_REG("a1")) +objc_msg_lookup_stret_m68k(void) { + OBJC_M68K_ARG(id, obj, a0) + OBJC_M68K_ARG(SEL, sel, a1) + return objc_msg_lookup_stret(obj, sel); } IMP __saveds -glue_objc_msg_lookup_super(struct objc_super *super OBJC_M68K_REG("a0"), - SEL sel OBJC_M68K_REG("a1")) +objc_msg_lookup_super_m68k(void) { + OBJC_M68K_ARG(struct objc_super *, super, a0) + OBJC_M68K_ARG(SEL, sel, a1) + return objc_msg_lookup_super(super, sel); } IMP __saveds -glue_objc_msg_lookup_super_stret(struct objc_super *super OBJC_M68K_REG("a0"), - SEL sel OBJC_M68K_REG("a1")) +objc_msg_lookup_super_stret_m68k(void) { + OBJC_M68K_ARG(struct objc_super *, super, a0) + OBJC_M68K_ARG(SEL, sel, a1) + return objc_msg_lookup_super_stret(super, sel); } Class __saveds -glue_objc_lookUpClass(const char *name OBJC_M68K_REG("a0")) +objc_lookUpClass_m68k(void) { + OBJC_M68K_ARG(const char *, name, a0) + return objc_lookUpClass(name); } Class __saveds -glue_objc_getClass(const char *name OBJC_M68K_REG("a0")) +objc_getClass_m68k(void) { + OBJC_M68K_ARG(const char *, name, a0) + return objc_getClass(name); } Class __saveds -glue_objc_getRequiredClass(const char *name OBJC_M68K_REG("a0")) +objc_getRequiredClass_m68k(void) { + OBJC_M68K_ARG(const char *, name, a0) + return objc_getRequiredClass(name); } Class __saveds -glue_objc_lookup_class(const char *name OBJC_M68K_REG("a0")) +objc_lookup_class_m68k(void) { + OBJC_M68K_ARG(const char *, name, a0) + return objc_lookup_class(name); } Class __saveds -glue_objc_get_class(const char *name OBJC_M68K_REG("a0")) +objc_get_class_m68k(void) { + OBJC_M68K_ARG(const char *, name, a0) + return objc_get_class(name); } void __saveds -glue_objc_exception_throw(id object OBJC_M68K_REG("a0")) +objc_exception_throw_m68k(void) { + OBJC_M68K_ARG(id, object, a0) + objc_exception_throw(object); OF_UNREACHABLE } int __saveds -glue_objc_sync_enter(id object OBJC_M68K_REG("a0")) +objc_sync_enter_m68k(void) { + OBJC_M68K_ARG(id, object, a0) + return objc_sync_enter(object); } int __saveds -glue_objc_sync_exit(id object OBJC_M68K_REG("a0")) +objc_sync_exit_m68k(void) { + OBJC_M68K_ARG(id, object, a0) + return objc_sync_exit(object); } id __saveds -glue_objc_getProperty(id self OBJC_M68K_REG("a0"), SEL _cmd OBJC_M68K_REG("a1"), - ptrdiff_t offset OBJC_M68K_REG("d0"), bool atomic OBJC_M68K_REG("d1")) +objc_getProperty_m68k(void) { + OBJC_M68K_ARG(id, self, a0) + OBJC_M68K_ARG(SEL, _cmd, a1) + OBJC_M68K_ARG(ptrdiff_t, offset, d0) + OBJC_M68K_ARG(bool, atomic, d1) + return objc_getProperty(self, _cmd, offset, atomic); } void __saveds -glue_objc_setProperty(id self OBJC_M68K_REG("a0"), SEL _cmd OBJC_M68K_REG("a1"), - ptrdiff_t offset OBJC_M68K_REG("d0"), id value OBJC_M68K_REG("a2"), - bool atomic OBJC_M68K_REG("d1"), signed char copy OBJC_M68K_REG("d2")) +objc_setProperty_m68k(void) { + OBJC_M68K_ARG(id, self, a0) + OBJC_M68K_ARG(SEL, _cmd, a1) + OBJC_M68K_ARG(ptrdiff_t, offset, d0) + OBJC_M68K_ARG(id, value, a2) + OBJC_M68K_ARG(bool, atomic, d1) + OBJC_M68K_ARG(signed char, copy, d2) + objc_setProperty(self, _cmd, offset, value, atomic, copy); } void __saveds -glue_objc_getPropertyStruct(void *dest OBJC_M68K_REG("a0"), - const void *src OBJC_M68K_REG("a1"), ptrdiff_t size OBJC_M68K_REG("d0"), - bool atomic OBJC_M68K_REG("d1"), bool strong OBJC_M68K_REG("d2")) +objc_getPropertyStruct_m68k(void) { + OBJC_M68K_ARG(void *, dest, a0) + OBJC_M68K_ARG(const void *, src, a1) + OBJC_M68K_ARG(ptrdiff_t, size, d0) + OBJC_M68K_ARG(bool, atomic, d1) + OBJC_M68K_ARG(bool, strong, d2) + objc_getPropertyStruct(dest, src, size, atomic, strong); } void __saveds -glue_objc_setPropertyStruct(void *dest OBJC_M68K_REG("a0"), - const void *src OBJC_M68K_REG("a1"), ptrdiff_t size OBJC_M68K_REG("d0"), - bool atomic OBJC_M68K_REG("d1"), bool strong OBJC_M68K_REG("d2")) +objc_setPropertyStruct_m68k(void) { + OBJC_M68K_ARG(void *, dest, a0) + OBJC_M68K_ARG(const void *, src, a1) + OBJC_M68K_ARG(ptrdiff_t, size, d0) + OBJC_M68K_ARG(bool, atomic, d1) + OBJC_M68K_ARG(bool, strong, d2) + objc_setPropertyStruct(dest, src, size, atomic, strong); } void __saveds -glue_objc_enumerationMutation(id obj OBJC_M68K_REG("a0")) +objc_enumerationMutation_m68k(void) { + OBJC_M68K_ARG(id, obj, a0) + objc_enumerationMutation(obj); } int __saveds -glue___gnu_objc_personality_v0(int version OBJC_M68K_REG("d0"), - int actions OBJC_M68K_REG("d1"), uint64_t *ex_class OBJC_M68K_REG("d2"), - void *ex OBJC_M68K_REG("a0"), void *ctx OBJC_M68K_REG("a1")) +__gnu_objc_personality_v0_m68k(void) { +#ifndef HAVE_SJLJ_EXCEPTIONS + OBJC_M68K_ARG(int, version, d0) + OBJC_M68K_ARG(int, actions, d1) + OBJC_M68K_ARG(uint64_t *, ex_class, d2) + OBJC_M68K_ARG(void *, ex, a0) + OBJC_M68K_ARG(void *, ctx, a1) + return __gnu_objc_personality_v0(version, actions, *ex_class, ex, ctx); +#else + abort(); + + OF_UNREACHABLE +#endif +} + +int __saveds +__gnu_objc_personality_sj0_m68k(void) +{ +#ifdef HAVE_SJLJ_EXCEPTIONS + OBJC_M68K_ARG(int, version, d0) + OBJC_M68K_ARG(int, actions, d1) + OBJC_M68K_ARG(uint64_t *, ex_class, d2) + OBJC_M68K_ARG(void *, ex, a0) + OBJC_M68K_ARG(void *, ctx, a1) + + return __gnu_objc_personality_sj0(version, actions, *ex_class, ex, ctx); +#else + abort(); + + OF_UNREACHABLE +#endif } id __saveds -glue_objc_retain(id object OBJC_M68K_REG("a0")) +objc_retain_m68k(void) { + OBJC_M68K_ARG(id, object, a0) + return objc_retain(object); } id __saveds -glue_objc_retainBlock(id block OBJC_M68K_REG("a0")) +objc_retainBlock_m68k(void) { + OBJC_M68K_ARG(id, block, a0) + return objc_retainBlock(block); } id __saveds -glue_objc_retainAutorelease(id object OBJC_M68K_REG("a0")) +objc_retainAutorelease_m68k(void) { + OBJC_M68K_ARG(id, object, a0) + return objc_retainAutorelease(object); } void __saveds -glue_objc_release(id object OBJC_M68K_REG("a0")) +objc_release_m68k(void) { + OBJC_M68K_ARG(id, object, a0) + objc_release(object); } id __saveds -glue_objc_autorelease(id object OBJC_M68K_REG("a0")) +objc_autorelease_m68k(void) { + OBJC_M68K_ARG(id, object, a0) + return objc_autorelease(object); } id __saveds -glue_objc_autoreleaseReturnValue(id object OBJC_M68K_REG("a0")) +objc_autoreleaseReturnValue_m68k(void) { + OBJC_M68K_ARG(id, object, a0) + return objc_autoreleaseReturnValue(object); } id __saveds -glue_objc_retainAutoreleaseReturnValue(id object OBJC_M68K_REG("a0")) +objc_retainAutoreleaseReturnValue_m68k(void) { + OBJC_M68K_ARG(id, object, a0) + return objc_retainAutoreleaseReturnValue(object); } id __saveds -glue_objc_retainAutoreleasedReturnValue(id object OBJC_M68K_REG("a0")) +objc_retainAutoreleasedReturnValue_m68k(void) { + OBJC_M68K_ARG(id, object, a0) + return objc_retainAutoreleasedReturnValue(object); } id __saveds -glue_objc_storeStrong(id *object OBJC_M68K_REG("a0"), - id value OBJC_M68K_REG("a1")) +objc_storeStrong_m68k(void) { + OBJC_M68K_ARG(id *, object, a0) + OBJC_M68K_ARG(id, value, a1) + return objc_storeStrong(object, value); } id __saveds -glue_objc_storeWeak(id *object OBJC_M68K_REG("a0"), - id value OBJC_M68K_REG("a1")) +objc_storeWeak_m68k(void) { + OBJC_M68K_ARG(id *, object, a0) + OBJC_M68K_ARG(id, value, a1) + return objc_storeWeak(object, value); } id __saveds -glue_objc_loadWeakRetained(id *object OBJC_M68K_REG("a0")) +objc_loadWeakRetained_m68k(void) { + OBJC_M68K_ARG(id *, object, a0) + return objc_loadWeakRetained(object); } id __saveds -glue_objc_initWeak(id *object OBJC_M68K_REG("a0"), id value OBJC_M68K_REG("a1")) +objc_initWeak_m68k(void) { + OBJC_M68K_ARG(id *, object, a0) + OBJC_M68K_ARG(id, value, a1) + return objc_initWeak(object, value); } void __saveds -glue_objc_destroyWeak(id *object OBJC_M68K_REG("a0")) +objc_destroyWeak_m68k(void) { + OBJC_M68K_ARG(id *, object, a0) + objc_destroyWeak(object); } id __saveds -glue_objc_loadWeak(id *object OBJC_M68K_REG("a0")) +objc_loadWeak_m68k(void) { + OBJC_M68K_ARG(id *, object, a0) + return objc_loadWeak(object); } void __saveds -glue_objc_copyWeak(id *dest OBJC_M68K_REG("a0"), id *src OBJC_M68K_REG("a1")) +objc_copyWeak_m68k(void) { + OBJC_M68K_ARG(id *, dest, a0) + OBJC_M68K_ARG(id *, src, a1) + objc_copyWeak(dest, src); } void __saveds -glue_objc_moveWeak(id *dest OBJC_M68K_REG("a0"), id *src OBJC_M68K_REG("a1")) +objc_moveWeak_m68k(void) { + OBJC_M68K_ARG(id *, dest, a0) + OBJC_M68K_ARG(id *, src, a1) + objc_moveWeak(dest, src); } + +SEL __saveds +sel_registerName_m68k(void) +{ + OBJC_M68K_ARG(const char *, name, a0) + + return sel_registerName(name); +} + +const char *__saveds +sel_getName_m68k(void) +{ + OBJC_M68K_ARG(SEL, sel, a0) + + return sel_getName(sel); +} + +bool __saveds +sel_isEqual_m68k(void) +{ + OBJC_M68K_ARG(SEL, sel1, a0) + OBJC_M68K_ARG(SEL, sel2, a1) + + return sel_isEqual(sel1, sel2); +} + +Class __saveds +objc_allocateClassPair_m68k(void) +{ + OBJC_M68K_ARG(Class, superclass, a0) + OBJC_M68K_ARG(const char *, name, a1) + OBJC_M68K_ARG(size_t, extra_bytes, d0) + + return objc_allocateClassPair(superclass, name, extra_bytes); +} + +void __saveds +objc_registerClassPair_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + + objc_registerClassPair(cls); +} + +unsigned int __saveds +objc_getClassList_m68k(void) +{ + OBJC_M68K_ARG(Class *, buf, a0) + OBJC_M68K_ARG(unsigned int, count, d0) + + return objc_getClassList(buf, count); +} + +Class *__saveds +objc_copyClassList_m68k(void) +{ + OBJC_M68K_ARG(unsigned int *, len, a0) + + return objc_copyClassList(len); +} + +bool __saveds +class_isMetaClass_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + + return class_isMetaClass(cls); +} + +const char *__saveds +class_getName_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + + return class_getName(cls); +} + +Class __saveds +class_getSuperclass_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + + return class_getSuperclass(cls); +} + +unsigned long __saveds +class_getInstanceSize_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + + return class_getInstanceSize(cls); +} + +bool __saveds +class_respondsToSelector_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + OBJC_M68K_ARG(SEL, sel, a1) + + return class_respondsToSelector(cls, sel); +} + +bool __saveds +class_conformsToProtocol_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + OBJC_M68K_ARG(Protocol *, p, a1) + + return class_conformsToProtocol(cls, p); +} + +IMP __saveds +class_getMethodImplementation_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + OBJC_M68K_ARG(SEL, sel, a1) + + return class_getMethodImplementation(cls, sel); +} + +IMP __saveds +class_getMethodImplementation_stret_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + OBJC_M68K_ARG(SEL, sel, a1) + + return class_getMethodImplementation_stret(cls, sel); +} + +const char *__saveds +class_getMethodTypeEncoding_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + OBJC_M68K_ARG(SEL, sel, a1) + + return class_getMethodTypeEncoding(cls, sel); +} + +bool __saveds +class_addMethod_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + OBJC_M68K_ARG(SEL, sel, a1) + OBJC_M68K_ARG(IMP, imp, a2) + OBJC_M68K_ARG(const char *, types, a3) + + return class_addMethod(cls, sel, imp, types); +} + +IMP __saveds +class_replaceMethod_m68k(void) +{ + OBJC_M68K_ARG(Class, cls, a0) + OBJC_M68K_ARG(SEL, sel, a1) + OBJC_M68K_ARG(IMP, imp, a2) + OBJC_M68K_ARG(const char *, types, a3) + + return class_replaceMethod(cls, sel, imp, types); +} + +Class __saveds +object_getClass_m68k(void) +{ + OBJC_M68K_ARG(id, object, a0) + + return object_getClass(object); +} + +Class __saveds +object_setClass_m68k(void) +{ + OBJC_M68K_ARG(id, object, a0) + OBJC_M68K_ARG(Class, cls, a1) + + return object_setClass(object, cls); +} + +const char *__saveds +object_getClassName_m68k(void) +{ + OBJC_M68K_ARG(id, object, a0) + + return object_getClassName(object); +} + +const char *__saveds +protocol_getName_m68k(void) +{ + OBJC_M68K_ARG(Protocol *, p, a0) + + return protocol_getName(p); +} + +bool __saveds +protocol_isEqual_m68k(void) +{ + OBJC_M68K_ARG(Protocol *, a, a0) + OBJC_M68K_ARG(Protocol *, b, a1) + + return protocol_isEqual(a, b); +} + +bool __saveds +protocol_conformsToProtocol_m68k(void) +{ + OBJC_M68K_ARG(Protocol *, a, a0) + OBJC_M68K_ARG(Protocol *, b, a1) + + return protocol_conformsToProtocol(a, b); +} + +void __saveds +objc_exit_m68k(void) +{ + objc_exit(); +} + +objc_uncaught_exception_handler __saveds +objc_setUncaughtExceptionHandler_m68k(void) +{ + OBJC_M68K_ARG(objc_uncaught_exception_handler, handler, a0) + + return objc_setUncaughtExceptionHandler(handler); +} + +void __saveds +objc_setForwardHandler_m68k(void) +{ + OBJC_M68K_ARG(IMP, forward, a0) + OBJC_M68K_ARG(IMP, forward_stret, a1) + + objc_setForwardHandler(forward, forward_stret); +} + +void __saveds +objc_setEnumerationMutationHandler_m68k(void) +{ + OBJC_M68K_ARG(objc_enumeration_mutation_handler, handler, a0) + + objc_setEnumerationMutationHandler(handler); +} + +void __saveds +objc_zero_weak_references_m68k(void) +{ + OBJC_M68K_ARG(id, value, a0) + + objc_zero_weak_references(value); +} Index: src/runtime/amiga-library.m ================================================================== --- src/runtime/amiga-library.m +++ src/runtime/amiga-library.m @@ -17,11 +17,10 @@ #include "config.h" #import "ObjFW_RT.h" #import "private.h" -#import "platform.h" #ifdef OF_AMIGAOS3 # define INTUITION_CLASSES_H #endif @@ -32,11 +31,21 @@ #define CONCAT_VERSION2(major, minor) #major "." #minor #define CONCAT_VERSION(major, minor) CONCAT_VERSION2(major, minor) #define VERSION_STRING CONCAT_VERSION(OBJFW_RT_LIB_MAJOR, OBJFW_RT_LIB_MINOR) -#define DATA_OFFSET 0x7FFE +#if defined(OF_AMIGAOS3) +# define DATA_OFFSET 0x7FFE +#elif defined(OF_MORPHOS) +# define DATA_OFFSET 0x8000 +#endif + +#ifdef OF_AMIGAOS3 +# define OBJC_M68K_REG(reg) __asm__ (#reg) +#else +# define OBJC_M68K_REG(reg) +#endif /* This always needs to be the first thing in the file. */ int _start() { @@ -47,78 +56,213 @@ struct Library library; void *seg_list; struct ObjFWRTBase *parent; char *data_seg; bool initialized; - struct objc_libc libc; }; -extern uintptr_t __CTOR_LIST__[], __DTOR_LIST__[]; +#ifdef OF_AMIGAOS3 +extern uintptr_t __CTOR_LIST__[]; extern const void *_EH_FRAME_BEGINS__; extern void *_EH_FRAME_OBJECTS__; -extern void *__a4_init, *__data_size; +#endif + +extern void __objc_exec_class_m68k(void); +extern IMP _Nonnull objc_msg_lookup_m68k(void); +extern IMP _Nonnull objc_msg_lookup_stret_m68k(void); +extern IMP _Nonnull objc_msg_lookup_super_m68k(void); +extern IMP _Nonnull objc_msg_lookup_super_stret_m68k(void); +extern Class _Nullable objc_lookUpClass_m68k(void); +extern Class _Nullable objc_getClass_m68k(void); +extern Class _Nonnull objc_getRequiredClass_m68k(void); +extern Class _Nullable objc_lookup_class_m68k(void); +extern Class _Nonnull objc_get_class_m68k(void); +extern void objc_exception_throw_m68k(void); +extern int objc_sync_enter_m68k(void); +extern int objc_sync_exit_m68k(void); +extern id _Nullable objc_getProperty_m68k(void); +extern void objc_setProperty_m68k(void); +extern void objc_getPropertyStruct_m68k(void); +extern void objc_setPropertyStruct_m68k(void); +extern void objc_enumerationMutation_m68k(void); +extern int __gnu_objc_personality_sj0_m68k(void); +extern int __gnu_objc_personality_v0_m68k(void); +extern id _Nullable objc_retain_m68k(void); +extern id _Nullable objc_retainBlock_m68k(void); +extern id _Nullable objc_retainAutorelease_m68k(void); +extern void objc_release_m68k(void); +extern id _Nullable objc_autorelease_m68k(void); +extern id _Nullable objc_autoreleaseReturnValue_m68k(void); +extern id _Nullable objc_retainAutoreleaseReturnValue_m68k(void); +extern id _Nullable objc_retainAutoreleasedReturnValue_m68k(void); +extern id _Nullable objc_storeStrong_m68k(void); +extern id _Nullable objc_storeWeak_m68k(void); +extern id _Nullable objc_loadWeakRetained_m68k(void); +extern id _Nullable objc_initWeak_m68k(void); +extern void objc_destroyWeak_m68k(void); +extern id _Nullable objc_loadWeak_m68k(void); +extern void objc_copyWeak_m68k(void); +extern void objc_moveWeak_m68k(void); +extern SEL _Nonnull sel_registerName_m68k(void); +extern const char *_Nonnull sel_getName_m68k(void); +extern bool sel_isEqual_m68k(void); +extern Class _Nonnull objc_allocateClassPair_m68k(void); +extern void objc_registerClassPair_m68k(void); +extern unsigned int objc_getClassList_m68k(void); +extern Class _Nonnull *_Nonnull objc_copyClassList_m68k(void); +extern bool class_isMetaClass_m68k(void); +extern const char *_Nullable class_getName_m68k(void); +extern Class _Nullable class_getSuperclass_m68k(void); +extern unsigned long class_getInstanceSize_m68k(void); +extern bool class_respondsToSelector_m68k(void); +extern bool class_conformsToProtocol_m68k(void); +extern IMP _Nullable class_getMethodImplementation_m68k(void); +extern IMP _Nullable class_getMethodImplementation_stret_m68k(void); +extern const char *_Nullable class_getMethodTypeEncoding_m68k(void); +extern bool class_addMethod_m68k(void); +extern IMP _Nullable class_replaceMethod_m68k(void); +extern Class _Nullable object_getClass_m68k(void); +extern Class _Nullable object_setClass_m68k(void); +extern const char *_Nullable object_getClassName_m68k(void); +extern const char *_Nonnull protocol_getName_m68k(void); +extern bool protocol_isEqual_m68k(void); +extern bool protocol_conformsToProtocol_m68k(void); +extern void objc_exit_m68k(void); +extern _Nullable objc_uncaught_exception_handler + objc_setUncaughtExceptionHandler_m68k(void); +extern void objc_setForwardHandler_m68k(void); +extern void objc_setEnumerationMutationHandler_m68k(void); +extern void objc_zero_weak_references_m68k(void); #ifdef OF_MORPHOS const ULONG __abox__ = 1; #endif struct ExecBase *SysBase; +struct objc_libc libc; FILE *stdout; FILE *stderr; +#if defined(OF_AMIGAOS3) __asm__ ( ".text\n" ".globl ___restore_a4\n" ".align 1\n" "___restore_a4:\n" " movea.l 42(a6), a4\n" " rts" ); +#elif defined(OF_MORPHOS) +__asm__ ( + ".section .text\n" + ".globl __restore_r13\n" + ".align 2\n" + "__restore_r13:\n" + " lwz %r13, 56(%r2)\n" + " lwz %r13, 44(%r13)\n" + " blr\n" + ".type __restore_r13, @function\n" + ".size __restore_r13, .-__restore_r13" +); +#endif static OF_INLINE char * get_data_seg(void) { char *data_seg; - __asm__ __volatile__ ( - "move.l #___a4_init, %0" : "=r"(data_seg) +#if defined(OF_AMIGAOS3) + __asm__ ( + "move.l #___a4_init, %0" + : "=r"(data_seg) + ); +#elif defined(OF_MORPHOS) + __asm__ ( + "lis %0, __r13_init@ha\n\t" + "la %0, __r13_init@l(%0)" + : "=r"(data_seg) ); +#endif return data_seg; } + +static OF_INLINE size_t +get_data_size(void) +{ + size_t data_size; + +#if defined(OF_AMIGAOS3) + __asm__ ( + "move.l #___data_size, %0" + : "=r"(data_size) + ); +#elif defined(OF_MORPHOS) + __asm__ ( + "lis %0, __sdata_size@ha\n\t" + "la %0, __sdata_size@l(%0)\n\t" + "lis %%r9, __sbss_size@ha\n\t" + "la %%r9, __sbss_size@l(%%r9)\n\t" + "add %0, %0, %%r9" + : "=r"(data_size) + :: "r9" + ); +#endif + + return data_size; +} static OF_INLINE size_t * get_datadata_relocs(void) { size_t *datadata_relocs; - __asm__ __volatile__ ( - "move.l #___datadata_relocs, %0" : "=r"(datadata_relocs) +#if defined(OF_AMIGAOS3) + __asm__ ( + "move.l #___datadata_relocs, %0" + : "=r"(datadata_relocs) + ); +#elif defined(OF_MORPHOS) + __asm__ ( + "lis %0, __datadata_relocs@ha\n\t" + "la %0, __datadata_relocs@l(%0)\n\t" + : "=r"(datadata_relocs) ); +#endif return datadata_relocs; } static struct Library * -lib_init(struct ExecBase *sys_base OBJC_M68K_REG("a6"), - void *seg_list OBJC_M68K_REG("a0"), - struct ObjFWRTBase *base OBJC_M68K_REG("d0")) +lib_init(struct ObjFWRTBase *base OBJC_M68K_REG(d0), + void *seg_list OBJC_M68K_REG(a0), + struct ExecBase *sys_base OBJC_M68K_REG(a6)) { +#if defined(OF_AMIGAOS3) + __asm__ __volatile__ ( + "move.l a6, _SysBase" + :: "a"(sys_base) + ); +#elif defined(OF_MORPHOS) __asm__ __volatile__ ( - "move.l a6, _SysBase" :: "a"(sys_base) + "lis %%r9, SysBase@ha\n\t" + "stw %0, SysBase@l(%%r9)" + :: "r"(sys_base) : "r9" ); +#endif base->seg_list = seg_list; base->parent = NULL; base->data_seg = get_data_seg(); return &base->library; } struct Library *__saveds -OBJC_M68K_FUNC(lib_open, struct ObjFWRTBase *base OBJC_M68K_REG("a6")) +lib_open(void) { - OBJC_M68K_ARG(struct ObjFWRTBase *, base, REG_A6) + OBJC_M68K_ARG(struct ObjFWRTBase *, base, a6) + struct ObjFWRTBase *child; size_t data_size, *datadata_relocs; ptrdiff_t displacement; if (base->parent != NULL) @@ -143,12 +287,11 @@ child = (struct ObjFWRTBase *) ((char *)child + base->library.lib_NegSize); child->library.lib_OpenCnt = 1; child->parent = base; - data_size = (uintptr_t)&__data_size - - ((uintptr_t)&__a4_init - DATA_OFFSET); + data_size = get_data_size(); if ((child->data_seg = AllocMem(data_size, MEMF_ANY)) == NULL) { FreeMem((char *)child - child->library.lib_NegSize, child->library.lib_NegSize + child->library.lib_PosSize); base->library.lib_OpenCnt--; @@ -191,34 +334,35 @@ return seg_list; } static void *__saveds -OBJC_M68K_FUNC(lib_expunge, struct ObjFWRTBase *base OBJC_M68K_REG("a6")) +lib_expunge(void) { - OBJC_M68K_ARG(struct ObjFWRTBase *, base, REG_A6) + OBJC_M68K_ARG(struct ObjFWRTBase *, base, a6) return expunge(base); } static void *__saveds -OBJC_M68K_FUNC(lib_close, struct ObjFWRTBase *base OBJC_M68K_REG("a6")) +lib_close(void) { - OBJC_M68K_ARG(struct ObjFWRTBase *, base, REG_A6) + OBJC_M68K_ARG(struct ObjFWRTBase *, base, a6) if (base->parent != NULL) { struct ObjFWRTBase *parent; +#ifdef OF_AMIGAOS3 if (base->initialized) for (size_t i = 1; i <= (size_t)_EH_FRAME_BEGINS__; i++) - base->libc.__deregister_frame_info( + libc.__deregister_frame_info( (&_EH_FRAME_BEGINS__)[i]); +#endif parent = base->parent; - FreeMem(base->data_seg - DATA_OFFSET, (uintptr_t)&__data_size - - ((uintptr_t)&__a4_init - DATA_OFFSET)); + FreeMem(base->data_seg - DATA_OFFSET, get_data_size()); FreeMem((char *)base - base->library.lib_NegSize, base->library.lib_NegSize + base->library.lib_PosSize); base = parent; } @@ -225,43 +369,54 @@ if (--base->library.lib_OpenCnt == 0 && (base->library.lib_Flags & LIBF_DELEXP)) return expunge(base); - return 0; + return NULL; } static void * lib_null(void) { - return 0; + return NULL; } static bool __saveds -objc_init(unsigned int version OBJC_M68K_REG("d0"), - struct objc_libc *libc OBJC_M68K_REG("a0"), - FILE *stdout_ OBJC_M68K_REG("a1"), FILE *stderr_ OBJC_M68K_REG("a2")) +objc_init_m68k(void) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); + OBJC_M68K_ARG(struct ObjFWRTBase *, base, a6) + OBJC_M68K_ARG(unsigned int, version, d0) + OBJC_M68K_ARG(struct objc_libc *, libc_, a0) + OBJC_M68K_ARG(FILE *, stdout_, a1) + OBJC_M68K_ARG(FILE *, stderr_, a2) + uintptr_t *iter, *iter0; if (version > 1) return false; - memcpy(&base->libc, libc, sizeof(base->libc)); - + memcpy(&libc, libc_, sizeof(libc)); stdout = stdout_; stderr = stderr_; +#ifdef OF_AMIGAOS3 if ((size_t)_EH_FRAME_BEGINS__ != (size_t)_EH_FRAME_OBJECTS__) return false; for (size_t i = 1; i <= (size_t)_EH_FRAME_BEGINS__; i++) - base->libc.__register_frame_info((&_EH_FRAME_BEGINS__)[i], + libc.__register_frame_info((&_EH_FRAME_BEGINS__)[i], (&_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) + ); +#endif + for (iter = iter0; *iter != 0; iter++); while (iter > iter0) { void (*ctor)(void) = (void (*)(void))*--iter; ctor(); @@ -273,204 +428,210 @@ } void * malloc(size_t size) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - return base->libc.malloc(size); + return libc.malloc(size); } void * calloc(size_t count, size_t size) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - return base->libc.calloc(count, size); + return libc.calloc(count, size); } void * realloc(void *ptr, size_t size) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - return base->libc.realloc(ptr, size); + return libc.realloc(ptr, size); } void free(void *ptr) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - base->libc.free(ptr); + libc.free(ptr); } int fprintf(FILE *restrict stream, const char *restrict fmt, ...) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); int ret; va_list args; va_start(args, fmt); - ret = base->libc.vfprintf(stream, fmt, args); + ret = libc.vfprintf(stream, fmt, args); va_end(args); return ret; } int fflush(FILE *restrict stream) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - return base->libc.fflush(stream); + return libc.fflush(stream); } void exit(int status) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); + libc.exit(status); - base->libc.exit(status); + OF_UNREACHABLE } void abort(void) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); + libc.abort(); - base->libc.abort(); + OF_UNREACHABLE } +#ifdef HAVE_SJLJ_EXCEPTIONS +int +_Unwind_SjLj_RaiseException(void *ex) +{ + return libc._Unwind_SjLj_RaiseException(ex); +} +#else int _Unwind_RaiseException(void *ex) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - return base->libc._Unwind_RaiseException(ex); + return libc._Unwind_RaiseException(ex); } +#endif void _Unwind_DeleteException(void *ex) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - base->libc._Unwind_DeleteException(ex); + libc._Unwind_DeleteException(ex); } void * _Unwind_GetLanguageSpecificData(void *ctx) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - return base->libc._Unwind_GetLanguageSpecificData(ctx); + return libc._Unwind_GetLanguageSpecificData(ctx); } uintptr_t _Unwind_GetRegionStart(void *ctx) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - return base->libc._Unwind_GetRegionStart(ctx); + return libc._Unwind_GetRegionStart(ctx); } uintptr_t _Unwind_GetDataRelBase(void *ctx) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - return base->libc._Unwind_GetDataRelBase(ctx); + return libc._Unwind_GetDataRelBase(ctx); } uintptr_t _Unwind_GetTextRelBase(void *ctx) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - return base->libc._Unwind_GetTextRelBase(ctx); + return libc._Unwind_GetTextRelBase(ctx); } uintptr_t _Unwind_GetIP(void *ctx) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - return base->libc._Unwind_GetIP(ctx); + return libc._Unwind_GetIP(ctx); } uintptr_t _Unwind_GetGR(void *ctx, int gr) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - return base->libc._Unwind_GetGR(ctx, gr); + return libc._Unwind_GetGR(ctx, gr); } void _Unwind_SetIP(void *ctx, uintptr_t ip) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - base->libc._Unwind_SetIP(ctx, ip); + libc._Unwind_SetIP(ctx, ip); } void _Unwind_SetGR(void *ctx, int gr, uintptr_t value) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - base->libc._Unwind_SetGR(ctx, gr, value); + libc._Unwind_SetGR(ctx, gr, value); } +#ifdef HAVE_SJLJ_EXCEPTIONS +void +_Unwind_SjLj_Resume(void *ex) +{ + libc._Unwind_SjLj_Resume(ex); +} +#else void _Unwind_Resume(void *ex) { - register struct ObjFWRTBase *base OBJC_M68K_REG("a6"); - - base->libc._Unwind_Resume(ex); + libc._Unwind_Resume(ex); } +#endif #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" static CONST_APTR function_table[] = { +#ifdef OF_MORPHOS + (CONST_APTR)FUNCARRAY_BEGIN, + (CONST_APTR)FUNCARRAY_32BIT_NATIVE, +#endif (CONST_APTR)lib_open, (CONST_APTR)lib_close, (CONST_APTR)lib_expunge, (CONST_APTR)lib_null, #include "amiga-library-functable.inc" (CONST_APTR)-1, +#ifdef OF_MORPHOS + (CONST_APTR)FUNCARRAY_END +#endif }; #pragma GCC diagnostic pop static struct { ULONG data_size; CONST_APTR *function_table; ULONG *data_table; struct Library *(*init_func)( - struct ExecBase *exec_base OBJC_M68K_REG("a6"), - void *seg_list OBJC_M68K_REG("a0"), - struct ObjFWRTBase *base OBJC_M68K_REG("d0")); + struct ObjFWRTBase *base OBJC_M68K_REG(d0), + void *seg_list OBJC_M68K_REG(a0), + struct ExecBase *exec_base OBJC_M68K_REG(a6)); } init_table = { sizeof(struct ObjFWRTBase), function_table, NULL, lib_init }; -static struct Resident resident = { +struct Resident resident = { .rt_MatchWord = RTC_MATCHWORD, .rt_MatchTag = &resident, .rt_EndSkip = &resident + 1, .rt_Flags = RTF_AUTOINIT #ifndef OF_AMIGAOS3 | RTF_PPC #endif +#ifdef OF_MORPHOS + | RTF_EXTENDED +#endif , .rt_Version = OBJFW_RT_LIB_MAJOR, .rt_Type = NT_LIBRARY, .rt_Pri = 0, .rt_Name = (char *)"objfw_rt.library", .rt_IdString = (char *)"ObjFW_RT " VERSION_STRING " \xA9 2008-2018 Jonathan Schleifer", - .rt_Init = &init_table + .rt_Init = &init_table, +#ifdef OF_MORPHOS + .rt_Revision = OBJFW_RT_LIB_MINOR, + .rt_Tags = NULL, +#endif }; + +#ifdef OF_MORPHOS +__asm__ ( + ".section .ctors, \"aw\", @progbits\n" + "ctors:\n" + " .long -1\n" + ".section .text" +); +#endif Index: src/runtime/arc.m ================================================================== --- src/runtime/arc.m +++ src/runtime/arc.m @@ -268,12 +268,12 @@ if (!of_spinlock_unlock(&spinlock)) OBJC_ERROR("Failed to unlock spinlock!") #endif } -void __saveds -objc_zero_weak_references(id value OBJC_M68K_REG("a0")) +void +objc_zero_weak_references(id value) { struct weak_ref *ref; #ifdef OF_HAVE_THREADS if (!of_spinlock_lock(&spinlock)) Index: src/runtime/class.m ================================================================== --- src/runtime/class.m +++ src/runtime/class.m @@ -414,14 +414,12 @@ } process_load_queue(); } -Class __saveds -objc_allocateClassPair(Class superclass OBJC_M68K_REG("a0"), - const char *name OBJC_M68K_REG("a1"), - size_t extra_bytes OBJC_M68K_REG("d0")) +Class +objc_allocateClassPair(Class superclass, const char *name, size_t extra_bytes) { struct objc_class *cls, *metaclass; Class iter, rootclass = Nil; if (extra_bytes > LONG_MAX) @@ -450,12 +448,12 @@ superclass->isa->instance_size : 0) + (long)extra_bytes; return cls; } -void __saveds -objc_registerClassPair(Class cls OBJC_M68K_REG("a0")) +void +objc_registerClassPair(Class cls) { objc_global_mutex_lock(); register_class((struct objc_abi_class *)cls); @@ -527,13 +525,12 @@ objc_get_class(const char *name) { return objc_getRequiredClass(name); } -unsigned int __saveds -objc_getClassList(Class *buf OBJC_M68K_REG("a0"), - unsigned int count OBJC_M68K_REG("d0")) +unsigned int +objc_getClassList(Class *buf, unsigned int count) { unsigned int j; objc_global_mutex_lock(); if (buf == NULL) @@ -568,12 +565,12 @@ objc_global_mutex_unlock(); return j; } -Class *__saveds -objc_copyClassList(unsigned int *len OBJC_M68K_REG("a0")) +Class * +objc_copyClassList(unsigned int *len) { Class *ret; unsigned int count; objc_global_mutex_lock(); @@ -592,49 +589,48 @@ objc_global_mutex_unlock(); return ret; } -bool __saveds -class_isMetaClass(Class cls OBJC_M68K_REG("a0")) +bool +class_isMetaClass(Class cls) { if (cls == Nil) return false; return (cls->info & OBJC_CLASS_INFO_METACLASS); } -const char *__saveds -class_getName(Class cls OBJC_M68K_REG("a0")) +const char * +class_getName(Class cls) { if (cls == Nil) return ""; return cls->name; } -Class __saveds -class_getSuperclass(Class cls OBJC_M68K_REG("a0")) +Class +class_getSuperclass(Class cls) { if (cls == Nil) return Nil; return cls->superclass; } -unsigned long __saveds -class_getInstanceSize(Class cls OBJC_M68K_REG("a0")) +unsigned long +class_getInstanceSize(Class cls) { if (cls == Nil) return 0; return cls->instance_size; } -IMP __saveds -class_getMethodImplementation(Class cls OBJC_M68K_REG("a0"), - SEL sel OBJC_M68K_REG("a1")) +IMP +class_getMethodImplementation(Class cls, SEL sel) { /* * We use a dummy object here so that the normal lookup is used, even * though we don't have an object. Doing so is safe, as objc_msg_lookup * does not access the object, but only its class. @@ -653,13 +649,12 @@ dummy.isa = cls; return objc_msg_lookup((id)&dummy, sel); } -IMP __saveds -class_getMethodImplementation_stret(Class cls OBJC_M68K_REG("a0"), - SEL sel OBJC_M68K_REG("a1")) +IMP +class_getMethodImplementation_stret(Class cls, SEL sel) { /* * Same as above, but use objc_msg_lookup_stret instead, so that the * correct forwarding handler is returned. */ @@ -721,13 +716,12 @@ cls->methodlist = ml; objc_update_dtable(cls); } -const char *__saveds -class_getMethodTypeEncoding(Class cls OBJC_M68K_REG("a0"), - SEL sel OBJC_M68K_REG("a1")) +const char * +class_getMethodTypeEncoding(Class cls, SEL sel) { struct objc_method *method; if (cls == Nil) return NULL; @@ -746,13 +740,12 @@ return class_getMethodTypeEncoding(cls->superclass, sel); return NULL; } -bool __saveds -class_addMethod(Class cls OBJC_M68K_REG("a0"), SEL sel OBJC_M68K_REG("a1"), - IMP imp OBJC_M68K_REG("a2"), const char *types OBJC_M68K_REG("a3")) +bool +class_addMethod(Class cls, SEL sel, IMP imp, const char *types) { bool ret; objc_global_mutex_lock(); @@ -765,13 +758,12 @@ objc_global_mutex_unlock(); return ret; } -IMP __saveds -class_replaceMethod(Class cls OBJC_M68K_REG("a0"), SEL sel OBJC_M68K_REG("a1"), - IMP newimp OBJC_M68K_REG("a2"), const char *types OBJC_M68K_REG("a3")) +IMP +class_replaceMethod(Class cls, SEL sel, IMP newimp, const char *types) { struct objc_method *method; IMP oldimp; objc_global_mutex_lock(); @@ -788,12 +780,12 @@ objc_global_mutex_unlock(); return oldimp; } -Class __saveds -object_getClass(id obj_ OBJC_M68K_REG("a0")) +Class +object_getClass(id obj_) { struct objc_object *obj; if (obj_ == nil) return Nil; @@ -801,12 +793,12 @@ obj = (struct objc_object *)obj_; return obj->isa; } -Class __saveds -object_setClass(id obj_ OBJC_M68K_REG("a0"), Class cls OBJC_M68K_REG("a1")) +Class +object_setClass(id obj_, Class cls) { struct objc_object *obj; Class old; if (obj_ == nil) @@ -818,12 +810,12 @@ obj->isa = cls; return old; } -const char *__saveds -object_getClassName(id obj OBJC_M68K_REG("a0")) +const char * +object_getClassName(id obj) { return class_getName(object_getClass(obj)); } static void Index: src/runtime/exception.m ================================================================== --- src/runtime/exception.m +++ src/runtime/exception.m @@ -758,13 +758,12 @@ uncaught_exception_handler(object); OBJC_ERROR("_Unwind_RaiseException() returned!") } -objc_uncaught_exception_handler __saveds -objc_setUncaughtExceptionHandler( - objc_uncaught_exception_handler handler OBJC_M68K_REG("a0")) +objc_uncaught_exception_handler +objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler handler) { objc_uncaught_exception_handler old = uncaught_exception_handler; uncaught_exception_handler = handler; return old; Index: src/runtime/linklib/linklib.m ================================================================== --- src/runtime/linklib/linklib.m +++ src/runtime/linklib/linklib.m @@ -19,54 +19,62 @@ #import "ObjFW_RT.h" #import "private.h" #import "macros.h" +#ifdef OF_AMIGAOS3 +# define INTUITION_CLASSES_H +#endif #include + +#import "inline.h" + #include #include +#ifdef HAVE_SJLJ_EXCEPTIONS +extern int _Unwind_SjLj_RaiseException(void *); +#else extern int _Unwind_RaiseException(void *); +#endif extern void _Unwind_DeleteException(void *); extern void *_Unwind_GetLanguageSpecificData(void *); extern uintptr_t _Unwind_GetRegionStart(void *); extern uintptr_t _Unwind_GetDataRelBase(void *); extern uintptr_t _Unwind_GetTextRelBase(void *); extern uintptr_t _Unwind_GetIP(void *); extern uintptr_t _Unwind_GetGR(void *, int); extern void _Unwind_SetIP(void *, uintptr_t); extern void _Unwind_SetGR(void *, int, uintptr_t); +#ifdef HAVE_SJLJ_EXCEPTIONS +extern void _Unwind_SjLj_Resume(void *); +#else extern void _Unwind_Resume(void *); +#endif extern void __register_frame_info(const void *, void *); extern void __deregister_frame_info(const void *); struct Library *ObjFWRTBase; static void __attribute__((__constructor__)) init(void) { static bool initialized = false; - static struct objc_libc libc; - - if (initialized) - return; - - if ((ObjFWRTBase = OpenLibrary("objfw_rt.library", 0)) == NULL) { - fputs("Failed to open objfw_rt.library!\n", stderr); - abort(); - } - - libc = (struct objc_libc){ + struct objc_libc libc = { .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free, .vfprintf = vfprintf, .fflush = fflush, .exit = exit, .abort = abort, +#ifdef HAVE_SJLJ_EXCEPTIONS + ._Unwind_SjLj_RaiseException = _Unwind_SjLj_RaiseException, +#else ._Unwind_RaiseException = _Unwind_RaiseException, +#endif ._Unwind_DeleteException = _Unwind_DeleteException, ._Unwind_GetLanguageSpecificData = _Unwind_GetLanguageSpecificData, ._Unwind_GetRegionStart = _Unwind_GetRegionStart, ._Unwind_GetDataRelBase = _Unwind_GetDataRelBase, @@ -73,16 +81,28 @@ ._Unwind_GetTextRelBase = _Unwind_GetTextRelBase, ._Unwind_GetIP = _Unwind_GetIP, ._Unwind_GetGR = _Unwind_GetGR, ._Unwind_SetIP = _Unwind_SetIP, ._Unwind_SetGR = _Unwind_SetGR, +#ifdef HAVE_SJLJ_EXCEPTIONS + ._Unwind_SjLj_Resume = _Unwind_SjLj_Resume, +#else ._Unwind_Resume = _Unwind_Resume, +#endif .__register_frame_info = __register_frame_info, .__deregister_frame_info = __deregister_frame_info, }; - if (!objc_init(1, &libc, stdout, stderr)) { + if (initialized) + return; + + if ((ObjFWRTBase = OpenLibrary("objfw_rt.library", 0)) == NULL) { + fputs("Failed to open objfw_rt.library!\n", stderr); + abort(); + } + + if (!objc_init_m68k(1, &libc, stdout, stderr)) { fputs("Failed to initialize objfw_rt.library!\n", stderr); abort(); } initialized = true; @@ -100,70 +120,71 @@ * The compiler generates constructors that call into this, so it is * possible that we are not set up yet when we get called. */ init(); - glue___objc_exec_class(module); + __objc_exec_class_m68k(module); } IMP objc_msg_lookup(id obj, SEL sel) { - return glue_objc_msg_lookup(obj, sel); + return objc_msg_lookup_m68k(obj, sel); } IMP objc_msg_lookup_stret(id obj, SEL sel) { - return glue_objc_msg_lookup_stret(obj, sel); + return objc_msg_lookup_stret_m68k(obj, sel); } IMP objc_msg_lookup_super(struct objc_super *super, SEL sel) { - return glue_objc_msg_lookup_super(super, sel); + return objc_msg_lookup_super_m68k(super, sel); } IMP objc_msg_lookup_super_stret(struct objc_super *super, SEL sel) { - return glue_objc_msg_lookup_super_stret(super, sel); + return objc_msg_lookup_super_stret_m68k(super, sel); } Class objc_lookUpClass(const char *name) { - return glue_objc_lookUpClass(name); + return objc_lookUpClass_m68k(name); } Class objc_getClass(const char *name) { - return glue_objc_getClass(name); + return objc_getClass_m68k(name); } Class objc_getRequiredClass(const char *name) { - return glue_objc_getRequiredClass(name); + return objc_getRequiredClass_m68k(name); } Class objc_lookup_class(const char *name) { - return glue_objc_lookup_class(name); + return objc_lookup_class_m68k(name); } Class objc_get_class(const char *name) { - return glue_objc_get_class(name); + return objc_get_class_m68k(name); } void objc_exception_throw(id object) { +#ifdef OF_AMIGAOS3 /* * This does not use the glue code to hack around a compiler bug. * * When using the generated inline stubs, the compiler does not emit * any frame information, making the unwind fail. As unwind always @@ -170,60 +191,64 @@ * starts from objc_exception_throw(), this means exceptions would * never work. If, however, we're using a function pointer instead of * the inline stub, the compiler does generate a frame and everything * works fine. */ - register void *a6 OBJC_M68K_REG("a6") = ObjFWRTBase; + register void *a6 __asm__("a6") = ObjFWRTBase; uintptr_t throw = (((uintptr_t)ObjFWRTBase) - 0x60); - ((void (*)(id OBJC_M68K_REG("a0")))throw)(object); + ((void (*)(id __asm__("a0")))throw)(object); (void)a6; +#else + objc_exception_throw_m68k(object); +#endif OF_UNREACHABLE } int objc_sync_enter(id object) { - return glue_objc_sync_enter(object); + return objc_sync_enter_m68k(object); } int objc_sync_exit(id object) { - return glue_objc_sync_exit(object); + return objc_sync_exit_m68k(object); } id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, bool atomic) { - return glue_objc_getProperty(self, _cmd, offset, atomic); + return objc_getProperty_m68k(self, _cmd, offset, atomic); } void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id value, bool atomic, signed char copy) { - glue_objc_setProperty(self, _cmd, offset, value, atomic, copy); + objc_setProperty_m68k(self, _cmd, offset, value, atomic, copy); } void objc_getPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic, bool strong) { - glue_objc_getPropertyStruct(dest, src, size, atomic, strong); + objc_getPropertyStruct_m68k(dest, src, size, atomic, strong); } void objc_setPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic, bool strong) { - glue_objc_setPropertyStruct(dest, src, size, atomic, strong); + objc_setPropertyStruct_m68k(dest, src, size, atomic, strong); } void objc_enumerationMutation(id object) { +#ifdef OF_AMIGAOS3 /* * This does not use the glue code to hack around a compiler bug. * * When using the generated inline stubs, the compiler does not emit * any frame information, making the unwind fail. As a result @@ -230,20 +255,207 @@ * objc_enumerationMutation() might throw an exception that could never * be caught. If, however, we're using a function pointer instead of * the inline stub, the compiler does generate a frame and everything * works fine. */ - register void *a6 OBJC_M68K_REG("a6") = ObjFWRTBase; + register void *a6 __asm__("a6") = ObjFWRTBase; uintptr_t enumerationMutation = (((uintptr_t)ObjFWRTBase) - 0x8A); - ((void (*)(id OBJC_M68K_REG("a0")))enumerationMutation)(object); + ((void (*)(id __asm__("a0")))enumerationMutation)(object); (void)a6; +#else + objc_enumerationMutation_m68k(object); +#endif OF_UNREACHABLE } +#ifdef HAVE_SJLJ_EXCEPTIONS +int +__gnu_objc_personality_sj0(int version, int actions, uint64_t ex_class, + void *ex, void *ctx) +{ + return __gnu_objc_personality_sj0_m68k(version, actions, &ex_class, + ex, ctx); +} +#else int __gnu_objc_personality_v0(int version, int actions, uint64_t ex_class, void *ex, void *ctx) { - return glue___gnu_objc_personality_v0(version, actions, &ex_class, + return __gnu_objc_personality_v0_m68k(version, actions, &ex_class, ex, ctx); } +#endif + +SEL +sel_registerName(const char *name) +{ + return sel_registerName_m68k(name); +} + +const char * +sel_getName(SEL sel) +{ + return sel_getName_m68k(sel); +} + +bool +sel_isEqual(SEL sel1, SEL sel2) +{ + return sel_isEqual_m68k(sel1, sel2); +} + +Class +objc_allocateClassPair(Class superclass, const char *name, size_t extra_bytes) +{ + return objc_allocateClassPair_m68k(superclass, name, extra_bytes); +} + +void +objc_registerClassPair(Class cls) +{ + objc_registerClassPair_m68k(cls); +} + +unsigned int +objc_getClassList(Class *buf, unsigned int count) +{ + return objc_getClassList_m68k(buf, count); +} + +Class * +objc_copyClassList(unsigned int *len) +{ + return objc_copyClassList_m68k(len); +} + +bool +class_isMetaClass(Class cls) +{ + return class_isMetaClass_m68k(cls); +} + +const char * +class_getName(Class cls) +{ + return class_getName_m68k(cls); +} + +Class +class_getSuperclass(Class cls) +{ + return class_getSuperclass_m68k(cls); +} + +unsigned long +class_getInstanceSize(Class cls) +{ + return class_getInstanceSize_m68k(cls); +} + +bool +class_respondsToSelector(Class cls, SEL sel) +{ + return class_respondsToSelector_m68k(cls, sel); +} + +bool +class_conformsToProtocol(Class cls, Protocol *p) +{ + return class_conformsToProtocol_m68k(cls, p); +} + +IMP +class_getMethodImplementation(Class cls, SEL sel) +{ + return class_getMethodImplementation_m68k(cls, sel); +} + +IMP +class_getMethodImplementation_stret(Class cls, SEL sel) +{ + return class_getMethodImplementation_stret_m68k(cls, sel); +} + +const char * +class_getMethodTypeEncoding(Class cls, SEL sel) +{ + return class_getMethodTypeEncoding_m68k(cls, sel); +} + +bool +class_addMethod(Class cls, SEL sel, IMP imp, const char *types) +{ + return class_addMethod_m68k(cls, sel, imp, types); +} + +IMP +class_replaceMethod(Class cls, SEL sel, IMP imp, const char *types) +{ + return class_replaceMethod(cls, sel, imp, types); +} + +Class +object_getClass(id object) +{ + return object_getClass_m68k(object); +} + +Class +object_setClass(id object, Class cls) +{ + return object_setClass_m68k(object, cls); +} + +const char * +object_getClassName(id object) +{ + return object_getClassName_m68k(object); +} + +const char * +protocol_getName(Protocol *p) +{ + return protocol_getName_m68k(p); +} + +bool +protocol_isEqual(Protocol *a, Protocol *b) +{ + return protocol_isEqual_m68k(a, b); +} + +bool +protocol_conformsToProtocol(Protocol *a, Protocol *b) +{ + return protocol_conformsToProtocol_m68k(a, b); +} + +void +objc_exit(void) +{ + objc_exit_m68k(); +} + +objc_uncaught_exception_handler +objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler handler) +{ + return objc_setUncaughtExceptionHandler_m68k(handler); +} + +void +objc_setForwardHandler(IMP forward, IMP forward_stret) +{ + objc_setForwardHandler_m68k(forward, forward_stret); +} + +void +objc_setEnumerationMutationHandler(objc_enumeration_mutation_handler handler) +{ + objc_setEnumerationMutationHandler_m68k(handler); +} + +void +objc_zero_weak_references(id value) +{ + objc_zero_weak_references_m68k(value); +} Index: src/runtime/lookup.m ================================================================== --- src/runtime/lookup.m +++ src/runtime/lookup.m @@ -114,21 +114,19 @@ { return common_method_not_found(obj, sel, objc_msg_lookup_stret, forward_handler_stret); } -void __saveds -objc_setForwardHandler(IMP forward OBJC_M68K_REG("a0"), - IMP forward_stret OBJC_M68K_REG("a1")) +void +objc_setForwardHandler(IMP forward, IMP forward_stret) { forward_handler = forward; forward_handler_stret = forward_stret; } -bool __saveds -class_respondsToSelector(Class cls OBJC_M68K_REG("a0"), - SEL sel OBJC_M68K_REG("a1")) +bool +class_respondsToSelector(Class cls, SEL sel) { if (cls == Nil) return false; return (objc_dtable_get(cls->dtable, (uint32_t)sel->uid) != (IMP)0); Index: src/runtime/misc.m ================================================================== --- src/runtime/misc.m +++ src/runtime/misc.m @@ -23,20 +23,19 @@ #include "ObjFW_RT.h" #include "private.h" static objc_enumeration_mutation_handler enumeration_mutation_handler = NULL; -void __saveds +void objc_enumerationMutation(id obj) { if (enumeration_mutation_handler != NULL) enumeration_mutation_handler(obj); else OBJC_ERROR("Object was mutated during enumeration!"); } void -objc_setEnumerationMutationHandler( - objc_enumeration_mutation_handler handler OBJC_M68K_REG("a0")) +objc_setEnumerationMutationHandler(objc_enumeration_mutation_handler handler) { enumeration_mutation_handler = handler; } Index: src/runtime/private.h ================================================================== --- src/runtime/private.h +++ src/runtime/private.h @@ -134,123 +134,55 @@ } *_Nonnull buckets[256]; }; #if defined(OBJC_COMPILING_AMIGA_LIBRARY) || \ defined(OBJC_COMPILING_AMIGA_LINKLIB) -extern struct objc_libc { +struct objc_libc { void *(*malloc)(size_t); void *(*calloc)(size_t, size_t); void *(*realloc)(void *, size_t); void (*free)(void *); int (*vfprintf)(FILE *, const char *, va_list); int (*fflush)(FILE *); void (*exit)(int); void (*abort)(void); +# ifdef HAVE_SJLJ_EXCEPTIONS + int (*_Unwind_SjLj_RaiseException)(void *_Nonnull); +# else int (*_Unwind_RaiseException)(void *_Nonnull); +# endif void (*_Unwind_DeleteException)(void *_Nonnull); void *(*_Unwind_GetLanguageSpecificData)(void *_Nonnull); uintptr_t (*_Unwind_GetRegionStart)(void *_Nonnull); uintptr_t (*_Unwind_GetDataRelBase)(void *_Nonnull); uintptr_t (*_Unwind_GetTextRelBase)(void *_Nonnull); uintptr_t (*_Unwind_GetIP)(void *_Nonnull); uintptr_t (*_Unwind_GetGR)(void *_Nonnull, int); void (*_Unwind_SetIP)(void *_Nonnull, uintptr_t); void (*_Unwind_SetGR)(void *_Nonnull, int, uintptr_t); - void (*_Unwind_Resume)(void *); +# ifdef HAVE_SJLJ_EXCEPTIONS + void (*_Unwind_SjLj_Resume)(void *_Nonnull); +# else + void (*_Unwind_Resume)(void *_Nonnull); +# endif void (*__register_frame_info)(const void *, void *); void (*__deregister_frame_info)(const void *); -} *objc_libc; +}; #endif #ifdef OBJC_COMPILING_AMIGA_LIBRARY +# if defined(__MORPHOS__) +# include +# define OBJC_M68K_ARG(type, name, reg) type name = (type)REG_##reg; +# else +# define OBJC_M68K_ARG(type, name, reg) \ + register type reg_##name __asm__(#reg); \ + type name = reg_##name; +# endif # undef stdout # undef stderr extern FILE *stdout, *stderr; - -extern void glue___objc_exec_class(void *_Nonnull module OBJC_M68K_REG("a0")); -extern IMP _Nonnull glue_objc_msg_lookup(id _Nullable obj OBJC_M68K_REG("a0"), - SEL _Nonnull sel OBJC_M68K_REG("a1")); -extern IMP _Nonnull glue_objc_msg_lookup_stret( - id _Nullable obj OBJC_M68K_REG("a0"), SEL _Nonnull sel OBJC_M68K_REG("a1")); -extern IMP _Nonnull glue_objc_msg_lookup_super( - struct objc_super *_Nonnull super OBJC_M68K_REG("a0"), - SEL _Nonnull sel OBJC_M68K_REG("a1")); -extern IMP _Nonnull glue_objc_msg_lookup_super_stret( - struct objc_super *_Nonnull super OBJC_M68K_REG("a0"), - SEL _Nonnull sel OBJC_M68K_REG("a1")); -extern Class _Nullable glue_objc_lookUpClass( - const char *_Nonnull name OBJC_M68K_REG("a0")); -extern Class _Nullable glue_objc_getClass( - const char *_Nonnull name OBJC_M68K_REG("a0")); -extern Class _Nonnull glue_objc_getRequiredClass( - const char *_Nonnull name OBJC_M68K_REG("a0")); -extern Class _Nullable glue_objc_lookup_class( - const char *_Nonnull name OBJC_M68K_REG("a0")); -extern Class _Nonnull glue_objc_get_class( - const char *_Nonnull name OBJC_M68K_REG("a0")); -extern void glue_objc_exception_throw(id _Nullable object OBJC_M68K_REG("a0")); -extern int glue_objc_sync_enter(id _Nullable object OBJC_M68K_REG("a0")); -extern int glue_objc_sync_exit(id _Nullable object OBJC_M68K_REG("a0")); -extern id _Nullable glue_objc_getProperty(id _Nonnull self OBJC_M68K_REG("a0"), - SEL _Nonnull _cmd OBJC_M68K_REG("a1"), ptrdiff_t offset OBJC_M68K_REG("d0"), - bool atomic OBJC_M68K_REG("d1")); -extern void glue_objc_setProperty(id _Nonnull self OBJC_M68K_REG("a0"), - SEL _Nonnull _cmd OBJC_M68K_REG("a1"), ptrdiff_t offset OBJC_M68K_REG("d0"), - id _Nullable value OBJC_M68K_REG("a2"), bool atomic OBJC_M68K_REG("d1"), - signed char copy OBJC_M68K_REG("d2")); -extern void glue_objc_getPropertyStruct(void *_Nonnull dest OBJC_M68K_REG("a0"), - const void *_Nonnull src OBJC_M68K_REG("a1"), - ptrdiff_t size OBJC_M68K_REG("d0"), bool atomic OBJC_M68K_REG("d1"), - bool strong OBJC_M68K_REG("d2")); -extern void glue_objc_setPropertyStruct(void *_Nonnull dest OBJC_M68K_REG("a0"), - const void *_Nonnull src OBJC_M68K_REG("a1"), - ptrdiff_t size OBJC_M68K_REG("d0"), bool atomic OBJC_M68K_REG("d1"), - bool strong OBJC_M68K_REG("d2")); -extern void glue_objc_enumerationMutation(id _Nonnull obj OBJC_M68K_REG("a0")); -extern int glue___gnu_objc_personality_v0(int version OBJC_M68K_REG("d0"), - int actions OBJC_M68K_REG("d1"), - uint64_t *_Nonnull ex_class OBJC_M68K_REG("d2"), - void *_Nonnull ex OBJC_M68K_REG("a0"), - void *_Nonnull ctx OBJC_M68K_REG("a1")); -extern id _Nullable glue_objc_retain(id _Nullable object OBJC_M68K_REG("a0")); -extern id _Nullable glue_objc_retainBlock( - id _Nullable block OBJC_M68K_REG("a0")); -extern id _Nullable glue_objc_retainAutorelease( - id _Nullable object OBJC_M68K_REG("a0")); -extern void glue_objc_release(id _Nullable object OBJC_M68K_REG("a0")); -extern id _Nullable glue_objc_autorelease( - id _Nullable object OBJC_M68K_REG("a0")); -extern id _Nullable glue_objc_autoreleaseReturnValue( - id _Nullable object OBJC_M68K_REG("a0")); -extern id _Nullable glue_objc_retainAutoreleaseReturnValue( - id _Nullable object OBJC_M68K_REG("a0")); -extern id _Nullable glue_objc_retainAutoreleasedReturnValue( - id _Nullable object OBJC_M68K_REG("a0")); -extern id _Nullable glue_objc_storeStrong( - id _Nullable *_Nonnull object OBJC_M68K_REG("a0"), - id _Nullable value OBJC_M68K_REG("a1")); -extern id _Nullable glue_objc_storeWeak( - id _Nullable *_Nonnull object OBJC_M68K_REG("a0"), - id _Nullable value OBJC_M68K_REG("a1")); -extern id _Nullable glue_objc_loadWeakRetained( - id _Nullable *_Nonnull object OBJC_M68K_REG("a0")); -extern id _Nullable glue_objc_initWeak( - id _Nullable *_Nonnull object OBJC_M68K_REG("a0"), - id _Nullable value OBJC_M68K_REG("a1")); -extern void glue_objc_destroyWeak( - id _Nullable *_Nonnull object OBJC_M68K_REG("a0")); -extern id _Nullable glue_objc_loadWeak( - id _Nullable *_Nonnull object OBJC_M68K_REG("a0")); -extern void glue_objc_copyWeak(id _Nullable *_Nonnull dest OBJC_M68K_REG("a0"), - id _Nullable *_Nonnull src OBJC_M68K_REG("a1")); -extern void glue_objc_moveWeak(id _Nullable *_Nonnull dest OBJC_M68K_REG("a0"), - id _Nullable *_Nonnull src OBJC_M68K_REG("a1")); -#else -# ifdef __saveds -# undef __saveds -# endif -# define __saveds #endif extern void objc_register_all_categories(struct objc_abi_symtab *_Nonnull); extern struct objc_category *_Nullable *_Nullable objc_categories_for_class(Class _Nonnull); Index: src/runtime/protocol.m ================================================================== --- src/runtime/protocol.m +++ src/runtime/protocol.m @@ -23,26 +23,24 @@ #import "private.h" @implementation Protocol @end -const char *__saveds -protocol_getName(Protocol *p OBJC_M68K_REG("a0")) +const char * +protocol_getName(Protocol *p) { return p->name; } -bool __saveds -protocol_isEqual(Protocol *a OBJC_M68K_REG("a0"), - Protocol *b OBJC_M68K_REG("a1")) +bool +protocol_isEqual(Protocol *a, Protocol *b) { return (strcmp(protocol_getName(a), protocol_getName(b)) == 0); } -bool __saveds -protocol_conformsToProtocol(Protocol *a OBJC_M68K_REG("a0"), - Protocol *b OBJC_M68K_REG("a1")) +bool +protocol_conformsToProtocol(Protocol *a, Protocol *b) { if (protocol_isEqual(a, b)) return true; for (struct objc_protocol_list *pl = a->protocol_list; @@ -52,13 +50,12 @@ return true; return false; } -bool __saveds -class_conformsToProtocol(Class cls OBJC_M68K_REG("a0"), - Protocol *p OBJC_M68K_REG("a1")) +bool +class_conformsToProtocol(Class cls, Protocol *p) { struct objc_category **cats; if (cls == Nil) return false; Index: src/runtime/selector.m ================================================================== --- src/runtime/selector.m +++ src/runtime/selector.m @@ -38,11 +38,11 @@ static uint32_t selectors_cnt = 0; static struct objc_sparsearray *selector_names = NULL; static void **free_list = NULL; static size_t free_list_cnt = 0; -void __saveds +void objc_register_selector(struct objc_abi_selector *sel) { struct objc_selector *rsel; const char *name; @@ -67,11 +67,11 @@ objc_hashtable_set(selectors, name, rsel); objc_sparsearray_set(selector_names, (uint32_t)rsel->uid, (void *)name); } SEL -sel_registerName(const char *name OBJC_M68K_REG("a0")) +sel_registerName(const char *name) { const struct objc_abi_selector *rsel; struct objc_abi_selector *sel; objc_global_mutex_lock(); @@ -113,12 +113,12 @@ for (sel = symtab->sel_refs; sel->name != NULL; sel++) objc_register_selector(sel); } -const char *__saveds -sel_getName(SEL sel OBJC_M68K_REG("a0")) +const char * +sel_getName(SEL sel) { const char *ret; objc_global_mutex_lock(); ret = objc_sparsearray_get(selector_names, (uint32_t)sel->uid); @@ -125,12 +125,12 @@ objc_global_mutex_unlock(); return ret; } -bool __saveds -sel_isEqual(SEL sel1 OBJC_M68K_REG("a0"), SEL sel2 OBJC_M68K_REG("a1")) +bool +sel_isEqual(SEL sel1, SEL sel2) { return (sel1->uid == sel2->uid); } void