mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-11 14:10:34 +00:00
Gcc 3.1.0 pre-release's Objective C support bits from the FSF anoncvs repo
on 9-May-2002 15:57:15 EDT.
This commit is contained in:
parent
e3f07fb2c3
commit
641c89aab9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/gcc/dist/; revision=96297
@ -1,38 +1,291 @@
|
||||
Fri Mar 16 12:46:19 GMT 2001 Bernd Schmidt (bernds@redhat.com)
|
||||
2002-05-08 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* gcc-2.95.3 Released.
|
||||
* configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at
|
||||
script entry, and set LD to it when configuring multilibs.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2001-01-11 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
2002-04-19 David O'Brien <obrien@FreeBSD.org>
|
||||
|
||||
* encoding.c (MAX, MIN, ROUNDING): #undef before defining.
|
||||
|
||||
2002-04-09 Hans-Peter Nilsson <hp@bitrange.com>
|
||||
|
||||
PR objc/6107
|
||||
* objc/objc-api.h (struct objc_protocol_list): Change type of
|
||||
member count from int to size_t.
|
||||
|
||||
2002-02-11 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
|
||||
PR libobjc/4039
|
||||
* aclocal.m4: Replace with version copied from libstdc++-v3.
|
||||
* configure.in: Update for changes to aclocal and Makefile.
|
||||
* configure: Regenerate.
|
||||
* Makefile.in: Correct install of multilibs and shared libs, use
|
||||
INSTALL_DATA for include files.
|
||||
|
||||
Mon Dec 17 17:02:12 2001 Nicola Pero <nicola@brainstorm.co.uk>
|
||||
|
||||
* init.c (__objc_exec_class): Fixed bug in the loop on unclaimed
|
||||
categories - when an unclaimed category was found, the loop was
|
||||
doing two steps forward instead of one, so that in certain cases
|
||||
it was failing to properly load all the categories. (Reported
|
||||
with fix by Alexander Malmberg <alexander@malmberg.org>).
|
||||
|
||||
2001-11-14 Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
* encoding.c: Add target_flags.
|
||||
|
||||
2001-11-07 Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
* objc/objc-api.h (_C_VECTOR): New.
|
||||
|
||||
* encoding.c (VECTOR_TYPE): New.
|
||||
|
||||
Mon Oct 29 21:29:21 2001 Nicola Pero <n.pero@mi.flashnet.it>
|
||||
|
||||
* class.c: Rewritten the class table to use optimized, lock-free
|
||||
lookup. This more than doubles the speed of class method
|
||||
invocations. (class_table_setup), (class_table_insert),
|
||||
(class_table_replace), (class_table_get_safe),
|
||||
(class_table_next), (class_table_print),
|
||||
(class_table_print_histogram): New functions.
|
||||
(__objc_init_class_tables): Use class_table_setup.
|
||||
(__objc_add_class_to_hash): Use class_table_get_safe and
|
||||
class_table_insert. (objc_lookup_class), (objc_get_class): Do not
|
||||
assert the existence of the table; do not lock the runtime; use
|
||||
class_table_get_safe. (objc_next_class): Use class_table_next.
|
||||
(__objc_resolve_class_links): Use class_table_next.
|
||||
(class_pose_as): Use class_table_replace.
|
||||
|
||||
2001-09-10 Ovidiu Predescu <ovidiu@cup.hp.com>
|
||||
|
||||
* gc.c: Removed the DEBUG declaration.
|
||||
|
||||
Wed Jul 18 12:48:56 2001 Nicola Pero <n.pero@mi.flashnet.it>
|
||||
|
||||
* thr.c (objc_mutex_lock): Invoke __objc_thread_id directly,
|
||||
rather than through objc_thread_id, to save a function call.
|
||||
(objc_mutex_trylock, objc_mutex_unlock, objc_condition_wait):
|
||||
Ditto.
|
||||
|
||||
Mon Jul 16 12:15:00 2001 Nicola Pero <n.pero@mi.flashnet.it>
|
||||
|
||||
* objc/objc-api.h (object_is_class): Fixed - buggy code was trying
|
||||
to cast an id to a Class, which can not be done. Make the check
|
||||
by using CLS_ISMETA on the class pointer instead.
|
||||
(object_is_meta_class): Similar fix.
|
||||
|
||||
2001-06-09 Alexandre Oliva <aoliva@redhat.com>, Stephen L Moshier <moshier@mediaone.net>
|
||||
|
||||
* configure.in (AC_EXEEXT): Work around in case it expands to
|
||||
nothing, as in autoconf 2.50.
|
||||
* acinclude.m4: Likewise.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2001-06-08 Nicola Pero <n.pero@mi.flashnet.it>
|
||||
|
||||
* THREADS: Explain that when we compile libobjc inside GCC, we
|
||||
always use thr-objc.c as a backend, which uses GCC's thread code.
|
||||
|
||||
2001-06-06 Richard Frith-Macdonald <rrfm@gnu.org>
|
||||
|
||||
* init.c (__objc_send_message_in_list): When setting a new entry
|
||||
in __objc_load_methods use the method IMP as key, but check to see
|
||||
if the method is in the hashtable by looking at the IMP also.
|
||||
Also ... call the method after adding it to the hashtable rather
|
||||
than before ... thus preventing an obscure possibility of infinite
|
||||
recursion if a +load method itself loads a subclass.
|
||||
|
||||
2001-05-25 Ovidiu Predescu <ovidiu@cup.hp.com>
|
||||
|
||||
* init.c (__objc_send_message_in_list): When setting a new entry
|
||||
in __objc_load_methods use the method name as key, not the method
|
||||
IMP (reported by Richard Frith-Macdonald <richard@brainstorm.co.uk>).
|
||||
|
||||
2001-05-09 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* objc-features.texi: Move to ../gcc/objc.texi.
|
||||
* fdl.texi: Remove.
|
||||
* Makefile.in: Don't generate documentation from
|
||||
objc-features.texi.
|
||||
|
||||
2001-05-01 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* fdl.texi: New file.
|
||||
* objc-features.texi: Simplify.
|
||||
* Makefile.in: Adjust accordingly.
|
||||
|
||||
2001-04-30 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* objc-features.texi: Use the GFDL.
|
||||
|
||||
Wed Mar 21 04:44:58 EST 2001 John Wehle (john@feith.com)
|
||||
|
||||
* encoding.c (REAL_TYPE): Define.
|
||||
|
||||
2001-03-19 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* encoding.c (TYPE_MODE): Define.
|
||||
|
||||
2001-03-14 Nicola Pero <n.pero@mi.flashnet.it>
|
||||
|
||||
* thr.c (objc_thread_add): New function.
|
||||
(objc_thread_remove): Ditto.
|
||||
* objc/thr.h: Declare them.
|
||||
* libobjc.def: Mention them.
|
||||
|
||||
2001-02-28 Ovidiu Predescu <ovidiu@cup.hp.com>
|
||||
|
||||
* objc-features.texi: Document the @compatibility_alias compiler
|
||||
directive (description from Nicola Pero <n.pero@mi.flashnet.it>).
|
||||
|
||||
Fri Feb 23 18:12:00 2001 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
|
||||
|
||||
* sendmsg.c (__objc_forward): Delete strlen() declaration.
|
||||
|
||||
2001-02-08 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* configure.in: Don't run AC_PROG_CC_WORKS or AC_EXEEXT, because
|
||||
we're not interested in the result and they might fail.
|
||||
* configure: Regenerated.
|
||||
|
||||
2001-01-12 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* objc-features.texi: Use @email.
|
||||
|
||||
2001-01-12 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* sendmsg.c (__objc_print_dtable_stats): Don't use #ifdef inside
|
||||
printf.
|
||||
|
||||
2000-01-11 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* encoding.c (STRUCTURE_SIZE_BOUNDARY): Redefine in a way that
|
||||
determines the value dynamically.
|
||||
|
||||
Wed Jan 3 00:49:10 2001 Ovidiu Predescu <ovidiu@cup.hp.com>
|
||||
|
||||
* sendmsg.c: Added __objc_msg_forward, a hook that allows external
|
||||
libraries to provide a function that returns the real forwarding
|
||||
function. This can alleviate problems __builtin_apply() and
|
||||
friends have on various platforms. (Solution suggested by Helge
|
||||
Hess.)
|
||||
|
||||
* objc/objc-api.h: Define __objc_msg_forward.
|
||||
|
||||
* sendmsg.c: Define gen_rtx_REG.
|
||||
|
||||
2000-12-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
||||
|
||||
* thr-rtems.c: New file. Stub to compile.
|
||||
|
||||
2000-09-06 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* configure: Rebuilt with new libtool.m4.
|
||||
|
||||
Tue Aug 15 00:38:56 2000 Ovidiu Predescu <ovidiu@cup.hp.com>
|
||||
|
||||
* configure.in: Create a config.h file. Check for <sched.h>.
|
||||
* configure: Regenerate.
|
||||
|
||||
* config.h.in: Check for <sched.h>.
|
||||
|
||||
2000-08-14 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* configure: Regenerate after change to ../libtool.m4.
|
||||
|
||||
2000-08-14 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* objc-features.texi (Top): Move @menu at end of node.
|
||||
|
||||
2000-08-11 Manfred Hollstein <manfredh@redhat.com>
|
||||
|
||||
* objc-features.texi: Move @node Top before @menu.
|
||||
|
||||
Sun Aug 6 23:27:49 2000 Ovidiu Predescu <ovidiu@cup.hp.com>
|
||||
|
||||
* objc-features.texi: Documented the new -fconstant-string-class
|
||||
option.
|
||||
|
||||
Sun Aug 6 22:51:16 2000 Ovidiu Predescu <ovidiu@cup.hp.com>
|
||||
|
||||
* thr-posix.c: Integrated Chris Ball's <cball@fmco.com> changes to
|
||||
improve the Posix thread support for Objective-C.
|
||||
|
||||
2000-08-04 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* aclocal.m4: Replace copy of ../libtool.m4 with
|
||||
sinclude(../libtool.m4).
|
||||
|
||||
Fri Jul 28 08:58:02 2000 Nicola Pero <nicola@brainstorm.co.uk>
|
||||
|
||||
* configure.in: Added libtool support; build shared libraries
|
||||
if --enable-shared was passed on command line.
|
||||
* Makefile.in: Modified most compilation commands to use libtool.
|
||||
* aclocal.m4: New symbolic link to the ../libtool.m4, from the
|
||||
libtool distribution.
|
||||
|
||||
Sat Jul 29 00:10:21 2000 Ovidiu Predescu <ovidiu@cup.hp.com>
|
||||
|
||||
* sarray.c, Object.m: Removed the explicit prototypes for strlen
|
||||
and memcpy on 64-bit platforms (Suggested by Rodney Brown
|
||||
<rdb@cup.hp.com>).
|
||||
|
||||
2000-05-12 H.J. Lu (hjl@gnu.org)
|
||||
|
||||
* Makefile.in (GTHREAD_FLAGS): New.
|
||||
(ALL_CFLAGS): Add $(GTHREAD_FLAGS).
|
||||
(OBJC_THREAD_FILE): Changed to thr-objc.
|
||||
|
||||
* configure.in (GTHREAD_FLAGS): New, check and replace it for
|
||||
Makefile.
|
||||
(OBJC_THREAD_FILE): Removed.
|
||||
|
||||
* thr-objc.c: New.
|
||||
|
||||
2000-07-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* objc/hash.h: Include string.h.
|
||||
|
||||
2000-04-15 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* Object.m (strlen): 64-bit PowerPC is a 64bit platform as well.
|
||||
|
||||
2000-04-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* Object.m (strlen): Provide prototype on all 64bit platforms,
|
||||
not only alpha.
|
||||
* sarray.c (memcpy): Likewise.
|
||||
* encoding.c (objc_layout_finish_structure): Don't use
|
||||
ROUND_TYPE_ALIGN on sparc.
|
||||
|
||||
* encoding.c (objc_layout_structure_next_member): Do the whole
|
||||
procedure even for the first member, so that we get correct
|
||||
alignment.
|
||||
|
||||
2000-03-29 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* objc/Protocol.h, objc/objc-list.h: Change #endif labels to
|
||||
comments.
|
||||
|
||||
Sun Oct 24 23:54:10 PDT 1999 Jeff Law (law@cygnus.com)
|
||||
2000-02-23 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* gcc-2.95.2 Released.
|
||||
* Makefile.in: Add -DIN_TARGET_LIBS to ALL_CFLAGS.
|
||||
|
||||
Mon Aug 16 01:29:24 PDT 1999 Jeff Law (law@cygnus.com)
|
||||
Thu Sep 23 07:19:12 1999 Chris Ball <cball@fmco.com>
|
||||
|
||||
* gcc-2.95.1 Released.
|
||||
* thr-posix.c (__objc_mutex_deallocate): made deallocate work.
|
||||
|
||||
Tue Sep 21 07:47:10 1999 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* Makefile.in (gc.o, gc_gc.o): Do not pass -fgnu-runtime to
|
||||
the compiler when building C code.
|
||||
|
||||
Fri Aug 6 23:32:29 1999 Daniel Jacobowitz <drow@drow.them.org>
|
||||
|
||||
* Makefile.in (FLAGS_TO_PASS): Include prefix, exec_prefix,
|
||||
libdir, libsubdir and tooldir.
|
||||
|
||||
Wed Jul 28 21:39:31 PDT 1999 Jeff Law (law@cygnus.com)
|
||||
|
||||
* gcc-2.95 Released.
|
||||
|
||||
Sun Jul 25 23:40:51 PDT 1999 Jeff Law (law@cygnus.com)
|
||||
|
||||
* gcc-2.95 Released.
|
||||
|
||||
Mon Jun 21 05:40:15 1999 John David Anglin <dave@hiauly1>
|
||||
|
||||
* init.c (__objc_force_linking): Make global.
|
||||
|
@ -1,5 +1,5 @@
|
||||
#Makefile for GNU Objective C runtime library.
|
||||
#Copyright (C) 1993, 95-97, 1998 Free Software Foundation, Inc.
|
||||
#Copyright (C) 1993, 95-98, 1999, 2001 Free Software Foundation, Inc.
|
||||
|
||||
#This file is part of GNU CC.
|
||||
|
||||
@ -23,20 +23,27 @@
|
||||
#worthless.
|
||||
|
||||
SHELL = /bin/sh
|
||||
MAKEOVERRIDES=
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
srcdir = @glibcpp_srcdir@
|
||||
VPATH = @glibcpp_srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
target_alias = @target_alias@
|
||||
gcc_version = @gcc_version@
|
||||
gcc_version_trigger = @gcc_version_trigger@
|
||||
top_srcdir = @top_srcdir@
|
||||
toplevel_srcdir = @toplevel_srcdir@
|
||||
toolexecdir = @glibcpp_toolexecdir@
|
||||
glibcpp_toolexecdir = @glibcpp_toolexecdir@
|
||||
glibcpp_toolexeclibdir = @glibcpp_toolexeclibdir@
|
||||
|
||||
top_builddir = .
|
||||
|
||||
libdir = $(exec_prefix)/lib
|
||||
libsubdir = $(libdir)/gcc-lib/$(target_alias)/$(gcc_version)
|
||||
incinstalldir = $(libsubdir)/include
|
||||
|
||||
# Multilib support variables.
|
||||
MULTISRCTOP =
|
||||
@ -60,7 +67,24 @@ RANLIB = @RANLIB@
|
||||
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@
|
||||
ALL_CFLAGS = -I. -I$(srcdir) $(CPPFLAGS) $(DEFS) $(CFLAGS) -DIN_GCC
|
||||
GTHREAD_FLAGS=@GTHREAD_FLAGS@
|
||||
ALL_CFLAGS = -I. -I$(srcdir) $(CPPFLAGS) $(DEFS) $(CFLAGS) \
|
||||
$(GTHREAD_FLAGS) -DIN_GCC -DIN_TARGET_LIBS
|
||||
|
||||
# Libtool
|
||||
# The following strings describe the version of the obj-C library
|
||||
# begin compiled and compatibility issues.
|
||||
# Please refer to Libtool documentation about how to manage these
|
||||
# numbers.
|
||||
LIBOBJC_VERSION = 1:0:0
|
||||
LIBOBJC_GC_VERSION = 1:0:0
|
||||
# @LIBTOOL@ does not get it right, so we hack it in - FIXME
|
||||
LIBTOOL = ./libtool
|
||||
LIBTOOL_COMPILE = $(LIBTOOL) --mode=compile
|
||||
LIBTOOL_LINK = $(LIBTOOL) --mode=link
|
||||
LIBTOOL_INSTALL = $(LIBTOOL) --mode=install
|
||||
LIBTOOL_CLEAN = $(LIBTOOL) --mode=clean
|
||||
#LIBTOOL_UNINSTALL = $(LIBTOOL) --mode=uninstall
|
||||
|
||||
#
|
||||
# Define the cc1obj in terms of the CC that is passed on from higher
|
||||
@ -75,16 +99,17 @@ INCLUDES = -I$(srcdir)/objc -I$(srcdir)/$(MULTISRCTOP)../gcc \
|
||||
-I$(srcdir)/$(MULTISRCTOP)../include
|
||||
|
||||
OBJC_GCFLAGS=-DOBJC_WITH_GC=1
|
||||
OBJC_THREAD_FILE=thr-@OBJC_THREAD_FILE@
|
||||
OBJC_THREAD_FILE=thr-objc
|
||||
OBJC_BOEHM_GC=@OBJC_BOEHM_GC@
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .m .o
|
||||
.SUFFIXES: .c .m .lo
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
.c.lo:
|
||||
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
|
||||
.m.o:
|
||||
$(CC) -c $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
.m.lo:
|
||||
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
|
||||
# Flags to pass to a recursive make.
|
||||
FLAGS_TO_PASS = \
|
||||
@ -99,6 +124,7 @@ FLAGS_TO_PASS = \
|
||||
"INSTALL_DATA=$(INSTALL_DATA)" \
|
||||
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
|
||||
"LDFLAGS=$(LDFLAGS)" \
|
||||
"LIBTOOL=$(LIBTOOL)" \
|
||||
"LOADLIBES=$(LOADLIBES)" \
|
||||
"PICFLAG=$(PICFLAG)" \
|
||||
"RANLIB=$(RANLIB)" \
|
||||
@ -109,7 +135,7 @@ FLAGS_TO_PASS = \
|
||||
"libsubdir=$(libsubdir)" \
|
||||
"tooldir=$(tooldir)"
|
||||
|
||||
all: libobjc.a @OBJC_BOEHM_GC@
|
||||
all: libobjc.la $(OBJC_BOEHM_GC)
|
||||
$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=all
|
||||
|
||||
# User-visible header files.
|
||||
@ -120,111 +146,136 @@ OBJC_H = hash.h objc-list.h sarray.h objc.h objc-api.h \
|
||||
|
||||
# Modules that comprise the runtime library.
|
||||
|
||||
OBJS = archive.o class.o encoding.o gc.o hash.o init.o linking.o \
|
||||
misc.o nil_method.o NXConstStr.o Object.o objects.o \
|
||||
Protocol.o sarray.o selector.o sendmsg.o thr.o \
|
||||
$(OBJC_THREAD_FILE).o
|
||||
OBJS = archive.lo class.lo encoding.lo gc.lo hash.lo init.lo linking.lo \
|
||||
misc.lo nil_method.lo NXConstStr.lo Object.lo objects.lo \
|
||||
Protocol.lo sarray.lo selector.lo sendmsg.lo thr.lo \
|
||||
$(OBJC_THREAD_FILE).lo
|
||||
|
||||
OBJS_GC = archive_gc.o class_gc.o encoding_gc.o gc_gc.o hash_gc.o \
|
||||
init_gc.o linking_gc.o misc_gc.o nil_method_gc.o \
|
||||
NXConstStr_gc.o Object_gc.o objects_gc.o Protocol_gc.o \
|
||||
sarray_gc.o selector_gc.o sendmsg_gc.o thr_gc.o \
|
||||
$(OBJC_THREAD_FILE)_gc.o
|
||||
OBJS_GC = archive_gc.lo class_gc.lo encoding_gc.lo gc_gc.lo hash_gc.lo \
|
||||
init_gc.lo linking_gc.lo misc_gc.lo nil_method_gc.lo \
|
||||
NXConstStr_gc.lo Object_gc.lo objects_gc.lo Protocol_gc.lo \
|
||||
sarray_gc.lo selector_gc.lo sendmsg_gc.lo thr_gc.lo \
|
||||
$(OBJC_THREAD_FILE)_gc.lo
|
||||
|
||||
runtime-info.h:
|
||||
echo "" > tmp-runtime
|
||||
echo "/* This file is automatically generated */" > $@
|
||||
$(CC1OBJ) -print-objc-runtime-info tmp-runtime >> $@
|
||||
rm -f tmp-runtime
|
||||
echo "" > tmp-runtime
|
||||
echo "/* This file is automatically generated */" > $@
|
||||
$(CC1OBJ) -print-objc-runtime-info tmp-runtime >> $@
|
||||
rm -f tmp-runtime
|
||||
|
||||
archive_gc.o: archive.c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
archive_gc.lo: archive.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
class_gc.o: class.c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
class_gc.lo: class.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
encoding_gc.o: encoding.c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
encoding_gc.lo: encoding.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
gc.o: gc.c
|
||||
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
gc.lo: gc.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
|
||||
gc_gc.o: gc.c
|
||||
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
gc_gc.lo: gc.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
hash_gc.o: hash.c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
hash_gc.lo: hash.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
init_gc.o: init.c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
init_gc.lo: init.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
linking.o: linking.m
|
||||
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
linking.lo: linking.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
linking_gc.o: linking.m
|
||||
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
linking_gc.lo: linking.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
|
||||
misc_gc.o: misc.c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
misc_gc.lo: misc.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) -o $@ $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
nil_method_gc.o: nil_method.c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
nil_method_gc.lo: nil_method.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) -o $@ $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
NXConstStr.o: NXConstStr.m
|
||||
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
NXConstStr.lo: NXConstStr.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
NXConstStr_gc.o: NXConstStr.m
|
||||
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
NXConstStr_gc.lo: NXConstStr.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
|
||||
Object.o: Object.m
|
||||
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
Object.lo: Object.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
Object_gc.o: Object.m
|
||||
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
Object_gc.lo: Object.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
|
||||
objects_gc.o: objects.c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
objects_gc.lo: objects.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) -o $@ $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
Protocol.o: Protocol.m
|
||||
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
Protocol.lo: Protocol.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
Protocol_gc.o: Protocol.m
|
||||
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
Protocol_gc.lo: Protocol.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
|
||||
sarray_gc.o: sarray.c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
sarray_gc.lo: sarray.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
selector_gc.o: selector.c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
selector_gc.lo: selector.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
sendmsg.o: sendmsg.c runtime-info.h
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
sendmsg.lo: sendmsg.c runtime-info.h
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
|
||||
sendmsg_gc.o: sendmsg.c runtime-info.h
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
sendmsg_gc.lo: sendmsg.c runtime-info.h
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
thr_gc.o: thr.c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
thr_gc.lo: thr.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
$(OBJC_THREAD_FILE)_gc.o: $(OBJC_THREAD_FILE).c
|
||||
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
$(OBJC_THREAD_FILE)_gc.lo: $(OBJC_THREAD_FILE).c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
doc: info dvi html
|
||||
|
||||
libobjc.a: $(OBJS)
|
||||
$(AR) $(AR_FLAGS) $@ $(OBJS)
|
||||
$(RANLIB) $@
|
||||
libobjc.la: $(OBJS)
|
||||
$(LIBTOOL_LINK) $(CC) -o $@ $(OBJS) \
|
||||
-rpath $(glibcpp_toolexeclibdir) \
|
||||
-version-info $(LIBOBJC_VERSION)
|
||||
|
||||
libobjc_gc.a: $(OBJS_GC)
|
||||
$(AR) $(AR_FLAGS) $@ $(OBJS_GC)
|
||||
$(RANLIB) $@
|
||||
libobjc_gc.la: $(OBJS_GC)
|
||||
$(LIBTOOL_LINK) $(CC) -o $@ $(OBJS_GC) \
|
||||
-rpath $(glibcpp_toolexeclibdir) \
|
||||
-version-info $(LIBOBJC_GC_VERSION)
|
||||
|
||||
libobjc_s.a: libobjc.a
|
||||
#
|
||||
# FIXME -- The following part does not fit in the libtool context.
|
||||
# Libtool is supposed to [going to] be able to create a win 32 DLL
|
||||
# without extra code but since I don't have a win machine to test
|
||||
# if it already works, I leave the old code here.
|
||||
#
|
||||
libobjc_s.a: libobjc.la
|
||||
mv libobjc.a libobjc_s.a
|
||||
|
||||
# Create a relocatable DLL
|
||||
@ -241,19 +292,15 @@ libobjc.dll: libobjc_s.a libobjc_entry.o
|
||||
-o libobjc.dll libobjc_s.a libobjc_entry.o -lkernel32
|
||||
$(DLLTOOL) --dllname libobjc.dll --def $(srcdir)/libobjc.def \
|
||||
--output-lib libobjc.a
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
info: objc-features.info
|
||||
dvi: objc-features.dvi
|
||||
html: objc-features_toc.html
|
||||
|
||||
objc-features.info: $(srcdir)/objc-features.texi
|
||||
makeinfo $(srcdir)/objc-features.texi
|
||||
|
||||
objc-features.dvi: $(srcdir)/objc-features.texi
|
||||
texi2dvi $(srcdir)/objc-features.texi
|
||||
|
||||
objc-features_toc.html: objc-features.texi
|
||||
texi2html -split_node $(srcdir)/objc-features.texi
|
||||
info:
|
||||
dvi:
|
||||
html:
|
||||
|
||||
Makefile: Makefile.in config.status
|
||||
$(SHELL) config.status
|
||||
@ -267,43 +314,31 @@ ${srcdir}/configure: configure.in
|
||||
rm -f config.cache
|
||||
cd ${srcdir} && autoconf
|
||||
|
||||
install: install-libs copy-headers
|
||||
install: install-libs install-headers
|
||||
|
||||
install-libs: installdirs
|
||||
-if test -f libobjc.a ; then \
|
||||
rm -f $(libsubdir)/libobjc.a; \
|
||||
$(INSTALL_DATA) libobjc.a $(libsubdir)/libobjc.a; \
|
||||
chmod a-x $(libsubdir)/libobjc.a; \
|
||||
else true; fi
|
||||
-if test -f libobjc_gc.a ; then \
|
||||
rm -f $(libsubdir)/libobjc_gc.a; \
|
||||
$(INSTALL_DATA) libobjc_gc.a $(libsubdir)/libobjc_gc.a; \
|
||||
chmod a-x $(libsubdir)/libobjc_gc.a; \
|
||||
else true; fi
|
||||
-if test -f libobjc_s.a ; then \
|
||||
rm -f $(libsubdir)/libobjc_s.a; \
|
||||
$(INSTALL_DATA) libobjc_s.a $(libsubdir)/libobjc_s.a; \
|
||||
chmod a-x $(libsubdir)/libobjc_s.a; \
|
||||
else true; fi
|
||||
-if test -f libobjc.dll ; then \
|
||||
rm -f $(bindir)/libobjc.dll; \
|
||||
$(INSTALL_DATA) libobjc.dll $(bindir)/libobjc.dll; \
|
||||
else true; fi
|
||||
$(SHELL) $(toplevel_srcdir)/mkinstalldirs $(glibcpp_toolexeclibdir)
|
||||
$(LIBTOOL_INSTALL) $(INSTALL) libobjc.la $(glibcpp_toolexeclibdir);
|
||||
if [ "$(OBJC_BOEHM_GC)" ]; then \
|
||||
$(LIBTOOL_INSTALL) $(INSTALL) libobjc_gc.la \
|
||||
$(glibcpp_toolexeclibdir);\
|
||||
fi
|
||||
$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO="$@"
|
||||
@-$(LIBTOOL) --mode=finish $(glibcpp_toolexeclibdir)
|
||||
|
||||
# Copy Objective C headers to installation include directory.
|
||||
copy-headers:
|
||||
-rm -rf $(incinstalldir)/objc
|
||||
-mkdir $(incinstalldir)/objc
|
||||
install-headers:
|
||||
$(SHELL) $(toplevel_srcdir)/mkinstalldirs $(libsubdir)/include/objc
|
||||
for file in $(OBJC_H); do \
|
||||
realfile=$(srcdir)/objc/$${file}; \
|
||||
cp $${realfile} $(incinstalldir)/objc; \
|
||||
chmod a+r $(incinstalldir)/objc/$${file}; \
|
||||
$(INSTALL_DATA) $${realfile} $(libsubdir)/include/objc; \
|
||||
done
|
||||
|
||||
check uninstall install-strip dist installcheck installdirs:
|
||||
|
||||
mostlyclean:
|
||||
-rm -f runtime-info.h tmp-runtime.s *.o libobjc* xforward \
|
||||
-$(LIBTOOL_CLEAN) rm -f libobjc.la libobjc_gc.la *.lo
|
||||
-rm -f runtime-info.h tmp-runtime.s *.o *.lo libobjc* xforward \
|
||||
fflags *.aux *.cp *.dvi *.fn *.info *.ky *.log *.pg \
|
||||
*.toc *.tp *.vr *.html libobj.exp
|
||||
@$(MULTICLEAN) multi-clean DO=mostlyclean
|
||||
|
@ -320,10 +320,6 @@ extern int errno;
|
||||
object_get_class_name(self), sel_get_name(aSel)];
|
||||
}
|
||||
|
||||
#ifdef __alpha__
|
||||
extern size_t strlen(const char*);
|
||||
#endif
|
||||
|
||||
- error:(const char *)aString, ...
|
||||
{
|
||||
#define FMT "error: %s (%s)\n%s\n"
|
||||
|
@ -102,30 +102,33 @@ high degree of portability across platforms.
|
||||
|
||||
The backend is composed of a file with the necessary code to map the ObjC
|
||||
thread and mutex to a platform specific implementation. For example, the
|
||||
file thr-solaris.c contains the implementation for Solaris. When you
|
||||
configure GCC, it attempts to pick an appropriate backend file for the
|
||||
target platform; however, you can override this choice by assign the
|
||||
OBJC_THREAD_FILE make variable to the basename of the backend file. This
|
||||
is especially useful on platforms which have multiple thread libraries.
|
||||
For example:
|
||||
|
||||
make OBJC_THREAD_FILE=thr-posix
|
||||
|
||||
would indicate that the generic posix backend file, thr-posix.c, should be
|
||||
compiled with the ObjC runtime library. If your platform does not support
|
||||
threads then you should specify the OBJC_THREAD_FILE=thr-single backend file
|
||||
to compile the ObjC runtime library without thread or mutex support; note
|
||||
that programs which rely upon the ObjC thread and mutex functions will
|
||||
compile and link correctly but attempting to create a thread or mutex will
|
||||
result in an error.
|
||||
file thr-solaris.c contains the implementation for Solaris.
|
||||
|
||||
If you are compiling libobjc as part of GCC, the thr-objc.c backend is
|
||||
always used; this backend uses GCC's gthread code. The thread system
|
||||
is automatically configured when GCC is configured. Important: make
|
||||
sure you configure GCC using `--enable-threads' if you want threads !
|
||||
|
||||
If you want to compile libobjc standalone, then you would need to
|
||||
modify the configure.in and makefiles for it; and you need to pick an
|
||||
appropriate backend file for the target platform; you make this choice
|
||||
by assigning the OBJC_THREAD_FILE make variable to the basename of the
|
||||
backend file. For example, OBJC_THREAD_FILE=thr-posix would indicate
|
||||
that the generic posix backend file, thr-posix.c, should be compiled
|
||||
with the ObjC runtime library. If your platform does not support
|
||||
threads then you should specify the OBJC_THREAD_FILE=thr-single
|
||||
backend file to compile the ObjC runtime library without thread or
|
||||
mutex support; note that programs which rely upon the ObjC thread and
|
||||
mutex functions will compile and link correctly but attempting to
|
||||
create a thread or mutex will result in an error.
|
||||
|
||||
It is questionable whether it is really necessary to have both a
|
||||
frontend and backend function for all available functionality. On the
|
||||
one hand, it provides a clear, consistent differentiation between what
|
||||
is public and what is private with the downside of having the overhead
|
||||
of multiple functions calls. For example, the function to have a thread
|
||||
yield the processor is objc_thread_yield; in the current implementation
|
||||
this produces a function call set:
|
||||
of multiple functions calls. For example, the function to have a
|
||||
thread yield the processor is objc_thread_yield; in the current
|
||||
implementation this produces a function call set:
|
||||
|
||||
objc_thread_yield() -> __objc_thread_yield() -> system yield function
|
||||
|
||||
|
224
contrib/libobjc/aclocal.m4
vendored
Normal file
224
contrib/libobjc/aclocal.m4
vendored
Normal file
@ -0,0 +1,224 @@
|
||||
dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl This program is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
dnl PARTICULAR PURPOSE.
|
||||
|
||||
dnl
|
||||
dnl Initialize configure bits.
|
||||
dnl
|
||||
dnl GLIBCPP_CONFIGURE
|
||||
AC_DEFUN(GLIBCPP_CONFIGURE, [
|
||||
dnl Default to --enable-multilib
|
||||
AC_ARG_ENABLE(multilib,
|
||||
[ --enable-multilib build hella library versions (default)],
|
||||
[case "${enableval}" in
|
||||
yes) multilib=yes ;;
|
||||
no) multilib=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for multilib option) ;;
|
||||
esac], [multilib=yes])dnl
|
||||
|
||||
# When building with srcdir == objdir, links to the source files will
|
||||
# be created in directories within the target_subdir. We have to
|
||||
# adjust toplevel_srcdir accordingly, so that configure finds
|
||||
# install-sh and other auxiliary files that live in the top-level
|
||||
# source directory.
|
||||
if test "${srcdir}" = "."; then
|
||||
if test -z "${with_target_subdir}"; then
|
||||
toprel=".."
|
||||
else
|
||||
if test "${with_target_subdir}" != "."; then
|
||||
toprel="${with_multisrctop}../.."
|
||||
else
|
||||
toprel="${with_multisrctop}.."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
toprel=".."
|
||||
fi
|
||||
AC_CONFIG_AUX_DIR(${srcdir}/$toprel)
|
||||
toplevel_srcdir=\${top_srcdir}/$toprel
|
||||
AC_SUBST(toplevel_srcdir)
|
||||
|
||||
# Export build and source directories.
|
||||
# These need to be absolute paths, yet at the same time need to
|
||||
# canonicalize only relative paths, because then amd will not unmount
|
||||
# drives. Thus the use of PWDCMD: set it to 'pawd' or 'amq -w' if using amd.
|
||||
glibcpp_builddir=`pwd`
|
||||
case $srcdir in
|
||||
[\\/$]* | ?:[\\/]*) glibcpp_srcdir=${srcdir} ;;
|
||||
*) glibcpp_srcdir=`cd "$srcdir" && ${PWDCMD-pwd} || echo "$srcdir"` ;;
|
||||
esac
|
||||
AC_SUBST(glibcpp_builddir)
|
||||
AC_SUBST(glibcpp_srcdir)
|
||||
|
||||
dnl This is here just to satisfy automake.
|
||||
ifelse(not,equal,[AC_CONFIG_AUX_DIR(..)])
|
||||
|
||||
# Will set LN_S to either 'ln -s' or 'ln'. With autoconf 2.50+, can also
|
||||
# be 'cp -p' if linking isn't available.
|
||||
#ac_cv_prog_LN_S='cp -p'
|
||||
AC_PROG_LN_S
|
||||
|
||||
# We use these options to decide which functions to include.
|
||||
AC_ARG_WITH(target-subdir,
|
||||
[ --with-target-subdir=SUBDIR
|
||||
configuring in a subdirectory])
|
||||
AC_ARG_WITH(cross-host,
|
||||
[ --with-cross-host=HOST configuring with a cross compiler])
|
||||
|
||||
# Never versions of autoconf add an underscore to these functions.
|
||||
# Prevent future problems ...
|
||||
ifdef([AC_PROG_CC_G],[],[define([AC_PROG_CC_G],defn([_AC_PROG_CC_G]))])
|
||||
ifdef([AC_PROG_CC_GNU],[],[define([AC_PROG_CC_GNU],defn([_AC_PROG_CC_GNU]))])
|
||||
ifdef([AC_PROG_CXX_G],[],[define([AC_PROG_CXX_G],defn([_AC_PROG_CXX_G]))])
|
||||
ifdef([AC_PROG_CXX_GNU],[],[define([AC_PROG_CXX_GNU],defn([_AC_PROG_CXX_GNU]))])
|
||||
|
||||
# AC_PROG_CC
|
||||
|
||||
# FIXME: We temporarily define our own version of AC_PROG_CC. This is
|
||||
# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
|
||||
# are probably using a cross compiler, which will not be able to fully
|
||||
# link an executable. This should really be fixed in autoconf
|
||||
# itself.
|
||||
|
||||
AC_DEFUN(LIB_AC_PROG_CC,
|
||||
[AC_BEFORE([$0], [AC_PROG_CPP])dnl
|
||||
dnl Fool anybody using AC_PROG_CC.
|
||||
AC_PROVIDE([AC_PROG_CC])
|
||||
AC_CHECK_PROG(CC, gcc, gcc)
|
||||
if test -z "$CC"; then
|
||||
AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
|
||||
test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH])
|
||||
fi
|
||||
|
||||
AC_PROG_CC_GNU
|
||||
|
||||
if test $ac_cv_prog_gcc = yes; then
|
||||
GCC=yes
|
||||
dnl Check whether -g works, even if CFLAGS is set, in case the package
|
||||
dnl plays around with CFLAGS (such as to build both debugging and
|
||||
dnl normal versions of a library), tasteless as that idea is.
|
||||
ac_test_CFLAGS="${CFLAGS+set}"
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS=
|
||||
AC_PROG_CC_G
|
||||
if test "$ac_test_CFLAGS" = set; then
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
elif test $ac_cv_prog_cc_g = yes; then
|
||||
CFLAGS="-g -O2"
|
||||
else
|
||||
CFLAGS="-O2"
|
||||
fi
|
||||
else
|
||||
GCC=
|
||||
test "${CFLAGS+set}" = set || CFLAGS="-g"
|
||||
fi
|
||||
])
|
||||
|
||||
LIB_AC_PROG_CC
|
||||
|
||||
AC_CHECK_TOOL(AS, as)
|
||||
AC_CHECK_TOOL(AR, ar)
|
||||
AC_CHECK_TOOL(RANLIB, ranlib, ranlib-not-found-in-path-error)
|
||||
AC_PROG_INSTALL
|
||||
|
||||
# We need AC_EXEEXT to keep automake happy in cygnus mode. However,
|
||||
# at least currently, we never actually build a program, so we never
|
||||
# need to use $(EXEEXT). Moreover, the test for EXEEXT normally
|
||||
# fails, because we are probably configuring with a cross compiler
|
||||
# which can't create executables. So we include AC_EXEEXT to keep
|
||||
# automake happy, but we don't execute it, since we don't care about
|
||||
# the result.
|
||||
if false; then
|
||||
# autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
|
||||
# to nothing, so nothing would remain between `then' and `fi' if it
|
||||
# were not for the `:' below.
|
||||
:
|
||||
AC_EXEEXT
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl
|
||||
dnl GLIBCPP_EXPORT_INSTALL_INFO
|
||||
dnl calculates gxx_install_dir
|
||||
dnl exports glibcpp_toolexecdir
|
||||
dnl exports glibcpp_toolexeclibdir
|
||||
dnl exports glibcpp_prefixdir
|
||||
dnl
|
||||
dnl Assumes cross_compiling bits already done, and with_cross_host in
|
||||
dnl particular
|
||||
dnl
|
||||
dnl GLIBCPP_EXPORT_INSTALL_INFO
|
||||
AC_DEFUN(GLIBCPP_EXPORT_INSTALL_INFO, [
|
||||
# Assumes glibcpp_builddir, glibcpp_srcdir are alreay set up and
|
||||
# exported correctly in GLIBCPP_CONFIGURE.
|
||||
glibcpp_toolexecdir=no
|
||||
glibcpp_toolexeclibdir=no
|
||||
glibcpp_prefixdir=${prefix}
|
||||
|
||||
AC_MSG_CHECKING([for interface version number])
|
||||
libstdcxx_interface=$INTERFACE
|
||||
AC_MSG_RESULT($libstdcxx_interface)
|
||||
|
||||
# Process the option "--enable-version-specific-runtime-libs"
|
||||
AC_MSG_CHECKING([for --enable-version-specific-runtime-libs])
|
||||
AC_ARG_ENABLE(version-specific-runtime-libs,
|
||||
[ --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory ],
|
||||
[case "$enableval" in
|
||||
yes) version_specific_libs=yes ;;
|
||||
no) version_specific_libs=no ;;
|
||||
*) AC_MSG_ERROR([Unknown argument to enable/disable version-specific libs]);;
|
||||
esac],
|
||||
version_specific_libs=no)dnl
|
||||
# Option set, now we can test it.
|
||||
AC_MSG_RESULT($version_specific_libs)
|
||||
|
||||
gcc_version_trigger=${srcdir}/../gcc/version.c
|
||||
gcc_version_full=`grep version_string ${gcc_version_trigger} | sed -e 's/.*\"\([[^ \"]]*\)[[ \"]].*/\1/'`
|
||||
gcc_version=`echo ${gcc_version_full} | sed -e 's/\([^ ]*\) .*/\1/'`
|
||||
AC_SUBST(gcc_version)
|
||||
AC_SUBST(gcc_version_trigger)
|
||||
|
||||
if test $version_specific_libs = yes; then
|
||||
# Need the gcc compiler version to know where to install libraries
|
||||
# and header files if --enable-version-specific-runtime-libs option
|
||||
# is selected.
|
||||
changequote(,)dnl
|
||||
glibcpp_toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
|
||||
glibcpp_toolexeclibdir='$(toolexecdir)/'${gcc_version}'$(MULTISUBDIR)'
|
||||
changequote([,])dnl
|
||||
fi
|
||||
|
||||
# Calculate glibcpp_toolexecdir, glibcpp_toolexeclibdir
|
||||
# Install a library built with a cross compiler in tooldir, not libdir.
|
||||
if test x"$glibcpp_toolexecdir" = x"no"; then
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
glibcpp_toolexecdir='$(exec_prefix)/$(target_alias)'
|
||||
glibcpp_toolexeclibdir='$(toolexecdir)/lib$(MULTISUBDIR)'
|
||||
else
|
||||
glibcpp_toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
|
||||
glibcpp_toolexeclibdir='$(libdir)$(MULTISUBDIR)'
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(glibcpp_prefixdir)
|
||||
AC_SUBST(glibcpp_toolexecdir)
|
||||
AC_SUBST(glibcpp_toolexeclibdir)
|
||||
])
|
||||
|
||||
sinclude(../libtool.m4)
|
||||
dnl The lines below arrange for aclocal not to bring an installed
|
||||
dnl libtool.m4 into aclocal.m4, while still arranging for automake to
|
||||
dnl add a definition of LIBTOOL to Makefile.in.
|
||||
ifelse(,,,[AC_SUBST(LIBTOOL)
|
||||
AC_DEFUN([AM_PROG_LIBTOOL])
|
||||
AC_DEFUN([AC_LIBTOOL_DLOPEN])
|
||||
AC_DEFUN([AC_PROG_LD])
|
||||
])
|
@ -1,7 +1,10 @@
|
||||
/* GNU Objective C Runtime class related functions
|
||||
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 2001 Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup and Dennis Glatting.
|
||||
|
||||
Lock-free class table code designed and written from scratch by
|
||||
Nicola Pero, 2001.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify it under the
|
||||
@ -23,44 +26,411 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
however invalidate any other reasons why the executable file might be
|
||||
covered by the GNU General Public License. */
|
||||
|
||||
#include "runtime.h" /* the kitchen sink */
|
||||
/*
|
||||
The code in this file critically affects class method invocation
|
||||
speed. This long preamble comment explains why, and the issues
|
||||
involved.
|
||||
|
||||
|
||||
One of the traditional weaknesses of the GNU Objective-C runtime is
|
||||
that class method invocations are slow. The reason is that when you
|
||||
write
|
||||
|
||||
array = [NSArray new];
|
||||
|
||||
this gets basically compiled into the equivalent of
|
||||
|
||||
array = [(objc_get_class ("NSArray")) new];
|
||||
|
||||
objc_get_class returns the class pointer corresponding to the string
|
||||
`NSArray'; and because of the lookup, the operation is more
|
||||
complicated and slow than a simple instance method invocation.
|
||||
|
||||
Most high performance Objective-C code (using the GNU Objc runtime)
|
||||
I had the opportunity to read (or write) work around this problem by
|
||||
caching the class pointer:
|
||||
|
||||
Class arrayClass = [NSArray class];
|
||||
|
||||
... later on ...
|
||||
|
||||
array = [arrayClass new];
|
||||
array = [arrayClass new];
|
||||
array = [arrayClass new];
|
||||
|
||||
In this case, you always perform a class lookup (the first one), but
|
||||
then all the [arrayClass new] methods run exactly as fast as an
|
||||
instance method invocation. It helps if you have many class method
|
||||
invocations to the same class.
|
||||
|
||||
The long-term solution to this problem would be to modify the
|
||||
compiler to output tables of class pointers corresponding to all the
|
||||
class method invocations, and to add code to the runtime to update
|
||||
these tables - that should in the end allow class method invocations
|
||||
to perform precisely as fast as instance method invocations, because
|
||||
no class lookup would be involved. I think the Apple Objective-C
|
||||
runtime uses this technique. Doing this involves synchronized
|
||||
modifications in the runtime and in the compiler.
|
||||
|
||||
As a first medicine to the problem, I [NP] have redesigned and
|
||||
rewritten the way the runtime is performing class lookup. This
|
||||
doesn't give as much speed as the other (definitive) approach, but
|
||||
at least a class method invocation now takes approximately 4.5 times
|
||||
an instance method invocation on my machine (it would take approx 12
|
||||
times before the rewriting), which is a lot better.
|
||||
|
||||
One of the main reason the new class lookup is so faster is because
|
||||
I implemented it in a way that can safely run multithreaded without
|
||||
using locks - a so-called `lock-free' data structure. The atomic
|
||||
operation is pointer assignment. The reason why in this problem
|
||||
lock-free data structures work so well is that you never remove
|
||||
classes from the table - and the difficult thing with lock-free data
|
||||
structures is freeing data when is removed from the structures. */
|
||||
|
||||
#include "runtime.h" /* the kitchen sink */
|
||||
#include "sarray.h"
|
||||
|
||||
/* The table of classname->class. Used for objc_lookup_class and friends */
|
||||
static cache_ptr __objc_class_hash = 0; /* !T:MUTEX */
|
||||
#include <objc/objc.h>
|
||||
#include <objc/objc-api.h>
|
||||
#include <objc/thr.h>
|
||||
|
||||
/* This is a hook which is called by objc_get_class and
|
||||
objc_lookup_class if the runtime is not able to find the class.
|
||||
This may e.g. try to load in the class using dynamic loading */
|
||||
/* We use a table which maps a class name to the corresponding class
|
||||
* pointer. The first part of this file defines this table, and
|
||||
* functions to do basic operations on the table. The second part of
|
||||
* the file implements some higher level Objective-C functionality for
|
||||
* classes by using the functions provided in the first part to manage
|
||||
* the table. */
|
||||
|
||||
/**
|
||||
** Class Table Internals
|
||||
**/
|
||||
|
||||
/* A node holding a class */
|
||||
typedef struct class_node
|
||||
{
|
||||
struct class_node *next; /* Pointer to next entry on the list.
|
||||
NULL indicates end of list. */
|
||||
|
||||
const char *name; /* The class name string */
|
||||
int length; /* The class name string length */
|
||||
Class pointer; /* The Class pointer */
|
||||
|
||||
} *class_node_ptr;
|
||||
|
||||
/* A table containing classes is a class_node_ptr (pointing to the
|
||||
first entry in the table - if it is NULL, then the table is
|
||||
empty). */
|
||||
|
||||
/* We have 1024 tables. Each table contains all class names which
|
||||
have the same hash (which is a number between 0 and 1023). To look
|
||||
up a class_name, we compute its hash, and get the corresponding
|
||||
table. Once we have the table, we simply compare strings directly
|
||||
till we find the one which we want (using the length first). The
|
||||
number of tables is quite big on purpose (a normal big application
|
||||
has less than 1000 classes), so that you shouldn't normally get any
|
||||
collisions, and get away with a single comparison (which we can't
|
||||
avoid since we need to know that you have got the right thing). */
|
||||
#define CLASS_TABLE_SIZE 1024
|
||||
#define CLASS_TABLE_MASK 1023
|
||||
|
||||
static class_node_ptr class_table_array[CLASS_TABLE_SIZE];
|
||||
|
||||
/* The table writing mutex - we lock on writing to avoid conflicts
|
||||
between different writers, but we read without locks. That is
|
||||
possible because we assume pointer assignment to be an atomic
|
||||
operation. */
|
||||
static objc_mutex_t __class_table_lock = NULL;
|
||||
|
||||
/* CLASS_TABLE_HASH is how we compute the hash of a class name. It is
|
||||
a macro - *not* a function - arguments *are* modified directly.
|
||||
|
||||
INDEX should be a variable holding an int;
|
||||
HASH should be a variable holding an int;
|
||||
CLASS_NAME should be a variable holding a (char *) to the class_name.
|
||||
|
||||
After the macro is executed, INDEX contains the length of the
|
||||
string, and HASH the computed hash of the string; CLASS_NAME is
|
||||
untouched. */
|
||||
|
||||
#define CLASS_TABLE_HASH(INDEX, HASH, CLASS_NAME) \
|
||||
HASH = 0; \
|
||||
for (INDEX = 0; CLASS_NAME[INDEX] != '\0'; INDEX++) \
|
||||
{ \
|
||||
HASH = (HASH << 4) ^ (HASH >> 28) ^ CLASS_NAME[INDEX]; \
|
||||
} \
|
||||
\
|
||||
HASH = (HASH ^ (HASH >> 10) ^ (HASH >> 20)) & CLASS_TABLE_MASK;
|
||||
|
||||
/* Setup the table. */
|
||||
static void
|
||||
class_table_setup ()
|
||||
{
|
||||
/* Start - nothing in the table. */
|
||||
memset (class_table_array, 0, sizeof(class_node_ptr) * CLASS_TABLE_SIZE);
|
||||
|
||||
/* The table writing mutex. */
|
||||
__class_table_lock = objc_mutex_allocate ();
|
||||
}
|
||||
|
||||
|
||||
/* Insert a class in the table (used when a new class is registered). */
|
||||
static void
|
||||
class_table_insert (const char *class_name, Class class_pointer)
|
||||
{
|
||||
int hash, length;
|
||||
class_node_ptr new_node;
|
||||
|
||||
/* Find out the class name's hash and length. */
|
||||
CLASS_TABLE_HASH (length, hash, class_name);
|
||||
|
||||
/* Prepare the new node holding the class. */
|
||||
new_node = objc_malloc (sizeof (struct class_node));
|
||||
new_node->name = class_name;
|
||||
new_node->length = length;
|
||||
new_node->pointer = class_pointer;
|
||||
|
||||
/* Lock the table for modifications. */
|
||||
objc_mutex_lock (__class_table_lock);
|
||||
|
||||
/* Insert the new node in the table at the beginning of the table at
|
||||
class_table_array[hash]. */
|
||||
new_node->next = class_table_array[hash];
|
||||
class_table_array[hash] = new_node;
|
||||
|
||||
objc_mutex_unlock (__class_table_lock);
|
||||
}
|
||||
|
||||
/* Replace a class in the table (used only by poseAs:). */
|
||||
static void
|
||||
class_table_replace (Class old_class_pointer, Class new_class_pointer)
|
||||
{
|
||||
int hash;
|
||||
class_node_ptr node;
|
||||
|
||||
objc_mutex_lock (__class_table_lock);
|
||||
|
||||
hash = 0;
|
||||
node = class_table_array[hash];
|
||||
|
||||
while (hash < CLASS_TABLE_SIZE)
|
||||
{
|
||||
if (node == NULL)
|
||||
{
|
||||
hash++;
|
||||
if (hash < CLASS_TABLE_SIZE)
|
||||
{
|
||||
node = class_table_array[hash];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Class class1 = node->pointer;
|
||||
|
||||
if (class1 == old_class_pointer)
|
||||
{
|
||||
node->pointer = new_class_pointer;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
objc_mutex_unlock (__class_table_lock);
|
||||
}
|
||||
|
||||
|
||||
/* Get a class from the table. This does not need mutex protection.
|
||||
Currently, this function is called each time you call a static
|
||||
method, this is why it must be very fast. */
|
||||
static inline Class
|
||||
class_table_get_safe (const char *class_name)
|
||||
{
|
||||
class_node_ptr node;
|
||||
int length, hash;
|
||||
|
||||
/* Compute length and hash. */
|
||||
CLASS_TABLE_HASH (length, hash, class_name);
|
||||
|
||||
node = class_table_array[hash];
|
||||
|
||||
if (node != NULL)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (node->length == length)
|
||||
{
|
||||
/* Compare the class names. */
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if ((node->name)[i] != class_name[i])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == length)
|
||||
{
|
||||
/* They are equal! */
|
||||
return node->pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
while ((node = node->next) != NULL);
|
||||
}
|
||||
|
||||
return Nil;
|
||||
}
|
||||
|
||||
/* Enumerate over the class table. */
|
||||
struct class_table_enumerator
|
||||
{
|
||||
int hash;
|
||||
class_node_ptr node;
|
||||
};
|
||||
|
||||
|
||||
static Class
|
||||
class_table_next (struct class_table_enumerator **e)
|
||||
{
|
||||
struct class_table_enumerator *enumerator = *e;
|
||||
class_node_ptr next;
|
||||
|
||||
if (enumerator == NULL)
|
||||
{
|
||||
*e = objc_malloc (sizeof (struct class_table_enumerator));
|
||||
enumerator = *e;
|
||||
enumerator->hash = 0;
|
||||
enumerator->node = NULL;
|
||||
|
||||
next = class_table_array[enumerator->hash];
|
||||
}
|
||||
else
|
||||
{
|
||||
next = enumerator->node->next;
|
||||
}
|
||||
|
||||
if (next != NULL)
|
||||
{
|
||||
enumerator->node = next;
|
||||
return enumerator->node->pointer;
|
||||
}
|
||||
else
|
||||
{
|
||||
enumerator->hash++;
|
||||
|
||||
while (enumerator->hash < CLASS_TABLE_SIZE)
|
||||
{
|
||||
next = class_table_array[enumerator->hash];
|
||||
if (next != NULL)
|
||||
{
|
||||
enumerator->node = next;
|
||||
return enumerator->node->pointer;
|
||||
}
|
||||
enumerator->hash++;
|
||||
}
|
||||
|
||||
/* Ok - table finished - done. */
|
||||
objc_free (enumerator);
|
||||
return Nil;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* DEBUGGING FUNCTIONS */
|
||||
/* Debugging function - print the class table. */
|
||||
void
|
||||
class_table_print ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CLASS_TABLE_SIZE; i++)
|
||||
{
|
||||
class_node_ptr node;
|
||||
|
||||
printf ("%d:\n", i);
|
||||
node = class_table_array[i];
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
printf ("\t%s\n", node->name);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Debugging function - print an histogram of number of classes in
|
||||
function of hash key values. Useful to evaluate the hash function
|
||||
in real cases. */
|
||||
void
|
||||
class_table_print_histogram ()
|
||||
{
|
||||
int i, j;
|
||||
int counter = 0;
|
||||
|
||||
for (i = 0; i < CLASS_TABLE_SIZE; i++)
|
||||
{
|
||||
class_node_ptr node;
|
||||
|
||||
node = class_table_array[i];
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
counter++;
|
||||
node = node->next;
|
||||
}
|
||||
if (((i + 1) % 50) == 0)
|
||||
{
|
||||
printf ("%4d:", i + 1);
|
||||
for (j = 0; j < counter; j++)
|
||||
{
|
||||
printf ("X");
|
||||
}
|
||||
printf ("\n");
|
||||
counter = 0;
|
||||
}
|
||||
}
|
||||
printf ("%4d:", i + 1);
|
||||
for (j = 0; j < counter; j++)
|
||||
{
|
||||
printf ("X");
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
#endif /* DEBUGGING FUNCTIONS */
|
||||
|
||||
/**
|
||||
** Objective-C runtime functions
|
||||
**/
|
||||
|
||||
/* From now on, the only access to the class table data structure
|
||||
should be via the class_table_* functions. */
|
||||
|
||||
/* This is a hook which is called by objc_get_class and
|
||||
objc_lookup_class if the runtime is not able to find the class.
|
||||
This may e.g. try to load in the class using dynamic loading. */
|
||||
Class (*_objc_lookup_class)(const char* name) = 0; /* !T:SAFE */
|
||||
|
||||
|
||||
/* True when class links has been resolved */
|
||||
/* True when class links has been resolved. */
|
||||
BOOL __objc_class_links_resolved = NO; /* !T:UNUSED */
|
||||
|
||||
|
||||
/* Initial number of buckets size of class hash table. */
|
||||
#define CLASS_HASH_SIZE 32
|
||||
|
||||
void __objc_init_class_tables()
|
||||
{
|
||||
/* Allocate the class hash table */
|
||||
|
||||
if(__objc_class_hash)
|
||||
/* Allocate the class hash table. */
|
||||
|
||||
if(__class_table_lock)
|
||||
return;
|
||||
|
||||
|
||||
objc_mutex_lock(__objc_runtime_mutex);
|
||||
|
||||
__objc_class_hash
|
||||
= hash_new (CLASS_HASH_SIZE,
|
||||
(hash_func_type) hash_string,
|
||||
(compare_func_type) compare_strings);
|
||||
|
||||
class_table_setup ();
|
||||
|
||||
objc_mutex_unlock(__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
/* This function adds a class to the class hash table, and assigns the
|
||||
class a number, unless it's already known */
|
||||
/* This function adds a class to the class hash table, and assigns the
|
||||
class a number, unless it's already known. */
|
||||
void
|
||||
__objc_add_class_to_hash(Class class)
|
||||
{
|
||||
@ -68,14 +438,14 @@ __objc_add_class_to_hash(Class class)
|
||||
|
||||
objc_mutex_lock(__objc_runtime_mutex);
|
||||
|
||||
/* make sure the table is there */
|
||||
assert(__objc_class_hash);
|
||||
/* Make sure the table is there. */
|
||||
assert(__class_table_lock);
|
||||
|
||||
/* make sure it's not a meta class */
|
||||
/* Make sure it's not a meta class. */
|
||||
assert(CLS_ISCLASS(class));
|
||||
|
||||
/* Check to see if the class is already in the hash table. */
|
||||
h_class = hash_value_for_key (__objc_class_hash, class->name);
|
||||
h_class = class_table_get_safe (class->name);
|
||||
if (!h_class)
|
||||
{
|
||||
/* The class isn't in the hash table. Add the class and assign a class
|
||||
@ -86,7 +456,7 @@ __objc_add_class_to_hash(Class class)
|
||||
CLS_SETNUMBER(class->class_pointer, class_number);
|
||||
|
||||
++class_number;
|
||||
hash_add (&__objc_class_hash, class->name, class);
|
||||
class_table_insert (class->name, class);
|
||||
}
|
||||
|
||||
objc_mutex_unlock(__objc_runtime_mutex);
|
||||
@ -94,19 +464,12 @@ __objc_add_class_to_hash(Class class)
|
||||
|
||||
/* Get the class object for the class named NAME. If NAME does not
|
||||
identify a known class, the hook _objc_lookup_class is called. If
|
||||
this fails, nil is returned */
|
||||
this fails, nil is returned. */
|
||||
Class objc_lookup_class (const char* name)
|
||||
{
|
||||
Class class;
|
||||
|
||||
objc_mutex_lock(__objc_runtime_mutex);
|
||||
|
||||
/* Make sure the class hash table exists. */
|
||||
assert (__objc_class_hash);
|
||||
|
||||
class = hash_value_for_key (__objc_class_hash, name);
|
||||
|
||||
objc_mutex_unlock(__objc_runtime_mutex);
|
||||
class = class_table_get_safe (name);
|
||||
|
||||
if (class)
|
||||
return class;
|
||||
@ -119,20 +482,13 @@ Class objc_lookup_class (const char* name)
|
||||
|
||||
/* Get the class object for the class named NAME. If NAME does not
|
||||
identify a known class, the hook _objc_lookup_class is called. If
|
||||
this fails, an error message is issued and the system aborts */
|
||||
this fails, an error message is issued and the system aborts. */
|
||||
Class
|
||||
objc_get_class (const char *name)
|
||||
{
|
||||
Class class;
|
||||
|
||||
objc_mutex_lock(__objc_runtime_mutex);
|
||||
|
||||
/* Make sure the class hash table exists. */
|
||||
assert (__objc_class_hash);
|
||||
|
||||
class = hash_value_for_key (__objc_class_hash, name);
|
||||
|
||||
objc_mutex_unlock(__objc_runtime_mutex);
|
||||
class = class_table_get_safe (name);
|
||||
|
||||
if (class)
|
||||
return class;
|
||||
@ -144,7 +500,7 @@ objc_get_class (const char *name)
|
||||
return class;
|
||||
|
||||
objc_error(nil, OBJC_ERR_BAD_CLASS,
|
||||
"objc runtime: cannot find class %s\n", name);
|
||||
"objc runtime: cannot find class %s\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -166,44 +522,42 @@ objc_get_meta_class(const char *name)
|
||||
Class
|
||||
objc_next_class(void **enum_state)
|
||||
{
|
||||
Class class;
|
||||
|
||||
objc_mutex_lock(__objc_runtime_mutex);
|
||||
|
||||
/* Make sure the table is there. */
|
||||
assert(__class_table_lock);
|
||||
|
||||
/* make sure the table is there */
|
||||
assert(__objc_class_hash);
|
||||
|
||||
*(node_ptr*)enum_state =
|
||||
hash_next(__objc_class_hash, *(node_ptr*)enum_state);
|
||||
class = class_table_next ((struct class_table_enumerator **)enum_state);
|
||||
|
||||
objc_mutex_unlock(__objc_runtime_mutex);
|
||||
|
||||
if (*(node_ptr*)enum_state)
|
||||
return (*(node_ptr*)enum_state)->value;
|
||||
return (Class)0;
|
||||
|
||||
return class;
|
||||
}
|
||||
|
||||
/* Resolve super/subclass links for all classes. The only thing we
|
||||
can be sure of is that the class_pointer for class objects point
|
||||
to the right meta class objects */
|
||||
/* Resolve super/subclass links for all classes. The only thing we
|
||||
can be sure of is that the class_pointer for class objects point to
|
||||
the right meta class objects. */
|
||||
void __objc_resolve_class_links()
|
||||
{
|
||||
node_ptr node;
|
||||
struct class_table_enumerator *es = NULL;
|
||||
Class object_class = objc_get_class ("Object");
|
||||
Class class1;
|
||||
|
||||
assert(object_class);
|
||||
|
||||
objc_mutex_lock(__objc_runtime_mutex);
|
||||
|
||||
/* Assign subclass links */
|
||||
for (node = hash_next (__objc_class_hash, NULL); node;
|
||||
node = hash_next (__objc_class_hash, node))
|
||||
/* Assign subclass links. */
|
||||
while ((class1 = class_table_next (&es)))
|
||||
{
|
||||
Class class1 = node->value;
|
||||
|
||||
/* Make sure we have what we think we have. */
|
||||
assert (CLS_ISCLASS(class1));
|
||||
assert (CLS_ISMETA(class1->class_pointer));
|
||||
|
||||
/* The class_pointer of all meta classes point to Object's meta class. */
|
||||
/* The class_pointer of all meta classes point to Object's meta
|
||||
class. */
|
||||
class1->class_pointer->class_pointer = object_class->class_pointer;
|
||||
|
||||
if (!(CLS_ISRESOLV(class1)))
|
||||
@ -221,11 +575,11 @@ void __objc_resolve_class_links()
|
||||
DEBUG_PRINTF ("making class connections for: %s\n",
|
||||
class1->name);
|
||||
|
||||
/* assign subclass links for superclass */
|
||||
/* Assign subclass links for superclass. */
|
||||
class1->sibling_class = a_super_class->subclass_list;
|
||||
a_super_class->subclass_list = class1;
|
||||
|
||||
/* Assign subclass links for meta class of superclass */
|
||||
/* Assign subclass links for meta class of superclass. */
|
||||
if (a_super_class->class_pointer)
|
||||
{
|
||||
class1->class_pointer->sibling_class
|
||||
@ -234,8 +588,8 @@ void __objc_resolve_class_links()
|
||||
= class1->class_pointer;
|
||||
}
|
||||
}
|
||||
else /* a root class, make its meta object */
|
||||
/* be a subclass of Object */
|
||||
else /* A root class, make its meta object be a subclass of
|
||||
Object. */
|
||||
{
|
||||
class1->class_pointer->sibling_class
|
||||
= object_class->subclass_list;
|
||||
@ -244,11 +598,10 @@ void __objc_resolve_class_links()
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign superclass links */
|
||||
for (node = hash_next (__objc_class_hash, NULL); node;
|
||||
node = hash_next (__objc_class_hash, node))
|
||||
/* Assign superclass links. */
|
||||
es = NULL;
|
||||
while ((class1 = class_table_next (&es)))
|
||||
{
|
||||
Class class1 = node->value;
|
||||
Class sub_class;
|
||||
for (sub_class = class1->subclass_list; sub_class;
|
||||
sub_class = sub_class->sibling_class)
|
||||
@ -269,13 +622,10 @@ void __objc_resolve_class_links()
|
||||
Class
|
||||
class_pose_as (Class impostor, Class super_class)
|
||||
{
|
||||
node_ptr node;
|
||||
Class class1;
|
||||
|
||||
if (!CLS_ISRESOLV (impostor))
|
||||
__objc_resolve_class_links ();
|
||||
|
||||
/* preconditions */
|
||||
/* Preconditions */
|
||||
assert (impostor);
|
||||
assert (super_class);
|
||||
assert (impostor->super_class == super_class);
|
||||
@ -286,73 +636,64 @@ class_pose_as (Class impostor, Class super_class)
|
||||
{
|
||||
Class *subclass = &(super_class->subclass_list);
|
||||
|
||||
/* move subclasses of super_class to impostor */
|
||||
/* Move subclasses of super_class to impostor. */
|
||||
while (*subclass)
|
||||
{
|
||||
Class nextSub = (*subclass)->sibling_class;
|
||||
Class nextSub = (*subclass)->sibling_class;
|
||||
|
||||
if (*subclass != impostor)
|
||||
{
|
||||
Class sub = *subclass;
|
||||
if (*subclass != impostor)
|
||||
{
|
||||
Class sub = *subclass;
|
||||
|
||||
/* classes */
|
||||
sub->sibling_class = impostor->subclass_list;
|
||||
sub->super_class = impostor;
|
||||
impostor->subclass_list = sub;
|
||||
/* Classes */
|
||||
sub->sibling_class = impostor->subclass_list;
|
||||
sub->super_class = impostor;
|
||||
impostor->subclass_list = sub;
|
||||
|
||||
/* It will happen that SUB is not a class object if it is
|
||||
the top of the meta class hierarchy chain. (root
|
||||
meta-class objects inherit their class object) If that is
|
||||
the case... don't mess with the meta-meta class. */
|
||||
if (CLS_ISCLASS (sub))
|
||||
{
|
||||
/* meta classes */
|
||||
CLASSOF (sub)->sibling_class =
|
||||
CLASSOF (impostor)->subclass_list;
|
||||
CLASSOF (sub)->super_class = CLASSOF (impostor);
|
||||
CLASSOF (impostor)->subclass_list = CLASSOF (sub);
|
||||
}
|
||||
}
|
||||
/* It will happen that SUB is not a class object if it is
|
||||
the top of the meta class hierarchy chain (root
|
||||
meta-class objects inherit their class object). If
|
||||
that is the case... don't mess with the meta-meta
|
||||
class. */
|
||||
if (CLS_ISCLASS (sub))
|
||||
{
|
||||
/* Meta classes */
|
||||
CLASSOF (sub)->sibling_class =
|
||||
CLASSOF (impostor)->subclass_list;
|
||||
CLASSOF (sub)->super_class = CLASSOF (impostor);
|
||||
CLASSOF (impostor)->subclass_list = CLASSOF (sub);
|
||||
}
|
||||
}
|
||||
|
||||
*subclass = nextSub;
|
||||
*subclass = nextSub;
|
||||
}
|
||||
|
||||
/* set subclasses of superclass to be impostor only */
|
||||
/* Set subclasses of superclass to be impostor only. */
|
||||
super_class->subclass_list = impostor;
|
||||
CLASSOF (super_class)->subclass_list = CLASSOF (impostor);
|
||||
|
||||
/* set impostor to have no sibling classes */
|
||||
/* Set impostor to have no sibling classes. */
|
||||
impostor->sibling_class = 0;
|
||||
CLASSOF (impostor)->sibling_class = 0;
|
||||
}
|
||||
|
||||
/* check relationship of impostor and super_class is kept. */
|
||||
/* Check relationship of impostor and super_class is kept. */
|
||||
assert (impostor->super_class == super_class);
|
||||
assert (CLASSOF (impostor)->super_class == CLASSOF (super_class));
|
||||
|
||||
/* This is how to update the lookup table. Regardless of
|
||||
what the keys of the hashtable is, change all values that are
|
||||
superclass into impostor. */
|
||||
/* This is how to update the lookup table. Regardless of what the
|
||||
keys of the hashtable is, change all values that are superclass
|
||||
into impostor. */
|
||||
|
||||
objc_mutex_lock(__objc_runtime_mutex);
|
||||
|
||||
for (node = hash_next (__objc_class_hash, NULL); node;
|
||||
node = hash_next (__objc_class_hash, node))
|
||||
{
|
||||
class1 = (Class)node->value;
|
||||
if (class1 == super_class)
|
||||
{
|
||||
node->value = impostor; /* change hash table value */
|
||||
}
|
||||
}
|
||||
class_table_replace (super_class, impostor);
|
||||
|
||||
objc_mutex_unlock(__objc_runtime_mutex);
|
||||
|
||||
/* next, we update the dispatch tables... */
|
||||
/* Next, we update the dispatch tables... */
|
||||
__objc_update_dispatch_table_for_class (CLASSOF (impostor));
|
||||
__objc_update_dispatch_table_for_class (impostor);
|
||||
|
||||
return impostor;
|
||||
}
|
||||
|
||||
|
||||
|
2
contrib/libobjc/config.h.in
Normal file
2
contrib/libobjc/config.h.in
Normal file
@ -0,0 +1,2 @@
|
||||
/* Define this if you have the <sched.h> header file */
|
||||
#undef HAVE_SCHED_H
|
2255
contrib/libobjc/configure
vendored
2255
contrib/libobjc/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
# Copyright (C) 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1995, 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
|
||||
# Contributed by Dave Love (d.love@dl.ac.uk).
|
||||
#
|
||||
#This file is part of GNU Objective C.
|
||||
@ -21,20 +21,20 @@
|
||||
|
||||
AC_PREREQ(2.13)
|
||||
AC_INIT(objc/objc.h)
|
||||
#AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
if test "${srcdir}" = "." ; then
|
||||
if test "${with_target_subdir}" != "." ; then
|
||||
topsrcdir=${with_multisrctop}../..
|
||||
else
|
||||
topsrcdir=${with_multisrctop}..
|
||||
fi
|
||||
else
|
||||
topsrcdir=${srcdir}/..
|
||||
fi
|
||||
dnl This is needed for a multilibbed build in the source tree so
|
||||
dnl that install-sh and config.sub get found.
|
||||
AC_CONFIG_AUX_DIR($topsrcdir)
|
||||
# This works around the fact that libtool configuration may change LD
|
||||
# for this particular configuration, but some shells, instead of
|
||||
# keeping the changes in LD private, export them just because LD is
|
||||
# exported.
|
||||
ORIGINAL_LD_FOR_MULTILIBS=$LD
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
target_alias=${target_alias-$target}
|
||||
AC_SUBST(target_alias)
|
||||
|
||||
GLIBCPP_CONFIGURE(.)
|
||||
GLIBCPP_EXPORT_INSTALL_INFO
|
||||
|
||||
# If the language specific compiler does not exist, but the "gcc" directory
|
||||
# does, we do not build anything. Note, $r is set by the top-level Makefile.
|
||||
@ -65,10 +65,16 @@ then
|
||||
fi
|
||||
|
||||
dnl Checks for programs.
|
||||
# For ObjC we'll set CC to point at the built gcc, but this will get it into
|
||||
# the makefiles
|
||||
AC_PROG_CC
|
||||
|
||||
# Disable shared libs by default
|
||||
AC_DISABLE_SHARED
|
||||
# Enable Win32 DLL on MS Windows - FIXME
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
dnl These should be inherited in the recursive make, but ensure they are
|
||||
dnl defined:
|
||||
test "$AR" || AR=ar
|
||||
AC_SUBST(AR)
|
||||
if test "$RANLIB"; then :
|
||||
@ -77,8 +83,7 @@ else
|
||||
AC_PROG_RANLIB
|
||||
fi
|
||||
AC_PROG_INSTALL
|
||||
|
||||
dnl Checks for libraries.
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
dnl Checks for header files.
|
||||
# Sanity check for the cross-compilation case:
|
||||
@ -91,17 +96,19 @@ the Objective C runtime system. If necessary, install gcc now with
|
||||
|
||||
AC_HEADER_STDC
|
||||
|
||||
# Determine the name of the GCC thread file.
|
||||
AC_CHECK_HEADERS(sched.h)
|
||||
|
||||
AC_CACHE_CHECK([for thread file],objc_cv_thread_file,
|
||||
# Determine CFLAGS for gthread.
|
||||
|
||||
AC_CACHE_CHECK([for gthread cflags],objc_cv_gthread_flags,
|
||||
[if test -f "$r"/gcc/Makefile
|
||||
then
|
||||
objc_cv_thread_file=`grep \^GCC_THREAD_FILE "$r"/gcc/Makefile | awk -F= '{ print $2 }'`
|
||||
objc_cv_gthread_flags=`grep \^GTHREAD_FLAGS "$r"/gcc/Makefile | awk -F= '{ print $2 }'`
|
||||
else
|
||||
AC_MSG_ERROR([not found])
|
||||
fi])
|
||||
OBJC_THREAD_FILE=$objc_cv_thread_file
|
||||
AC_SUBST(OBJC_THREAD_FILE)
|
||||
GTHREAD_FLAGS=$objc_cv_gthread_flags
|
||||
AC_SUBST(GTHREAD_FLAGS)
|
||||
|
||||
AC_ARG_ENABLE(objc-gc,
|
||||
[ --enable-objc-gc enable the use of Boehm's garbage collector with
|
||||
@ -109,7 +116,7 @@ AC_ARG_ENABLE(objc-gc,
|
||||
if [[[ x$enable_objc_gc = xno ]]]; then
|
||||
OBJC_BOEHM_GC=''
|
||||
else
|
||||
OBJC_BOEHM_GC=libobjc_gc.a
|
||||
OBJC_BOEHM_GC=libobjc_gc.la
|
||||
fi,
|
||||
OBJC_BOEHM_GC='')
|
||||
AC_SUBST(OBJC_BOEHM_GC)
|
||||
@ -117,12 +124,13 @@ AC_SUBST(OBJC_BOEHM_GC)
|
||||
|
||||
# We need multilib support, but only if configuring for the target.
|
||||
AC_OUTPUT(Makefile,
|
||||
[test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
|
||||
[test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
|
||||
if test -n "$CONFIG_FILES"; then
|
||||
if test -n "${with_target_subdir}"; then
|
||||
# FIXME: We shouldn't need to set ac_file
|
||||
ac_file=Makefile
|
||||
. ${topsrcdir}/config-ml.in
|
||||
LD="${ORIGINAL_LD_FOR_MULTILIBS}"
|
||||
. ${toplevel_srcdir}/config-ml.in
|
||||
fi
|
||||
fi],
|
||||
srcdir=${srcdir}
|
||||
@ -131,10 +139,11 @@ target=${target}
|
||||
with_target_subdir=${with_target_subdir}
|
||||
with_multisubdir=${with_multisubdir}
|
||||
ac_configure_args="--enable-multilib ${ac_configure_args}"
|
||||
toplevel_srcdir=${toplevel_srcdir}
|
||||
CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
topsrcdir=${topsrcdir}
|
||||
)
|
||||
|
||||
|
||||
dnl Local Variables:
|
||||
dnl comment-start: "dnl "
|
||||
dnl comment-end: ""
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Encoding of types for Objective C.
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup
|
||||
Bitfield support by Ovidiu Predescu
|
||||
|
||||
@ -30,14 +30,17 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "objc-api.h"
|
||||
#include "encoding.h"
|
||||
|
||||
#undef MAX
|
||||
#define MAX(X, Y) \
|
||||
({ typeof(X) __x = (X), __y = (Y); \
|
||||
(__x > __y ? __x : __y); })
|
||||
|
||||
#undef MIN
|
||||
#define MIN(X, Y) \
|
||||
({ typeof(X) __x = (X), __y = (Y); \
|
||||
(__x < __y ? __x : __y); })
|
||||
|
||||
#undef ROUND
|
||||
#define ROUND(V, A) \
|
||||
({ typeof(V) __v=(V); typeof(A) __a=(A); \
|
||||
__a*((__v+__a-1)/__a); })
|
||||
@ -46,22 +49,37 @@ Boston, MA 02111-1307, USA. */
|
||||
/* Various hacks for objc_layout_record. These are used by the target
|
||||
macros. */
|
||||
|
||||
#define TREE_CODE(TYPE) *TYPE
|
||||
#define TREE_TYPE(TREE) TREE
|
||||
#define TREE_CODE(TYPE) *(TYPE)
|
||||
#define TREE_TYPE(TREE) (TREE)
|
||||
|
||||
#define RECORD_TYPE _C_STRUCT_B
|
||||
#define UNION_TYPE _C_UNION_B
|
||||
#define QUAL_UNION_TYPE _C_UNION_B
|
||||
#define ARRAY_TYPE _C_ARY_B
|
||||
|
||||
#define REAL_TYPE _C_DBL
|
||||
|
||||
#define VECTOR_TYPE _C_VECTOR
|
||||
|
||||
#define TYPE_FIELDS(TYPE) objc_skip_typespec (TYPE)
|
||||
|
||||
#define DECL_MODE(TYPE) *(TYPE)
|
||||
#define DECL_MODE(TYPE) *(TYPE)
|
||||
#define TYPE_MODE(TYPE) *(TYPE)
|
||||
|
||||
#define DFmode _C_DBL
|
||||
|
||||
#define get_inner_array_type(TYPE) ((TYPE) + 1)
|
||||
|
||||
/* Some ports (eg ARM) allow the structure size boundary to be
|
||||
selected at compile-time. We override the normal definition with
|
||||
one that has a constant value for this compilation. */
|
||||
#undef STRUCTURE_SIZE_BOUNDARY
|
||||
#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
|
||||
|
||||
/* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
|
||||
target_flags. Define a dummy entry here to so we don't die. */
|
||||
|
||||
static int target_flags = 0;
|
||||
|
||||
static inline int
|
||||
atoi (const char* str)
|
||||
@ -724,9 +742,7 @@ objc_layout_structure (const char *type,
|
||||
layout->record_size = 0;
|
||||
layout->record_align = BITS_PER_UNIT;
|
||||
|
||||
#ifdef STRUCTURE_SIZE_BOUNDARY
|
||||
layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -743,15 +759,6 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout)
|
||||
/* The current type without the type qualifiers */
|
||||
const char *type;
|
||||
|
||||
#if 1
|
||||
if (layout->prev_type == NULL)
|
||||
{
|
||||
layout->prev_type = layout->type;
|
||||
layout->type = objc_skip_typespec (layout->prev_type);
|
||||
return YES;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Add the size of the previous field to the size of the record. */
|
||||
if (layout->prev_type)
|
||||
{
|
||||
@ -760,7 +767,6 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout)
|
||||
if (*type != _C_BFLD)
|
||||
layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
|
||||
else {
|
||||
desired_align = 1;
|
||||
/* Get the bitfield's type */
|
||||
for (bfld_type = type + 1;
|
||||
isdigit(*bfld_type);
|
||||
@ -878,7 +884,7 @@ void objc_layout_finish_structure (struct objc_struct_layout *layout,
|
||||
in the record type. Round it up to a multiple of the record's
|
||||
alignment. */
|
||||
|
||||
#ifdef ROUND_TYPE_ALIGN
|
||||
#if defined(ROUND_TYPE_ALIGN) && !defined(__sparc__)
|
||||
layout->record_align = ROUND_TYPE_ALIGN (layout->original_type,
|
||||
1,
|
||||
layout->record_align);
|
||||
|
@ -324,12 +324,13 @@ __objc_generate_gc_type_description (Class class)
|
||||
if (current + 1 == type_size)
|
||||
class_structure_type = objc_realloc (class_structure_type, ++type_size);
|
||||
strcat (class_structure_type + current, "}");
|
||||
// printf ("type description for '%s' is %s\n", class->name, class_structure_type);
|
||||
#ifdef DEBUG
|
||||
printf ("type description for '%s' is %s\n", class->name, class_structure_type);
|
||||
#endif
|
||||
|
||||
__objc_gc_type_description_from_type (mask, class_structure_type);
|
||||
objc_free (class_structure_type);
|
||||
|
||||
#define DEBUG 1
|
||||
#ifdef DEBUG
|
||||
printf (" mask for '%s', type '%s' (bits %d, mask size %d) is:",
|
||||
class_structure_type, class->name, bits_no, size);
|
||||
|
@ -313,16 +313,16 @@ __objc_send_message_in_list (MethodList_t method_list, Class class, SEL op)
|
||||
Method_t mth = &method_list->method_list[i];
|
||||
|
||||
if (mth->method_name && sel_eq (mth->method_name, op)
|
||||
&& !hash_is_key_in_hash (__objc_load_methods, mth->method_name))
|
||||
&& !hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
|
||||
{
|
||||
/* The method was found and wasn't previously executed. */
|
||||
(*mth->method_imp) ((id)class, mth->method_name);
|
||||
|
||||
/* Add this method into the +load hash table */
|
||||
hash_add (&__objc_load_methods, mth->method_imp, mth->method_imp);
|
||||
|
||||
DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
|
||||
|
||||
/* The method was found and wasn't previously executed. */
|
||||
(*mth->method_imp) ((id)class, mth->method_name);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -599,9 +599,7 @@ __objc_exec_class (Module_t module)
|
||||
|
||||
/* Scan the unclaimed category hash. Attempt to attach any unclaimed
|
||||
categories to objects. */
|
||||
for (cell = &unclaimed_categories;
|
||||
*cell;
|
||||
({ if (*cell) cell = &(*cell)->tail; }))
|
||||
for (cell = &unclaimed_categories; *cell; )
|
||||
{
|
||||
Category_t category = (*cell)->head;
|
||||
Class class = objc_lookup_class (category->class_name);
|
||||
@ -630,6 +628,8 @@ __objc_exec_class (Module_t module)
|
||||
only done for root classes. */
|
||||
__objc_register_instance_methods_to_class(class);
|
||||
}
|
||||
else
|
||||
cell = &(*cell)->tail;
|
||||
}
|
||||
|
||||
if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
|
||||
|
@ -45,6 +45,8 @@ objc_thread_id
|
||||
objc_thread_set_data
|
||||
objc_thread_set_priority
|
||||
objc_thread_yield
|
||||
objc_thread_add
|
||||
objc_thread_remove
|
||||
__objc_class_name_Object
|
||||
__objc_class_name_Protocol
|
||||
__objc_class_name_NXConstantString
|
||||
|
@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#define __hash_INCLUDE_GNU
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <objc/objc.h>
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* GNU Objective-C Runtime API.
|
||||
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@ -75,6 +75,7 @@ struct objc_method_description
|
||||
#define _C_UNION_E ')'
|
||||
#define _C_STRUCT_B '{'
|
||||
#define _C_STRUCT_E '}'
|
||||
#define _C_VECTOR '!'
|
||||
|
||||
|
||||
/*
|
||||
@ -260,7 +261,7 @@ typedef struct objc_method_list {
|
||||
|
||||
struct objc_protocol_list {
|
||||
struct objc_protocol_list *next;
|
||||
int count;
|
||||
size_t count;
|
||||
Protocol *list[1];
|
||||
};
|
||||
|
||||
@ -414,6 +415,13 @@ extern void *(*_objc_realloc)(void *, size_t);
|
||||
extern void *(*_objc_calloc)(size_t, size_t);
|
||||
extern void (*_objc_free)(void *);
|
||||
|
||||
/*
|
||||
** Hook for method forwarding. This makes it easy to substitute a
|
||||
** library, such as ffcall, that implements closures, thereby avoiding
|
||||
** gcc's __builtin_apply problems.
|
||||
*/
|
||||
extern IMP (*__objc_msg_forward)(SEL);
|
||||
|
||||
Method_t class_get_class_method(MetaClass class, SEL aSel);
|
||||
|
||||
Method_t class_get_instance_method(Class class, SEL aSel);
|
||||
@ -571,21 +579,23 @@ object_get_super_class
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
object_is_class(id object)
|
||||
object_is_class (id object)
|
||||
{
|
||||
return CLS_ISCLASS((Class)object);
|
||||
return ((object != nil) && CLS_ISMETA (object->class_pointer));
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
object_is_instance (id object)
|
||||
{
|
||||
return ((object != nil) && CLS_ISCLASS (object->class_pointer));
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
object_is_instance(id object)
|
||||
object_is_meta_class (id object)
|
||||
{
|
||||
return (object!=nil)&&CLS_ISCLASS(object->class_pointer);
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
object_is_meta_class(id object)
|
||||
{
|
||||
return CLS_ISMETA((Class)object);
|
||||
return ((object != nil)
|
||||
&& !object_is_instance (object)
|
||||
&& !object_is_class (object));
|
||||
}
|
||||
|
||||
struct sarray*
|
||||
|
@ -96,6 +96,8 @@ int objc_thread_get_priority(void);
|
||||
void * objc_thread_get_data(void);
|
||||
int objc_thread_set_data(void *value);
|
||||
objc_thread_t objc_thread_id(void);
|
||||
void objc_thread_add(void);
|
||||
void objc_thread_remove(void);
|
||||
|
||||
/*
|
||||
Use this to set the hook function that will be called when the
|
||||
|
@ -44,10 +44,6 @@ const char* __objc_sparse2_id = "2 level sparse indices";
|
||||
const char* __objc_sparse3_id = "3 level sparse indices";
|
||||
#endif
|
||||
|
||||
#ifdef __alpha__
|
||||
const void *memcpy (void*, const void*, size_t);
|
||||
#endif
|
||||
|
||||
/* This function removes any structures left over from free operations
|
||||
that were not safe in a multi-threaded environment. */
|
||||
void
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* GNU Objective C Runtime message lookup
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 1998,
|
||||
2001 Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -33,6 +34,7 @@ Boston, MA 02111-1307, USA. */
|
||||
/* this is how we hack STRUCT_VALUE to be 1 or 0 */
|
||||
#define gen_rtx(args...) 1
|
||||
#define gen_rtx_MEM(args...) 1
|
||||
#define gen_rtx_REG(args...) 1
|
||||
#define rtx int
|
||||
|
||||
#if !defined(STRUCT_VALUE) || STRUCT_VALUE == 0
|
||||
@ -44,6 +46,11 @@ Boston, MA 02111-1307, USA. */
|
||||
/* The uninstalled dispatch table */
|
||||
struct sarray* __objc_uninstalled_dtable = 0; /* !T:MUTEX */
|
||||
|
||||
/* Hook for method forwarding. If it is set, is invoked to return a
|
||||
function that performs the real forwarding. Otherwise the libgcc
|
||||
based functions (__builtin_apply and friends) are used. */
|
||||
IMP (*__objc_msg_forward)(SEL) = NULL;
|
||||
|
||||
/* Send +initialize to class */
|
||||
static void __objc_send_initialize(Class);
|
||||
|
||||
@ -76,18 +83,27 @@ __inline__
|
||||
IMP
|
||||
__objc_get_forward_imp (SEL sel)
|
||||
{
|
||||
const char *t = sel->sel_types;
|
||||
|
||||
if (t && (*t == '[' || *t == '(' || *t == '{')
|
||||
#ifdef OBJC_MAX_STRUCT_BY_VALUE
|
||||
&& objc_sizeof_type(t) > OBJC_MAX_STRUCT_BY_VALUE
|
||||
#endif
|
||||
)
|
||||
return (IMP)__objc_block_forward;
|
||||
else if (t && (*t == 'f' || *t == 'd'))
|
||||
return (IMP)__objc_double_forward;
|
||||
if (__objc_msg_forward)
|
||||
{
|
||||
IMP result;
|
||||
if ((result = __objc_msg_forward (sel)))
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return (IMP)__objc_word_forward;
|
||||
{
|
||||
const char *t = sel->sel_types;
|
||||
|
||||
if (t && (*t == '[' || *t == '(' || *t == '{')
|
||||
#ifdef OBJC_MAX_STRUCT_BY_VALUE
|
||||
&& objc_sizeof_type(t) > OBJC_MAX_STRUCT_BY_VALUE
|
||||
#endif
|
||||
)
|
||||
return (IMP)__objc_block_forward;
|
||||
else if (t && (*t == 'f' || *t == 'd'))
|
||||
return (IMP)__objc_double_forward;
|
||||
else
|
||||
return (IMP)__objc_word_forward;
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a class and selector, return the selector's implementation. */
|
||||
@ -581,7 +597,6 @@ __objc_forward (id object, SEL sel, arglist_t args)
|
||||
/* The object doesn't recognize the method. Check for responding to
|
||||
error:. If it does then sent it. */
|
||||
{
|
||||
size_t strlen (const char*);
|
||||
char msg[256 + strlen ((const char*)sel_get_name (sel))
|
||||
+ strlen ((const char*)object->class_pointer->name)];
|
||||
|
||||
|
181
contrib/libobjc/thr-objc.c
Normal file
181
contrib/libobjc/thr-objc.c
Normal file
@ -0,0 +1,181 @@
|
||||
/* GNU Objective C Runtime Thread Interface.
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2, or (at your option) any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* As a special exception, if you link this library with files compiled with
|
||||
GCC to produce an executable, this does not cause the resulting executable
|
||||
to be covered by the GNU General Public License. This exception does not
|
||||
however invalidate any other reasons why the executable file might be
|
||||
covered by the GNU General Public License. */
|
||||
|
||||
#define _LIBOBJC
|
||||
#include "tconfig.h"
|
||||
#include "defaults.h"
|
||||
#include <objc/thr.h>
|
||||
#include "runtime.h"
|
||||
#include <gthr.h>
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__objc_init_thread_system(void)
|
||||
{
|
||||
return __gthread_objc_init_thread_system ();
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__objc_close_thread_system(void)
|
||||
{
|
||||
return __gthread_objc_close_thread_system ();
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__objc_thread_detach(void (*func)(void *), void *arg)
|
||||
{
|
||||
return __gthread_objc_thread_detach (func, arg);
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
__objc_thread_set_priority(int priority)
|
||||
{
|
||||
return __gthread_objc_thread_set_priority (priority);
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__objc_thread_get_priority(void)
|
||||
{
|
||||
return __gthread_objc_thread_get_priority ();
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
void
|
||||
__objc_thread_yield(void)
|
||||
{
|
||||
__gthread_objc_thread_yield ();
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__objc_thread_exit(void)
|
||||
{
|
||||
return __gthread_objc_thread_exit ();
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__objc_thread_id(void)
|
||||
{
|
||||
return __gthread_objc_thread_id ();
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__objc_thread_set_data(void *value)
|
||||
{
|
||||
return __gthread_objc_thread_set_data (value);
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__objc_thread_get_data(void)
|
||||
{
|
||||
return __gthread_objc_thread_get_data ();
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__objc_mutex_allocate(objc_mutex_t mutex)
|
||||
{
|
||||
return __gthread_objc_mutex_allocate (mutex);
|
||||
}
|
||||
|
||||
/* Deallocate a mutex. */
|
||||
int
|
||||
__objc_mutex_deallocate(objc_mutex_t mutex)
|
||||
{
|
||||
return __gthread_objc_mutex_deallocate (mutex);
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_lock(objc_mutex_t mutex)
|
||||
{
|
||||
return __gthread_objc_mutex_lock (mutex);
|
||||
}
|
||||
|
||||
/* Try to grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_trylock(objc_mutex_t mutex)
|
||||
{
|
||||
return __gthread_objc_mutex_trylock (mutex);
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__objc_mutex_unlock(objc_mutex_t mutex)
|
||||
{
|
||||
return __gthread_objc_mutex_unlock (mutex);
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__objc_condition_allocate(objc_condition_t condition)
|
||||
{
|
||||
return __gthread_objc_condition_allocate (condition);
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__objc_condition_deallocate(objc_condition_t condition)
|
||||
{
|
||||
return __gthread_objc_condition_deallocate (condition);
|
||||
}
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
return __gthread_objc_condition_wait (condition, mutex);
|
||||
}
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__objc_condition_broadcast(objc_condition_t condition)
|
||||
{
|
||||
return __gthread_objc_condition_broadcast (condition);
|
||||
}
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__objc_condition_signal(objc_condition_t condition)
|
||||
{
|
||||
return __gthread_objc_condition_signal (condition);
|
||||
}
|
||||
|
||||
/* End of File */
|
@ -2,6 +2,7 @@
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
Modified for Linux/Pthreads by Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de)
|
||||
Modified for posix compliance by Chris Ball (cball@fmco.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@ -31,6 +32,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Key structure for maintaining thread specific storage */
|
||||
static pthread_key_t _objc_thread_storage;
|
||||
static pthread_attr_t _objc_thread_attribs;
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
@ -39,14 +41,34 @@ int
|
||||
__objc_init_thread_system(void)
|
||||
{
|
||||
/* Initialize the thread storage key */
|
||||
return pthread_key_create(&_objc_thread_storage, NULL);
|
||||
if (pthread_key_create(&_objc_thread_storage, NULL) == 0)
|
||||
{
|
||||
/*
|
||||
* The normal default detach state for threads is PTHREAD_CREATE_JOINABLE
|
||||
* which causes threads to not die when you think they should.
|
||||
*/
|
||||
if (pthread_attr_init(&_objc_thread_attribs) == 0)
|
||||
{
|
||||
if (pthread_attr_setdetachstate(&_objc_thread_attribs,
|
||||
PTHREAD_CREATE_DETACHED) == 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__objc_close_thread_system(void)
|
||||
{
|
||||
return 0;
|
||||
if (pthread_key_delete(_objc_thread_storage) == 0)
|
||||
{
|
||||
if (pthread_attr_destroy(&_objc_thread_attribs) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
@ -57,20 +79,50 @@ __objc_thread_detach(void (*func)(void *arg), void *arg)
|
||||
{
|
||||
objc_thread_t thread_id;
|
||||
pthread_t new_thread_handle;
|
||||
|
||||
if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) )
|
||||
thread_id = *(objc_thread_t *)&new_thread_handle;
|
||||
|
||||
if (!(pthread_create(&new_thread_handle, &_objc_thread_attribs,
|
||||
(void *)func, arg)))
|
||||
thread_id = *(objc_thread_t *)&new_thread_handle;
|
||||
else
|
||||
thread_id = NULL;
|
||||
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
/* Set the current thread's priority.
|
||||
*
|
||||
* Be aware that the default schedpolicy often disallows thread priorities.
|
||||
*/
|
||||
int
|
||||
__objc_thread_set_priority(int priority)
|
||||
{
|
||||
/* Not implemented yet */
|
||||
pthread_t thread_id = pthread_self();
|
||||
int policy;
|
||||
struct sched_param params;
|
||||
int priority_min, priority_max;
|
||||
|
||||
if (pthread_getschedparam(thread_id, &policy, ¶ms) == 0)
|
||||
{
|
||||
if ((priority_max = sched_get_priority_max(policy)) != 0)
|
||||
return -1;
|
||||
|
||||
if ((priority_min = sched_get_priority_min(policy)) != 0)
|
||||
return -1;
|
||||
|
||||
if (priority > priority_max)
|
||||
priority = priority_max;
|
||||
else if (priority < priority_min)
|
||||
priority = priority_min;
|
||||
params.sched_priority = priority;
|
||||
|
||||
/*
|
||||
* The solaris 7 and several other man pages incorrectly state that
|
||||
* this should be a pointer to policy but pthread.h is universally
|
||||
* at odds with this.
|
||||
*/
|
||||
if (pthread_setschedparam(thread_id, policy, ¶ms) == 0)
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -78,8 +130,13 @@ __objc_thread_set_priority(int priority)
|
||||
int
|
||||
__objc_thread_get_priority(void)
|
||||
{
|
||||
/* Not implemented yet */
|
||||
return -1;
|
||||
int policy;
|
||||
struct sched_param params;
|
||||
|
||||
if (pthread_getschedparam(pthread_self(), &policy, ¶ms) == 0)
|
||||
return params.sched_priority;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
@ -113,7 +170,10 @@ __objc_thread_id(void)
|
||||
int
|
||||
__objc_thread_set_data(void *value)
|
||||
{
|
||||
return pthread_setspecific(_objc_thread_storage, value);
|
||||
if (pthread_setspecific(_objc_thread_storage, value) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
@ -145,6 +205,19 @@ __objc_mutex_allocate(objc_mutex_t mutex)
|
||||
int
|
||||
__objc_mutex_deallocate(objc_mutex_t mutex)
|
||||
{
|
||||
int count = 1;
|
||||
|
||||
/*
|
||||
* Posix Threads specifically require that the thread be unlocked for
|
||||
* pthread_mutex_destroy to work.
|
||||
*/
|
||||
|
||||
while (count)
|
||||
{
|
||||
if ((count = pthread_mutex_unlock((pthread_mutex_t*)mutex->backend)) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
|
||||
return -1;
|
||||
|
||||
@ -157,21 +230,30 @@ __objc_mutex_deallocate(objc_mutex_t mutex)
|
||||
int
|
||||
__objc_mutex_lock(objc_mutex_t mutex)
|
||||
{
|
||||
return pthread_mutex_lock((pthread_mutex_t *)mutex->backend);
|
||||
if (pthread_mutex_lock((pthread_mutex_t *)mutex->backend) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try to grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_trylock(objc_mutex_t mutex)
|
||||
{
|
||||
return pthread_mutex_trylock((pthread_mutex_t *)mutex->backend);
|
||||
if (pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__objc_mutex_unlock(objc_mutex_t mutex)
|
||||
{
|
||||
return pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
|
||||
if (pthread_mutex_unlock((pthread_mutex_t *)mutex->backend) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
@ -208,22 +290,29 @@ __objc_condition_deallocate(objc_condition_t condition)
|
||||
int
|
||||
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
return pthread_cond_wait((pthread_cond_t *)condition->backend,
|
||||
(pthread_mutex_t *)mutex->backend);
|
||||
if (pthread_cond_wait((pthread_cond_t *)condition->backend,
|
||||
(pthread_mutex_t *)mutex->backend) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__objc_condition_broadcast(objc_condition_t condition)
|
||||
{
|
||||
return pthread_cond_broadcast((pthread_cond_t *)condition->backend);
|
||||
if (pthread_cond_broadcast((pthread_cond_t *)condition->backend) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__objc_condition_signal(objc_condition_t condition)
|
||||
{
|
||||
return pthread_cond_signal((pthread_cond_t *)condition->backend);
|
||||
if (pthread_cond_signal((pthread_cond_t *)condition->backend) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* End of File */
|
||||
|
194
contrib/libobjc/thr-rtems.c
Normal file
194
contrib/libobjc/thr-rtems.c
Normal file
@ -0,0 +1,194 @@
|
||||
/* GNU Objective C Runtime Thread Implementation
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
Renamed from thr-vxworks.c to thr-rtems.c by
|
||||
Ralf Corsepius (corsepiu@faw.uni-ulm.de)
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2, or (at your option) any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
GNU CC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* As a special exception, if you link this library with files compiled with
|
||||
GCC to produce an executable, this does not cause the resulting executable
|
||||
to be covered by the GNU General Public License. This exception does not
|
||||
however invalidate any other reasons why the executable file might be
|
||||
covered by the GNU General Public License. */
|
||||
|
||||
#include <objc/thr.h>
|
||||
#include "runtime.h"
|
||||
|
||||
/* Thread local storage for a single thread */
|
||||
static void *thread_local_storage = NULL;
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__objc_init_thread_system(void)
|
||||
{
|
||||
/* No thread support available */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__objc_close_thread_system(void)
|
||||
{
|
||||
/* No thread support available */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__objc_thread_detach(void (*func)(void *arg), void *arg)
|
||||
{
|
||||
/* No thread support available */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
__objc_thread_set_priority(int priority)
|
||||
{
|
||||
/* No thread support available */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__objc_thread_get_priority(void)
|
||||
{
|
||||
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
void
|
||||
__objc_thread_yield(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__objc_thread_exit(void)
|
||||
{
|
||||
/* No thread support available */
|
||||
/* Should we really exit the program */
|
||||
/* exit(&__objc_thread_exit_status); */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__objc_thread_id(void)
|
||||
{
|
||||
/* No thread support, use 1. */
|
||||
return (objc_thread_t)1;
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__objc_thread_set_data(void *value)
|
||||
{
|
||||
thread_local_storage = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__objc_thread_get_data(void)
|
||||
{
|
||||
return thread_local_storage;
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__objc_mutex_allocate(objc_mutex_t mutex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a mutex. */
|
||||
int
|
||||
__objc_mutex_deallocate(objc_mutex_t mutex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_lock(objc_mutex_t mutex)
|
||||
{
|
||||
/* There can only be one thread, so we always get the lock */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_trylock(objc_mutex_t mutex)
|
||||
{
|
||||
/* There can only be one thread, so we always get the lock */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__objc_mutex_unlock(objc_mutex_t mutex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__objc_condition_allocate(objc_condition_t condition)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__objc_condition_deallocate(objc_condition_t condition)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__objc_condition_broadcast(objc_condition_t condition)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__objc_condition_signal(objc_condition_t condition)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End of File */
|
@ -318,7 +318,7 @@ objc_mutex_lock(objc_mutex_t mutex)
|
||||
return -1;
|
||||
|
||||
/* If we already own the lock then increment depth */
|
||||
thread_id = objc_thread_id();
|
||||
thread_id = __objc_thread_id();
|
||||
if (mutex->owner == thread_id)
|
||||
return ++mutex->depth;
|
||||
|
||||
@ -350,7 +350,7 @@ objc_mutex_trylock(objc_mutex_t mutex)
|
||||
return -1;
|
||||
|
||||
/* If we already own the lock then increment depth */
|
||||
thread_id = objc_thread_id();
|
||||
thread_id = __objc_thread_id();
|
||||
if (mutex->owner == thread_id)
|
||||
return ++mutex->depth;
|
||||
|
||||
@ -385,7 +385,7 @@ objc_mutex_unlock(objc_mutex_t mutex)
|
||||
return -1;
|
||||
|
||||
/* If another thread owns the lock then abort */
|
||||
thread_id = objc_thread_id();
|
||||
thread_id = __objc_thread_id();
|
||||
if (mutex->owner != thread_id)
|
||||
return -1;
|
||||
|
||||
@ -477,7 +477,7 @@ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
|
||||
return -1;
|
||||
|
||||
/* Make sure we are owner of mutex */
|
||||
thread_id = objc_thread_id();
|
||||
thread_id = __objc_thread_id();
|
||||
if (mutex->owner != thread_id)
|
||||
return -1;
|
||||
|
||||
@ -531,4 +531,33 @@ objc_condition_signal(objc_condition_t condition)
|
||||
return __objc_condition_signal(condition);
|
||||
}
|
||||
|
||||
/* Make the objc thread system aware that a thread which is managed
|
||||
(started, stopped) by external code could access objc facilities
|
||||
from now on. This is used when you are interfacing with some
|
||||
external non-objc-based environment/system - you must call
|
||||
objc_thread_add() before an alien thread makes any calls to
|
||||
Objective-C. Do not cause the _objc_became_multi_threaded hook to
|
||||
be executed. */
|
||||
void
|
||||
objc_thread_add(void)
|
||||
{
|
||||
objc_mutex_lock(__objc_runtime_mutex);
|
||||
__objc_is_multi_threaded = 1;
|
||||
__objc_runtime_threads_alive++;
|
||||
objc_mutex_unlock(__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
/* Make the objc thread system aware that a thread managed (started,
|
||||
stopped) by some external code will no longer access objc and thus
|
||||
can be forgotten by the objc thread system. Call
|
||||
objc_thread_remove() when your alien thread is done with making
|
||||
calls to Objective-C. */
|
||||
void
|
||||
objc_thread_remove(void)
|
||||
{
|
||||
objc_mutex_lock(__objc_runtime_mutex);
|
||||
__objc_runtime_threads_alive--;
|
||||
objc_mutex_unlock(__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
/* End of File */
|
||||
|
Loading…
Reference in New Issue
Block a user