From: Apple Date: Mon, 24 Oct 2005 23:57:17 +0000 (+0000) Subject: objc4-267.tar.gz X-Git-Tag: mac-os-x-1043^0 X-Git-Url: https://git.saurik.com/apple/objc4.git/commitdiff_plain/cacad47438703123f9c9514e1482b3462c33ea9f objc4-267.tar.gz --- diff --git a/Makefile b/Makefile index 00ce383..53ea4d2 100644 --- a/Makefile +++ b/Makefile @@ -158,345 +158,3 @@ MODULE_SOURCES= OTHER_SOURCES= # headers to install in /usr/include/objc PUBLIC_HEADERS= -# headers that don't get installed -PRIVATE_HEADERS= -# headers to install in /usr/local/include/objc -OTHER_HEADERS= - -# runtime -SOURCES += $(addprefix runtime/, \ - Object.m Protocol.m hashtable2.m maptable.m objc-class.m objc-errors.m \ - objc-file.m objc-load.m objc-moninit.c objc-runtime.m objc-sel.m \ - objc-sync.m objc-exception.m objc-auto.m objc-sel-set.m objc-rtp.m \ - ) -PUBLIC_HEADERS += $(addprefix runtime/, \ - objc-class.h objc-api.h objc-load.h objc-runtime.h objc.h Object.h \ - objc-sync.h objc-exception.h objc-auto.h \ - Protocol.h error.h hashtable2.h \ - ) -PRIVATE_HEADERS += runtime/objc-private.h runtime/objc-config.h runtime/objc-sel-table.h runtime/objc-sel-set.h runtime/objc-rtp.h -OTHER_HEADERS += runtime/maptable.h runtime/objc-auto.h - -# OldClasses -SOURCES += runtime/OldClasses.subproj/List.m -PUBLIC_HEADERS += runtime/OldClasses.subproj/List.h - -# Messengers -SOURCES += runtime/Messengers.subproj/objc-msg.s -OTHER_SOURCES += runtime/Messengers.subproj/objc-msg-ppc.s runtime/Messengers.subproj/objc-msg-i386.s - -# Auto support -SOURCES += runtime/Auto.subproj/objc-auto.s -OTHER_SOURCES += runtime/Auto.subproj/objc-auto-ppc.s runtime/Auto.subproj/objc-auto-i386.s - -# RTP symbols for gdb -# See also $(OBJROOT)/runtime/objc-rtp-sym.ppc.o rule below. -OTHER_SOURCES += runtime/objc-rtp-sym.s - -# Interposing support. -# This code is built into a second module so dyld's function interposing -# can manipulate the calls. -MODULE_SOURCES += runtime/Messengers.subproj/objc-msg-stub.s -OTHER_SOURCES += runtime/Messengers.subproj/objc-msg-stub-ppc.s runtime/Messengers.subproj/objc-msg-stub-i386.s - -# project root -OTHER_SOURCES += Makefile APPLE_LICENSE objc-exports - -OBJECTS = $(addprefix $(OBJROOT)/, $(addsuffix .o, $(basename $(SOURCES) ) ) ) -OBJECTS_OPTIMIZED = $(OBJECTS:.o=.opt.o) -OBJECTS_DEBUG = $(OBJECTS:.o=.debug.o) -OBJECTS_PROFILE = $(OBJECTS:.o=.profile.o) - -MODULE_OBJECTS = $(addprefix $(OBJROOT)/, $(addsuffix .o, $(basename $(MODULE_SOURCES) ) ) ) -MODULE_OBJECTS_OPTIMIZED = $(MODULE_OBJECTS:.o=.opt.o) -MODULE_OBJECTS_DEBUG = $(MODULE_OBJECTS:.o=.debug.o) -MODULE_OBJECTS_PROFILE = $(MODULE_OBJECTS:.o=.profile.o) - -# For simplicity, each object target depends on all objc headers. Most of -# them come close to requiring this anyway, and rebuild from scratch is fast. -DEPEND_HEADERS = $(addprefix $(SRCROOT)/, \ - $(PUBLIC_HEADERS) $(PRIVATE_HEADERS) $(OTHER_HEADERS) ) - -$(OBJROOT)/%.opt.o : $(SRCROOT)/%.m $(DEPEND_HEADERS) - $(SILENT) $(ECHO) " ... $<" - $(SILENT) $(CC) $(CFLAGS_OPTIMIZED) "$<" -c -o "$@" - -$(OBJROOT)/%.debug.o : $(SRCROOT)/%.m $(DEPEND_HEADERS) - $(SILENT) $(ECHO) " ... $<" - $(SILENT) $(CC) $(CFLAGS_DEBUG) "$<" -c -o "$@" - -$(OBJROOT)/%.profile.o : $(SRCROOT)/%.m $(DEPEND_HEADERS) - $(SILENT) $(ECHO) " ... $<" - $(SILENT) $(CC) $(CFLAGS_PROFILE) "$<" -c -o "$@" - -$(OBJROOT)/%.opt.o : $(SRCROOT)/%.c $(DEPEND_HEADERS) - $(SILENT) $(ECHO) " ... $<" - $(SILENT) $(CC) $(CFLAGS_OPTIMIZED) "$<" -c -o "$@" - -$(OBJROOT)/%.debug.o : $(SRCROOT)/%.c $(DEPEND_HEADERS) - $(SILENT) $(ECHO) " ... $<" - $(SILENT) $(CC) $(CFLAGS_DEBUG) "$<" -c -o "$@" - -$(OBJROOT)/%.profile.o : $(SRCROOT)/%.c $(DEPEND_HEADERS) - $(SILENT) $(ECHO) " ... $<" - $(SILENT) $(CC) $(CFLAGS_PROFILE) "$<" -c -o "$@" - -$(OBJROOT)/%.opt.o : $(SRCROOT)/%.s $(DEPEND_HEADERS) - $(SILENT) $(ECHO) " ... $<" - $(SILENT) $(CC) $(CFLAGS_OPTIMIZED) "$<" -c -o "$@" - -$(OBJROOT)/%.debug.o : $(SRCROOT)/%.s $(DEPEND_HEADERS) - $(SILENT) $(ECHO) " ... $<" - $(SILENT) $(CC) $(CFLAGS_DEBUG) "$<" -c -o "$@" - -$(OBJROOT)/%.profile.o : $(SRCROOT)/%.s $(DEPEND_HEADERS) - $(SILENT) $(ECHO) " ... $<" - $(SILENT) $(CC) $(CFLAGS_PROFILE) "$<" -c -o "$@" - -# Additional dependency: objc-msg.s depends on objc-msg-ppc.s and -# objc-msg-i386.s, which it includes. -$(OBJROOT)/runtime/Messengers.subproj/objc-msg.opt.o \ -$(OBJROOT)/runtime/Messengers.subproj/objc-msg.debug.o \ -$(OBJROOT)/runtime/Messengers.subproj/objc-msg.profile.o : \ - $(SRCROOT)/runtime/Messengers.subproj/objc-msg-ppc.s \ - $(SRCROOT)/runtime/Messengers.subproj/objc-msg-i386.s - -# Additional dependency: objc-msg-sutb.s depends on objc-msg-stub-ppc.s and -# objc-msg-stub-i386.s, which it includes. -$(OBJROOT)/runtime/Messengers.subproj/objc-msg-stub.opt.o \ -$(OBJROOT)/runtime/Messengers.subproj/objc-msg-stub.debug.o \ -$(OBJROOT)/runtime/Messengers.subproj/objc-msg-stub.profile.o : \ - $(SRCROOT)/runtime/Messengers.subproj/objc-msg-stub-ppc.s \ - $(SRCROOT)/runtime/Messengers.subproj/objc-msg-stub-i386.s - -# Additional dependency: objc-auto.s depends on objc-auto-ppc.s and -# objc-auto-i386.s, which it includes. -$(OBJROOT)/runtime/Auto.subproj/objc-auto.opt.o \ -$(OBJROOT)/runtime/Auto.subproj/objc-auto.debug.o \ -$(OBJROOT)/runtime/Auto.subproj/objc-auto.profile.o : \ - $(SRCROOT)/runtime/Auto.subproj/objc-auto-ppc.s \ - $(SRCROOT)/runtime/Auto.subproj/objc-auto-i386.s - -# Additional rules: objc-rtp-sym.s needs to be built with a per-arch seg1addr, -# and need to be stripped here because stripping the dylib does not remove -# debug info from the magic sections. -# objc-rtp-sym.s is not in SOURCES, and objc-rtp-sym.o is not in OBJECTS -$(OBJROOT)/runtime/objc-rtp-sym.ppc.o: $(SRCROOT)/runtime/objc-rtp-sym.s - $(SILENT) $(CC) $(CFLAGS_OPTIMIZED) -arch ppc "$<" -c -o "$@.temp" - $(SILENT) $(STRIP) -S "$@.temp" - $(SILENT) $(LD) -arch ppc -seg1addr 0xfffec000 "$@.temp" -r -o "$@" - -$(OBJROOT)/runtime/objc-rtp-sym.i386.o: $(SRCROOT)/runtime/objc-rtp-sym.s - $(SILENT) $(CC) $(CFLAGS_OPTIMIZED) -arch i386 "$<" -c -o "$@.temp" - $(SILENT) $(STRIP) -S "$@.temp" - $(SILENT) $(LD) -arch i386 -seg1addr 0xfffe8000 "$@.temp" -r -o "$@" - - -# These are the main targets: -# build builds the library to OBJROOT and SYMROOT -# installsrc copies the sources to SRCROOT -# installhdrs install only the headers to DSTROOT -# install build, then install the headers and library to DSTROOT -# clean removes build products in OBJROOT and SYMROOT -# -# optimized same as 'build' but builds optimized library only -# debug same as 'build' but builds debug library only -# profile same as 'build' but builds profile library only - -# Default build doesn't currently build the debug library. -build: prebuild build-optimized build-profile postbuild - -optimized: prebuild build-optimized postbuild -debug: prebuild build-debug postbuild -profile: prebuild build-profile postbuild - -installsrc: - $(SILENT) $(ECHO) "Installing source from . to $(SRCROOT)..." -ifeq "$(SRCROOT)" "." - $(SILENT) $(ECHO) "SRCROOT must be defined to be the destination directory; it cannot be '.'" - exit 1 -endif - $(SILENT) $(TAR) -cf $(SRCROOT)/objc4.sources.tar $(SOURCES) $(PUBLIC_HEADERS) $(PRIVATE_HEADERS) $(OTHER_HEADERS) $(OTHER_SOURCES) $(MODULE_SOURCES) - $(SILENT) $(CD) $(SRCROOT) && $(TAR) -xf $(SRCROOT)/objc4.sources.tar - $(SILENT) $(REMOVE) -f $(SRCROOT)/objc4.sources.tar - -installhdrs: - $(SILENT) $(ECHO) "Installing headers from $(SRCROOT) to $(DSTROOT)/$(HEADER_INSTALLDIR)..." - - $(SILENT) $(MKDIRS) $(DSTROOT)/$(PUBLIC_HEADER_INSTALLDIR) - -$(SILENT) $(CHMOD) +w $(DSTROOT)/$(PUBLIC_HEADER_INSTALLDIR)/*.h - $(SILENT) $(COPY) $(addprefix $(SRCROOT)/, $(PUBLIC_HEADERS) ) \ - $(DSTROOT)/$(PUBLIC_HEADER_INSTALLDIR) -# duplicate hashtable2.h to hashtable.h - $(SILENT) $(COPY) $(DSTROOT)/$(PUBLIC_HEADER_INSTALLDIR)/hashtable2.h \ - $(DSTROOT)/$(PUBLIC_HEADER_INSTALLDIR)/hashtable.h - $(SILENT) $(CHMOD) -w $(DSTROOT)/$(PUBLIC_HEADER_INSTALLDIR)/*.h - $(SILENT) $(CHMOD) a+r $(DSTROOT)/$(PUBLIC_HEADER_INSTALLDIR)/*.h - - $(SILENT) $(MKDIRS) $(DSTROOT)/$(OTHER_HEADER_INSTALLDIR) - -$(SILENT) $(CHMOD) +w $(DSTROOT)/$(OTHER_HEADER_INSTALLDIR)/*.h - $(SILENT) $(COPY) $(addprefix $(SRCROOT)/, $(OTHER_HEADERS) ) \ - $(DSTROOT)/$(OTHER_HEADER_INSTALLDIR) - $(SILENT) $(CHMOD) -w $(DSTROOT)/$(OTHER_HEADER_INSTALLDIR)/*.h - $(SILENT) $(CHMOD) a+r $(DSTROOT)/$(OTHER_HEADER_INSTALLDIR)/*.h - - - $(SILENT) $(RM) -f $(DSTROOT)$(PUBLIC_HEADER_DIR)$(PUBLIC_HEADER_DIR_SUFFIX)/hashtable.h - - -install: build installhdrs - $(SILENT) $(ECHO) "Installing products from $(SYMROOT) to $(DSTROOT)..." - - $(SILENT) $(MKDIRS) $(DSTROOT)/$(INSTALLDIR) - -$(SILENT) $(CHMOD) +w $(DSTROOT)/$(INSTALLDIR) - - $(SILENT) $(REMOVE) -f $(DSTROOT)/$(INSTALLDIR)/libobjc.$(VERSION_NAME)$(LIBRARY_EXT) - $(SILENT) $(REMOVE) -f $(DSTROOT)/$(INSTALLDIR)/libobjc_debug.$(VERSION_NAME)$(LIBRARY_EXT) - $(SILENT) $(REMOVE) -f $(DSTROOT)/$(INSTALLDIR)/libobjc_profile.$(VERSION_NAME)$(LIBRARY_EXT) - -# optimized - $(SILENT) $(COPY) $(SYMROOT)/libobjc.$(VERSION_NAME)$(LIBRARY_EXT) $(DSTROOT)/$(INSTALLDIR) - $(SILENT) $(STRIP) -S $(DSTROOT)/$(INSTALLDIR)/libobjc.$(VERSION_NAME)$(LIBRARY_EXT) - -$(SILENT) $(CHOWN) root:wheel $(DSTROOT)/$(INSTALLDIR)/libobjc.$(VERSION_NAME)$(LIBRARY_EXT) - $(SILENT) $(CHMOD) 755 $(DSTROOT)/$(INSTALLDIR)/libobjc.$(VERSION_NAME)$(LIBRARY_EXT) - $(SILENT) $(CD) $(DSTROOT)/$(INSTALLDIR) && \ - $(SYMLINK) libobjc.$(VERSION_NAME)$(LIBRARY_EXT) libobjc$(LIBRARY_EXT) - -# debug (allowed not to exist) - -$(SILENT) $(COPY) $(SYMROOT)/libobjc_debug.$(VERSION_NAME)$(LIBRARY_EXT) $(DSTROOT)/$(INSTALLDIR) - -$(SILENT) $(CHOWN) root:wheel $(DSTROOT)/$(INSTALLDIR)/libobjc_debug.$(VERSION_NAME)$(LIBRARY_EXT) - -$(SILENT) $(CHMOD) 755 $(DSTROOT)/$(INSTALLDIR)/libobjc_debug.$(VERSION_NAME)$(LIBRARY_EXT) - -$(SILENT) $(CD) $(DSTROOT)/$(INSTALLDIR) && \ - test -e libobjc_debug.$(VERSION_NAME)$(LIBRARY_EXT) && \ - $(SYMLINK) libobjc_debug.$(VERSION_NAME)$(LIBRARY_EXT) libobjc_debug$(LIBRARY_EXT) && \ - $(SYMLINK) libobjc_debug.$(VERSION_NAME)$(LIBRARY_EXT) libobjc.$(VERSION_NAME)_debug$(LIBRARY_EXT) - - -# profile (allowed not to exist) - -$(SILENT) $(COPY) $(SYMROOT)/libobjc_profile.$(VERSION_NAME)$(LIBRARY_EXT) $(DSTROOT)/$(INSTALLDIR) - -$(SILENT) $(CHOWN) root:wheel $(DSTROOT)/$(INSTALLDIR)/libobjc_profile.$(VERSION_NAME)$(LIBRARY_EXT) - -$(SILENT) $(CHMOD) 755 $(DSTROOT)/$(INSTALLDIR)/libobjc_profile.$(VERSION_NAME)$(LIBRARY_EXT) - -$(SILENT) $(CD) $(DSTROOT)/$(INSTALLDIR) && \ - test -e libobjc_profile.$(VERSION_NAME)$(LIBRARY_EXT) && \ - $(SYMLINK) libobjc_profile.$(VERSION_NAME)$(LIBRARY_EXT) libobjc_profile$(LIBRARY_EXT) && \ - $(SYMLINK) libobjc_profile.$(VERSION_NAME)$(LIBRARY_EXT) libobjc.$(VERSION_NAME)_profile$(LIBRARY_EXT) - - -clean: - $(SILENT) $(ECHO) "Deleting build products..." - $(SILENT) $(REMOVE) -f \ - $(foreach A, $(ARCH_LIST), \ - $(OBJROOT)/libobjc_debug.$A.$(VERSION_NAME)$(LIBRARY_EXT) \ - $(OBJROOT)/libobjc_profile.$A.$(VERSION_NAME)$(LIBRARY_EXT) \ - $(OBJROOT)/libobjc.$A.$(VERSION_NAME)$(LIBRARY_EXT) \ - $(OBJROOT)/runtime/objc-rtp-sym.$A.o \ - $(OBJROOT)/runtime/objc-rtp-sym.$A.o.temp \ - ) - - $(SILENT) $(REMOVE) -f $(SYMROOT)/libobjc.optimized.o - $(SILENT) $(REMOVE) -f $(SYMROOT)/libobjc.debug.o - $(SILENT) $(REMOVE) -f $(SYMROOT)/libobjc.profile.o - - $(SILENT) $(REMOVE) -f $(SYMROOT)/libobjc.$(VERSION_NAME)$(LIBRARY_EXT) - $(SILENT) $(REMOVE) -f $(SYMROOT)/libobjc_debug.$(VERSION_NAME)$(LIBRARY_EXT) - $(SILENT) $(REMOVE) -f $(SYMROOT)/libobjc_profile.$(VERSION_NAME)$(LIBRARY_EXT) - - $(SILENT) $(REMOVE) -f $(OBJECTS_OPTIMIZED) - $(SILENT) $(REMOVE) -f $(OBJECTS_DEBUG) - $(SILENT) $(REMOVE) -f $(OBJECTS_PROFILE) - - $(SILENT) $(REMOVE) -f $(MODULE_OBJECTS_OPTIMIZED) - $(SILENT) $(REMOVE) -f $(MODULE_OBJECTS_DEBUG) - $(SILENT) $(REMOVE) -f $(MODULE_OBJECTS_PROFILE) - - $(SILENT) $(REMOVE) -rf $(SYMROOT)/ProjectHeaders - -prebuild: - $(SILENT) $(ECHO) "Prebuild-setup..." - -# Install headers into $(SYMROOT)/ProjectHeaders so #includes can find them -# even if they're not installed in /usr. - $(SILENT) $(MKDIRS) $(SYMROOT) - $(SILENT) $(REMOVE_RECUR) $(SYMROOT)/ProjectHeaders - $(SILENT) $(MKDIRS) $(SYMROOT)/ProjectHeaders - $(SILENT) $(ECHO) "Copying headers from $(SRCROOT) to $(SYMROOT)/ProjectHeaders..." - $(SILENT) $(COPY) $(addprefix $(SRCROOT)/, $(PRIVATE_HEADERS) ) $(SYMROOT)/ProjectHeaders - $(SILENT) $(MKDIRS) $(SYMROOT)/ProjectHeaders/objc - $(SILENT) $(COPY) $(addprefix $(SRCROOT)/, $(PUBLIC_HEADERS) ) $(SYMROOT)/ProjectHeaders/objc - $(SILENT) $(COPY) $(addprefix $(SRCROOT)/, $(OTHER_HEADERS) ) $(SYMROOT)/ProjectHeaders/objc - - - -build-optimized: prebuild-optimized compile-optimized link-optimized -build-debug: prebuild-debug compile-debug link-debug -build-profile: prebuild-profile compile-profile link-profile - - -prebuild-optimized: - $(SILENT) $(ECHO) "Building (optimized) ..." - $(SILENT) $(MKDIRS) $(foreach S, $(SUBDIRS), $(OBJROOT)/$(S) ) - -prebuild-debug: - $(SILENT) $(ECHO) "Building (debug) ..." - $(SILENT) $(MKDIRS) $(foreach S, $(SUBDIRS), $(OBJROOT)/$(S) ) - -prebuild-profile: - $(SILENT) $(ECHO) "Building (profile) ..." - $(SILENT) $(MKDIRS) $(foreach S, $(SUBDIRS), $(OBJROOT)/$(S) ) - - -compile-optimized: $(OBJECTS_OPTIMIZED) $(MODULE_OBJECTS_OPTIMIZED) $(foreach A, $(ARCH_LIST), $(OBJROOT)/runtime/objc-rtp-sym.$A.o ) -compile-debug: $(OBJECTS_DEBUG) $(MODULE_OBJECTS_DEBUG) $(foreach A, $(ARCH_LIST), $(OBJROOT)/runtime/objc-rtp-sym.$A.o ) -compile-profile: $(OBJECTS_PROFILE) $(MODULE_OBJECTS_PROFILE) $(foreach A, $(ARCH_LIST), $(OBJROOT)/runtime/objc-rtp-sym.$A.o ) - - -# link lib-suffix, LDFLAGS, OBJECTS, MODULE_OBJECTS -# libsuffix should be "" or _debug or _profile -ifeq "$(PLATFORM)" "Darwin" - -define link - $(foreach A, $(ARCH_LIST), \ - $(SILENT) $(LD) -r \ - -arch $A \ - -o $(OBJROOT)/libobjc$1.$A.o \ - $3 ; \ - $(SILENT) $(CC) $2 \ - -arch $A \ - -Wl,-exported_symbols_list,$(SRCROOT)/objc-exports \ - $(ORDER) \ - -sectcreate __DATA __commpage $(OBJROOT)/runtime/objc-rtp-sym.$A.o \ - -install_name /$(INSTALLDIR)/libobjc$1.$(VERSION_NAME)$(LIBRARY_EXT) \ - -o $(OBJROOT)/libobjc$1.$A.$(VERSION_NAME)$(LIBRARY_EXT) \ - $(OBJROOT)/libobjc$1.$A.o $4 ; \ - ) - $(SILENT) $(LIPO) \ - -create -output $(SYMROOT)/libobjc$1.$(VERSION_NAME)$(LIBRARY_EXT) \ - $(foreach A, $(ARCH_LIST), -arch $A $(OBJROOT)/libobjc$1.$A.$(VERSION_NAME)$(LIBRARY_EXT) ) -endef - -else -# PLATFORM != Darwin -define link - $(SILENT) $(ECHO) "Don't know how to link for platform '$(PLATFORM)'" -endef - -endif - - -link-optimized: - $(SILENT) $(ECHO) "Linking (optimized)..." - $(call link,,$(LDFLAGS_OPTIMIZED),$(OBJECTS_OPTIMIZED),$(MODULE_OBJECTS_OPTIMIZED) ) - -link-debug: - $(SILENT) $(ECHO) "Linking (debug)..." - $(call link,_debug,$(LDFLAGS_DEBUG),$(OBJECTS_DEBUG),$(MODULE_OBJECTS_DEBUG) ) - -link-profile: - $(SILENT) $(ECHO) "Linking (profile)..." - $(call link,_profile,$(LDFLAGS_PROFILE),$(OBJECTS_PROFILE),$(MODULE_OBJECTS_PROFILE) ) - - -postbuild: - $(SILENT) $(ECHO) "Done!" - - diff --git a/runtime/objc-class.h b/runtime/objc-class.h index 83e7b64..120a65b 100644 --- a/runtime/objc-class.h +++ b/runtime/objc-class.h @@ -71,6 +71,8 @@ struct objc_class { #define CLS_HAS_CXX_STRUCTORS 0x2000L // Lazy method list arrays #define CLS_NO_METHOD_ARRAY 0x4000L +// +load implementation +// #define CLS_HAS_LOAD_METHOD 0x8000L /* diff --git a/runtime/objc-class.m b/runtime/objc-class.m index ed66e78..8bf14b4 100644 --- a/runtime/objc-class.m +++ b/runtime/objc-class.m @@ -193,6 +193,7 @@ * CLS_FROM_BUNDLE: class load * CLS_HAS_CXX_STRUCTORS: compile-time and class load * CLS_NO_METHOD_ARRAY: class load and messaging + * CLS_HAS_LOAD_METHOD: class load * * CLS_INITIALIZED and CLS_INITIALIZING have additional thread-safety * constraints to support thread-safe +initialize. See "Thread safety diff --git a/runtime/objc-private.h b/runtime/objc-private.h index 0aca0b4..90b80dc 100644 --- a/runtime/objc-private.h +++ b/runtime/objc-private.h @@ -328,5 +328,8 @@ typedef struct { // CoreFoundation-only process from three to two. See #3857126 and #3857136. #define NOBSS __attribute__((section("__DATA,__data"))) +// +load implementation +#define CLS_HAS_LOAD_METHOD 0x8000L + #endif /* _OBJC_PRIVATE_H_ */ diff --git a/runtime/objc-runtime.m b/runtime/objc-runtime.m index 8687470..6a61be9 100644 --- a/runtime/objc-runtime.m +++ b/runtime/objc-runtime.m @@ -84,6 +84,7 @@ * * Read all classes in all new images. * Add them all to unconnected_class_hash. + * Note any +load implementations before categories are attached. * Fix up any pended classrefs referring to them. * Attach any pending categories. * Read all categories in all new images. @@ -129,6 +130,11 @@ * implementations expect to use another class in a linked-to library, * even if the two classes don't share a direct superclass relationship. * + * Correctness: all classes are scanned for +load before any categories + * are attached. Otherwise, if a category implements +load and its class + * has no class methods, the class's +load scan would find the category's + * +load method, which would then be called twice. + * **********************************************************************/ @@ -1311,9 +1317,11 @@ static void add_class_to_loadable_list(struct objc_class *cls) IMP method = NULL; struct objc_method_list *mlist; - mlist = get_base_method_list(cls->isa); - if (mlist) { - method = lookupNamedMethodInMethodList (mlist, "load"); + if (cls->isa->info & CLS_HAS_LOAD_METHOD) { + mlist = get_base_method_list(cls->isa); + if (mlist) { + method = lookupNamedMethodInMethodList (mlist, "load"); + } } // Don't bother if cls has no +load method if (!method) return; @@ -1785,6 +1793,7 @@ static BOOL connect_class(struct objc_class *cls) /*********************************************************************** * _objc_read_classes_from_image. * Read classes from the given image, perform assorted minor fixups, +* scan for +load implementation. * Does not connect classes to superclasses. * Does attach pended categories to the classes. * Adds all classes to unconnected_class_hash. class_hash is unchanged. @@ -1823,6 +1832,7 @@ static void _objc_read_classes_from_image(header_info *hi) for (index = 0; index < mods[midx].symtab->cls_def_cnt; index += 1) { struct objc_class * newCls; + struct objc_method_list *mlist; // Locate the class description pointer newCls = mods[midx].symtab->defs[index]; @@ -1844,6 +1854,13 @@ static void _objc_read_classes_from_image(header_info *hi) // methodLists is NULL or a single list, not an array newCls->info |= CLS_NO_METHOD_ARRAY; newCls->isa->info |= CLS_NO_METHOD_ARRAY; + + // Check for +load implementation before categories are attached + if ((mlist = get_base_method_list(newCls->isa))) { + if (lookupNamedMethodInMethodList (mlist, "load")) { + newCls->isa->info |= CLS_HAS_LOAD_METHOD; + } + } // Install into unconnected_class_hash OBJC_LOCK(&classLock);