From ee32f78b0abe3e9829092c5567a5cc9126937bb8 Mon Sep 17 00:00:00 2001 From: theraven Date: Fri, 1 Oct 2010 13:11:48 +0000 Subject: [PATCH] Tweaked the GNUmakefile to (more or less) work with gcc. Fixed block introspection for the new (Apple-compatible) ABI. --- GNUmakefile | 7 ++-- blocks_runtime.m | 76 +++++++++++++++++++++++++++++++---------- objc/blocks_runtime.h | 2 +- toydispatch/GNUmakefile | 13 ++++--- 4 files changed, 72 insertions(+), 26 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index b4c7baa..1f84ca4 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -83,12 +83,13 @@ libobjc_LIB_DIRS += -L toydispatch/obj libobjc_CFLAGS += -O3 ifneq ($(findstring gcc, $(CC)),) -libobjc_CFLAGS += -fgnu89-inline + # Hack to get the __sync_* GCC builtins to work with GCC + ifeq ($(GNUSTEP_TARGET_CPU), ix86) + libobjc_CFLAGS += -march=i586 + endif endif ifeq ($(GNUSTEP_TARGET_OS), mingw32) -# Hack to get the __sync_* GCC builtins to work on Windows -libobjc_CFLAGS += -march=i586 # Hack to get mingw to provide declaration for strdup (since it is non-standard) libobjc_CPPFLAGS += -U__STRICT_ANSI__ endif diff --git a/blocks_runtime.m b/blocks_runtime.m index 070fd07..8046bc0 100644 --- a/blocks_runtime.m +++ b/blocks_runtime.m @@ -38,10 +38,11 @@ // Descriptor attributes enum { - BLOCK_HAS_COPY_DISPOSE = (1 << 25), - BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code - BLOCK_IS_GLOBAL = (1 << 28), - BLOCK_HAS_DESCRIPTOR = (1 << 29), // interim until complete world build is accomplished + BLOCK_HAS_COPY_DISPOSE = (1 << 25), + BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code + BLOCK_IS_GLOBAL = (1 << 28), + BLOCK_HAS_DESCRIPTOR = (1 << 29), // interim until complete world build is accomplished + BLOCK_HAS_SIGNATURE = (1 << 30) }; // _Block_object_assign() and _Block_object_dispose() flag helpers. @@ -55,20 +56,50 @@ enum { BLOCK_BYREF_CALLER = 128, // called from byref copy/dispose helpers }; +/** + * Block descriptor that contains copy and dispose operations. + */ +struct block_descriptor_copydispose +{ + unsigned long int reserved; + /** Size of the block. */ + unsigned long int size; + /** + * Copy function, generated by the compiler to help copy the block if it + * contains nontrivial copy operations. + */ + void (*copy_helper)(void *dst, void *src); + /** + * Dispose function, generated by the compiler to help copy the block if it + * contains nontrivial destructors. + */ + void (*dispose_helper)(void *src); + /** + * Objective-C type encoding of the block. + */ + const char *encoding; +}; +/** + * Block descriptor that does not contain copy and dispose helper functions. + */ +struct block_descriptor +{ + unsigned long int reserved; + /** Size of the block. */ + unsigned long int size; + /** + * Objective-C type encoding of the block. + */ + const char *encoding; +}; + // Helper structure struct psy_block_literal { void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock int flags; int reserved; void (*invoke)(void *, ...); - struct { - unsigned long int reserved; // NULL - unsigned long int size; // sizeof(struct Block_literal_1) - // optional helper functions - void (*copy_helper)(void *dst, void *src); - void (*dispose_helper)(void *src); - } *descriptor; - const char *types; + struct block_descriptor_copydispose *descriptor; }; // Helper structure @@ -81,6 +112,21 @@ struct psy_block_byref_obj { void (*byref_dispose)(struct psy_block_byref_obj *); }; +const char *block_getType_np(void *b) +{ + struct psy_block_literal *block = b; + if ((NULL == block) || !(block->flags & BLOCK_HAS_SIGNATURE)) + { + return NULL; + } + if (!(block->flags & BLOCK_HAS_COPY_DISPOSE)) + { + return ((struct block_descriptor*)block->descriptor)->encoding; + } + return block->descriptor->encoding; +} + + /* Certain field types require runtime assistance when being copied to the * heap. The following function is used to copy fields of types: blocks, * pointers to byref structures, and objects (including @@ -240,9 +286,3 @@ void _Block_release(void *src) } } } - -const char *_Block_get_types(void *blk) -{ - struct psy_block_literal *block = blk; - return block->types; -} diff --git a/objc/blocks_runtime.h b/objc/blocks_runtime.h index 2def0a4..8a64bf2 100644 --- a/objc/blocks_runtime.h +++ b/objc/blocks_runtime.h @@ -11,7 +11,7 @@ BLOCKS_EXPORT void *_Block_copy(void *); BLOCKS_EXPORT void _Block_release(void *); -BLOCKS_EXPORT const char *_Block_get_types(void*) OBJC_NONPORTABLE; +BLOCKS_EXPORT const char *block_getType_np(void *b) OBJC_NONPORTABLE; #define Block_copy(x) ((__typeof(x))_Block_copy((void *)(x))) #define Block_release(x) _Block_release((void *)(x)) diff --git a/toydispatch/GNUmakefile b/toydispatch/GNUmakefile index 331491a..21d7a7f 100644 --- a/toydispatch/GNUmakefile +++ b/toydispatch/GNUmakefile @@ -15,11 +15,16 @@ toydispatch_LIBRARIES_DEPEND_UPON += -lpthread toydispatch_CFLAGS += -Werror -std=c99 +ifneq ($(findstring gcc, $(CC)),) + # Hack to get the __sync_* GCC builtins to work with GCC + ifeq ($(GNUSTEP_TARGET_CPU), ix86) + toydispatch_CFLAGS += -march=i586 + endif +endif + ifeq ($(GNUSTEP_TARGET_OS), mingw32) -# Hack to get the __sync_* GCC builtins to work on Windows -toydispatch_CFLAGS += -march=i586 -# Hack to get mingw to provide declaration for strdup (since it is non-standard) -toydispatch_CPPFLAGS += -U__STRICT_ANSI__ + # Hack to get mingw to provide declaration for strdup (since it is non-standard) + toydispatch_CPPFLAGS += -U__STRICT_ANSI__ endif include $(GNUSTEP_MAKEFILES)/library.make