From 3c42c64c14d912d5af31146d6dba435515b1defe Mon Sep 17 00:00:00 2001 From: Hugo Melder Date: Thu, 4 Jan 2024 11:35:21 +0100 Subject: [PATCH] Skip tests using objc_msgSend if not available (#263) * Add __GNUSTEP_MSGSEND__ definition * Mark test as skipped if return code is 77 * Skip tests using objc_msgSend if not available * ManyManySelectors: Skip objc_msgSend if not available * Skip UnexpectedException test on ARM and AArch64 * Add UnexpectedException.m to list of unit tests * Call manyArgs with objc_msgSend directly --- Test/CMakeLists.txt | 7 ++----- Test/ManyManySelectors.m | 4 +++- Test/UnexpectedException.m | 4 ++++ Test/objc_msgSend.m | 12 ++++++++++-- objc/message.h | 6 ++++++ 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/Test/CMakeLists.txt b/Test/CMakeLists.txt index 73e72b8..059fa82 100644 --- a/Test/CMakeLists.txt +++ b/Test/CMakeLists.txt @@ -51,6 +51,7 @@ set(TESTS hash_table_delete.c hash_test.c setSuperclass.m + UnexpectedException.m ) set(ENABLE_ALL_OBJC_ARC_TESTS On) @@ -79,11 +80,6 @@ if (ENABLE_ALL_OBJC_ARC_TESTS) ) endif() -# UnexpectedException test currently fails on ARM and needs to be fixed -if(NOT ARCHITECTURE MATCHES "^(arm|aarch64)") - list(APPEND TESTS UnexpectedException.m) -endif() - # List of single-file tests that won't work with the legacy ABI and so # shouldn't be run in legacy mode. set(NEW_TESTS @@ -124,6 +120,7 @@ function(addtest_flags TEST_NAME FLAGS TEST_SOURCE) LINK_FLAGS ${INCREMENTAL} LINKER_LANGUAGE C ) + set_property(TEST ${TEST_NAME} PROPERTY SKIP_RETURN_CODE 77) set_property(TEST ${TEST_NAME} PROPERTY ENVIRONMENT "LD_LIBRARY_PATH=" "LLVM_PROFILE_FILE=${TEST_NAME}.profraw" ) diff --git a/Test/ManyManySelectors.m b/Test/ManyManySelectors.m index baa45ae..b2fad79 100644 --- a/Test/ManyManySelectors.m +++ b/Test/ManyManySelectors.m @@ -24,6 +24,7 @@ static id x(id self, SEL _cmd) int main(void) { + SEL nextSel; Class cls = [Test class]; assert(cls != Nil); @@ -46,8 +47,9 @@ int main(void) objc_msg_lookup(cls, nextSel)(cls, nextSel); assert(methodCalled == YES); methodCalled = NO; +#ifdef __GNUSTEP_MSGSEND__ objc_msgSend([Test class], nextSel); assert(methodCalled == YES); +#endif return 0; } - diff --git a/Test/UnexpectedException.m b/Test/UnexpectedException.m index 486c221..61b9d89 100644 --- a/Test/UnexpectedException.m +++ b/Test/UnexpectedException.m @@ -30,6 +30,7 @@ LONG WINAPI _UnhandledExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) int main(void) { + #if !(defined(__arm__) || defined(__ARM_ARCH_ISA_A64)) #ifdef _WIN32 // also verify that an existing handler still gets called after we set ours SetUnhandledExceptionFilter(&_UnhandledExceptionFilter); @@ -40,4 +41,7 @@ int main(void) assert(0 && "should not be reached!"); return -1; + #endif + // FIXME: Test currently fails on ARM and AArch64 + return 77; // Skip test } diff --git a/Test/objc_msgSend.m b/Test/objc_msgSend.m index 4689172..9fd76b7 100644 --- a/Test/objc_msgSend.m +++ b/Test/objc_msgSend.m @@ -10,6 +10,7 @@ //#define assert(x) if (!(x)) { printf("Failed %d\n", __LINE__); } +typedef void (*fwdManyFunc)(id, SEL, int, int, int, int, int, int, int, int, int, int, int, float, float, float, float, float, float, float, float, float, float, float); typedef struct { int a,b,c,d,e; } s; @interface Fake @@ -175,6 +176,7 @@ struct objc_slot *forward_slot(id o, SEL s) int main(void) { +#ifdef __GNUSTEP_MSGSEND__ __objc_msg_forward2 = forward; __objc_msg_forward3 = forward_slot; TestCls = objc_getClass("MsgTest"); @@ -220,8 +222,12 @@ int main(void) assert(0 == [f dzero]); assert(0 == [f ldzero]); assert(0 == [f fzero]); - [TestCls manyArgs: 0 : 1 : 2 : 3: 4: 5: 6: 7: 8: 9: 10 : 0 : 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10]; + // Call manyArgs with objc_msgSend explicitly to test the slow lookup path + SEL manyArgsSel = sel_registerName("manyArgs::::::::::::::::::::::"); + ((fwdManyFunc)objc_msgSend)(TestCls, manyArgsSel, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); assert(forwardcalls == 2); + [TestCls manyArgs: 0 : 1 : 2 : 3: 4: 5: 6: 7: 8: 9: 10 : 0 : 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10]; + assert(forwardcalls == 3); #ifdef BENCHMARK const int iterations = 1000000000; double times[3]; @@ -252,6 +258,8 @@ int main(void) times[2] = ((double)c2 - (double)c1) / (double)CLOCKS_PER_SEC; fprintf(stderr, "Direct IMP call took %f seconds. \n", times[2]); printf("%f\t%f\t%f\n", times[0], times[1], times[2]); -#endif +#endif // BENCHMARK return 0; +#endif // __GNUSTEP_MSGSEND__ + return 77; // Skip test } diff --git a/objc/message.h b/objc/message.h index b267e95..d5df0c1 100644 --- a/objc/message.h +++ b/objc/message.h @@ -11,6 +11,12 @@ defined(__ARM_ARCH_ISA_A64) || \ (defined(__riscv) && __riscv_xlen == 64 && \ defined(__riscv_float_abi_double)) + +// Define __GNUSTEP_MSGSEND__ if available +#ifndef __GNUSTEP_MSGSEND__ +#define __GNUSTEP_MSGSEND__ +#endif + /** * Standard message sending function. This function must be cast to the * correct types for the function before use. The first argument is the