Remove libobjc and other Objective-C related components, as these are
extremely outdated, and not used by anything in the base system. Silence from: current@
This commit is contained in:
parent
af77c5286d
commit
6d67f69487
@ -306,7 +306,6 @@ LIB32WMAKEENV+= MAKEOBJDIRPREFIX=${OBJTREE}/lib32 \
|
||||
PATH=${TMPPATH} \
|
||||
CC="${CC} ${LIB32FLAGS}" \
|
||||
CXX="${CXX} ${LIB32FLAGS}" \
|
||||
OBJC="${OBJC} ${LIB32FLAGS}" \
|
||||
LIBDIR=/usr/lib32 \
|
||||
SHLIBDIR=/usr/lib32
|
||||
|
||||
|
@ -38,6 +38,26 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20110417: removal of Objective-C support
|
||||
OLD_FILES+=usr/include/objc/encoding.h
|
||||
OLD_FILES+=usr/include/objc/hash.h
|
||||
OLD_FILES+=usr/include/objc/NXConstStr.h
|
||||
OLD_FILES+=usr/include/objc/objc-api.h
|
||||
OLD_FILES+=usr/include/objc/objc-decls.h
|
||||
OLD_FILES+=usr/include/objc/objc-list.h
|
||||
OLD_FILES+=usr/include/objc/objc.h
|
||||
OLD_FILES+=usr/include/objc/Object.h
|
||||
OLD_FILES+=usr/include/objc/Protocol.h
|
||||
OLD_FILES+=usr/include/objc/runtime.h
|
||||
OLD_FILES+=usr/include/objc/sarray.h
|
||||
OLD_FILES+=usr/include/objc/thr.h
|
||||
OLD_FILES+=usr/include/objc/typedstream.h
|
||||
OLD_FILES+=usr/lib/libobjc.a
|
||||
OLD_FILES+=usr/lib/libobjc.so
|
||||
OLD_FILES+=usr/lib/libobjc_p.a
|
||||
OLD_FILES+=usr/libexec/cc1obj
|
||||
OLD_LIBS+=usr/lib/libobjc.so.4
|
||||
OLD_DIRS+=usr/include/objc
|
||||
# 20110224: sticky.8 -> sticky.7
|
||||
OLD_FILES+=usr/share/man/man8/sticky.8.gz
|
||||
# 20110220: new clang import which bumps version from 2.8 to 2.9
|
||||
|
@ -153,14 +153,14 @@ before compilation. It is called a macro processor because it allows
|
||||
you to define \fImacros\fR, which are brief abbreviations for longer
|
||||
constructs.
|
||||
.PP
|
||||
The C preprocessor is intended to be used only with C, \*(C+, and
|
||||
Objective-C source code. In the past, it has been abused as a general
|
||||
text processor. It will choke on input which does not obey C's lexical
|
||||
rules. For example, apostrophes will be interpreted as the beginning of
|
||||
character constants, and cause errors. Also, you cannot rely on it
|
||||
preserving characteristics of the input which are not significant to
|
||||
C\-family languages. If a Makefile is preprocessed, all the hard tabs
|
||||
will be removed, and the Makefile will not work.
|
||||
The C preprocessor is intended to be used only with C and \*(C+ source
|
||||
code. In the past, it has been abused as a general text processor. It
|
||||
will choke on input which does not obey C's lexical rules. For
|
||||
example, apostrophes will be interpreted as the beginning of character
|
||||
constants, and cause errors. Also, you cannot rely on it preserving
|
||||
characteristics of the input which are not significant to C\-family
|
||||
languages. If a Makefile is preprocessed, all the hard tabs will be
|
||||
removed, and the Makefile will not work.
|
||||
.PP
|
||||
Having said that, you can often get away with using cpp on things which
|
||||
are not C. Other Algol-ish programming languages are often safe
|
||||
@ -482,19 +482,16 @@ header files.
|
||||
.PD 0
|
||||
.IP "\fB\-x c++\fR" 4
|
||||
.IX Item "-x c++"
|
||||
.IP "\fB\-x objective-c\fR" 4
|
||||
.IX Item "-x objective-c"
|
||||
.IP "\fB\-x assembler-with-cpp\fR" 4
|
||||
.IX Item "-x assembler-with-cpp"
|
||||
.PD
|
||||
Specify the source language: C, \*(C+, Objective\-C, or assembly. This has
|
||||
nothing to do with standards conformance or extensions; it merely
|
||||
selects which base syntax to expect. If you give none of these options,
|
||||
cpp will deduce the language from the extension of the source file:
|
||||
\&\fB.c\fR, \fB.cc\fR, \fB.m\fR, or \fB.S\fR. Some other common
|
||||
extensions for \*(C+ and assembly are also recognized. If cpp does not
|
||||
recognize the extension, it will treat the file as C; this is the most
|
||||
generic mode.
|
||||
Specify the source language: C, \*(C+, or assembly. This has nothing
|
||||
to do with standards conformance or extensions; it merely selects which
|
||||
base syntax to expect. If you give none of these options, cpp will
|
||||
deduce the language from the extension of the source file: \&\fB.c\fR,
|
||||
\fB.cc\fR, or \fB.S\fR. Some other common extensions for \*(C+ and
|
||||
assembly are also recognized. If cpp does not recognize the extension,
|
||||
it will treat the file as C; this is the most generic mode.
|
||||
.Sp
|
||||
\&\fINote:\fR Previous versions of cpp accepted a \fB\-lang\fR option
|
||||
which selected both the language and the standards conformance level.
|
||||
@ -854,8 +851,6 @@ configuration of \s-1GCC\s0.
|
||||
.IX Item "C_INCLUDE_PATH"
|
||||
.IP "\fB\s-1CPLUS_INCLUDE_PATH\s0\fR" 4
|
||||
.IX Item "CPLUS_INCLUDE_PATH"
|
||||
.IP "\fB\s-1OBJC_INCLUDE_PATH\s0\fR" 4
|
||||
.IX Item "OBJC_INCLUDE_PATH"
|
||||
.PD
|
||||
Each variable's value is a list of directories separated by a special
|
||||
character, much like \fB\s-1PATH\s0\fR, in which to look for header files.
|
||||
|
@ -72,9 +72,9 @@ This manual contains no Invariant Sections. The Front-Cover Texts are
|
||||
@ifnottex
|
||||
@node Top
|
||||
@top
|
||||
The C preprocessor implements the macro language used to transform C,
|
||||
C++, and Objective-C programs before they are compiled. It can also be
|
||||
useful on its own.
|
||||
The C preprocessor implements the macro language used to transform C
|
||||
and C++ programs before they are compiled. It can also be useful on
|
||||
its own.
|
||||
|
||||
@menu
|
||||
* Overview::
|
||||
@ -186,14 +186,14 @@ before compilation. It is called a macro processor because it allows
|
||||
you to define @dfn{macros}, which are brief abbreviations for longer
|
||||
constructs.
|
||||
|
||||
The C preprocessor is intended to be used only with C, C++, and
|
||||
Objective-C source code. In the past, it has been abused as a general
|
||||
text processor. It will choke on input which does not obey C's lexical
|
||||
rules. For example, apostrophes will be interpreted as the beginning of
|
||||
character constants, and cause errors. Also, you cannot rely on it
|
||||
preserving characteristics of the input which are not significant to
|
||||
C-family languages. If a Makefile is preprocessed, all the hard tabs
|
||||
will be removed, and the Makefile will not work.
|
||||
The C preprocessor is intended to be used only with C and C++ source
|
||||
code. In the past, it has been abused as a general text processor. It
|
||||
will choke on input which does not obey C's lexical rules. For
|
||||
example, apostrophes will be interpreted as the beginning of character
|
||||
constants, and cause errors. Also, you cannot rely on it preserving
|
||||
characteristics of the input which are not significant to C-family
|
||||
languages. If a Makefile is preprocessed, all the hard tabs will be
|
||||
removed, and the Makefile will not work.
|
||||
|
||||
Having said that, you can often get away with using cpp on things which
|
||||
are not C@. Other Algol-ish programming languages are often safe
|
||||
@ -1878,7 +1878,7 @@ the 1999 revision of the C standard. Support for the 1999 revision is
|
||||
not yet complete.
|
||||
|
||||
This macro is not defined if the @option{-traditional-cpp} option is
|
||||
used, nor when compiling C++ or Objective-C@.
|
||||
used, nor when compiling C++.
|
||||
|
||||
@item __STDC_HOSTED__
|
||||
This macro is defined, with value 1, if the compiler's target is a
|
||||
@ -1895,11 +1895,6 @@ GNU C++ compiler is not yet fully conforming, so it uses @code{1}
|
||||
instead. It is hoped to complete the implementation of standard C++
|
||||
in the near future.
|
||||
|
||||
@item __OBJC__
|
||||
This macro is defined, with value 1, when the Objective-C compiler is in
|
||||
use. You can use @code{__OBJC__} to test whether a header is compiled
|
||||
by a C compiler or a Objective-C compiler.
|
||||
|
||||
@item __ASSEMBLER__
|
||||
This macro is defined with value 1 when preprocessing assembly
|
||||
language.
|
||||
@ -1921,9 +1916,9 @@ underscores.
|
||||
@itemx __GNUC_MINOR__
|
||||
@itemx __GNUC_PATCHLEVEL__
|
||||
These macros are defined by all GNU compilers that use the C
|
||||
preprocessor: C, C++, and Objective-C@. Their values are the major
|
||||
version, minor version, and patch level of the compiler, as integer
|
||||
constants. For example, GCC 3.2.1 will define @code{__GNUC__} to 3,
|
||||
preprocessor: C and C++. Their values are the major version, minor
|
||||
version, and patch level of the compiler, as integer constants. For
|
||||
example, GCC 3.2.1 will define @code{__GNUC__} to 3,
|
||||
@code{__GNUC_MINOR__} to 2, and @code{__GNUC_PATCHLEVEL__} to 1. These
|
||||
macros are also defined if you invoke the preprocessor directly.
|
||||
|
||||
@ -2125,12 +2120,6 @@ general, user code should not need to make use of this macro; the
|
||||
purpose of this macro is to ease implementation of the C++ runtime
|
||||
library provided with G++.
|
||||
|
||||
@item __NEXT_RUNTIME__
|
||||
This macro is defined, with value 1, if (and only if) the NeXT runtime
|
||||
(as in @option{-fnext-runtime}) is in use for Objective-C@. If the GNU
|
||||
runtime is used, this macro is not defined, so that you can use this
|
||||
macro to determine which runtime (NeXT or GNU) is being used.
|
||||
|
||||
@item __LP64__
|
||||
@itemx _LP64
|
||||
These macros are defined, with value 1, if (and only if) the compilation
|
||||
@ -3433,11 +3422,10 @@ produce no output, rather than a line of output containing just a
|
||||
@node Preprocessor Output
|
||||
@chapter Preprocessor Output
|
||||
|
||||
When the C preprocessor is used with the C, C++, or Objective-C
|
||||
compilers, it is integrated into the compiler and communicates a stream
|
||||
of binary tokens directly to the compiler's parser. However, it can
|
||||
also be used in the more conventional standalone mode, where it produces
|
||||
textual output.
|
||||
When the C preprocessor is used with the C or C++ compilers, it is
|
||||
integrated into the compiler and communicates a stream of binary tokens
|
||||
directly to the compiler's parser. However, it can also be used in the
|
||||
more conventional standalone mode, where it produces textual output.
|
||||
@c FIXME: Document the library interface.
|
||||
|
||||
@cindex output format
|
||||
@ -4053,33 +4041,13 @@ You can also make or cancel assertions using command line options.
|
||||
@node Obsolete once-only headers
|
||||
@subsection Obsolete once-only headers
|
||||
|
||||
CPP supports two more ways of indicating that a header file should be
|
||||
read only once. Neither one is as portable as a wrapper @samp{#ifndef},
|
||||
and we recommend you do not use them in new programs.
|
||||
CPP supports one more way of indicating that a header file should be
|
||||
read only once. This is not as portable as a wrapper @samp{#ifndef},
|
||||
and we recommend you do not use it in new programs.
|
||||
|
||||
@findex #import
|
||||
In the Objective-C language, there is a variant of @samp{#include}
|
||||
called @samp{#import} which includes a file, but does so at most once.
|
||||
If you use @samp{#import} instead of @samp{#include}, then you don't
|
||||
need the conditionals inside the header file to prevent multiple
|
||||
inclusion of the contents. GCC permits the use of @samp{#import} in C
|
||||
and C++ as well as Objective-C@. However, it is not in standard C or C++
|
||||
and should therefore not be used by portable programs.
|
||||
|
||||
@samp{#import} is not a well designed feature. It requires the users of
|
||||
a header file to know that it should only be included once. It is much
|
||||
better for the header file's implementor to write the file so that users
|
||||
don't need to know this. Using a wrapper @samp{#ifndef} accomplishes
|
||||
this goal.
|
||||
|
||||
In the present implementation, a single use of @samp{#import} will
|
||||
prevent the file from ever being read again, by either @samp{#import} or
|
||||
@samp{#include}. You should not rely on this; do not use both
|
||||
@samp{#import} and @samp{#include} to refer to the same header file.
|
||||
|
||||
Another way to prevent a header file from being included more than once
|
||||
is with the @samp{#pragma once} directive. If @samp{#pragma once} is
|
||||
seen when scanning a header file, that file will never be read again, no
|
||||
A way to prevent a header file from being included more than once is
|
||||
with the @samp{#pragma once} directive. If @samp{#pragma once} is seen
|
||||
when scanning a header file, that file will never be read again, no
|
||||
matter what.
|
||||
|
||||
@samp{#pragma once} does not have the problems that @samp{#import} does,
|
||||
|
@ -14,9 +14,6 @@
|
||||
@item CPATH
|
||||
@itemx C_INCLUDE_PATH
|
||||
@itemx CPLUS_INCLUDE_PATH
|
||||
@itemx OBJC_INCLUDE_PATH
|
||||
@c Commented out until ObjC++ is part of GCC:
|
||||
@c @itemx OBJCPLUS_INCLUDE_PATH
|
||||
Each variable's value is a list of directories separated by a special
|
||||
character, much like @env{PATH}, in which to look for header files.
|
||||
The special character, @code{PATH_SEPARATOR}, is target-dependent and
|
||||
|
@ -72,10 +72,10 @@ into another language, under the above conditions for modified versions.
|
||||
|
||||
The GNU C preprocessor is
|
||||
implemented as a library, @dfn{cpplib}, so it can be easily shared between
|
||||
a stand-alone preprocessor, and a preprocessor integrated with the C,
|
||||
C++ and Objective-C front ends. It is also available for use by other
|
||||
programs, though this is not recommended as its exposed interface has
|
||||
not yet reached a point of reasonable stability.
|
||||
a stand-alone preprocessor, and a preprocessor integrated with the C
|
||||
and C++ front ends. It is also available for use by other programs,
|
||||
though this is not recommended as its exposed interface has not yet
|
||||
reached a point of reasonable stability.
|
||||
|
||||
The library has been written to be re-entrant, so that it can be used
|
||||
to preprocess many files simultaneously if necessary. It has also been
|
||||
@ -91,7 +91,7 @@ the way they have.
|
||||
|
||||
@menu
|
||||
* Conventions:: Conventions used in the code.
|
||||
* Lexer:: The combined C, C++ and Objective-C Lexer.
|
||||
* Lexer:: The combined C and C++ Lexer.
|
||||
* Hash Nodes:: All identifiers are entered into a hash table.
|
||||
* Macro Expansion:: Macro expansion algorithm.
|
||||
* Token Spacing:: Spacing and paste avoidance issues.
|
||||
@ -131,12 +131,12 @@ behavior.
|
||||
|
||||
@section Overview
|
||||
The lexer is contained in the file @file{lex.c}. It is a hand-coded
|
||||
lexer, and not implemented as a state machine. It can understand C, C++
|
||||
and Objective-C source code, and has been extended to allow reasonably
|
||||
successful preprocessing of assembly language. The lexer does not make
|
||||
an initial pass to strip out trigraphs and escaped newlines, but handles
|
||||
them as they are encountered in a single pass of the input file. It
|
||||
returns preprocessing tokens individually, not a line at a time.
|
||||
lexer, and not implemented as a state machine. It can understand C and
|
||||
C++ source code, and has been extended to allow reasonably successful
|
||||
preprocessing of assembly language. The lexer does not make an initial
|
||||
pass to strip out trigraphs and escaped newlines, but handles them as
|
||||
they are encountered in a single pass of the input file. It returns
|
||||
preprocessing tokens individually, not a line at a time.
|
||||
|
||||
It is mostly transparent to users of the library, since the library's
|
||||
interface for obtaining the next token, @code{cpp_get_token}, takes care
|
||||
@ -303,9 +303,9 @@ don't allow the terminators of header names to be escaped; the first
|
||||
@samp{"} or @samp{>} terminates the header name.
|
||||
|
||||
Interpretation of some character sequences depends upon whether we are
|
||||
lexing C, C++ or Objective-C, and on the revision of the standard in
|
||||
force. For example, @samp{::} is a single token in C++, but in C it is
|
||||
two separate @samp{:} tokens and almost certainly a syntax error. Such
|
||||
lexing C or C++, and on the revision of the standard in force. For
|
||||
example, @samp{::} is a single token in C++, but in C it is two
|
||||
separate @samp{:} tokens and almost certainly a syntax error. Such
|
||||
cases are handled by @code{_cpp_lex_direct} based upon command-line
|
||||
flags stored in the @code{cpp_options} structure.
|
||||
|
||||
|
@ -347,17 +347,15 @@ current directory.
|
||||
@end ifclear
|
||||
@item -x c
|
||||
@itemx -x c++
|
||||
@itemx -x objective-c
|
||||
@itemx -x assembler-with-cpp
|
||||
@opindex x
|
||||
Specify the source language: C, C++, Objective-C, or assembly. This has
|
||||
nothing to do with standards conformance or extensions; it merely
|
||||
selects which base syntax to expect. If you give none of these options,
|
||||
cpp will deduce the language from the extension of the source file:
|
||||
@samp{.c}, @samp{.cc}, @samp{.m}, or @samp{.S}. Some other common
|
||||
extensions for C++ and assembly are also recognized. If cpp does not
|
||||
recognize the extension, it will treat the file as C; this is the most
|
||||
generic mode.
|
||||
Specify the source language: C, C++, or assembly. This has nothing to
|
||||
do with standards conformance or extensions; it merely selects which
|
||||
base syntax to expect. If you give none of these options, cpp will
|
||||
deduce the language from the extension of the source file: @samp{.c},
|
||||
@samp{.cc}, or @samp{.S}. Some other common extensions for C++ and
|
||||
assembly are also recognized. If cpp does not recognize the extension,
|
||||
it will treat the file as C; this is the most generic mode.
|
||||
|
||||
@emph{Note:} Previous versions of cpp accepted a @option{-lang} option
|
||||
which selected both the language and the standards conformance level.
|
||||
|
@ -16,9 +16,9 @@ any of these features is used.) To test for the availability of these
|
||||
features in conditional compilation, check for a predefined macro
|
||||
@code{__GNUC__}, which is always defined under GCC@.
|
||||
|
||||
These extensions are available in C and Objective-C@. Most of them are
|
||||
also available in C++. @xref{C++ Extensions,,Extensions to the
|
||||
C++ Language}, for extensions that apply @emph{only} to C++.
|
||||
These extensions are available in C. Most of them are also available
|
||||
in C++. @xref{C++ Extensions,,Extensions to the C++ Language}, for
|
||||
extensions that apply @emph{only} to C++.
|
||||
|
||||
Some features that are in ISO C99 but not C89 or C++ are also, as
|
||||
extensions, accepted by GCC in C89 mode and in C++.
|
||||
@ -1716,8 +1716,6 @@ been called. Functions with these attributes are useful for
|
||||
initializing data that will be used implicitly during the execution of
|
||||
the program.
|
||||
|
||||
These attributes are not currently implemented for Objective-C@.
|
||||
|
||||
@item deprecated
|
||||
@cindex @code{deprecated} attribute.
|
||||
The @code{deprecated} attribute results in a warning if the function
|
||||
@ -2605,9 +2603,9 @@ Preprocessing Directives, cpp, The GNU C Preprocessor}.
|
||||
|
||||
This section describes the syntax with which @code{__attribute__} may be
|
||||
used, and the constructs to which attribute specifiers bind, for the C
|
||||
language. Some details may vary for C++ and Objective-C@. Because of
|
||||
infelicities in the grammar for attributes, some forms described here
|
||||
may not be successfully parsed in all cases.
|
||||
language. Some details may vary for C++. Because of infelicities in
|
||||
the grammar for attributes, some forms described here may not be
|
||||
successfully parsed in all cases.
|
||||
|
||||
There are some problems with the semantics of attributes in C++. For
|
||||
example, there are no manglings for attributes, although they may affect
|
||||
@ -9896,9 +9894,8 @@ The Solaris target supports @code{#pragma redefine_extname}
|
||||
Increase the minimum alignment of each @var{variable} to @var{alignment}.
|
||||
This is the same as GCC's @code{aligned} attribute @pxref{Variable
|
||||
Attributes}). Macro expansion occurs on the arguments to this pragma
|
||||
when compiling C and Objective-C. It does not currently occur when
|
||||
compiling C++, but this is a bug which may be fixed in a future
|
||||
release.
|
||||
when compiling C. It does not currently occur when compiling C++, but
|
||||
this is a bug which may be fixed in a future release.
|
||||
|
||||
@item fini (@var{function} [, @var{function}]...)
|
||||
@cindex pragma, fini
|
||||
|
@ -12,13 +12,10 @@
|
||||
@cindex Ada
|
||||
@cindex Fortran
|
||||
@cindex Java
|
||||
@cindex Objective-C
|
||||
@cindex Objective-C++
|
||||
@cindex treelang
|
||||
GCC stands for ``GNU Compiler Collection''. GCC is an integrated
|
||||
distribution of compilers for several major programming languages. These
|
||||
languages currently include C, C++, Objective-C, Objective-C++, Java,
|
||||
Fortran, and Ada.
|
||||
languages currently include C, C++, Java, Fortran, and Ada.
|
||||
|
||||
The abbreviation @dfn{GCC} has multiple meanings in common use. The
|
||||
current official meaning is ``GNU Compiler Collection'', which refers
|
||||
@ -59,5 +56,4 @@ have been implemented as ``preprocessors'' which emit another high
|
||||
level language such as C@. None of the compilers included in GCC are
|
||||
implemented this way; they all generate machine code directly. This
|
||||
sort of preprocessor should not be confused with the @dfn{C
|
||||
preprocessor}, which is an integral feature of the C, C++, Objective-C
|
||||
and Objective-C++ languages.
|
||||
preprocessor}, which is an integral feature of the C and C++ languages.
|
||||
|
@ -219,22 +219,6 @@ in the following sections.
|
||||
\&\-Wno\-non\-template\-friend \-Wold\-style\-cast
|
||||
\&\-Woverloaded\-virtual \-Wno\-pmf\-conversions
|
||||
\&\-Wsign\-promo\fR
|
||||
.IP "\fIObjective-C and Objective\-\*(C+ Language Options\fR" 4
|
||||
.IX Item "Objective-C and Objective- Language Options"
|
||||
\&\fB\-fconstant\-string\-class=\fR\fIclass-name\fR
|
||||
\&\fB\-fgnu\-runtime \-fnext\-runtime
|
||||
\&\-fno\-nil\-receivers
|
||||
\&\-fobjc\-call\-cxx\-cdtors
|
||||
\&\-fobjc\-direct\-dispatch
|
||||
\&\-fobjc\-exceptions
|
||||
\&\-fobjc\-gc
|
||||
\&\-freplace\-objc\-classes
|
||||
\&\-fzero\-link
|
||||
\&\-gen\-decls
|
||||
\&\-Wassign\-intercept
|
||||
\&\-Wno\-protocol \-Wselector
|
||||
\&\-Wstrict\-selector\-match
|
||||
\&\-Wundeclared\-selector\fR
|
||||
.IP "\fILanguage Independent Options\fR" 4
|
||||
.IX Item "Language Independent Options"
|
||||
\&\fB\-fmessage\-length=\fR\fIn\fR
|
||||
@ -815,29 +799,9 @@ C source code which should not be preprocessed.
|
||||
.IP "\fIfile\fR\fB.ii\fR" 4
|
||||
.IX Item "file.ii"
|
||||
\&\*(C+ source code which should not be preprocessed.
|
||||
.IP "\fIfile\fR\fB.m\fR" 4
|
||||
.IX Item "file.m"
|
||||
Objective-C source code. Note that you must link with the \fIlibobjc\fR
|
||||
library to make an Objective-C program work.
|
||||
.IP "\fIfile\fR\fB.mi\fR" 4
|
||||
.IX Item "file.mi"
|
||||
Objective-C source code which should not be preprocessed.
|
||||
.IP "\fIfile\fR\fB.mm\fR" 4
|
||||
.IX Item "file.mm"
|
||||
.PD 0
|
||||
.IP "\fIfile\fR\fB.M\fR" 4
|
||||
.IX Item "file.M"
|
||||
.PD
|
||||
Objective\-\*(C+ source code. Note that you must link with the \fIlibobjc\fR
|
||||
library to make an Objective\-\*(C+ program work. Note that \fB.M\fR refers
|
||||
to a literal capital M.
|
||||
.IP "\fIfile\fR\fB.mii\fR" 4
|
||||
.IX Item "file.mii"
|
||||
Objective\-\*(C+ source code which should not be preprocessed.
|
||||
.IP "\fIfile\fR\fB.h\fR" 4
|
||||
.IX Item "file.h"
|
||||
C, \*(C+, Objective-C or Objective\-\*(C+ header file to be turned into a
|
||||
precompiled header.
|
||||
C, or \*(C+ header file to be turned into a precompiled header.
|
||||
.IP "\fIfile\fR\fB.cc\fR" 4
|
||||
.IX Item "file.cc"
|
||||
.PD 0
|
||||
@ -857,16 +821,6 @@ precompiled header.
|
||||
\&\*(C+ source code which must be preprocessed. Note that in \fB.cxx\fR,
|
||||
the last two letters must both be literally \fBx\fR. Likewise,
|
||||
\&\fB.C\fR refers to a literal capital C.
|
||||
.IP "\fIfile\fR\fB.mm\fR" 4
|
||||
.IX Item "file.mm"
|
||||
.PD 0
|
||||
.IP "\fIfile\fR\fB.M\fR" 4
|
||||
.IX Item "file.M"
|
||||
.PD
|
||||
Objective\-\*(C+ source code which must be preprocessed.
|
||||
.IP "\fIfile\fR\fB.mii\fR" 4
|
||||
.IX Item "file.mii"
|
||||
Objective\-\*(C+ source code which should not be preprocessed.
|
||||
.IP "\fIfile\fR\fB.hh\fR" 4
|
||||
.IX Item "file.hh"
|
||||
.PD 0
|
||||
@ -941,8 +895,6 @@ the next \fB\-x\fR option. Possible values for \fIlanguage\fR are:
|
||||
.Vb 9
|
||||
\& c c-header c-cpp-output
|
||||
\& c++ c++-header c++-cpp-output
|
||||
\& objective-c objective-c-header objective-c-cpp-output
|
||||
\& objective-c++ objective-c++-header objective-c++-cpp-output
|
||||
\& assembler assembler-with-cpp
|
||||
\& ada
|
||||
\& f95 f95-cpp-input
|
||||
@ -1095,8 +1047,7 @@ languages; or options that are meaningful only for \*(C+ programs.
|
||||
.Sh "Options Controlling C Dialect"
|
||||
.IX Subsection "Options Controlling C Dialect"
|
||||
The following options control the dialect of C (or languages derived
|
||||
from C, such as \*(C+, Objective-C and Objective\-\*(C+) that the compiler
|
||||
accepts:
|
||||
from C, such as \*(C+) that the compiler accepts:
|
||||
.IP "\fB\-ansi\fR" 4
|
||||
.IX Item "-ansi"
|
||||
In C mode, support all \s-1ISO\s0 C90 programs. In \*(C+ mode,
|
||||
@ -1840,251 +1791,6 @@ unsignedness, but the standard mandates the current behavior.
|
||||
.Sp
|
||||
In this example, G++ will synthesize a default \fBA& operator =
|
||||
(const A&);\fR, while cfront will use the user-defined \fBoperator =\fR.
|
||||
.Sh "Options Controlling Objective-C and Objective\-\*(C+ Dialects"
|
||||
.IX Subsection "Options Controlling Objective-C and Objective- Dialects"
|
||||
(\s-1NOTE:\s0 This manual does not describe the Objective-C and Objective\-\*(C+
|
||||
languages themselves. See
|
||||
.PP
|
||||
This section describes the command-line options that are only meaningful
|
||||
for Objective-C and Objective\-\*(C+ programs, but you can also use most of
|
||||
the language-independent \s-1GNU\s0 compiler options.
|
||||
For example, you might compile a file \f(CW\*(C`some_class.m\*(C'\fR like this:
|
||||
.PP
|
||||
.Vb 1
|
||||
\& gcc -g -fgnu-runtime -O -c some_class.m
|
||||
.Ve
|
||||
.PP
|
||||
In this example, \fB\-fgnu\-runtime\fR is an option meant only for
|
||||
Objective-C and Objective\-\*(C+ programs; you can use the other options with
|
||||
any language supported by \s-1GCC\s0.
|
||||
.PP
|
||||
Note that since Objective-C is an extension of the C language, Objective-C
|
||||
compilations may also use options specific to the C front-end (e.g.,
|
||||
\&\fB\-Wtraditional\fR). Similarly, Objective\-\*(C+ compilations may use
|
||||
\&\*(C+\-specific options (e.g., \fB\-Wabi\fR).
|
||||
.PP
|
||||
Here is a list of options that are \fIonly\fR for compiling Objective-C
|
||||
and Objective\-\*(C+ programs:
|
||||
.IP "\fB\-fconstant\-string\-class=\fR\fIclass-name\fR" 4
|
||||
.IX Item "-fconstant-string-class=class-name"
|
||||
Use \fIclass-name\fR as the name of the class to instantiate for each
|
||||
literal string specified with the syntax \f(CW\*(C`@"..."\*(C'\fR. The default
|
||||
class name is \f(CW\*(C`NXConstantString\*(C'\fR if the \s-1GNU\s0 runtime is being used, and
|
||||
\&\f(CW\*(C`NSConstantString\*(C'\fR if the NeXT runtime is being used (see below). The
|
||||
\&\fB\-fconstant\-cfstrings\fR option, if also present, will override the
|
||||
\&\fB\-fconstant\-string\-class\fR setting and cause \f(CW\*(C`@"..."\*(C'\fR literals
|
||||
to be laid out as constant CoreFoundation strings.
|
||||
.IP "\fB\-fgnu\-runtime\fR" 4
|
||||
.IX Item "-fgnu-runtime"
|
||||
Generate object code compatible with the standard \s-1GNU\s0 Objective-C
|
||||
runtime. This is the default for most types of systems.
|
||||
.IP "\fB\-fnext\-runtime\fR" 4
|
||||
.IX Item "-fnext-runtime"
|
||||
Generate output compatible with the NeXT runtime. This is the default
|
||||
for NeXT-based systems, including Darwin and Mac \s-1OS\s0 X. The macro
|
||||
\&\f(CW\*(C`_\|_NEXT_RUNTIME_\|_\*(C'\fR is predefined if (and only if) this option is
|
||||
used.
|
||||
.IP "\fB\-fno\-nil\-receivers\fR" 4
|
||||
.IX Item "-fno-nil-receivers"
|
||||
Assume that all Objective-C message dispatches (e.g.,
|
||||
\&\f(CW\*(C`[receiver message:arg]\*(C'\fR) in this translation unit ensure that the receiver
|
||||
is not \f(CW\*(C`nil\*(C'\fR. This allows for more efficient entry points in the runtime
|
||||
to be used. Currently, this option is only available in conjunction with
|
||||
the NeXT runtime on Mac \s-1OS\s0 X 10.3 and later.
|
||||
.IP "\fB\-fobjc\-call\-cxx\-cdtors\fR" 4
|
||||
.IX Item "-fobjc-call-cxx-cdtors"
|
||||
For each Objective-C class, check if any of its instance variables is a
|
||||
\&\*(C+ object with a non-trivial default constructor. If so, synthesize a
|
||||
special \f(CW\*(C`\- (id) .cxx_construct\*(C'\fR instance method that will run
|
||||
non-trivial default constructors on any such instance variables, in order,
|
||||
and then return \f(CW\*(C`self\*(C'\fR. Similarly, check if any instance variable
|
||||
is a \*(C+ object with a non-trivial destructor, and if so, synthesize a
|
||||
special \f(CW\*(C`\- (void) .cxx_destruct\*(C'\fR method that will run
|
||||
all such default destructors, in reverse order.
|
||||
.Sp
|
||||
The \f(CW\*(C`\- (id) .cxx_construct\*(C'\fR and/or \f(CW\*(C`\- (void) .cxx_destruct\*(C'\fR methods
|
||||
thusly generated will only operate on instance variables declared in the
|
||||
current Objective-C class, and not those inherited from superclasses. It
|
||||
is the responsibility of the Objective-C runtime to invoke all such methods
|
||||
in an object's inheritance hierarchy. The \f(CW\*(C`\- (id) .cxx_construct\*(C'\fR methods
|
||||
will be invoked by the runtime immediately after a new object
|
||||
instance is allocated; the \f(CW\*(C`\- (void) .cxx_destruct\*(C'\fR methods will
|
||||
be invoked immediately before the runtime deallocates an object instance.
|
||||
.Sp
|
||||
As of this writing, only the NeXT runtime on Mac \s-1OS\s0 X 10.4 and later has
|
||||
support for invoking the \f(CW\*(C`\- (id) .cxx_construct\*(C'\fR and
|
||||
\&\f(CW\*(C`\- (void) .cxx_destruct\*(C'\fR methods.
|
||||
.IP "\fB\-fobjc\-direct\-dispatch\fR" 4
|
||||
.IX Item "-fobjc-direct-dispatch"
|
||||
Allow fast jumps to the message dispatcher. On Darwin this is
|
||||
accomplished via the comm page.
|
||||
.IP "\fB\-fobjc\-exceptions\fR" 4
|
||||
.IX Item "-fobjc-exceptions"
|
||||
Enable syntactic support for structured exception handling in Objective\-C,
|
||||
similar to what is offered by \*(C+ and Java. This option is
|
||||
unavailable in conjunction with the NeXT runtime on Mac \s-1OS\s0 X 10.2 and
|
||||
earlier.
|
||||
.Sp
|
||||
.Vb 23
|
||||
\& @try {
|
||||
\& ...
|
||||
\& @throw expr;
|
||||
\& ...
|
||||
\& }
|
||||
\& @catch (AnObjCClass *exc) {
|
||||
\& ...
|
||||
\& @throw expr;
|
||||
\& ...
|
||||
\& @throw;
|
||||
\& ...
|
||||
\& }
|
||||
\& @catch (AnotherClass *exc) {
|
||||
\& ...
|
||||
\& }
|
||||
\& @catch (id allOthers) {
|
||||
\& ...
|
||||
\& }
|
||||
\& @finally {
|
||||
\& ...
|
||||
\& @throw expr;
|
||||
\& ...
|
||||
\& }
|
||||
.Ve
|
||||
.Sp
|
||||
The \f(CW@throw\fR statement may appear anywhere in an Objective-C or
|
||||
Objective\-\*(C+ program; when used inside of a \f(CW@catch\fR block, the
|
||||
\&\f(CW@throw\fR may appear without an argument (as shown above), in which case
|
||||
the object caught by the \f(CW@catch\fR will be rethrown.
|
||||
.Sp
|
||||
Note that only (pointers to) Objective-C objects may be thrown and
|
||||
caught using this scheme. When an object is thrown, it will be caught
|
||||
by the nearest \f(CW@catch\fR clause capable of handling objects of that type,
|
||||
analogously to how \f(CW\*(C`catch\*(C'\fR blocks work in \*(C+ and Java. A
|
||||
\&\f(CW\*(C`@catch(id ...)\*(C'\fR clause (as shown above) may also be provided to catch
|
||||
any and all Objective-C exceptions not caught by previous \f(CW@catch\fR
|
||||
clauses (if any).
|
||||
.Sp
|
||||
The \f(CW@finally\fR clause, if present, will be executed upon exit from the
|
||||
immediately preceding \f(CW\*(C`@try ... @catch\*(C'\fR section. This will happen
|
||||
regardless of whether any exceptions are thrown, caught or rethrown
|
||||
inside the \f(CW\*(C`@try ... @catch\*(C'\fR section, analogously to the behavior
|
||||
of the \f(CW\*(C`finally\*(C'\fR clause in Java.
|
||||
.Sp
|
||||
There are several caveats to using the new exception mechanism:
|
||||
.RS 4
|
||||
.IP "*" 4
|
||||
Although currently designed to be binary compatible with \f(CW\*(C`NS_HANDLER\*(C'\fR\-style
|
||||
idioms provided by the \f(CW\*(C`NSException\*(C'\fR class, the new
|
||||
exceptions can only be used on Mac \s-1OS\s0 X 10.3 (Panther) and later
|
||||
systems, due to additional functionality needed in the (NeXT) Objective-C
|
||||
runtime.
|
||||
.IP "*" 4
|
||||
As mentioned above, the new exceptions do not support handling
|
||||
types other than Objective-C objects. Furthermore, when used from
|
||||
Objective\-\*(C+, the Objective-C exception model does not interoperate with \*(C+
|
||||
exceptions at this time. This means you cannot \f(CW@throw\fR an exception
|
||||
from Objective-C and \f(CW\*(C`catch\*(C'\fR it in \*(C+, or vice versa
|
||||
(i.e., \f(CW\*(C`throw ... @catch\*(C'\fR).
|
||||
.RE
|
||||
.RS 4
|
||||
.Sp
|
||||
The \fB\-fobjc\-exceptions\fR switch also enables the use of synchronization
|
||||
blocks for thread-safe execution:
|
||||
.Sp
|
||||
.Vb 3
|
||||
\& @synchronized (ObjCClass *guard) {
|
||||
\& ...
|
||||
\& }
|
||||
.Ve
|
||||
.Sp
|
||||
Upon entering the \f(CW@synchronized\fR block, a thread of execution shall
|
||||
first check whether a lock has been placed on the corresponding \f(CW\*(C`guard\*(C'\fR
|
||||
object by another thread. If it has, the current thread shall wait until
|
||||
the other thread relinquishes its lock. Once \f(CW\*(C`guard\*(C'\fR becomes available,
|
||||
the current thread will place its own lock on it, execute the code contained in
|
||||
the \f(CW@synchronized\fR block, and finally relinquish the lock (thereby
|
||||
making \f(CW\*(C`guard\*(C'\fR available to other threads).
|
||||
.Sp
|
||||
Unlike Java, Objective-C does not allow for entire methods to be marked
|
||||
\&\f(CW@synchronized\fR. Note that throwing exceptions out of
|
||||
\&\f(CW@synchronized\fR blocks is allowed, and will cause the guarding object
|
||||
to be unlocked properly.
|
||||
.RE
|
||||
.IP "\fB\-fobjc\-gc\fR" 4
|
||||
.IX Item "-fobjc-gc"
|
||||
Enable garbage collection (\s-1GC\s0) in Objective-C and Objective\-\*(C+ programs.
|
||||
.IP "\fB\-freplace\-objc\-classes\fR" 4
|
||||
.IX Item "-freplace-objc-classes"
|
||||
Emit a special marker instructing \fB\f(BIld\fB\|(1)\fR not to statically link in
|
||||
the resulting object file, and allow \fB\f(BIdyld\fB\|(1)\fR to load it in at
|
||||
run time instead. This is used in conjunction with the Fix-and-Continue
|
||||
debugging mode, where the object file in question may be recompiled and
|
||||
dynamically reloaded in the course of program execution, without the need
|
||||
to restart the program itself. Currently, Fix-and-Continue functionality
|
||||
is only available in conjunction with the NeXT runtime on Mac \s-1OS\s0 X 10.3
|
||||
and later.
|
||||
.IP "\fB\-fzero\-link\fR" 4
|
||||
.IX Item "-fzero-link"
|
||||
When compiling for the NeXT runtime, the compiler ordinarily replaces calls
|
||||
to \f(CW\*(C`objc_getClass("...")\*(C'\fR (when the name of the class is known at
|
||||
compile time) with static class references that get initialized at load time,
|
||||
which improves run-time performance. Specifying the \fB\-fzero\-link\fR flag
|
||||
suppresses this behavior and causes calls to \f(CW\*(C`objc_getClass("...")\*(C'\fR
|
||||
to be retained. This is useful in Zero-Link debugging mode, since it allows
|
||||
for individual class implementations to be modified during program execution.
|
||||
.IP "\fB\-gen\-decls\fR" 4
|
||||
.IX Item "-gen-decls"
|
||||
Dump interface declarations for all classes seen in the source file to a
|
||||
file named \fI\fIsourcename\fI.decl\fR.
|
||||
.IP "\fB\-Wassign\-intercept\fR" 4
|
||||
.IX Item "-Wassign-intercept"
|
||||
Warn whenever an Objective-C assignment is being intercepted by the
|
||||
garbage collector.
|
||||
.IP "\fB\-Wno\-protocol\fR" 4
|
||||
.IX Item "-Wno-protocol"
|
||||
If a class is declared to implement a protocol, a warning is issued for
|
||||
every method in the protocol that is not implemented by the class. The
|
||||
default behavior is to issue a warning for every method not explicitly
|
||||
implemented in the class, even if a method implementation is inherited
|
||||
from the superclass. If you use the \fB\-Wno\-protocol\fR option, then
|
||||
methods inherited from the superclass are considered to be implemented,
|
||||
and no warning is issued for them.
|
||||
.IP "\fB\-Wselector\fR" 4
|
||||
.IX Item "-Wselector"
|
||||
Warn if multiple methods of different types for the same selector are
|
||||
found during compilation. The check is performed on the list of methods
|
||||
in the final stage of compilation. Additionally, a check is performed
|
||||
for each selector appearing in a \f(CW\*(C`@selector(...)\*(C'\fR
|
||||
expression, and a corresponding method for that selector has been found
|
||||
during compilation. Because these checks scan the method table only at
|
||||
the end of compilation, these warnings are not produced if the final
|
||||
stage of compilation is not reached, for example because an error is
|
||||
found during compilation, or because the \fB\-fsyntax\-only\fR option is
|
||||
being used.
|
||||
.IP "\fB\-Wstrict\-selector\-match\fR" 4
|
||||
.IX Item "-Wstrict-selector-match"
|
||||
Warn if multiple methods with differing argument and/or return types are
|
||||
found for a given selector when attempting to send a message using this
|
||||
selector to a receiver of type \f(CW\*(C`id\*(C'\fR or \f(CW\*(C`Class\*(C'\fR. When this flag
|
||||
is off (which is the default behavior), the compiler will omit such warnings
|
||||
if any differences found are confined to types which share the same size
|
||||
and alignment.
|
||||
.IP "\fB\-Wundeclared\-selector\fR" 4
|
||||
.IX Item "-Wundeclared-selector"
|
||||
Warn if a \f(CW\*(C`@selector(...)\*(C'\fR expression referring to an
|
||||
undeclared selector is found. A selector is considered undeclared if no
|
||||
method with that name has been declared before the
|
||||
\&\f(CW\*(C`@selector(...)\*(C'\fR expression, either explicitly in an
|
||||
\&\f(CW@interface\fR or \f(CW@protocol\fR declaration, or implicitly in
|
||||
an \f(CW@implementation\fR section. This option always performs its
|
||||
checks as soon as a \f(CW\*(C`@selector(...)\*(C'\fR expression is found,
|
||||
while \fB\-Wselector\fR only performs its checks in the final stage of
|
||||
compilation. This also enforces the coding style convention
|
||||
that methods and selectors must be declared before being used.
|
||||
.IP "\fB\-print\-objc\-runtime\-info\fR" 4
|
||||
.IX Item "-print-objc-runtime-info"
|
||||
Generate C header describing the largest structure that is passed by
|
||||
value, if any.
|
||||
.Sh "Options to Control Diagnostic Messages Formatting"
|
||||
.IX Subsection "Options to Control Diagnostic Messages Formatting"
|
||||
Traditionally, diagnostic messages have been formatted irrespective of
|
||||
@ -2136,8 +1842,7 @@ two forms, whichever is not the default.
|
||||
.PP
|
||||
The following options control the amount and kinds of warnings produced
|
||||
by \s-1GCC\s0; for further, language-specific options also refer to
|
||||
\&\fB\*(C+ Dialect Options\fR and \fBObjective-C and Objective\-\*(C+ Dialect
|
||||
Options\fR.
|
||||
\&\fB\*(C+ Dialect Options\fR.
|
||||
.IP "\fB\-fsyntax\-only\fR" 4
|
||||
.IX Item "-fsyntax-only"
|
||||
Check the code for syntax errors, but don't do anything beyond that.
|
||||
@ -2287,8 +1992,8 @@ requiring a non-null value by the \f(CW\*(C`nonnull\*(C'\fR function attribute.
|
||||
.Sp
|
||||
\&\fB\-Wnonnull\fR is included in \fB\-Wall\fR and \fB\-Wformat\fR. It
|
||||
can be disabled with the \fB\-Wno\-nonnull\fR option.
|
||||
.IP "\fB\-Winit\-self\fR (C, \*(C+, Objective-C and Objective\-\*(C+ only)" 4
|
||||
.IX Item "-Winit-self (C, , Objective-C and Objective- only)"
|
||||
.IP "\fB\-Winit\-self\fR (C, \*(C+ only)" 4
|
||||
.IX Item "-Winit-self (C, only)"
|
||||
Warn about uninitialized variables which are initialized with themselves.
|
||||
Note this option can only be used with the \fB\-Wuninitialized\fR option,
|
||||
which in turn only works with \fB\-O1\fR and above.
|
||||
@ -2339,8 +2044,8 @@ bracketed, but that for \fBb\fR is fully bracketed.
|
||||
.Ve
|
||||
.Sp
|
||||
This warning is enabled by \fB\-Wall\fR.
|
||||
.IP "\fB\-Wmissing\-include\-dirs\fR (C, \*(C+, Objective-C and Objective\-\*(C+ only)" 4
|
||||
.IX Item "-Wmissing-include-dirs (C, , Objective-C and Objective- only)"
|
||||
.IP "\fB\-Wmissing\-include\-dirs\fR (C and \*(C+ only)" 4
|
||||
.IX Item "-Wmissing-include-dirs (C, only)"
|
||||
Warn if a user-supplied include directory does not exist.
|
||||
.IP "\fB\-Wparentheses\fR" 4
|
||||
.IX Item "-Wparentheses"
|
||||
@ -2675,8 +2380,7 @@ All of the above \fB\-W\fR options combined. This enables all the
|
||||
warnings about constructions that some users consider questionable, and
|
||||
that are easy to avoid (or modify to prevent the warning), even in
|
||||
conjunction with macros. This also enables some language-specific
|
||||
warnings described in \fB\*(C+ Dialect Options\fR and
|
||||
\&\fBObjective-C and Objective\-\*(C+ Dialect Options\fR.
|
||||
warnings described in \fB\*(C+ Dialect Options\fR.
|
||||
.PP
|
||||
The following \fB\-W...\fR options are not implied by \fB\-Wall\fR.
|
||||
Some of them warn about constructions that users generally do not
|
||||
@ -3224,8 +2928,8 @@ itself is likely to take inordinate amounts of time.
|
||||
.IP "\fB\-Wpointer\-sign\fR" 4
|
||||
.IX Item "-Wpointer-sign"
|
||||
Warn for pointer argument passing or assignment with different signedness.
|
||||
This option is only supported for C and Objective\-C. It is implied by
|
||||
\&\fB\-Wall\fR and by \fB\-pedantic\fR, which can be disabled with
|
||||
This option is only supported for C. It is implied by \&\fB\-Wall\fR
|
||||
and by \fB\-pedantic\fR, which can be disabled with
|
||||
\&\fB\-Wno\-pointer\-sign\fR.
|
||||
.IP "\fB\-Werror\fR" 4
|
||||
.IX Item "-Werror"
|
||||
@ -6294,12 +5998,10 @@ current directory.
|
||||
.PD 0
|
||||
.IP "\fB\-x c++\fR" 4
|
||||
.IX Item "-x c++"
|
||||
.IP "\fB\-x objective-c\fR" 4
|
||||
.IX Item "-x objective-c"
|
||||
.IP "\fB\-x assembler-with-cpp\fR" 4
|
||||
.IX Item "-x assembler-with-cpp"
|
||||
.PD
|
||||
Specify the source language: C, \*(C+, Objective\-C, or assembly. This has
|
||||
Specify the source language: C, \*(C+, or assembly. This has
|
||||
nothing to do with standards conformance or extensions; it merely
|
||||
selects which base syntax to expect. If you give none of these options,
|
||||
cpp will deduce the language from the extension of the source file:
|
||||
@ -6728,10 +6430,6 @@ ordinary object file, it is linked in the usual fashion. The only
|
||||
difference between using an \fB\-l\fR option and specifying a file name
|
||||
is that \fB\-l\fR surrounds \fIlibrary\fR with \fBlib\fR and \fB.a\fR
|
||||
and searches several directories.
|
||||
.IP "\fB\-lobjc\fR" 4
|
||||
.IX Item "-lobjc"
|
||||
You need this special case of the \fB\-l\fR option in order to
|
||||
link an Objective-C or Objective\-\*(C+ program.
|
||||
.IP "\fB\-nostartfiles\fR" 4
|
||||
.IX Item "-nostartfiles"
|
||||
Do not use the standard system startup files when linking.
|
||||
@ -13035,8 +12733,6 @@ preprocessor.
|
||||
.IX Item "C_INCLUDE_PATH"
|
||||
.IP "\fB\s-1CPLUS_INCLUDE_PATH\s0\fR" 4
|
||||
.IX Item "CPLUS_INCLUDE_PATH"
|
||||
.IP "\fB\s-1OBJC_INCLUDE_PATH\s0\fR" 4
|
||||
.IX Item "OBJC_INCLUDE_PATH"
|
||||
.PD
|
||||
Each variable's value is a list of directories separated by a special
|
||||
character, much like \fB\s-1PATH\s0\fR, in which to look for header files.
|
||||
|
@ -129,7 +129,6 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}.
|
||||
* C Implementation:: How GCC implements the ISO C specification.
|
||||
* C Extensions:: GNU extensions to the C language family.
|
||||
* C++ Extensions:: GNU extensions to the C++ language.
|
||||
* Objective-C:: GNU Objective-C runtime features.
|
||||
* Compatibility:: Binary Compatibility
|
||||
* Gcov:: @command{gcov}---a test coverage program.
|
||||
* Trouble:: If you have trouble using GCC.
|
||||
@ -154,7 +153,6 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}.
|
||||
@include invoke.texi
|
||||
@include implement-c.texi
|
||||
@include extend.texi
|
||||
@include objc.texi
|
||||
@include compat.texi
|
||||
@include gcov.texi
|
||||
@include trouble.texi
|
||||
|
@ -124,8 +124,6 @@ only one of these two forms, whichever one is not the default.
|
||||
* Invoking G++:: Compiling C++ programs.
|
||||
* C Dialect Options:: Controlling the variant of C language compiled.
|
||||
* C++ Dialect Options:: Variations on C++.
|
||||
* Objective-C and Objective-C++ Dialect Options:: Variations on Objective-C
|
||||
and Objective-C++.
|
||||
* Language Independent Options:: Controlling how diagnostics should be
|
||||
formatted.
|
||||
* Warning Options:: How picky should the compiler be?
|
||||
@ -195,24 +193,6 @@ in the following sections.
|
||||
-Woverloaded-virtual -Wno-pmf-conversions @gol
|
||||
-Wsign-promo}
|
||||
|
||||
@item Objective-C and Objective-C++ Language Options
|
||||
@xref{Objective-C and Objective-C++ Dialect Options,,Options Controlling
|
||||
Objective-C and Objective-C++ Dialects}.
|
||||
@gccoptlist{-fconstant-string-class=@var{class-name} @gol
|
||||
-fgnu-runtime -fnext-runtime @gol
|
||||
-fno-nil-receivers @gol
|
||||
-fobjc-call-cxx-cdtors @gol
|
||||
-fobjc-direct-dispatch @gol
|
||||
-fobjc-exceptions @gol
|
||||
-fobjc-gc @gol
|
||||
-freplace-objc-classes @gol
|
||||
-fzero-link @gol
|
||||
-gen-decls @gol
|
||||
-Wassign-intercept @gol
|
||||
-Wno-protocol -Wselector @gol
|
||||
-Wstrict-selector-match @gol
|
||||
-Wundeclared-selector}
|
||||
|
||||
@item Language Independent Options
|
||||
@xref{Language Independent Options,,Options to Control Diagnostic Messages Formatting}.
|
||||
@gccoptlist{-fmessage-length=@var{n} @gol
|
||||
@ -795,8 +775,6 @@ See S/390 and zSeries Options.
|
||||
or preprocessed source.
|
||||
* C Dialect Options:: Controlling the variant of C language compiled.
|
||||
* C++ Dialect Options:: Variations on C++.
|
||||
* Objective-C and Objective-C++ Dialect Options:: Variations on Objective-C
|
||||
and Objective-C++.
|
||||
* Language Independent Options:: Controlling how diagnostics should be
|
||||
formatted.
|
||||
* Warning Options:: How picky should the compiler be?
|
||||
@ -837,25 +815,8 @@ C source code which should not be preprocessed.
|
||||
@item @var{file}.ii
|
||||
C++ source code which should not be preprocessed.
|
||||
|
||||
@item @var{file}.m
|
||||
Objective-C source code. Note that you must link with the @file{libobjc}
|
||||
library to make an Objective-C program work.
|
||||
|
||||
@item @var{file}.mi
|
||||
Objective-C source code which should not be preprocessed.
|
||||
|
||||
@item @var{file}.mm
|
||||
@itemx @var{file}.M
|
||||
Objective-C++ source code. Note that you must link with the @file{libobjc}
|
||||
library to make an Objective-C++ program work. Note that @samp{.M} refers
|
||||
to a literal capital M@.
|
||||
|
||||
@item @var{file}.mii
|
||||
Objective-C++ source code which should not be preprocessed.
|
||||
|
||||
@item @var{file}.h
|
||||
C, C++, Objective-C or Objective-C++ header file to be turned into a
|
||||
precompiled header.
|
||||
C, or C++ header file to be turned into a precompiled header.
|
||||
|
||||
@item @var{file}.cc
|
||||
@itemx @var{file}.cp
|
||||
@ -868,13 +829,6 @@ C++ source code which must be preprocessed. Note that in @samp{.cxx},
|
||||
the last two letters must both be literally @samp{x}. Likewise,
|
||||
@samp{.C} refers to a literal capital C@.
|
||||
|
||||
@item @var{file}.mm
|
||||
@itemx @var{file}.M
|
||||
Objective-C++ source code which must be preprocessed.
|
||||
|
||||
@item @var{file}.mii
|
||||
Objective-C++ source code which should not be preprocessed.
|
||||
|
||||
@item @var{file}.hh
|
||||
@itemx @var{file}.H
|
||||
C++ header file to be turned into a precompiled header.
|
||||
@ -946,8 +900,6 @@ the next @option{-x} option. Possible values for @var{language} are:
|
||||
@smallexample
|
||||
c c-header c-cpp-output
|
||||
c++ c++-header c++-cpp-output
|
||||
objective-c objective-c-header objective-c-cpp-output
|
||||
objective-c++ objective-c++-header objective-c++-cpp-output
|
||||
assembler assembler-with-cpp
|
||||
ada
|
||||
f95 f95-cpp-input
|
||||
@ -1121,8 +1073,7 @@ explanations of options that are meaningful only for C++ programs.
|
||||
@cindex options, dialect
|
||||
|
||||
The following options control the dialect of C (or languages derived
|
||||
from C, such as C++, Objective-C and Objective-C++) that the compiler
|
||||
accepts:
|
||||
from C, such as C++) that the compiler accepts:
|
||||
|
||||
@table @gcctabopt
|
||||
@cindex ANSI support
|
||||
@ -1955,278 +1906,6 @@ In this example, G++ will synthesize a default @samp{A& operator =
|
||||
(const A&);}, while cfront will use the user-defined @samp{operator =}.
|
||||
@end table
|
||||
|
||||
@node Objective-C and Objective-C++ Dialect Options
|
||||
@section Options Controlling Objective-C and Objective-C++ Dialects
|
||||
|
||||
@cindex compiler options, Objective-C and Objective-C++
|
||||
@cindex Objective-C and Objective-C++ options, command line
|
||||
@cindex options, Objective-C and Objective-C++
|
||||
(NOTE: This manual does not describe the Objective-C and Objective-C++
|
||||
languages themselves. See @xref{Standards,,Language Standards
|
||||
Supported by GCC}, for references.)
|
||||
|
||||
This section describes the command-line options that are only meaningful
|
||||
for Objective-C and Objective-C++ programs, but you can also use most of
|
||||
the language-independent GNU compiler options.
|
||||
For example, you might compile a file @code{some_class.m} like this:
|
||||
|
||||
@smallexample
|
||||
gcc -g -fgnu-runtime -O -c some_class.m
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
In this example, @option{-fgnu-runtime} is an option meant only for
|
||||
Objective-C and Objective-C++ programs; you can use the other options with
|
||||
any language supported by GCC@.
|
||||
|
||||
Note that since Objective-C is an extension of the C language, Objective-C
|
||||
compilations may also use options specific to the C front-end (e.g.,
|
||||
@option{-Wtraditional}). Similarly, Objective-C++ compilations may use
|
||||
C++-specific options (e.g., @option{-Wabi}).
|
||||
|
||||
Here is a list of options that are @emph{only} for compiling Objective-C
|
||||
and Objective-C++ programs:
|
||||
|
||||
@table @gcctabopt
|
||||
@item -fconstant-string-class=@var{class-name}
|
||||
@opindex fconstant-string-class
|
||||
Use @var{class-name} as the name of the class to instantiate for each
|
||||
literal string specified with the syntax @code{@@"@dots{}"}. The default
|
||||
class name is @code{NXConstantString} if the GNU runtime is being used, and
|
||||
@code{NSConstantString} if the NeXT runtime is being used (see below). The
|
||||
@option{-fconstant-cfstrings} option, if also present, will override the
|
||||
@option{-fconstant-string-class} setting and cause @code{@@"@dots{}"} literals
|
||||
to be laid out as constant CoreFoundation strings.
|
||||
|
||||
@item -fgnu-runtime
|
||||
@opindex fgnu-runtime
|
||||
Generate object code compatible with the standard GNU Objective-C
|
||||
runtime. This is the default for most types of systems.
|
||||
|
||||
@item -fnext-runtime
|
||||
@opindex fnext-runtime
|
||||
Generate output compatible with the NeXT runtime. This is the default
|
||||
for NeXT-based systems, including Darwin and Mac OS X@. The macro
|
||||
@code{__NEXT_RUNTIME__} is predefined if (and only if) this option is
|
||||
used.
|
||||
|
||||
@item -fno-nil-receivers
|
||||
@opindex fno-nil-receivers
|
||||
Assume that all Objective-C message dispatches (e.g.,
|
||||
@code{[receiver message:arg]}) in this translation unit ensure that the receiver
|
||||
is not @code{nil}. This allows for more efficient entry points in the runtime
|
||||
to be used. Currently, this option is only available in conjunction with
|
||||
the NeXT runtime on Mac OS X 10.3 and later.
|
||||
|
||||
@item -fobjc-call-cxx-cdtors
|
||||
@opindex fobjc-call-cxx-cdtors
|
||||
For each Objective-C class, check if any of its instance variables is a
|
||||
C++ object with a non-trivial default constructor. If so, synthesize a
|
||||
special @code{- (id) .cxx_construct} instance method that will run
|
||||
non-trivial default constructors on any such instance variables, in order,
|
||||
and then return @code{self}. Similarly, check if any instance variable
|
||||
is a C++ object with a non-trivial destructor, and if so, synthesize a
|
||||
special @code{- (void) .cxx_destruct} method that will run
|
||||
all such default destructors, in reverse order.
|
||||
|
||||
The @code{- (id) .cxx_construct} and/or @code{- (void) .cxx_destruct} methods
|
||||
thusly generated will only operate on instance variables declared in the
|
||||
current Objective-C class, and not those inherited from superclasses. It
|
||||
is the responsibility of the Objective-C runtime to invoke all such methods
|
||||
in an object's inheritance hierarchy. The @code{- (id) .cxx_construct} methods
|
||||
will be invoked by the runtime immediately after a new object
|
||||
instance is allocated; the @code{- (void) .cxx_destruct} methods will
|
||||
be invoked immediately before the runtime deallocates an object instance.
|
||||
|
||||
As of this writing, only the NeXT runtime on Mac OS X 10.4 and later has
|
||||
support for invoking the @code{- (id) .cxx_construct} and
|
||||
@code{- (void) .cxx_destruct} methods.
|
||||
|
||||
@item -fobjc-direct-dispatch
|
||||
@opindex fobjc-direct-dispatch
|
||||
Allow fast jumps to the message dispatcher. On Darwin this is
|
||||
accomplished via the comm page.
|
||||
|
||||
@item -fobjc-exceptions
|
||||
@opindex fobjc-exceptions
|
||||
Enable syntactic support for structured exception handling in Objective-C,
|
||||
similar to what is offered by C++ and Java. This option is
|
||||
unavailable in conjunction with the NeXT runtime on Mac OS X 10.2 and
|
||||
earlier.
|
||||
|
||||
@smallexample
|
||||
@@try @{
|
||||
@dots{}
|
||||
@@throw expr;
|
||||
@dots{}
|
||||
@}
|
||||
@@catch (AnObjCClass *exc) @{
|
||||
@dots{}
|
||||
@@throw expr;
|
||||
@dots{}
|
||||
@@throw;
|
||||
@dots{}
|
||||
@}
|
||||
@@catch (AnotherClass *exc) @{
|
||||
@dots{}
|
||||
@}
|
||||
@@catch (id allOthers) @{
|
||||
@dots{}
|
||||
@}
|
||||
@@finally @{
|
||||
@dots{}
|
||||
@@throw expr;
|
||||
@dots{}
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
The @code{@@throw} statement may appear anywhere in an Objective-C or
|
||||
Objective-C++ program; when used inside of a @code{@@catch} block, the
|
||||
@code{@@throw} may appear without an argument (as shown above), in which case
|
||||
the object caught by the @code{@@catch} will be rethrown.
|
||||
|
||||
Note that only (pointers to) Objective-C objects may be thrown and
|
||||
caught using this scheme. When an object is thrown, it will be caught
|
||||
by the nearest @code{@@catch} clause capable of handling objects of that type,
|
||||
analogously to how @code{catch} blocks work in C++ and Java. A
|
||||
@code{@@catch(id @dots{})} clause (as shown above) may also be provided to catch
|
||||
any and all Objective-C exceptions not caught by previous @code{@@catch}
|
||||
clauses (if any).
|
||||
|
||||
The @code{@@finally} clause, if present, will be executed upon exit from the
|
||||
immediately preceding @code{@@try @dots{} @@catch} section. This will happen
|
||||
regardless of whether any exceptions are thrown, caught or rethrown
|
||||
inside the @code{@@try @dots{} @@catch} section, analogously to the behavior
|
||||
of the @code{finally} clause in Java.
|
||||
|
||||
There are several caveats to using the new exception mechanism:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Although currently designed to be binary compatible with @code{NS_HANDLER}-style
|
||||
idioms provided by the @code{NSException} class, the new
|
||||
exceptions can only be used on Mac OS X 10.3 (Panther) and later
|
||||
systems, due to additional functionality needed in the (NeXT) Objective-C
|
||||
runtime.
|
||||
|
||||
@item
|
||||
As mentioned above, the new exceptions do not support handling
|
||||
types other than Objective-C objects. Furthermore, when used from
|
||||
Objective-C++, the Objective-C exception model does not interoperate with C++
|
||||
exceptions at this time. This means you cannot @code{@@throw} an exception
|
||||
from Objective-C and @code{catch} it in C++, or vice versa
|
||||
(i.e., @code{throw @dots{} @@catch}).
|
||||
@end itemize
|
||||
|
||||
The @option{-fobjc-exceptions} switch also enables the use of synchronization
|
||||
blocks for thread-safe execution:
|
||||
|
||||
@smallexample
|
||||
@@synchronized (ObjCClass *guard) @{
|
||||
@dots{}
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
Upon entering the @code{@@synchronized} block, a thread of execution shall
|
||||
first check whether a lock has been placed on the corresponding @code{guard}
|
||||
object by another thread. If it has, the current thread shall wait until
|
||||
the other thread relinquishes its lock. Once @code{guard} becomes available,
|
||||
the current thread will place its own lock on it, execute the code contained in
|
||||
the @code{@@synchronized} block, and finally relinquish the lock (thereby
|
||||
making @code{guard} available to other threads).
|
||||
|
||||
Unlike Java, Objective-C does not allow for entire methods to be marked
|
||||
@code{@@synchronized}. Note that throwing exceptions out of
|
||||
@code{@@synchronized} blocks is allowed, and will cause the guarding object
|
||||
to be unlocked properly.
|
||||
|
||||
@item -fobjc-gc
|
||||
@opindex fobjc-gc
|
||||
Enable garbage collection (GC) in Objective-C and Objective-C++ programs.
|
||||
|
||||
@item -freplace-objc-classes
|
||||
@opindex freplace-objc-classes
|
||||
Emit a special marker instructing @command{ld(1)} not to statically link in
|
||||
the resulting object file, and allow @command{dyld(1)} to load it in at
|
||||
run time instead. This is used in conjunction with the Fix-and-Continue
|
||||
debugging mode, where the object file in question may be recompiled and
|
||||
dynamically reloaded in the course of program execution, without the need
|
||||
to restart the program itself. Currently, Fix-and-Continue functionality
|
||||
is only available in conjunction with the NeXT runtime on Mac OS X 10.3
|
||||
and later.
|
||||
|
||||
@item -fzero-link
|
||||
@opindex fzero-link
|
||||
When compiling for the NeXT runtime, the compiler ordinarily replaces calls
|
||||
to @code{objc_getClass("@dots{}")} (when the name of the class is known at
|
||||
compile time) with static class references that get initialized at load time,
|
||||
which improves run-time performance. Specifying the @option{-fzero-link} flag
|
||||
suppresses this behavior and causes calls to @code{objc_getClass("@dots{}")}
|
||||
to be retained. This is useful in Zero-Link debugging mode, since it allows
|
||||
for individual class implementations to be modified during program execution.
|
||||
|
||||
@item -gen-decls
|
||||
@opindex gen-decls
|
||||
Dump interface declarations for all classes seen in the source file to a
|
||||
file named @file{@var{sourcename}.decl}.
|
||||
|
||||
@item -Wassign-intercept
|
||||
@opindex Wassign-intercept
|
||||
Warn whenever an Objective-C assignment is being intercepted by the
|
||||
garbage collector.
|
||||
|
||||
@item -Wno-protocol
|
||||
@opindex Wno-protocol
|
||||
If a class is declared to implement a protocol, a warning is issued for
|
||||
every method in the protocol that is not implemented by the class. The
|
||||
default behavior is to issue a warning for every method not explicitly
|
||||
implemented in the class, even if a method implementation is inherited
|
||||
from the superclass. If you use the @option{-Wno-protocol} option, then
|
||||
methods inherited from the superclass are considered to be implemented,
|
||||
and no warning is issued for them.
|
||||
|
||||
@item -Wselector
|
||||
@opindex Wselector
|
||||
Warn if multiple methods of different types for the same selector are
|
||||
found during compilation. The check is performed on the list of methods
|
||||
in the final stage of compilation. Additionally, a check is performed
|
||||
for each selector appearing in a @code{@@selector(@dots{})}
|
||||
expression, and a corresponding method for that selector has been found
|
||||
during compilation. Because these checks scan the method table only at
|
||||
the end of compilation, these warnings are not produced if the final
|
||||
stage of compilation is not reached, for example because an error is
|
||||
found during compilation, or because the @option{-fsyntax-only} option is
|
||||
being used.
|
||||
|
||||
@item -Wstrict-selector-match
|
||||
@opindex Wstrict-selector-match
|
||||
Warn if multiple methods with differing argument and/or return types are
|
||||
found for a given selector when attempting to send a message using this
|
||||
selector to a receiver of type @code{id} or @code{Class}. When this flag
|
||||
is off (which is the default behavior), the compiler will omit such warnings
|
||||
if any differences found are confined to types which share the same size
|
||||
and alignment.
|
||||
|
||||
@item -Wundeclared-selector
|
||||
@opindex Wundeclared-selector
|
||||
Warn if a @code{@@selector(@dots{})} expression referring to an
|
||||
undeclared selector is found. A selector is considered undeclared if no
|
||||
method with that name has been declared before the
|
||||
@code{@@selector(@dots{})} expression, either explicitly in an
|
||||
@code{@@interface} or @code{@@protocol} declaration, or implicitly in
|
||||
an @code{@@implementation} section. This option always performs its
|
||||
checks as soon as a @code{@@selector(@dots{})} expression is found,
|
||||
while @option{-Wselector} only performs its checks in the final stage of
|
||||
compilation. This also enforces the coding style convention
|
||||
that methods and selectors must be declared before being used.
|
||||
|
||||
@item -print-objc-runtime-info
|
||||
@opindex print-objc-runtime-info
|
||||
Generate C header describing the largest structure that is passed by
|
||||
value, if any.
|
||||
|
||||
@end table
|
||||
|
||||
@node Language Independent Options
|
||||
@section Options to Control Diagnostic Messages Formatting
|
||||
@cindex options to control diagnostics formatting
|
||||
@ -2294,8 +1973,7 @@ two forms, whichever is not the default.
|
||||
|
||||
The following options control the amount and kinds of warnings produced
|
||||
by GCC; for further, language-specific options also refer to
|
||||
@ref{C++ Dialect Options} and @ref{Objective-C and Objective-C++ Dialect
|
||||
Options}.
|
||||
@ref{C++ Dialect Options}.
|
||||
|
||||
@table @gcctabopt
|
||||
@cindex syntax checking
|
||||
@ -2468,7 +2146,7 @@ requiring a non-null value by the @code{nonnull} function attribute.
|
||||
@option{-Wnonnull} is included in @option{-Wall} and @option{-Wformat}. It
|
||||
can be disabled with the @option{-Wno-nonnull} option.
|
||||
|
||||
@item -Winit-self @r{(C, C++, Objective-C and Objective-C++ only)}
|
||||
@item -Winit-self @r{(C and C++ only)}
|
||||
@opindex Winit-self
|
||||
Warn about uninitialized variables which are initialized with themselves.
|
||||
Note this option can only be used with the @option{-Wuninitialized} option,
|
||||
@ -2525,7 +2203,7 @@ int b[2][2] = @{ @{ 0, 1 @}, @{ 2, 3 @} @};
|
||||
|
||||
This warning is enabled by @option{-Wall}.
|
||||
|
||||
@item -Wmissing-include-dirs @r{(C, C++, Objective-C and Objective-C++ only)}
|
||||
@item -Wmissing-include-dirs @r{(C and C++ only)}
|
||||
@opindex Wmissing-include-dirs
|
||||
Warn if a user-supplied include directory does not exist.
|
||||
|
||||
@ -2893,8 +2571,7 @@ All of the above @samp{-W} options combined. This enables all the
|
||||
warnings about constructions that some users consider questionable, and
|
||||
that are easy to avoid (or modify to prevent the warning), even in
|
||||
conjunction with macros. This also enables some language-specific
|
||||
warnings described in @ref{C++ Dialect Options} and
|
||||
@ref{Objective-C and Objective-C++ Dialect Options}.
|
||||
warnings described in @ref{C++ Dialect Options}.
|
||||
@end table
|
||||
|
||||
The following @option{-W@dots{}} options are not implied by @option{-Wall}.
|
||||
@ -3545,8 +3222,8 @@ itself is likely to take inordinate amounts of time.
|
||||
@opindex Wpointer-sign
|
||||
@opindex Wno-pointer-sign
|
||||
Warn for pointer argument passing or assignment with different signedness.
|
||||
This option is only supported for C and Objective-C@. It is implied by
|
||||
@option{-Wall} and by @option{-pedantic}, which can be disabled with
|
||||
This option is only supported for C. It is implied by @option{-Wall}
|
||||
and by @option{-pedantic}, which can be disabled with
|
||||
@option{-Wno-pointer-sign}.
|
||||
|
||||
@item -Werror
|
||||
@ -6538,11 +6215,6 @@ difference between using an @option{-l} option and specifying a file name
|
||||
is that @option{-l} surrounds @var{library} with @samp{lib} and @samp{.a}
|
||||
and searches several directories.
|
||||
|
||||
@item -lobjc
|
||||
@opindex lobjc
|
||||
You need this special case of the @option{-l} option in order to
|
||||
link an Objective-C or Objective-C++ program.
|
||||
|
||||
@item -nostartfiles
|
||||
@opindex nostartfiles
|
||||
Do not use the standard system startup files when linking.
|
||||
@ -7218,7 +6890,9 @@ first argument in the outfiles array and replaces it with the second argument.
|
||||
is a small example of its usage:
|
||||
|
||||
@smallexample
|
||||
%@{fgnu-runtime:%:replace-outfile(-lobjc -lobjc-gnu)@}
|
||||
%@{static|static-libgcc|static-libstdc++:%:replace-outfile(-lstdc++ \
|
||||
libstdc++.a%s)@}
|
||||
|
||||
@end smallexample
|
||||
|
||||
@end table
|
||||
|
@ -1,478 +0,0 @@
|
||||
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
@c 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
@c This is part of the GCC manual.
|
||||
@c For copying conditions, see the file gcc.texi.
|
||||
|
||||
@node Objective-C
|
||||
@comment node-name, next, previous, up
|
||||
|
||||
@chapter GNU Objective-C runtime features
|
||||
|
||||
This document is meant to describe some of the GNU Objective-C runtime
|
||||
features. It is not intended to teach you Objective-C, there are several
|
||||
resources on the Internet that present the language. Questions and
|
||||
comments about this document to Ovidiu Predescu
|
||||
@email{ovidiu@@cup.hp.com}.
|
||||
|
||||
@menu
|
||||
* Executing code before main::
|
||||
* Type encoding::
|
||||
* Garbage Collection::
|
||||
* Constant string objects::
|
||||
* compatibility_alias::
|
||||
@end menu
|
||||
|
||||
@node Executing code before main, Type encoding, Objective-C, Objective-C
|
||||
@section @code{+load}: Executing code before main
|
||||
|
||||
The GNU Objective-C runtime provides a way that allows you to execute
|
||||
code before the execution of the program enters the @code{main}
|
||||
function. The code is executed on a per-class and a per-category basis,
|
||||
through a special class method @code{+load}.
|
||||
|
||||
This facility is very useful if you want to initialize global variables
|
||||
which can be accessed by the program directly, without sending a message
|
||||
to the class first. The usual way to initialize global variables, in the
|
||||
@code{+initialize} method, might not be useful because
|
||||
@code{+initialize} is only called when the first message is sent to a
|
||||
class object, which in some cases could be too late.
|
||||
|
||||
Suppose for example you have a @code{FileStream} class that declares
|
||||
@code{Stdin}, @code{Stdout} and @code{Stderr} as global variables, like
|
||||
below:
|
||||
|
||||
@smallexample
|
||||
|
||||
FileStream *Stdin = nil;
|
||||
FileStream *Stdout = nil;
|
||||
FileStream *Stderr = nil;
|
||||
|
||||
@@implementation FileStream
|
||||
|
||||
+ (void)initialize
|
||||
@{
|
||||
Stdin = [[FileStream new] initWithFd:0];
|
||||
Stdout = [[FileStream new] initWithFd:1];
|
||||
Stderr = [[FileStream new] initWithFd:2];
|
||||
@}
|
||||
|
||||
/* @r{Other methods here} */
|
||||
@@end
|
||||
|
||||
@end smallexample
|
||||
|
||||
In this example, the initialization of @code{Stdin}, @code{Stdout} and
|
||||
@code{Stderr} in @code{+initialize} occurs too late. The programmer can
|
||||
send a message to one of these objects before the variables are actually
|
||||
initialized, thus sending messages to the @code{nil} object. The
|
||||
@code{+initialize} method which actually initializes the global
|
||||
variables is not invoked until the first message is sent to the class
|
||||
object. The solution would require these variables to be initialized
|
||||
just before entering @code{main}.
|
||||
|
||||
The correct solution of the above problem is to use the @code{+load}
|
||||
method instead of @code{+initialize}:
|
||||
|
||||
@smallexample
|
||||
|
||||
@@implementation FileStream
|
||||
|
||||
+ (void)load
|
||||
@{
|
||||
Stdin = [[FileStream new] initWithFd:0];
|
||||
Stdout = [[FileStream new] initWithFd:1];
|
||||
Stderr = [[FileStream new] initWithFd:2];
|
||||
@}
|
||||
|
||||
/* @r{Other methods here} */
|
||||
@@end
|
||||
|
||||
@end smallexample
|
||||
|
||||
The @code{+load} is a method that is not overridden by categories. If a
|
||||
class and a category of it both implement @code{+load}, both methods are
|
||||
invoked. This allows some additional initializations to be performed in
|
||||
a category.
|
||||
|
||||
This mechanism is not intended to be a replacement for @code{+initialize}.
|
||||
You should be aware of its limitations when you decide to use it
|
||||
instead of @code{+initialize}.
|
||||
|
||||
@menu
|
||||
* What you can and what you cannot do in +load::
|
||||
@end menu
|
||||
|
||||
|
||||
@node What you can and what you cannot do in +load, , Executing code before main, Executing code before main
|
||||
@subsection What you can and what you cannot do in @code{+load}
|
||||
|
||||
The @code{+load} implementation in the GNU runtime guarantees you the following
|
||||
things:
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
you can write whatever C code you like;
|
||||
|
||||
@item
|
||||
you can send messages to Objective-C constant strings (@code{@@"this is a
|
||||
constant string"});
|
||||
|
||||
@item
|
||||
you can allocate and send messages to objects whose class is implemented
|
||||
in the same file;
|
||||
|
||||
@item
|
||||
the @code{+load} implementation of all super classes of a class are executed before the @code{+load} of that class is executed;
|
||||
|
||||
@item
|
||||
the @code{+load} implementation of a class is executed before the
|
||||
@code{+load} implementation of any category.
|
||||
|
||||
@end itemize
|
||||
|
||||
In particular, the following things, even if they can work in a
|
||||
particular case, are not guaranteed:
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
allocation of or sending messages to arbitrary objects;
|
||||
|
||||
@item
|
||||
allocation of or sending messages to objects whose classes have a
|
||||
category implemented in the same file;
|
||||
|
||||
@end itemize
|
||||
|
||||
You should make no assumptions about receiving @code{+load} in sibling
|
||||
classes when you write @code{+load} of a class. The order in which
|
||||
sibling classes receive @code{+load} is not guaranteed.
|
||||
|
||||
The order in which @code{+load} and @code{+initialize} are called could
|
||||
be problematic if this matters. If you don't allocate objects inside
|
||||
@code{+load}, it is guaranteed that @code{+load} is called before
|
||||
@code{+initialize}. If you create an object inside @code{+load} the
|
||||
@code{+initialize} method of object's class is invoked even if
|
||||
@code{+load} was not invoked. Note if you explicitly call @code{+load}
|
||||
on a class, @code{+initialize} will be called first. To avoid possible
|
||||
problems try to implement only one of these methods.
|
||||
|
||||
The @code{+load} method is also invoked when a bundle is dynamically
|
||||
loaded into your running program. This happens automatically without any
|
||||
intervening operation from you. When you write bundles and you need to
|
||||
write @code{+load} you can safely create and send messages to objects whose
|
||||
classes already exist in the running program. The same restrictions as
|
||||
above apply to classes defined in bundle.
|
||||
|
||||
|
||||
|
||||
@node Type encoding, Garbage Collection, Executing code before main, Objective-C
|
||||
@section Type encoding
|
||||
|
||||
The Objective-C compiler generates type encodings for all the
|
||||
types. These type encodings are used at runtime to find out information
|
||||
about selectors and methods and about objects and classes.
|
||||
|
||||
The types are encoded in the following way:
|
||||
|
||||
@c @sp 1
|
||||
|
||||
@multitable @columnfractions .25 .75
|
||||
@item @code{_Bool}
|
||||
@tab @code{B}
|
||||
@item @code{char}
|
||||
@tab @code{c}
|
||||
@item @code{unsigned char}
|
||||
@tab @code{C}
|
||||
@item @code{short}
|
||||
@tab @code{s}
|
||||
@item @code{unsigned short}
|
||||
@tab @code{S}
|
||||
@item @code{int}
|
||||
@tab @code{i}
|
||||
@item @code{unsigned int}
|
||||
@tab @code{I}
|
||||
@item @code{long}
|
||||
@tab @code{l}
|
||||
@item @code{unsigned long}
|
||||
@tab @code{L}
|
||||
@item @code{long long}
|
||||
@tab @code{q}
|
||||
@item @code{unsigned long long}
|
||||
@tab @code{Q}
|
||||
@item @code{float}
|
||||
@tab @code{f}
|
||||
@item @code{double}
|
||||
@tab @code{d}
|
||||
@item @code{void}
|
||||
@tab @code{v}
|
||||
@item @code{id}
|
||||
@tab @code{@@}
|
||||
@item @code{Class}
|
||||
@tab @code{#}
|
||||
@item @code{SEL}
|
||||
@tab @code{:}
|
||||
@item @code{char*}
|
||||
@tab @code{*}
|
||||
@item unknown type
|
||||
@tab @code{?}
|
||||
@item Complex types
|
||||
@tab @code{j} followed by the inner type. For example @code{_Complex double} is encoded as "jd".
|
||||
@item bit-fields
|
||||
@tab @code{b} followed by the starting position of the bit-field, the type of the bit-field and the size of the bit-field (the bit-fields encoding was changed from the NeXT's compiler encoding, see below)
|
||||
@end multitable
|
||||
|
||||
@c @sp 1
|
||||
|
||||
The encoding of bit-fields has changed to allow bit-fields to be properly
|
||||
handled by the runtime functions that compute sizes and alignments of
|
||||
types that contain bit-fields. The previous encoding contained only the
|
||||
size of the bit-field. Using only this information it is not possible to
|
||||
reliably compute the size occupied by the bit-field. This is very
|
||||
important in the presence of the Boehm's garbage collector because the
|
||||
objects are allocated using the typed memory facility available in this
|
||||
collector. The typed memory allocation requires information about where
|
||||
the pointers are located inside the object.
|
||||
|
||||
The position in the bit-field is the position, counting in bits, of the
|
||||
bit closest to the beginning of the structure.
|
||||
|
||||
The non-atomic types are encoded as follows:
|
||||
|
||||
@c @sp 1
|
||||
|
||||
@multitable @columnfractions .2 .8
|
||||
@item pointers
|
||||
@tab @samp{^} followed by the pointed type.
|
||||
@item arrays
|
||||
@tab @samp{[} followed by the number of elements in the array followed by the type of the elements followed by @samp{]}
|
||||
@item structures
|
||||
@tab @samp{@{} followed by the name of the structure (or @samp{?} if the structure is unnamed), the @samp{=} sign, the type of the members and by @samp{@}}
|
||||
@item unions
|
||||
@tab @samp{(} followed by the name of the structure (or @samp{?} if the union is unnamed), the @samp{=} sign, the type of the members followed by @samp{)}
|
||||
@end multitable
|
||||
|
||||
Here are some types and their encodings, as they are generated by the
|
||||
compiler on an i386 machine:
|
||||
|
||||
@sp 1
|
||||
|
||||
@multitable @columnfractions .25 .75
|
||||
@item Objective-C type
|
||||
@tab Compiler encoding
|
||||
@item
|
||||
@smallexample
|
||||
int a[10];
|
||||
@end smallexample
|
||||
@tab @code{[10i]}
|
||||
@item
|
||||
@smallexample
|
||||
struct @{
|
||||
int i;
|
||||
float f[3];
|
||||
int a:3;
|
||||
int b:2;
|
||||
char c;
|
||||
@}
|
||||
@end smallexample
|
||||
@tab @code{@{?=i[3f]b128i3b131i2c@}}
|
||||
@end multitable
|
||||
|
||||
@sp 1
|
||||
|
||||
In addition to the types the compiler also encodes the type
|
||||
specifiers. The table below describes the encoding of the current
|
||||
Objective-C type specifiers:
|
||||
|
||||
@sp 1
|
||||
|
||||
@multitable @columnfractions .25 .75
|
||||
@item Specifier
|
||||
@tab Encoding
|
||||
@item @code{const}
|
||||
@tab @code{r}
|
||||
@item @code{in}
|
||||
@tab @code{n}
|
||||
@item @code{inout}
|
||||
@tab @code{N}
|
||||
@item @code{out}
|
||||
@tab @code{o}
|
||||
@item @code{bycopy}
|
||||
@tab @code{O}
|
||||
@item @code{oneway}
|
||||
@tab @code{V}
|
||||
@end multitable
|
||||
|
||||
@sp 1
|
||||
|
||||
The type specifiers are encoded just before the type. Unlike types
|
||||
however, the type specifiers are only encoded when they appear in method
|
||||
argument types.
|
||||
|
||||
|
||||
@node Garbage Collection, Constant string objects, Type encoding, Objective-C
|
||||
@section Garbage Collection
|
||||
|
||||
Support for a new memory management policy has been added by using a
|
||||
powerful conservative garbage collector, known as the
|
||||
Boehm-Demers-Weiser conservative garbage collector. It is available from
|
||||
@w{@uref{http://www.hpl.hp.com/personal/Hans_Boehm/gc/}}.
|
||||
|
||||
To enable the support for it you have to configure the compiler using an
|
||||
additional argument, @w{@option{--enable-objc-gc}}. You need to have
|
||||
garbage collector installed before building the compiler. This will
|
||||
build an additional runtime library which has several enhancements to
|
||||
support the garbage collector. The new library has a new name,
|
||||
@file{libobjc_gc.a} to not conflict with the non-garbage-collected
|
||||
library.
|
||||
|
||||
When the garbage collector is used, the objects are allocated using the
|
||||
so-called typed memory allocation mechanism available in the
|
||||
Boehm-Demers-Weiser collector. This mode requires precise information on
|
||||
where pointers are located inside objects. This information is computed
|
||||
once per class, immediately after the class has been initialized.
|
||||
|
||||
There is a new runtime function @code{class_ivar_set_gcinvisible()}
|
||||
which can be used to declare a so-called @dfn{weak pointer}
|
||||
reference. Such a pointer is basically hidden for the garbage collector;
|
||||
this can be useful in certain situations, especially when you want to
|
||||
keep track of the allocated objects, yet allow them to be
|
||||
collected. This kind of pointers can only be members of objects, you
|
||||
cannot declare a global pointer as a weak reference. Every type which is
|
||||
a pointer type can be declared a weak pointer, including @code{id},
|
||||
@code{Class} and @code{SEL}.
|
||||
|
||||
Here is an example of how to use this feature. Suppose you want to
|
||||
implement a class whose instances hold a weak pointer reference; the
|
||||
following class does this:
|
||||
|
||||
@smallexample
|
||||
|
||||
@@interface WeakPointer : Object
|
||||
@{
|
||||
const void* weakPointer;
|
||||
@}
|
||||
|
||||
- initWithPointer:(const void*)p;
|
||||
- (const void*)weakPointer;
|
||||
@@end
|
||||
|
||||
|
||||
@@implementation WeakPointer
|
||||
|
||||
+ (void)initialize
|
||||
@{
|
||||
class_ivar_set_gcinvisible (self, "weakPointer", YES);
|
||||
@}
|
||||
|
||||
- initWithPointer:(const void*)p
|
||||
@{
|
||||
weakPointer = p;
|
||||
return self;
|
||||
@}
|
||||
|
||||
- (const void*)weakPointer
|
||||
@{
|
||||
return weakPointer;
|
||||
@}
|
||||
|
||||
@@end
|
||||
|
||||
@end smallexample
|
||||
|
||||
Weak pointers are supported through a new type character specifier
|
||||
represented by the @samp{!} character. The
|
||||
@code{class_ivar_set_gcinvisible()} function adds or removes this
|
||||
specifier to the string type description of the instance variable named
|
||||
as argument.
|
||||
|
||||
@c =========================================================================
|
||||
@node Constant string objects
|
||||
@section Constant string objects
|
||||
|
||||
GNU Objective-C provides constant string objects that are generated
|
||||
directly by the compiler. You declare a constant string object by
|
||||
prefixing a C constant string with the character @samp{@@}:
|
||||
|
||||
@smallexample
|
||||
id myString = @@"this is a constant string object";
|
||||
@end smallexample
|
||||
|
||||
The constant string objects are by default instances of the
|
||||
@code{NXConstantString} class which is provided by the GNU Objective-C
|
||||
runtime. To get the definition of this class you must include the
|
||||
@file{objc/NXConstStr.h} header file.
|
||||
|
||||
User defined libraries may want to implement their own constant string
|
||||
class. To be able to support them, the GNU Objective-C compiler provides
|
||||
a new command line options @option{-fconstant-string-class=@var{class-name}}.
|
||||
The provided class should adhere to a strict structure, the same
|
||||
as @code{NXConstantString}'s structure:
|
||||
|
||||
@smallexample
|
||||
|
||||
@@interface MyConstantStringClass
|
||||
@{
|
||||
Class isa;
|
||||
char *c_string;
|
||||
unsigned int len;
|
||||
@}
|
||||
@@end
|
||||
|
||||
@end smallexample
|
||||
|
||||
@code{NXConstantString} inherits from @code{Object}; user class
|
||||
libraries may choose to inherit the customized constant string class
|
||||
from a different class than @code{Object}. There is no requirement in
|
||||
the methods the constant string class has to implement, but the final
|
||||
ivar layout of the class must be the compatible with the given
|
||||
structure.
|
||||
|
||||
When the compiler creates the statically allocated constant string
|
||||
object, the @code{c_string} field will be filled by the compiler with
|
||||
the string; the @code{length} field will be filled by the compiler with
|
||||
the string length; the @code{isa} pointer will be filled with
|
||||
@code{NULL} by the compiler, and it will later be fixed up automatically
|
||||
at runtime by the GNU Objective-C runtime library to point to the class
|
||||
which was set by the @option{-fconstant-string-class} option when the
|
||||
object file is loaded (if you wonder how it works behind the scenes, the
|
||||
name of the class to use, and the list of static objects to fixup, are
|
||||
stored by the compiler in the object file in a place where the GNU
|
||||
runtime library will find them at runtime).
|
||||
|
||||
As a result, when a file is compiled with the
|
||||
@option{-fconstant-string-class} option, all the constant string objects
|
||||
will be instances of the class specified as argument to this option. It
|
||||
is possible to have multiple compilation units referring to different
|
||||
constant string classes, neither the compiler nor the linker impose any
|
||||
restrictions in doing this.
|
||||
|
||||
@c =========================================================================
|
||||
@node compatibility_alias
|
||||
@section compatibility_alias
|
||||
|
||||
This is a feature of the Objective-C compiler rather than of the
|
||||
runtime, anyway since it is documented nowhere and its existence was
|
||||
forgotten, we are documenting it here.
|
||||
|
||||
The keyword @code{@@compatibility_alias} allows you to define a class name
|
||||
as equivalent to another class name. For example:
|
||||
|
||||
@smallexample
|
||||
@@compatibility_alias WOApplication GSWApplication;
|
||||
@end smallexample
|
||||
|
||||
tells the compiler that each time it encounters @code{WOApplication} as
|
||||
a class name, it should replace it with @code{GSWApplication} (that is,
|
||||
@code{WOApplication} is just an alias for @code{GSWApplication}).
|
||||
|
||||
There are some constraints on how this can be used---
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item @code{WOApplication} (the alias) must not be an existing class;
|
||||
|
||||
@item @code{GSWApplication} (the real class) must be an existing class.
|
||||
|
||||
@end itemize
|
@ -75,9 +75,6 @@ The Java runtime library.
|
||||
The @code{libmudflap} library, used for instrumenting pointer and array
|
||||
dereferencing operations.
|
||||
|
||||
@item libobjc
|
||||
The Objective-C and Objective-C++ runtime library.
|
||||
|
||||
@item libstdc++-v3
|
||||
The C++ runtime library.
|
||||
|
||||
@ -125,8 +122,7 @@ The @file{gcc} directory contains the following subdirectories:
|
||||
@item @var{language}
|
||||
Subdirectories for various languages. Directories containing a file
|
||||
@file{config-lang.in} are language subdirectories. The contents of
|
||||
the subdirectories @file{cp} (for C++), @file{objc} (for Objective-C)
|
||||
and @file{objcp} (for Objective-C++) are documented in this manual
|
||||
the subdirectory @file{cp} (for C++) is documented in this manual
|
||||
(@pxref{Passes, , Passes and Files of the Compiler}); those for other
|
||||
languages are not. @xref{Front End, , Anatomy of a Language Front End},
|
||||
for details of the files in these directories.
|
||||
@ -449,7 +445,7 @@ A pointer to the GNU Service Directory.
|
||||
@end table
|
||||
|
||||
FIXME: document such files in subdirectories, at least @file{config},
|
||||
@file{cp}, @file{objc}, @file{testsuite}.
|
||||
@file{cp}, @file{testsuite}.
|
||||
|
||||
@node Front End
|
||||
@subsection Anatomy of a Language Front End
|
||||
@ -682,13 +678,11 @@ Java front end depends on the C++ front end, so sets
|
||||
@samp{lang_requires=c++}.
|
||||
@item subdir_requires
|
||||
If defined, this variable lists (space-separated) front end directories
|
||||
other than C that this front end requires to be present. For example,
|
||||
the Objective-C++ front end uses source files from the C++ and
|
||||
Objective-C front ends, so sets @samp{subdir_requires="cp objc"}.
|
||||
other than C that this front end requires to be present.
|
||||
@item target_libs
|
||||
If defined, this variable lists (space-separated) targets in the top
|
||||
level @file{Makefile} to build the runtime libraries for this
|
||||
language, such as @code{target-libobjc}.
|
||||
language.
|
||||
@item lang_dirs
|
||||
If defined, this variable lists (space-separated) top level
|
||||
directories (parallel to @file{gcc}), apart from the runtime libraries,
|
||||
|
@ -156,27 +156,6 @@ information concerning the history of C that is available online, see
|
||||
|
||||
@c FIXME: details of C++ standard.
|
||||
|
||||
@cindex Objective-C
|
||||
@cindex Objective-C++
|
||||
|
||||
There is no formal written standard for Objective-C or Objective-C++@. The most
|
||||
authoritative manual is ``Object-Oriented Programming and the
|
||||
Objective-C Language'', available at a number of web sites:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
@uref{http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/}
|
||||
is a recent (and periodically updated) version;
|
||||
@item
|
||||
@uref{http://www.toodarkpark.org/computers/objc/}
|
||||
is an older example;
|
||||
@item
|
||||
@uref{http://www.gnustep.org}
|
||||
and
|
||||
@uref{http://gcc.gnu.org/readings.html}
|
||||
have additional useful information.
|
||||
@end itemize
|
||||
|
||||
@cindex treelang
|
||||
There is no standard for treelang, which is a sample language front end
|
||||
for GCC@. Its only purpose is as a sample for people wishing to write a
|
||||
|
@ -700,11 +700,11 @@ and possibly @code{unix}; passing @code{_mips} defines @code{__mips},
|
||||
defines only @code{_ABI64}.
|
||||
|
||||
You can also test for the C dialect being compiled. The variable
|
||||
@code{c_language} is set to one of @code{clk_c}, @code{clk_cplusplus}
|
||||
or @code{clk_objective_c}. Note that if we are preprocessing
|
||||
assembler, this variable will be @code{clk_c} but the function-like
|
||||
macro @code{preprocessing_asm_p()} will return true, so you might want
|
||||
to check for that first. If you need to check for strict ANSI, the
|
||||
@code{c_language} is set to one of @code{clk_c} or
|
||||
@code{clk_cplusplus}. Note that if we are preprocessing assembler,
|
||||
this variable will be @code{clk_c} but the function-like macro
|
||||
@code{preprocessing_asm_p()} will return true, so you might want to
|
||||
check for that first. If you need to check for strict ANSI, the
|
||||
variable @code{flag_iso} can be used. The function-like macro
|
||||
@code{preprocessing_trad_p()} can be used to check for traditional
|
||||
preprocessing.
|
||||
@ -781,9 +781,8 @@ Don't use this macro to turn on various extra optimizations for
|
||||
|
||||
@defmac C_COMMON_OVERRIDE_OPTIONS
|
||||
This is similar to @code{OVERRIDE_OPTIONS} but is only used in the C
|
||||
language frontends (C, Objective-C, C++, Objective-C++) and so can be
|
||||
used to alter option flag variables which only exist in those
|
||||
frontends.
|
||||
language frontends (C, C++) and so can be used to alter option flag
|
||||
variables which only exist in those frontends.
|
||||
@end defmac
|
||||
|
||||
@defmac OPTIMIZATION_OPTIONS (@var{level}, @var{size})
|
||||
@ -5029,16 +5028,6 @@ number of existing systems lacks support for these functions in the runtime so
|
||||
they needs this macro to be redefined to 0.
|
||||
@end defmac
|
||||
|
||||
@defmac NEXT_OBJC_RUNTIME
|
||||
Define this macro to generate code for Objective-C message sending using
|
||||
the calling convention of the NeXT system. This calling convention
|
||||
involves passing the object, the selector and the method arguments all
|
||||
at once to the method-lookup library function.
|
||||
|
||||
The default calling convention passes just the object and the selector
|
||||
to the lookup function, which returns a pointer to the method.
|
||||
@end defmac
|
||||
|
||||
@node Addressing Modes
|
||||
@section Addressing Modes
|
||||
@cindex addressing modes
|
||||
@ -7329,47 +7318,6 @@ Define this macro if the target only supports weak aliases; define
|
||||
@code{ASM_OUTPUT_DEF} instead if possible.
|
||||
@end defmac
|
||||
|
||||
@defmac OBJC_GEN_METHOD_LABEL (@var{buf}, @var{is_inst}, @var{class_name}, @var{cat_name}, @var{sel_name})
|
||||
Define this macro to override the default assembler names used for
|
||||
Objective-C methods.
|
||||
|
||||
The default name is a unique method number followed by the name of the
|
||||
class (e.g.@: @samp{_1_Foo}). For methods in categories, the name of
|
||||
the category is also included in the assembler name (e.g.@:
|
||||
@samp{_1_Foo_Bar}).
|
||||
|
||||
These names are safe on most systems, but make debugging difficult since
|
||||
the method's selector is not present in the name. Therefore, particular
|
||||
systems define other ways of computing names.
|
||||
|
||||
@var{buf} is an expression of type @code{char *} which gives you a
|
||||
buffer in which to store the name; its length is as long as
|
||||
@var{class_name}, @var{cat_name} and @var{sel_name} put together, plus
|
||||
50 characters extra.
|
||||
|
||||
The argument @var{is_inst} specifies whether the method is an instance
|
||||
method or a class method; @var{class_name} is the name of the class;
|
||||
@var{cat_name} is the name of the category (or @code{NULL} if the method is not
|
||||
in a category); and @var{sel_name} is the name of the selector.
|
||||
|
||||
On systems where the assembler can handle quoted names, you can use this
|
||||
macro to provide more human-readable names.
|
||||
@end defmac
|
||||
|
||||
@defmac ASM_DECLARE_CLASS_REFERENCE (@var{stream}, @var{name})
|
||||
A C statement (sans semicolon) to output to the stdio stream
|
||||
@var{stream} commands to declare that the label @var{name} is an
|
||||
Objective-C class reference. This is only needed for targets whose
|
||||
linkers have special support for NeXT-style runtimes.
|
||||
@end defmac
|
||||
|
||||
@defmac ASM_DECLARE_UNRESOLVED_REFERENCE (@var{stream}, @var{name})
|
||||
A C statement (sans semicolon) to output to the stdio stream
|
||||
@var{stream} commands to declare that the label @var{name} is an
|
||||
unresolved Objective-C class reference. This is only needed for targets
|
||||
whose linkers have special support for NeXT-style runtimes.
|
||||
@end defmac
|
||||
|
||||
@node Initialization
|
||||
@subsection How Initialization Functions Are Handled
|
||||
@cindex initialization routines
|
||||
@ -9969,8 +9917,3 @@ This macro determines whether to use the JCR section to register Java
|
||||
classes. By default, TARGET_USE_JCR_SECTION is defined to 1 if both
|
||||
SUPPORTS_WEAK and TARGET_HAVE_NAMED_SECTIONS are true, else 0.
|
||||
@end defmac
|
||||
|
||||
@defmac OBJC_JBLEN
|
||||
This macro determines the size of the objective C jump buffer for the
|
||||
NeXT runtime. By default, OBJC_JBLEN is defined to an innocuous value.
|
||||
@end defmac
|
||||
|
@ -1,957 +0,0 @@
|
||||
2007-07-19 Release Manager
|
||||
|
||||
* GCC 4.2.1 released.
|
||||
|
||||
2007-05-13 Release Manager
|
||||
|
||||
* GCC 4.2.0 released.
|
||||
|
||||
2007-01-23 Andrew Pinski <pinskia@gmail.com>
|
||||
|
||||
PR objc/27438
|
||||
* objc-act.c (objc_add_static_instance): Mark the decl as
|
||||
TREE_USED.
|
||||
|
||||
2007-01-20 Andrew Pinski <pinskia@gmail.com>
|
||||
|
||||
PR objc/30479
|
||||
* objc-act.c (hash_interface): Use IDENTIFIER_HASH_VALUE instead
|
||||
of htab_hash_pointer.
|
||||
(lookup_interface): Likewise.
|
||||
(add_class): Likewise.
|
||||
|
||||
2006-10-10 Brooks Moses <bmoses@stanford.edu>
|
||||
|
||||
* Make-lang.in: Added empty "objc.pdf" target.
|
||||
|
||||
2006-09-26 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR objc/29195
|
||||
* objc-act.c (objc_push_parm): If we change the type of the
|
||||
decl, relayout the decl.
|
||||
|
||||
2006-09-19 Eric Christopher <echristo@apple.com>
|
||||
|
||||
* objc-act.c (JBLEN): Rename to OBJC_JBLEN,
|
||||
default to something innocuous.
|
||||
(build_next_objc_exception_stuff): Rename JBLEN.
|
||||
|
||||
2006-07-28 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
* Make-lang.in: Use $(HEADER_H) instead of header.h in dependencies.
|
||||
|
||||
2006-07-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
PR obj-c++/28434
|
||||
* objc-act.c (lookup_and_install_protocols): Skip error_mark_nodes.
|
||||
|
||||
2006-06-06 Mike Stump <mrs@apple.com>
|
||||
|
||||
* objc-act.c: Remove prototype for objc_build_volatilized_type.
|
||||
|
||||
2006-05-24 Mike Stump <mrs@apple.com>
|
||||
|
||||
* objc-act.c (build_next_objc_exception_stuff): Use JBLEN instead of _JBLEN.
|
||||
|
||||
2006-05-05 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
PR objc/27240
|
||||
* objc-act.c (objc_is_public): Return early on invalid type.
|
||||
|
||||
2006-03-02 Fariborz Jahanian <fjahanian@apple.com>
|
||||
|
||||
* objc-act.c (init_module_descriptor): Remove file name from
|
||||
module descriptor.
|
||||
(gen_type_name_0): Fix ICE when issuing warning.
|
||||
|
||||
2006-02-20 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||
* Make-lang.in (OBJC): Remove
|
||||
(OBJECTIVE-C): Remove
|
||||
(objective-c): Remove
|
||||
(.PHONY): Remove objective-c and ObjC
|
||||
|
||||
2005-12-14 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR objc/25360
|
||||
* objc/objc-act.c (encode_type): Encode Complex types as 'j' followed
|
||||
by the inner type.
|
||||
|
||||
2005-12-12 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR objc/25348
|
||||
* objc-act.c (encode_array): Handle arrays to zero sized types.
|
||||
|
||||
2005-12-07 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||
|
||||
* Make-lang.in (objc.all.build, objc.install-normal): Remove.
|
||||
|
||||
2005-12-07 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||
|
||||
* Make-lang.in: Remove all dependencies on s-gtype.
|
||||
|
||||
2005-12-02 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* objc-act.c (objc_build_exc_ptr, next_sjlj_build_enter_and_setjmp
|
||||
next_sjlj_build_exc_extract, next_sjlj_build_catch_list,
|
||||
next_sjlj_build_try_catch_finally, objc_begin_catch_clause,
|
||||
build_objc_method_call, objc_rewrite_function_call): Use buildN
|
||||
instead of build.
|
||||
|
||||
2005-10-20 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* objc-act.c (synth_module_prologue): Clear TREE_NOTHROW
|
||||
on objc_msgSend and like builtin functions.
|
||||
|
||||
2005-10-17 Andreas Krebbel <krebbel1@de.ibm.com>
|
||||
|
||||
* objc-act.c (objc_build_component_ref): Adjust call to
|
||||
finish_class_member_access_expr due to a changed prototype.
|
||||
|
||||
2005-08-31 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR objc/23306
|
||||
* objc-act.c (generate_strings): Remove and move code to
|
||||
finish decl to ...
|
||||
(add_objc_string): here when creating a new string decl.
|
||||
(finish_objc): Don't call generate_strings.
|
||||
|
||||
2005-08-31 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR objc/23381
|
||||
* objc-act.c (next_sjlj_build_try_catch_finally): Set
|
||||
TREE_SIDE_EFFECTS on catch_seq after building it.
|
||||
|
||||
2005-08-09 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
part of PR objc/21992
|
||||
* objc-act.c (handle_class_ref): The ref decl is always referenced.
|
||||
|
||||
2005-07-20 Giovanni Bajo <giovannibajo@libero.it>
|
||||
|
||||
Make CONSTRUCTOR use VEC to store initializers.
|
||||
* objc-act.c (objc_build_constructor): Use build_constructor_from_list
|
||||
instead of build_constructor.
|
||||
|
||||
2005-07-08 Daniel Berlin <dberlin@dberlin.org>
|
||||
|
||||
* objc-act.c (objc_push_parm): DECL_ARG_TYPE_AS_WRITTEN is
|
||||
removed.
|
||||
* objc-act.h (KEYWORD_ARG_NAME): Use decl_non_common.
|
||||
(KEYWORD_KEY_NAME): Use decl_minimal.
|
||||
(METHOD_SEL_NAME): Ditto..
|
||||
(METHOD_SEL_ARGS): Use decl_non_common.
|
||||
(METHOD_ADD_ARGS): Ditto.
|
||||
(METHOD_ADD_ARGS_ELLIPSIS_P): Use decl_common.
|
||||
(METHOD_DEFINITION): Ditto.
|
||||
(METHOD_ENCODING): Ditto.
|
||||
* objc-lang.c: (objc_init_ts): New function.
|
||||
|
||||
2005-07-07 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (objc_build_struct): Pass in an actual @interface
|
||||
instead of its name, and annotate the struct created (and all
|
||||
existing variants thereof) with the @interface.
|
||||
(objc_compare_types): Treat forward-declared ObjC classes
|
||||
as stand-alone (root) classes for purposes of type comparisons.
|
||||
(build_private_template): Move some code to objc_build_struct().
|
||||
|
||||
2005-07-07 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
PR objc/22274
|
||||
* objc-act.c (objc_build_string_object): For GNU-style constants,
|
||||
use the @interface type rather than the built-in type.
|
||||
|
||||
2005-07-03 Kazu Hirata <kazu@codesourcery.com>
|
||||
|
||||
* Make-lang.in (cc1plus-checksum.c): Use
|
||||
build/genchecksum$(build_exeext), not build/genchecksum$(exeext).
|
||||
|
||||
2005-07-02 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
* objc-act.c: Use %q to quote in diagnostics.
|
||||
|
||||
2005-07-02 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
* objc-act.c: Use '+' flag instead of %J. Use 'q' flag for
|
||||
quoting.
|
||||
|
||||
2005-06-30 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (objc_build_volatilized_type): New function.
|
||||
(objc_volatilize_decl): Call objc_build_volatilized_type()
|
||||
instead of build_qualified_type().
|
||||
|
||||
2005-06-29 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (objc_build_internal_const_str_type): New function.
|
||||
(check_string_class_template): Use objc_get_class_ivars() instead
|
||||
of TYPE_FIELDS() to retrieve ivar list.
|
||||
(AT_LEAST_AS_LARGE_AS): Check the size of each field's type rather
|
||||
than the field itself.
|
||||
(objc_build_string_object): Synthesize a "__builtin_ObjCString"
|
||||
type and use it to lay out compile-time string objects.
|
||||
* objc-act.h (OCTI_INTERNAL_CNST_STR_TYPE, internal_const_str_type):
|
||||
New.
|
||||
|
||||
2005-06-28 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* objc-act.c (objc_init_exceptions): Call
|
||||
default_init_unwind_resume_libfunc.
|
||||
|
||||
2005-06-27 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (objc_build_struct): Save the TYPE_OBJC_INFO
|
||||
portion of TYPE_LANG_SPECIFIC info for all variants of
|
||||
a class before calling finish_struct(), and restore
|
||||
same TYPE_OBJC_INFO afterwards.
|
||||
|
||||
2005-06-25 Kelley Cook <kcook@gcc.gnu.org>
|
||||
|
||||
* all files: Update FSF address in copyright headers.
|
||||
|
||||
2005-06-15 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
* objc-act.c (my_build_string_pointer): New.
|
||||
(objc_get_class_reference, get_super_receiver): Call
|
||||
my_build_string_pointer instead of my_build_string when building
|
||||
function arguments.
|
||||
|
||||
2005-05-25 Mike Stump <mrs@mrs.kithrup.com>
|
||||
|
||||
* objc-act.c (volatilized_hash): Avoid warnings on 64-bit
|
||||
machines.
|
||||
|
||||
2005-05-24 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (objc_build_struct): New function.
|
||||
(objc_derived_from_p): Likewise.
|
||||
(objc_build_component_ref): Likewise.
|
||||
(objc_copy_binfo): Likewise.
|
||||
(objc_xref_basetypes): Likewise.
|
||||
(objc_lookup_protocol): Likewise.
|
||||
(objc_compare_protocols): Likewise.
|
||||
(objc_volatilize_decl): Likewise.
|
||||
(encode_aggregate_fields): Likewise.
|
||||
(volatilized_hash): Likewise.
|
||||
(volatilized_eq): Likewise.
|
||||
(objc_compare_types): Likewise.
|
||||
(objc_type_quals_match): Likewise.
|
||||
(DERIVED_FROM_P): New ObjC macro, corresponding to C++ macro
|
||||
of same name.
|
||||
(get_class_ivars): Add second parameter indicating if entire
|
||||
hierarchy is desired.
|
||||
(struct volatilized_type): New type.
|
||||
(volatilized_htab): New hash table.
|
||||
(objc_types_compatible_p, objc_comptypes): Remove functions.
|
||||
(synth_module_prologue): Do not initialize 'unused_list'.
|
||||
(objc_get_class_reference): Fix ObjC++ impedance mismatches.
|
||||
(objc_declare_alias): Implement as a typedef.
|
||||
(objc_substitute_decl, objc_gimplify_expr): Reformat.
|
||||
(objc_get_class_ivars): Adjust call to get_class_ivars().
|
||||
(next_sjlj_build_enter_and_setjmp, synth_forward_declarations,
|
||||
build_ivar_reference, get_super_receiver): Call
|
||||
objc_build_component_ref() instead of build_component_ref().
|
||||
(objc_begin_catch_clause): Use DERIVED_FROM_P() instead of
|
||||
objc_comptypes().
|
||||
(build_private_template): Call objc_build_struct() instead of
|
||||
start_struct() and finish_struct().
|
||||
(hash_init): Initialize volatilized_htab.
|
||||
(objc_is_public): Adjust calls to objc_get_ivars(); adjust
|
||||
ObjC++ impedance mismatches.
|
||||
(encode_aggregate_within): Streamline by calling
|
||||
encode_aggregate_fields().
|
||||
* objc-act.h (objc_types_compatible_p): Remove prototype.
|
||||
(OCTI_UNUSED_LIST, unused_list): Remove slot.
|
||||
* objc-lang.c (LANG_HOOKS_TYPES_COMPATIBLE_P): Remove.
|
||||
|
||||
2005-05-18 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* Make-lang.in (cc1obj-dummy): New.
|
||||
(cc1obj-checksum.c): New.
|
||||
(cc1obj-checksum.o): New.
|
||||
(cc1obj): Add cc1obj-checksum.o.
|
||||
|
||||
2005-05-18 Mike Stump <mrs@apple.com>
|
||||
|
||||
PR objc/21641
|
||||
* objc-act.c (struct interface_tuple): Mark it up for GC.
|
||||
(interface_htab): It is really a struct interface_tuple.
|
||||
|
||||
2005-05-17 Ziemowit Laski <zlaski@apple.com>
|
||||
Mike Stump <mrs@apple.com>
|
||||
|
||||
Yet more Objective-C++...
|
||||
|
||||
* objc-act.c (objc_finish_try_stmt): Add return value.
|
||||
(objc_build_synchronized): Likewise.
|
||||
|
||||
* objc-act.c (objc_is_gcable_type): Add.
|
||||
(objc_substitute_decl): Add.
|
||||
(objc_build_ivar_assignment): Add.
|
||||
(objc_build_global_assignment): Add.
|
||||
(objc_build_strong_cast_assignment): Add.
|
||||
(objc_is_ivar_reference_p): Add.
|
||||
(objc_is_global_reference_p): Add.
|
||||
(objc_generate_write_barrier): Add.
|
||||
(objc_rewrite_function_call): Add.
|
||||
(objc_gimplify_expr): Add Objective-C++ support.
|
||||
* objc-act.h (ALLOC_OBJC_TYPE_LANG_SPECIFIC): Likewise.
|
||||
(SIZEOF_OBJC_TYPE_LANG_SPECIFIC): Add.
|
||||
(INIT_TYPE_OBJC_INFO): Add Objective-C++ support.
|
||||
(DUP_TYPE_OBJC_INFO): Likewise.
|
||||
(struct imp_entry): Add field has_cxx_cdtors.
|
||||
(struct imp_entry *imp_list): Add OCTI_UMSG_FAST_DECL,
|
||||
OCTI_METH_LIST_TEMPL, OCTI_METH_PROTO_LIST_TEMPL,
|
||||
OCTI_IVAR_LIST_TEMPL, OCTI_ASSIGN_IVAR_DECL,
|
||||
OCTI_ASSIGN_IVAR_FAST_DECL, OCTI_ASSIGN_GLOBAL_DECL,
|
||||
OCTI_ASSIGN_STRONGCAST_DECL.
|
||||
(umsg_fast_decl): Add.
|
||||
(objc_assign_ivar_decl): Add.
|
||||
(objc_assign_ivar_fast_decl): Add.
|
||||
(objc_assign_global_decl): Add.
|
||||
(objc_assign_strong_cast_decl): Add.
|
||||
(objc_method_list_ptr): Add.
|
||||
(objc_method_proto_list_ptr): Add.
|
||||
(objc_ivar_list_ptr): Add.
|
||||
|
||||
* objc-act.c (should_call_super_dealloc): Add.
|
||||
(OBJC_VERSION): Bump to 6.
|
||||
(objc_is_gcable_type): Add.
|
||||
(objc_substitute_decl): Add.
|
||||
(objc_build_ivar_assignment): Add.
|
||||
(objc_build_global_assignment): Add.
|
||||
(objc_build_strong_cast_assignment): Add.
|
||||
(objc_is_gcable_p): Add.
|
||||
(objc_is_ivar_reference_p): Add.
|
||||
(objc_is_global_reference_p): Add.
|
||||
(generate_shared_structures): Add flags parameter.
|
||||
(objc_generate_cxx_ctor_or_dtor): Add.
|
||||
(objc_generate_cxx_cdtors): Add.
|
||||
(add_class): Add name parameter.
|
||||
(objc_types_share_size_and_alignment): Add.
|
||||
(comp_proto_with_proto): Add strict parameter.
|
||||
(CLS_HAS_CXX_STRUCTORS): Add.
|
||||
(TAG_ASSIGNIVAR): Add.
|
||||
(TAG_ASSIGNGLOBAL): Add.
|
||||
(TAG_ASSIGNSTRONGCAST): Add.
|
||||
(TAG_MSGSEND_FAST): Add.
|
||||
(TAG_ASSIGNIVAR_FAST): Add.
|
||||
(TAG_CXX_CONSTRUCT): Add.
|
||||
(TAG_CXX_DESTRUCT): Add.
|
||||
(OBJC_LOOKUP_CLASS): Add.
|
||||
(OBJC_LOOKUP_NO_SUPER): Add.
|
||||
(objc_finish_file): Add pch support.
|
||||
(objc_finish_implementation): Add Objective-C++ support.
|
||||
(synth_module_prologue): Likewise.
|
||||
(synth_module_prologue): Add fast dispatching.
|
||||
(objc_get_class_reference): Add Objective-C++ support.
|
||||
(objc_generate_write_barrier): Likewise.
|
||||
(next_sjlj_build_enter_and_setjmp): Likewise.
|
||||
(objc_begin_try_stmt): Likewise.
|
||||
(build_next_objc_exception_stuff): Add fast ivar support.
|
||||
(build_private_template): Mark the record as used so debug
|
||||
information is generated.
|
||||
(build_protocol_template): Add Objective-C++ support.
|
||||
(objc_method_parm_type) Likewise.
|
||||
(objc_generate_cxx_ctor_or_dtor): Likewise.
|
||||
(objc_generate_cxx_cdtors): Likewise.
|
||||
(build_protocol_initializer): Likewise.
|
||||
(build_category_template): Likewise.
|
||||
(build_class_template): Likewise.
|
||||
(build_method_list_template): Likewise.
|
||||
(build_category_initializer): Likewise.
|
||||
(build_shared_structure_initializer): Likewise.
|
||||
(objc_finish_message_expr): Likewise.
|
||||
(build_objc_method_call): Add fast dispatch support.
|
||||
(lookup_method_static): Add support to end search at superclasses.
|
||||
(add_method_to_hash_list): Add strict parameter to
|
||||
comp_proto_with_proto.
|
||||
(objc_add_method): Likewise.
|
||||
(objc_add_method): Also set the interface_value.
|
||||
(add_instance_variable): Add Objective-C++ support.
|
||||
(objc_is_public): Likewise.
|
||||
(start_class): Likewise.
|
||||
(continue_class): Likewise.
|
||||
(encode_aggregate_within): Likewise.
|
||||
(start_method_def): Likewise.
|
||||
(objc_start_function): Clear current_function_returns_value
|
||||
and current_function_returns_null.
|
||||
(really_start_method): Add Objective-C++ support.
|
||||
(objc_finish_method_definition): Add warning for missing
|
||||
[super dealloc].
|
||||
(finish_objc): Add Objective-C++ support.
|
||||
(generate_objc_image_info): Likewise.
|
||||
(objc_lookup_ivar): Likewise.
|
||||
* objc-act.h (TYPE_HAS_OBJC_INFO): Likewise.
|
||||
(INIT_TYPE_OBJC_INFO): Likewise.
|
||||
(DUP_TYPE_OBJC_INFO): Likewise.
|
||||
|
||||
2005-04-23 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* objc-act.c: Adjust warning() callers.
|
||||
|
||||
2005-04-21 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* objc-act.h (METHOD_ADD_ARGS_ELLIPSIS_P): New macro for accessing
|
||||
this field of an objc method decl.
|
||||
* objc-act.c (build_method_decl): Take an additional "ellipsis"
|
||||
argument, and set METHOD_ADD_ARGS_ELLIPSIS_P as appropriate.
|
||||
(objc_build_method_signature): Accept additional "ellipsis"
|
||||
argument and pass it to build_method_decl.
|
||||
(get_arg_type_list, start_method_def, gen_method_decl): Use
|
||||
the new METHOD_ADD_ARGS_ELLIPSIS_P instead of examining the
|
||||
TREE_OVERFLOW field of a TREE_LIST node.
|
||||
|
||||
2005-04-20 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/12913
|
||||
* objc-act.c (objc_start_function): Create stack level for context
|
||||
of identifiers with variably modified type.
|
||||
|
||||
2005-03-30 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/772
|
||||
PR c/17913
|
||||
* objc-act.c (objc_start_function): Push context on
|
||||
label_context_stack.
|
||||
|
||||
2005-03-23 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
* objc-act.c (next_sjlj_build_enter_and_setjmp,
|
||||
next_sjlj_build_catch_list, next_sjlj_build_try_catch_finally):
|
||||
Call c_common_truthvalue_conversion.
|
||||
|
||||
2005-02-25 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
* Make-lang.in (objc/objc-parse.o-warn, objc/objc-parse.o,
|
||||
objc/objc-parse.c, objc/objc-parse.y): Remove
|
||||
(OBJC_OBJS, objc.srcextra, objc.tags, objc.mostlyclean,
|
||||
objc.distclean, objc.maintainer-clean): Update for new parser.
|
||||
* config-lang.in (gtfiles): Update for new parser.
|
||||
|
||||
2005-01-29 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* lang-specs.h, objc-act.c, objc-act.h, objc-lang.c: Update
|
||||
copyright.
|
||||
|
||||
2005-01-27 Matt Austern <austern@apple.com>
|
||||
|
||||
* objc-act.c (objc_finish_file): In ObjC++ mode, set at_eof before
|
||||
calling instantiate_pending_templates.
|
||||
|
||||
2005-01-26 Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
PR objc/18862
|
||||
* objc-act.c (build_selector_translation_table): Use
|
||||
input_location in the diagnostic for the GNU runtime or if
|
||||
TREE_PURPOSE (chain) is NULL.
|
||||
|
||||
2005-01-25 Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
PR objc/18408
|
||||
* objc-act.c (objc_types_compatible_p): New function.
|
||||
* objc-act.h (objc_types_compatible_p): Declare.
|
||||
* objc-lang.c (LANG_HOOKS_TYPES_COMPATIBLE_P): Define.
|
||||
|
||||
2005-01-16 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (objc_push_parm): Call c_type_promotes_to()
|
||||
via a lang-hook.
|
||||
|
||||
2005-01-15 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
PR objc/19321
|
||||
* objc-act.c (get_arg_type_list): Decay function arguments into
|
||||
pointers.
|
||||
(objc_push_parm): Likewise; bring PARM_DECL construction closer
|
||||
in line with what the C front-end does.
|
||||
(objc_get_parm_info): Call pushdecl() and finish_decl() on
|
||||
each PARM_DECL, like the C front-end does.
|
||||
(start_method_def): Remove redundant ARRAY_TYPE decay.
|
||||
(objc_start_function): Bring closer in line with what the
|
||||
C front-end does for functions.
|
||||
|
||||
2005-01-14 Mike Stump <mrs@apple.com>
|
||||
|
||||
* lang-specs.h ("@objective-c"): Use cc1obj when -E is used so
|
||||
that -fobjc-exceptions is accepted.
|
||||
|
||||
2004-12-30 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
PR objc/18971
|
||||
* objc-act.c (get_arg_type_list, start_method_def): Decay
|
||||
array arguments into pointers.
|
||||
(gen_type_name_0): Learn to pretty-print array types.
|
||||
|
||||
2004-12-15 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (build_private_template): Change to return 'void'; do
|
||||
not set ivar_context, uprivate_record or objc_instance_type.
|
||||
(objc_comptypes, gen_type_name_0): For types 'id' and 'Class',
|
||||
retrieve protocol list from the pointee rather than the pointer itself;
|
||||
check TYPE_HAS_OBJC_INFO(...) precondition before accessing
|
||||
TYPE_OBJC_PROTOCOL_LIST.
|
||||
(objc_get_protocol_qualified_type): For types 'id' and 'Class',
|
||||
construct a variant of the pointee as well as the pointer, and
|
||||
store protocol information in the former. When creating variants
|
||||
of RECORD_TYPEs, clone their TYPE_LANG_SPECIFIC fields and propagate
|
||||
TYPE_OBJC_INTERFACE information.
|
||||
(objc_declare_class): If a TYPE_DECL is looked up, retrieve the
|
||||
underlying RECORD_TYPE to check for presence of TYPE_OBJC_INTERFACE;
|
||||
for newly-created RECORD_TYPEs, create a tentative TYPE_OBJC_INTERFACE
|
||||
holding an IDENTIFIER_NODE.
|
||||
(objc_finish_message_expr): Check TYPE_HAS_OBJC_INFO(...) before
|
||||
accessing TYPE_OBJC_PROTOCOL_LIST; Use TYPE_OBJC_INTERFACE instead
|
||||
of calling lookup_interface(); allow for TYPE_OBJC_INTERFACE holding
|
||||
an IDENTIFIER_NODE (meaning a @class forward-declaration only).
|
||||
(objc_is_public): Check TYPE_OBJC_INTERFACE instead of calling
|
||||
lookup_interface().
|
||||
(continue_class): For @implementations, set ivar_context,
|
||||
uprivate_record and objc_instance_type, for @interfaces, call
|
||||
build_private_template().
|
||||
(encode_pointer): Check TYPE_HAS_OBJC_INFO(...) before accessing
|
||||
TYPE_OBJC_INTERFACE.
|
||||
(objc_types_are_equivalent): Check TYPE_HAS_OBJC_INFO(...) before
|
||||
accessing TYPE_OBJC_PROTOCOL_LIST.
|
||||
* objc-act.h (OBJC_INFO_SLOT_ELTS, TYPE_OBJC_INFO, INIT_TYPE_OBJC_INFO,
|
||||
DUP_TYPE_OBJC_INFO, ALLOC_OBJC_TYPE_LANG_SPECIFIC,
|
||||
SIZEOF_OBJC_TYPE_LANG_SPECIFIC): New macros.
|
||||
(TYPE_OBJC_INTERFACE): Replaces TREE_STATIC_INSTANCE and now points
|
||||
to an actual @interface; stored in TYPE_LANG_SPECIFIC(...).
|
||||
(TYPE_OBJC_PROTOCOL_LIST): Replaces TYPE_PROTOCOL_LIST; stored in
|
||||
TYPE_LANG_SPECIFIC(...).
|
||||
(TREE_STATIC_INSTANCE, TYPE_PROTOCOL_LIST): Delete.
|
||||
(IS_ID, IS_CLASS, IS_PROTOCOL_QUALIFIED_UNTYPED, IS_SUPER,
|
||||
TYPED_OBJECT): Check for POINTER_TYPE rather than POINTER_TYPE_P;
|
||||
adjust for use of TYPE_OBJC_INTERFACE and TYPE_OBJC_PROTOCOL_LIST
|
||||
instead of TREE_STATIC_INSTANCE and TYPE_PROTOCOL_LIST.
|
||||
|
||||
2004-11-29 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/7544
|
||||
* Make-lang.in (objc/objc-act.o): Update dependencies.
|
||||
* objc-act.c (objc_finish_file): Call
|
||||
maybe_apply_pending_pragma_weaks if not OBJCPLUS.
|
||||
|
||||
2004-11-09 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR objc/18406
|
||||
* obj-act.c (encode_type): 96bits doubles are encoded the
|
||||
same way as 64bit and 128bit doubles are.
|
||||
|
||||
2004-11-09 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
* objc-act.c: Use %q, %< and %> for quoting in diagnostics.
|
||||
|
||||
2004-11-08 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR objc/16546
|
||||
* objc-act.c (generate_method_descriptors): Remove setting
|
||||
the new decls' type to variable_length_type.
|
||||
(generate_ivar_lists): Likewise.
|
||||
(generate_dispatch_tables): Likewise.
|
||||
|
||||
2004-10-30 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (objc_lookup_ivar): The new OTHER parameter
|
||||
contains the result of the ID lookup by the C or C++
|
||||
front-end; in class methods, use OTHER if it exists;
|
||||
in instance methods, use OTHER only if it is locally
|
||||
declared.
|
||||
|
||||
2004-10-26 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (finish_class): Do not synthesize bogus
|
||||
'extern objc_object *_Foo;' declarations for @interface Foo.
|
||||
|
||||
2004-10-25 Ziemowit Laski <zlaski@apple.com>
|
||||
David Ayers <d.ayers@inode.at>
|
||||
|
||||
* objc-act.c (objc_comptypes): Use IS_PROTOCOL_QUALIFIED_UNTYPED
|
||||
instead of IS_PROTOCOL_QUALIFIED_ID; add comparisons for:
|
||||
'Class <Protocol> != id <Protocol>'; 'Class <Protocol> != <class> *';
|
||||
'Class <Protocol> == id' and 'Class <Protocol> == Class'.
|
||||
(objc_is_id): Add test for 'super'.
|
||||
(objc_finish_message_expr): Allow for messaging of 'Class <Proto>'
|
||||
receivers; if class methods are not found in protocol lists, search
|
||||
for instance methods therein and warn if one is found. Look in
|
||||
global hash tables for suitable method as a last resort when messaging
|
||||
'id <Proto>', 'Class <Proto>' and invalid receiver types.
|
||||
(objc_add_method): Insert instance methods listed in protocols into
|
||||
the global class method hash table.
|
||||
* objc-act.h (IS_PROTOCOL_QUALIFIED_ID): Rename to
|
||||
IS_PROTOCOL_QUALIFIED_UNTYPED and allow for 'Class <Proto>' in
|
||||
addition to 'id <Proto>'.
|
||||
|
||||
2004-10-21 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR objc/17923
|
||||
* objc-act.c (objc_build_string_object): Create a CONST_DECL
|
||||
for the NeXT runtime case.
|
||||
|
||||
2004-10-02 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* objc-act.c: Fix comment typos.
|
||||
|
||||
2004-09-24 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (init_objc_symtab, init_module_descriptor,
|
||||
build_shared_structure_initializer): When initializing 'long'
|
||||
fields, ensure that the initializer value is also 'long'.
|
||||
|
||||
2004-09-24 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
* objc-act.c: Change annotate_with_locus to SET_EXPR_LOCATION
|
||||
throughout.
|
||||
(objc_init): Only set input_line to 0 #ifndef USE_MAPPED_LOCATION.
|
||||
(build_selector_translation_table): Use %J in diagnostic
|
||||
instead of diddling input_line. Fix spelling.
|
||||
|
||||
2004-09-21 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (objc_fold_objc_type_ref): New function.
|
||||
* objc-act.h (objc_fold_objc_type_ref): New prototype.
|
||||
|
||||
2004-09-09 Joseph S. Myers <jsm@polyomino.org.uk>
|
||||
|
||||
* objc-act.c (objc_start_function, really_start_method,
|
||||
objc_get_parm_info, start_method_def): Update to new arg_info
|
||||
structures.
|
||||
|
||||
2004-09-07 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* Make-lang.in (objc/objc-parse.o): Depend on $(C_COMMON_H) instead of
|
||||
objc/objc-act.h.
|
||||
(objc/objc-act.o): Depend on $(HASHTAB_H).
|
||||
* objc-act.c: Include hashtab.h; in ObjC++ mode, include cp-tree.h and
|
||||
objcp-decl.h instead of c-tree.h.
|
||||
(build_module_descriptor, get_class_ivars, synth_id_with_class_suffix,
|
||||
error_with_ivar, gen_method_decl, gen_declaration, setup_string_decl,
|
||||
build_protocol_template): Adjust prototypes.
|
||||
(build_module_initializer_routine, start_class, continue_class,
|
||||
finish_class, start_method_def, objc_start_function, start_protocol,
|
||||
build_method_decl, objc_add_method, add_instance_variable,
|
||||
build_ivar_reference, is_ivar, is_private, get_super_receiver,
|
||||
build_selector_table_decl, objc_push_parm, objc_get_parm_info,
|
||||
gen_type_name, gen_type_name_0, start_var_decl, finish_var_decl,
|
||||
create_field_decl): New prototypes.
|
||||
(objc_expand_function_end, comp_method_with_proto, objc_expr_last,
|
||||
gen_declaration_1, gen_declarator, is_complex_decl, adorn_decl,
|
||||
define_decl, create_builtin_decl, gen_declspecs): Remove prototypes.
|
||||
(TYPE_ID): Rename to OBJECT_TYPEDEF_NAME.
|
||||
(CLASS_TYPEDEF_NAME): New.
|
||||
(TAG_EXECCLASS): Change from a global variable to a #define.
|
||||
(TAG_RETURN_STRUCT): Delete.
|
||||
(TAG_GNUINIT): New, holds '__objc_gnu_init' name.
|
||||
(objc_inherit_code, objc_public_flag): New, moved from c-parse.in.
|
||||
(string_descriptor): New struct.
|
||||
(string_htab): New hash table.
|
||||
(string_hash, string_eq): New prototypes.
|
||||
(generate_struct_by_value_array): Call create_field_decl() instead of
|
||||
create_builtin_decl().
|
||||
(objc_init): Do not initialize objc_ellipsis_node or TAG_EXECCLASS;
|
||||
In ObjC++ mode, call cxx_init() instead of c_objc_common_init().
|
||||
(objc_finish_file): In ObjC++, call instantiate_pending_templates()
|
||||
and cp_finish_file().
|
||||
(define_decl, get_static_reference, get_protocol_reference,
|
||||
create_builtin_decl): Remove functions.
|
||||
(objc_start_class_interface, objc_start_category_interface,
|
||||
objc_start_protocol, objc_continue_interface, objc_finish_interface,
|
||||
objc_start_class_implementation, objc_start_category_implementation,
|
||||
objc_continue_implementation, objc_finish_implementation,
|
||||
objc_set_visibility, objc_set_method_type,
|
||||
objc_build_method_signature, objc_add_method_declaration,
|
||||
objc_start_method_definition, objc_add_instance_variable,
|
||||
objc_get_protocol_qualified_type, create_field_decl,
|
||||
start_var_decl, finish_var_decl): New functions.
|
||||
(setup_string_decl): Simplify since it is only called once.
|
||||
(synth_module_prologue): Call build_class_template(); predefine 'id'
|
||||
and 'Class' as typedefs; rename 'temp_type' to 'type'; disable debug
|
||||
hooks for duration of function; fix GNU runtime messenger signatures
|
||||
to correspond to reality; forward-declare '__objc_exec_class' for the
|
||||
GNU runtime; call build_selector_table_decl(); in ObjC++ mode, generate
|
||||
'extern "C" { ... }' wrappers around synthesized declarations; call
|
||||
build_protocol_template() and build_category_template().
|
||||
(string_hash, string_eq): New functions.
|
||||
(objc_build_string_object): Check metaclass correctness only once;
|
||||
store string literals in hash table.
|
||||
(objc_build_constructor): Do not convert initializer elements;
|
||||
adjust for ObjC++ impedance mismatch.
|
||||
(build_objc_symtab_template): Call create_field_decl() instead of
|
||||
create_builtin_decl().
|
||||
(init_objc_symtab): Add missing conversion to initializer element.
|
||||
(build_metadata_decl): Call start_var_decl() instead of define_decl().
|
||||
(generate_objc_symtab_decl): Do not call build_category_template();
|
||||
call start_var_decl() and finish_var_decl() instead of start_decl()
|
||||
and finish_decl().
|
||||
(build_module_descriptor): Call create_field_decl() instead of
|
||||
grokfield(); call start_var_decl() and finish_var_decl() instead of
|
||||
start_decl() and finish_decl(); always mark module descriptor as
|
||||
used; move GNU runtime-specific functionality to
|
||||
build_module_initializer_routine().
|
||||
(build_module_initializer_routine): New function, broken off of
|
||||
build_module_descriptor().
|
||||
(objc_static_init_needed_p, objc_generate_static_init_call): New
|
||||
functions.
|
||||
(generate_static_references, generate_strings,
|
||||
build_selector_translation_table, generate_descriptor_table,
|
||||
generate_ivars_list, generate_dispatch_table, generate_category): Call
|
||||
start_var_decl() and finish_var_decl() instead of start_decl() and
|
||||
finish_decl(); build a type directly instead of via groktypename().
|
||||
(build_selector_reference_decl, build_selector_table_decl,
|
||||
build_class_reference_decl, build_protocol_reference,
|
||||
generate_objc_image_info): Call start_var_decl() instead of
|
||||
build_decl().
|
||||
(build_selector_reference): For GNU runtime, do not call
|
||||
build_selector_reference_decl().
|
||||
(build_selector, build_typed_selector_reference): Always convert
|
||||
result to the selector type.
|
||||
(add_objc_string): Cast return value to 'char *'.
|
||||
(build_method_prototype_template, build_selector_template,
|
||||
build_method_template): Use actual selector type for fields
|
||||
pointing to selectors.
|
||||
(finish_objc): For GNU runtime, call
|
||||
build_module_initializer_routine() after build_module_descriptor().
|
||||
(generate_protocol_list, generate_shared_structures): Call
|
||||
start_var_decl() and finish_var_decl() instead of start_decl() and
|
||||
finish_decl(); build a type directly instead of via
|
||||
groktypename().
|
||||
(synth_id_with_class_suffix): Return a string.
|
||||
(get_arg_type_list): For instance methods, use the instance type for
|
||||
'self'; do not call groktypename_in_parm_context().
|
||||
(build_objc_string_decl): Squash redeclaration errors in ObjC++.
|
||||
(objc_is_class_name): Use OBJC_TYPE_NAME instead of TYPE_NAME;
|
||||
handle RECORD_TYPEs in ObjC as well as ObjC++.
|
||||
(objc_is_id): New function.
|
||||
(objc_is_object_ptr): Return the canonical type node.
|
||||
(objc_get_class_ivars): Simplify using get_class_ivars().
|
||||
(get_class_ivars): Remove second parameter; create a fresh copy
|
||||
of the ivar list for each call; do not check for existence of
|
||||
super class.
|
||||
(objc_eh_runtime_type): Mark #ifndef OBJCPLUS.
|
||||
(objc_init_exceptions): When using SJLJ-style exceptions, require
|
||||
the use of '-fobjc-exceptions' flag; do not require it for DWARF-style
|
||||
exceptions.
|
||||
(objc_build_exc_ptr, next_sjlj_build_try_catch_finally): Use
|
||||
objc_object_type instead of objc_id_type.
|
||||
(objc_begin_catch_clause): Convert the incoming PARM_DECL into
|
||||
a VAR_DECL before placing it in the appropriate scope; do not
|
||||
call define_decl(); adjust call to c_begin_compound_stmt();
|
||||
use objc_object_type instead of objc_id_type.
|
||||
(build_next_objc_exception_stuff): Call create_field_decl() instead
|
||||
of create_builtin_decl(); construct type directly instead of calling
|
||||
groktypename(); use OBJC_VOID_AT_END to mark end of function parameters.
|
||||
(build_private_template): Adjust call to get_class_ivars(); build
|
||||
a type directly instead of via groktypename().
|
||||
(build_protocol_template, build_method_prototype_list_template,
|
||||
build_method_prototype_template, build_category_template,
|
||||
build_selector_template, build_class_template, build_super_template,
|
||||
build_ivar_template, build_ivar_list_template,
|
||||
build_method_list_template, build_method_template):
|
||||
Call create_field_decl() instead of grokfield().
|
||||
(objc_method_parm_type): Do not call groktypename().
|
||||
(generate_descriptor_table): Call start_var_decl() and
|
||||
finish_var_decl() instead of start_decl() and finish_decl().
|
||||
(generate_method_descriptors, build_protocol_initializer,
|
||||
generate_dispatch_tables, build_category_initializer,
|
||||
build_shared_structure_initializer): Do not call groktypename().
|
||||
(generate_protocols): Call start_var_decl() and finish_var_decl()
|
||||
instead of start_decl() and finish_decl(); do not call groktypename().
|
||||
(error_with_ivar): Remove last parameter.
|
||||
(check_ivars): Do not iterate ovar CLASS_RAW_IVARS lists in addition
|
||||
to CLASS_IVARS lists; adjust calls to error_with_ivar().
|
||||
(generate_ivar_lists): Convert one of the initializer elements; do
|
||||
not call groktypename().
|
||||
(get_arg_type_list, start_method_def, gen_method_def): Account for
|
||||
new representation of variable arguments and '...' in Objective-C
|
||||
methods; add Objective-C++ impedance matching code.
|
||||
(is_objc_type_qualifier): Remove function.
|
||||
(adjust_type_for_id_default): Simplify; there is no longer a need to
|
||||
wade through declspecs.
|
||||
(lookup_interface, start_class, continue_class,
|
||||
finish_class, start_method_def, start_protocol, build_method_decl,
|
||||
objc_add_method, add_instance_variable, build_ivar_reference,
|
||||
is_ivar, is_private, get_super_receiver, objc_build_finally_epilogue):
|
||||
Make into static functions.
|
||||
(receiver_is_class_object): Use new IS_CLASS() macro.
|
||||
(objc_build_message_expr): Tweak ObjC++ message argument handling;
|
||||
call objc_finish_message_expr() instead of finish_message_expr().
|
||||
(finish_message_expr): Rename to objc_finish_message_expr(); use
|
||||
OBJC_TYPE_NAME and OBJC_SET_TYPE_NAME macros instead of TYPE_NAME.
|
||||
call gen_type_name() instead of gen_declaration(); call objc_is_id()
|
||||
instead of using IS_ID and IS_CLASS; Use objc_class_name instead of
|
||||
calling get_identifier("Class"); handle CONVERT_EXPRs in receiver.
|
||||
(build_objc_method_call, warn_with_method): Do not call groktypename().
|
||||
(build_ivar_reference): Call convert() instead of clobbering in a
|
||||
type.
|
||||
(hash_init): Initialize string_htab hash table.
|
||||
(add_instance_variable): Simplify parameter list; do not call grokfield();
|
||||
do not populate CLASS_IVARS list.
|
||||
(start_class): Check for the existence of super class, if one was specified.
|
||||
(continue_class): Use CLASS_RAW_IVARS rather than CLASS_IVARS; do not
|
||||
call build_class_template(); adjust call to get_class_ivars(); call
|
||||
build_decl(), pushdecl() and finish_decl() instead of define_decl().
|
||||
(finish_class): Call build_decl(), pushdecl() and finish_decl() instead
|
||||
of define_decl().
|
||||
(add_protocols): Use PROTOCOL_BINFO_ELTS for the tree vector size.
|
||||
(start_protocol): Do not call build_protocol_template(); use
|
||||
PROTOCOL_BINFO_ELTS for the tree vector size.
|
||||
(encode_type_qualifiers): Do not handle the 'const' qualifier here.
|
||||
(encode_pointer): Encode 'const char *' as 'r*', for backwards
|
||||
compatibility.
|
||||
(encode_array): Use HOST_WIDE_INT_PRINT_DEC instead of "%ld".
|
||||
(encode_type): Handle the 'const' qualifier here.
|
||||
(objc_parmlist): New global variable, sued by objc_push_parm and
|
||||
objc_get_parm_info().
|
||||
(objc_push_parm, objc_get_parm_info): New functions.
|
||||
(objc_expr_last): Remove function.
|
||||
(synth_self_and_ucmd_args): For instance methods, use the instance
|
||||
type for 'self'; call objc_push_parm() instead of push_parm_decl().
|
||||
(start_method_def): Do not call push_scope(), declare_parm_level(),
|
||||
pop_scope(), push_parm_decl(), store_parm_decls() or objc_expr_last();
|
||||
just use objc_push_parm() and objc_get_parm_info().
|
||||
(comp_method_with_proto): Remove function.
|
||||
(objc_types_are_equivalent): Strip away indirections before comparing
|
||||
underlying types.
|
||||
(comp_proto_with_proto): Do not call groktypename(); types are no
|
||||
longer in raw declspec format.
|
||||
(objc_start_function): New function.
|
||||
(really_start_method): Call comp_proto_with_proto() instead of
|
||||
comp_method_with_proto(); call objc_start_function() instead of
|
||||
hand-crafting a function declarator.
|
||||
(continue_method_def, objc_expand_function_end): Remove functions.
|
||||
(get_super_receiver): Call objc_get_current_scope() instead of
|
||||
get_current_scope(); reference 'super_class' field (instead of
|
||||
'class').
|
||||
(finish_method_def): Rename to objc_finish_method_definition() and
|
||||
add a function decl parameter; move method encoding call from
|
||||
objc_expand_function_end().
|
||||
(is_complex_decl, adorn_decl, gen_declarator, gen_declspecs,
|
||||
gen_declaration_1): Remove functions.
|
||||
(tmpbuf, RAW_DECLSPEC): Remove.
|
||||
(gen_declaration): Remove second parameter; simplify to deal
|
||||
with TYPE_P nodes instead of raw declspecs.
|
||||
(gen_type_name, gen_type_name_0): New functions.
|
||||
(gen_method_decl): Remove second parameter; call gen_type_name()
|
||||
instead of gen_declaration_1().
|
||||
(dump_interface): Adjust calls to gen_declaration() and
|
||||
gen_method_decl(); do not allocate a separate string buffer.
|
||||
(init_objc): Allocate a larger string buffer to accommodate
|
||||
dump_interface(); adjust call to build_module_descriptor();
|
||||
add call to build_module_initializer_routine() for the GNU
|
||||
runtime.
|
||||
(generate_classref_translation_entry): Do not call start_decl(); call
|
||||
finish_var_decl() instead of finish_decl(); call convert() instead of
|
||||
build_c_cast().
|
||||
* objc-act.h (CLASS_OWN_IVARS): Remove accessor.
|
||||
(CLASS_BINFO_ELTS): Reduce from 6 to 5, now that CLASS_OWN_IVARS is
|
||||
gone.
|
||||
(OCTI_GNU_INIT_DECL, GNU_INIT_decl): New.
|
||||
(OCTI_ELLIPSIS_NODE, objc_ellipsis_node): Remove.
|
||||
(OCTI_ID_ID, id_type, objc_id_id): Rename to OCTI_ID_NAME,
|
||||
objc_object_type and objc_object_name, respectively.
|
||||
(OCTI_CLS_REF, OCTI_CLASS_NAME, objc_class_reference,
|
||||
objc_class_name): New.
|
||||
(IS_CLASS): New macro.
|
||||
(IS_ID, IS_SUPER): Robustify.
|
||||
(OCTI_EXECCLASS_DECL, execclass_decl): New.
|
||||
(finish_file, start_class, continue_class, finish_class,
|
||||
start_method_def, continue_method_def, finish_method_def,
|
||||
start_protocol, finish_protocol, objc_build_throw_stmt,
|
||||
objc_build_try_catch_finally_stmt, objc_build_synchronized_prologue,
|
||||
objc_build_synchronized_epilogue, objc_build_try_prologue,
|
||||
objc_build_try_epilogue, objc_build_catch_stmt, objc_build_catch_epilogue,
|
||||
objc_build_finally_prologue, objc_build_finally_epilogue,
|
||||
is_ivar, is_private, is_public, add_instance_variable, objc_add_method,
|
||||
get_super_receiver, objc_clear_super_receiver, get_class_ivars_from_name,
|
||||
get_class_reference, get_static_reference, get_object_reference,
|
||||
build_message_expr, finish_message_expr, build_selector_expr,
|
||||
build_ivar_reference, build_keyword_decl, build_method_decl,
|
||||
build_protocol_expr, build_objc_string_object, objc_declare_alias,
|
||||
objc_declare_class, objc_declare_protocols, objc_comptypes,
|
||||
objc_check_decl, build_encode_expr): Remove prototypes.
|
||||
(imp_count, cat_count): Make GGC-aware.
|
||||
(OBJC_SET_TYPE_NAME): New macro.
|
||||
|
||||
2004-09-03 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* config-lang.in: Update copyright notice.
|
||||
(lang_requires): Indicate that ObjC requires C to be built first.
|
||||
|
||||
2004-09-01 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (objc_check_decl): Use OBJC_TYPE_NAME macro instead of
|
||||
TYPE_NAME.
|
||||
(build_objc_string_object): Rename to objc_build_string_object().
|
||||
(get_class_reference): Rename to objc_get_class_reference().
|
||||
(get_class_ivars_from_name): Rename to objc_get_class_ivars().
|
||||
(next_sjlj_build_catch_list, get_super_receiver): Call
|
||||
objc_get_class_reference() instead of get_class_reference().
|
||||
(build_keyword_decl): Rename to objc_build_keyword_decl().
|
||||
(build_message_expr): Rename to objc_build_message_expr().
|
||||
(build_protocol_expr): Rename to objc_build_protocol_expr().
|
||||
(build_selector_expr): Rename to objc_build_selector_expr().
|
||||
(build_encode_expr): Rename to objc_build_encode_expr().
|
||||
* objc-act.h (get_class_ivars_from_name): Rename prototype to
|
||||
objc_get_class_ivars().
|
||||
(get_class_reference): Rename prototype to objc_get_class_reference().
|
||||
(build_message_expr): Rename prototype to objc_build_message_expr().
|
||||
(build_selector_expr): Rename prototype to objc_build_selector_expr().
|
||||
(build_keyword_decl): Rename prototype to objc_build_keyword_decl().
|
||||
(build_protocol_expr): Rename prototype to objc_build_prototype_expr().
|
||||
(build_objc_string_object): Rename prototype to
|
||||
objc_build_string_object().
|
||||
|
||||
2004-09-01 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (lookup_interface): Make function 'static' and add a
|
||||
local prototype.
|
||||
(objc_check_decl, get_class_reference, objc_declare_alias,
|
||||
objc_declare_class, objc_is_object_ptr): Call objc_is_class_name()
|
||||
instead of is_class_name().
|
||||
(get_super_receiver, objc_clear_super_receiver): Call
|
||||
objc_get_current_scope() instead of get_current_scope().
|
||||
(is_class_name): Rename to objc_is_class_name.
|
||||
(lookup_objc_ivar): Rename to objc_lookup_ivar.
|
||||
|
||||
2004-08-28 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (objc_is_reserved_word): New function.
|
||||
|
||||
2004-08-15 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* Make-lang.in (objc/objc-lang.o): Depend on $(C_PRETTY_PRINT_H),
|
||||
$(DIAGNOSTIC_H), c-objc-common.h and gtype-objc.h, but not on toplev.h.
|
||||
(objc/objc-parse.o): Do not depend on gtype-objc.h.
|
||||
* objc-act.c: Do not include gtype-objc.h.
|
||||
(finish_file): Rename to objc_finish_file().
|
||||
* objc-act.h (finish_file): Update copyright notice; remove prototype.
|
||||
* objc-lang.c: Update copyright notice; include diagnostic.h,
|
||||
c-objc-common.h, c-pretty-print.h and gtype-objc.h; do not include
|
||||
toplev.h.
|
||||
(finish_file): New hook routine.
|
||||
(LANG_HOOKS_FINISH, LANG_HOOKS_INIT_OPTIONS,
|
||||
LANG_HOOKS_INITIALIZE_DIAGNOSTICS, LANG_HOOKS_HANDLE_OPTION,
|
||||
LANG_HOOKS_MISSING_ARGUMENT, LANG_HOOKS_POST_OPTIONS,
|
||||
LANG_HOOKS_GET_ALIAS_SET, LANG_HOOKS_SAFE_FROM_P,
|
||||
LANG_HOOKS_EXPAND_EXPR, LANG_HOOKS_MARK_ADDRESSABLE,
|
||||
LANG_HOOKS_PARSE_FILE, LANG_HOOKS_TRUTHVALUE_CONVERSION,
|
||||
LANG_HOOKS_FINISH_INCOMPLETE_DECL, LANG_HOOKS_UNSAFE_FOR_REEVAL,
|
||||
LANG_HOOKS_STATICP, LANG_HOOKS_SET_DECL_ASSEMBLER_NAME,
|
||||
LANG_HOOKS_NO_BODY_BLOCKS, LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL,
|
||||
LANG_HOOKS_PRINT_IDENTIFIER, LANG_HOOKS_FUNCTION_ENTER_NESTED,
|
||||
LANG_HOOKS_FUNCTION_LEAVE_NESTED, LANG_HOOKS_DUP_LANG_SPECIFIC_DECL,
|
||||
LANG_HOOKS_DECL_UNINIT, LANG_HOOKS_RTL_EXPAND_STMT,
|
||||
LANG_HOOKS_COMMON_ATTRIBUTE_TABLE, LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE,
|
||||
LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN,
|
||||
LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS,
|
||||
LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P,
|
||||
LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING,
|
||||
LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS,
|
||||
LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN,
|
||||
LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION, LANG_HOOKS_TYPE_FOR_MODE,
|
||||
LANG_HOOKS_TYPE_FOR_SIZE, LANG_HOOKS_SIGNED_TYPE,
|
||||
LANG_HOOKS_UNSIGNED_TYPE, LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE,
|
||||
LANG_HOOKS_INCOMPLETE_TYPE_ERROR, LANG_HOOKS_TYPE_PROMOTES_TO,
|
||||
LANG_HOOKS_REGISTER_BUILTIN_TYPE, LANG_HOOKS_WRITE_GLOBALS):
|
||||
Move to c-objc-common.h.
|
@ -1,142 +0,0 @@
|
||||
# Top level -*- makefile -*- fragment for GNU Objective-C
|
||||
# Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
#This file is part of GCC.
|
||||
|
||||
#GCC 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.
|
||||
|
||||
#GCC 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 GCC; see the file COPYING. If not, write to
|
||||
#the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
#Boston, MA 02110-1301, USA.
|
||||
|
||||
# This file provides the language dependent support in the main Makefile.
|
||||
# Each language makefile fragment must provide the following targets:
|
||||
#
|
||||
# foo.all.cross, foo.start.encap, foo.rest.encap,
|
||||
# foo.install-common, foo.install-man, foo.install-info, foo.dvi, foo.pdf
|
||||
# foo.uninstall,
|
||||
# foo.mostlyclean, foo.clean, foo.distclean,
|
||||
# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4
|
||||
#
|
||||
# where `foo' is the name of the language.
|
||||
#
|
||||
# It should also provide rules for:
|
||||
#
|
||||
# - making any compiler driver (eg: g++)
|
||||
# - the compiler proper (eg: cc1plus)
|
||||
# - define the names for selecting the language in LANGUAGES.
|
||||
|
||||
#
|
||||
# Define the names for selecting Objective-C in LANGUAGES.
|
||||
objc: cc1obj$(exeext)
|
||||
|
||||
# Tell GNU make to ignore these if they exist.
|
||||
.PHONY: objc
|
||||
|
||||
# Use maximal warnings for this front end.
|
||||
objc-warn = $(STRICT_WARN)
|
||||
|
||||
# Language-specific object files for Objective C.
|
||||
OBJC_OBJS = objc/objc-lang.o objc/objc-act.o
|
||||
|
||||
cc1obj-dummy$(exeext): $(OBJC_OBJS) $(C_AND_OBJC_OBJS) dummy-checksum.o $(BACKEND) $(LIBDEPS)
|
||||
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
|
||||
$(OBJC_OBJS) $(C_AND_OBJC_OBJS) dummy-checksum.o \
|
||||
$(BACKEND) $(LIBS)
|
||||
|
||||
cc1obj-checksum.c : cc1obj-dummy$(exeext) build/genchecksum$(build_exeext)
|
||||
build/genchecksum$(build_exeext) cc1obj-dummy$(exeext) > $@
|
||||
|
||||
cc1obj-checksum.o : cc1obj-checksum.c
|
||||
|
||||
cc1obj$(exeext): $(OBJC_OBJS) $(C_AND_OBJC_OBJS) cc1obj-checksum.o $(BACKEND) $(LIBDEPS)
|
||||
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
|
||||
$(OBJC_OBJS) $(C_AND_OBJC_OBJS) cc1obj-checksum.o \
|
||||
$(BACKEND) $(LIBS)
|
||||
|
||||
# Objective C language specific files.
|
||||
|
||||
objc/objc-lang.o : objc/objc-lang.c \
|
||||
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(C_TREE_H) $(DIAGNOSTIC_H) \
|
||||
$(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-objc.h \
|
||||
c-objc-common.h objc/objc-act.h $(TREE_GIMPLE_H)
|
||||
|
||||
objc/objc-act.o : objc/objc-act.c \
|
||||
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) $(TM_P_H) \
|
||||
$(EXPR_H) $(TARGET_H) $(C_TREE_H) $(DIAGNOSTIC_H) toplev.h $(FLAGS_H) \
|
||||
objc/objc-act.h input.h $(FUNCTION_H) output.h debug.h langhooks.h \
|
||||
$(LANGHOOKS_DEF_H) $(HASHTAB_H) $(C_PRAGMA_H) gt-objc-objc-act.h \
|
||||
$(TREE_GIMPLE_H)
|
||||
|
||||
objc.srcextra:
|
||||
|
||||
#
|
||||
# Build hooks:
|
||||
|
||||
objc.all.cross:
|
||||
objc.start.encap:
|
||||
objc.rest.encap:
|
||||
objc.info:
|
||||
objc.install-info:
|
||||
objc.dvi:
|
||||
objc.pdf:
|
||||
objc.html:
|
||||
objc.man:
|
||||
objc.srcinfo:
|
||||
objc.srcman:
|
||||
|
||||
objc.tags: force
|
||||
cd $(srcdir)/objc; etags -o TAGS.sub *.c *.h; \
|
||||
etags --include TAGS.sub --include ../TAGS.sub
|
||||
|
||||
lang_checks += check-objc
|
||||
|
||||
#
|
||||
# Install hooks:
|
||||
# cc1obj is installed elsewhere as part of $(COMPILERS).
|
||||
|
||||
objc.install-common:
|
||||
|
||||
objc.install-man:
|
||||
|
||||
objc.uninstall:
|
||||
#
|
||||
# Clean hooks:
|
||||
# A lot of the ancillary files are deleted by the main makefile.
|
||||
# We just have to delete files specific to us.
|
||||
objc.mostlyclean:
|
||||
-rm -f objc/*$(objext) objc/xforward objc/fflags
|
||||
-rm -f objc/*$(coverageexts)
|
||||
objc.clean: objc.mostlyclean
|
||||
-rm -rf objc-headers
|
||||
objc.distclean:
|
||||
-rm -f objc/Makefile objc/Make-host objc/Make-target
|
||||
-rm -f objc/config.status objc/config.cache
|
||||
objc.maintainer-clean:
|
||||
|
||||
#
|
||||
# Stage hooks:
|
||||
|
||||
objc.stage1: stage1-start
|
||||
-mv objc/*$(objext) stage1/objc
|
||||
objc.stage2: stage2-start
|
||||
-mv objc/*$(objext) stage2/objc
|
||||
objc.stage3: stage3-start
|
||||
-mv objc/*$(objext) stage3/objc
|
||||
objc.stage4: stage4-start
|
||||
-mv objc/*$(objext) stage4/objc
|
||||
objc.stageprofile: stageprofile-start
|
||||
-mv objc/*$(objext) stageprofile/objc
|
||||
objc.stagefeedback: stagefeedback-start
|
||||
-mv objc/*$(objext) stagefeedback/objc
|
@ -1,97 +0,0 @@
|
||||
|
||||
GNU Objective C notes
|
||||
*********************
|
||||
|
||||
This document is to explain what has been done, and a little about how
|
||||
specific features differ from other implementations. The runtime has
|
||||
been completely rewritten in gcc 2.4. The earlier runtime had several
|
||||
severe bugs and was rather incomplete. The compiler has had several
|
||||
new features added as well.
|
||||
|
||||
This is not documentation for Objective C, it is usable to someone
|
||||
who knows Objective C from somewhere else.
|
||||
|
||||
|
||||
Runtime API functions
|
||||
=====================
|
||||
|
||||
The runtime is modeled after the NeXT Objective C runtime. That is,
|
||||
most functions have semantics as it is known from the NeXT. The
|
||||
names, however, have changed. All runtime API functions have names
|
||||
of lowercase letters and underscores as opposed to the
|
||||
`traditional' mixed case names.
|
||||
The runtime api functions are not documented as of now.
|
||||
Someone offered to write it, and did it, but we were not allowed to
|
||||
use it by his university (Very sad story). We have started writing
|
||||
the documentation over again. This will be announced in appropriate
|
||||
places when it becomes available.
|
||||
|
||||
|
||||
Protocols
|
||||
=========
|
||||
|
||||
Protocols are now fully supported. The semantics is exactly as on the
|
||||
NeXT. There is a flag to specify how protocols should be typechecked
|
||||
when adopted to classes. The normal typechecker requires that all
|
||||
methods in a given protocol must be implemented in the class that
|
||||
adopts it -- it is not enough to inherit them. The flag
|
||||
`-Wno-protocol' causes it to allow inherited methods, while
|
||||
`-Wprotocols' is the default which requires them defined.
|
||||
|
||||
|
||||
+initialize
|
||||
===========
|
||||
|
||||
This method, if defined, is called before any other instance or class
|
||||
methods of that particular class. This method is not inherited, and
|
||||
is thus not called as initializer for a subclass that doesn't define
|
||||
it itself. Thus, each +initialize method is called exactly once (or
|
||||
never if no methods of that particular class is never called).
|
||||
Besides this, it is allowed to have several +initialize methods, one
|
||||
for each category. The order in which these (multiple methods) are
|
||||
called is not well defined. I am not completely certain what the
|
||||
semantics of this method is for other implementations, but this is
|
||||
how it works for GNU Objective C.
|
||||
|
||||
|
||||
Passivation/Activation/Typedstreams
|
||||
===================================
|
||||
|
||||
This is supported in the style of NeXT TypedStream's. Consult the
|
||||
headerfile Typedstreams.h for api functions. I (Kresten) have
|
||||
rewritten it in Objective C, but this implementation is not part of
|
||||
2.4, it is available from the GNU Objective C prerelease archive.
|
||||
There is one difference worth noting concerning objects stored with
|
||||
objc_write_object_reference (aka NXWriteObjectReference). When these
|
||||
are read back in, their object is not guaranteed to be available until
|
||||
the `-awake' method is called in the object that requests that object.
|
||||
To objc_read_object you must pass a pointer to an id, which is valid
|
||||
after exit from the function calling it (like e.g. an instance
|
||||
variable). In general, you should not use objects read in until the
|
||||
-awake method is called.
|
||||
|
||||
|
||||
Acknowledgements
|
||||
================
|
||||
|
||||
The GNU Objective C team: Geoffrey Knauth <gsk@marble.com> (manager),
|
||||
Tom Wood <wood@next.com> (compiler) and Kresten Krab Thorup
|
||||
<krab@iesd.auc.dk> (runtime) would like to thank a some people for
|
||||
participating in the development of the present GNU Objective C.
|
||||
|
||||
Paul Burchard <burchard@geom.umn.edu> and Andrew McCallum
|
||||
<mccallum@cs.rochester.edu> has been very helpful debugging the
|
||||
runtime. Eric Herring <herring@iesd.auc.dk> has been very helpful
|
||||
cleaning up after the documentation-copyright disaster and is now
|
||||
helping with the new documentation.
|
||||
|
||||
Steve Naroff <snaroff@next.com> and Richard Stallman
|
||||
<rms@gnu.ai.mit.edu> has been very helpful with implementation details
|
||||
in the compiler.
|
||||
|
||||
|
||||
Bug Reports
|
||||
===========
|
||||
|
||||
Please read the section `Submitting Bugreports' of the gcc manual
|
||||
before you submit any bugs.
|
@ -1,40 +0,0 @@
|
||||
# Top level configure fragment for GNU Objective-C
|
||||
# Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
#This file is part of GCC.
|
||||
|
||||
#GCC 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.
|
||||
|
||||
#GCC 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 GCC; see the file COPYING. If not, write to
|
||||
#the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
#Boston, MA 02110-1301, USA.
|
||||
|
||||
# Configure looks for the existence of this file to auto-config each language.
|
||||
# We define several parameters used by configure:
|
||||
#
|
||||
# language - name of language as it would appear in $(LANGUAGES)
|
||||
# compilers - value to add to $(COMPILERS)
|
||||
# stagestuff - files to add to $(STAGESTUFF)
|
||||
|
||||
language="objc"
|
||||
|
||||
compilers="cc1obj\$(exeext)"
|
||||
|
||||
stagestuff="cc1obj\$(exeext)"
|
||||
|
||||
target_libs=target-libobjc
|
||||
|
||||
# Most of the object files for cc1obj actually come from C.
|
||||
lang_requires="c"
|
||||
|
||||
gtfiles="\$(srcdir)/objc/objc-act.h \$(srcdir)/c-parser.c \$(srcdir)/c-tree.h \$(srcdir)/c-decl.c \$(srcdir)/c-objc-common.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c \$(srcdir)/objc/objc-act.c"
|
@ -1,54 +0,0 @@
|
||||
/* Definitions for specs for Objective-C.
|
||||
Copyright (C) 1998, 1999, 2002, 2002, 2003, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* This is the contribution to the `default_compilers' array in gcc.c for
|
||||
objc. */
|
||||
|
||||
{".m", "@objective-c", 0, 0, 0},
|
||||
{"@objective-c",
|
||||
"%{E|M|MM:cc1obj -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp}\
|
||||
%(cpp_options) %(cpp_debug_options)}\
|
||||
%{!E:%{!M:%{!MM:\
|
||||
%{traditional|ftraditional|traditional-cpp:\
|
||||
%eGNU Objective C no longer supports traditional compilation}\
|
||||
%{save-temps|no-integrated-cpp:cc1obj -E %(cpp_options) -o %{save-temps:%b.mi} %{!save-temps:%g.mi} \n\
|
||||
cc1obj -fpreprocessed %{save-temps:%b.mi} %{!save-temps:%g.mi} %(cc1_options) %{print-objc-runtime-info} %{gen-decls}}\
|
||||
%{!save-temps:%{!no-integrated-cpp:\
|
||||
cc1obj %(cpp_unique_options) %(cc1_options) %{print-objc-runtime-info} %{gen-decls}}}\
|
||||
%{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
|
||||
{".mi", "@objc-cpp-output", 0, 0, 0},
|
||||
{"@objc-cpp-output",
|
||||
"%{!M:%{!MM:%{!E:cc1obj -fpreprocessed %i %(cc1_options) %{print-objc-runtime-info} %{gen-decls}\
|
||||
%{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
|
||||
{"@objective-c-header",
|
||||
"%{E|M|MM:cc1obj -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp}\
|
||||
%(cpp_options) %(cpp_debug_options)}\
|
||||
%{!E:%{!M:%{!MM:\
|
||||
%{traditional|ftraditional|traditional-cpp:\
|
||||
%eGNU Objective C no longer supports traditional compilation}\
|
||||
%{save-temps|no-integrated-cpp:cc1obj -E %(cpp_options) -o %{save-temps:%b.mi} %{!save-temps:%g.mi} \n\
|
||||
cc1obj -fpreprocessed %b.mi %(cc1_options) %{print-objc-runtime-info} %{gen-decls}\
|
||||
-o %g.s %{!o*:--output-pch=%i.gch}\
|
||||
%W{o*:--output-pch=%*}%V}\
|
||||
%{!save-temps:%{!no-integrated-cpp:\
|
||||
cc1obj %(cpp_unique_options) %(cc1_options) %{print-objc-runtime-info} %{gen-decls}\
|
||||
-o %g.s %{!o*:--output-pch=%i.gch}\
|
||||
%W{o*:--output-pch=%*}%V}}}}}", 0, 0, 0},
|
File diff suppressed because it is too large
Load Diff
@ -1,457 +0,0 @@
|
||||
/* Declarations for objc-act.c.
|
||||
Copyright (C) 1990, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_OBJC_ACT_H
|
||||
#define GCC_OBJC_ACT_H
|
||||
|
||||
/* For enum gimplify_status */
|
||||
#include "tree-gimple.h"
|
||||
|
||||
/*** Language hooks ***/
|
||||
|
||||
bool objc_init (void);
|
||||
const char *objc_printable_name (tree, int);
|
||||
tree objc_get_callee_fndecl (tree);
|
||||
void objc_finish_file (void);
|
||||
tree objc_fold_obj_type_ref (tree, tree);
|
||||
enum gimplify_status objc_gimplify_expr (tree *, tree *, tree *);
|
||||
|
||||
/* NB: The remaining public functions are prototyped in c-common.h, for the
|
||||
benefit of stub-objc.c and objc-act.c. */
|
||||
|
||||
/* Objective-C structures */
|
||||
|
||||
#define CLASS_LANG_SLOT_ELTS 5
|
||||
#define PROTOCOL_LANG_SLOT_ELTS 2
|
||||
#define OBJC_INFO_SLOT_ELTS 2
|
||||
|
||||
/* KEYWORD_DECL */
|
||||
#define KEYWORD_KEY_NAME(DECL) ((DECL)->decl_minimal.name)
|
||||
#define KEYWORD_ARG_NAME(DECL) ((DECL)->decl_non_common.arguments)
|
||||
|
||||
/* INSTANCE_METHOD_DECL, CLASS_METHOD_DECL */
|
||||
#define METHOD_SEL_NAME(DECL) ((DECL)->decl_minimal.name)
|
||||
#define METHOD_SEL_ARGS(DECL) ((DECL)->decl_non_common.arguments)
|
||||
#define METHOD_ADD_ARGS(DECL) ((DECL)->decl_non_common.result)
|
||||
#define METHOD_ADD_ARGS_ELLIPSIS_P(DECL) ((DECL)->decl_common.lang_flag_0)
|
||||
#define METHOD_DEFINITION(DECL) ((DECL)->decl_common.initial)
|
||||
#define METHOD_ENCODING(DECL) ((DECL)->decl_minimal.context)
|
||||
|
||||
/* CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
|
||||
CATEGORY_INTERFACE_TYPE, CATEGORY_IMPLEMENTATION_TYPE,
|
||||
PROTOCOL_INTERFACE_TYPE */
|
||||
#define CLASS_NAME(CLASS) ((CLASS)->type.name)
|
||||
#define CLASS_SUPER_NAME(CLASS) (TYPE_CHECK (CLASS)->type.context)
|
||||
#define CLASS_IVARS(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 0)
|
||||
#define CLASS_RAW_IVARS(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 1)
|
||||
#define CLASS_NST_METHODS(CLASS) ((CLASS)->type.minval)
|
||||
#define CLASS_CLS_METHODS(CLASS) ((CLASS)->type.maxval)
|
||||
#define CLASS_STATIC_TEMPLATE(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 2)
|
||||
#define CLASS_CATEGORY_LIST(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 3)
|
||||
#define CLASS_PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 4)
|
||||
#define PROTOCOL_NAME(CLASS) ((CLASS)->type.name)
|
||||
#define PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 0)
|
||||
#define PROTOCOL_NST_METHODS(CLASS) ((CLASS)->type.minval)
|
||||
#define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval)
|
||||
#define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 1)
|
||||
#define PROTOCOL_DEFINED(CLASS) TREE_USED (CLASS)
|
||||
|
||||
/* ObjC-specific information pertaining to RECORD_TYPEs are stored in
|
||||
the LANG_SPECIFIC structures, which may itself need allocating first. */
|
||||
|
||||
/* The following three macros must be overridden (in objcp/objcp-decl.h)
|
||||
for Objective-C++. */
|
||||
#define TYPE_OBJC_INFO(TYPE) TYPE_LANG_SPECIFIC (TYPE)->objc_info
|
||||
#define SIZEOF_OBJC_TYPE_LANG_SPECIFIC sizeof (struct lang_type)
|
||||
#define ALLOC_OBJC_TYPE_LANG_SPECIFIC(NODE) \
|
||||
do { \
|
||||
TYPE_LANG_SPECIFIC (NODE) = GGC_CNEW (struct lang_type); \
|
||||
} while (0)
|
||||
|
||||
#define TYPE_HAS_OBJC_INFO(TYPE) \
|
||||
(TYPE_LANG_SPECIFIC (TYPE) && TYPE_OBJC_INFO (TYPE))
|
||||
#define TYPE_OBJC_INTERFACE(TYPE) TREE_VEC_ELT (TYPE_OBJC_INFO (TYPE), 0)
|
||||
#define TYPE_OBJC_PROTOCOL_LIST(TYPE) TREE_VEC_ELT (TYPE_OBJC_INFO (TYPE), 1)
|
||||
|
||||
|
||||
#define INIT_TYPE_OBJC_INFO(TYPE) \
|
||||
do \
|
||||
{ \
|
||||
if (!TYPE_LANG_SPECIFIC (TYPE)) \
|
||||
ALLOC_OBJC_TYPE_LANG_SPECIFIC(TYPE); \
|
||||
if (!TYPE_OBJC_INFO (TYPE)) \
|
||||
TYPE_OBJC_INFO (TYPE) \
|
||||
= make_tree_vec (OBJC_INFO_SLOT_ELTS); \
|
||||
} \
|
||||
while (0)
|
||||
#define DUP_TYPE_OBJC_INFO(DST, SRC) \
|
||||
do \
|
||||
{ \
|
||||
ALLOC_OBJC_TYPE_LANG_SPECIFIC(DST); \
|
||||
if (TYPE_LANG_SPECIFIC (SRC)) \
|
||||
memcpy (TYPE_LANG_SPECIFIC (DST), \
|
||||
TYPE_LANG_SPECIFIC (SRC), \
|
||||
SIZEOF_OBJC_TYPE_LANG_SPECIFIC); \
|
||||
TYPE_OBJC_INFO (DST) \
|
||||
= make_tree_vec (OBJC_INFO_SLOT_ELTS); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define TYPED_OBJECT(TYPE) \
|
||||
(TREE_CODE (TYPE) == RECORD_TYPE \
|
||||
&& TYPE_HAS_OBJC_INFO (TYPE) \
|
||||
&& TYPE_OBJC_INTERFACE (TYPE))
|
||||
#define OBJC_TYPE_NAME(TYPE) TYPE_NAME(TYPE)
|
||||
#define OBJC_SET_TYPE_NAME(TYPE, NAME) (TYPE_NAME (TYPE) = NAME)
|
||||
|
||||
/* Define the Objective-C or Objective-C++ language-specific tree codes. */
|
||||
|
||||
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
|
||||
enum objc_tree_code {
|
||||
#if defined (GCC_CP_TREE_H)
|
||||
LAST_BASE_TREE_CODE = LAST_CPLUS_TREE_CODE,
|
||||
#else
|
||||
#if defined (GCC_C_TREE_H)
|
||||
LAST_BASE_TREE_CODE = LAST_C_TREE_CODE,
|
||||
#else
|
||||
#error You must include <c-tree.h> or <cp/cp-tree.h> before <objc/objc-act.h>
|
||||
#endif
|
||||
#endif
|
||||
#include "objc-tree.def"
|
||||
LAST_OBJC_TREE_CODE
|
||||
};
|
||||
#undef DEFTREECODE
|
||||
|
||||
/* Hash tables to manage the global pool of method prototypes. */
|
||||
|
||||
typedef struct hashed_entry *hash;
|
||||
typedef struct hashed_attribute *attr;
|
||||
|
||||
struct hashed_attribute GTY(())
|
||||
{
|
||||
attr next;
|
||||
tree value;
|
||||
};
|
||||
struct hashed_entry GTY(())
|
||||
{
|
||||
attr list;
|
||||
hash next;
|
||||
tree key;
|
||||
};
|
||||
|
||||
extern GTY ((length ("SIZEHASHTABLE"))) hash *nst_method_hash_list;
|
||||
extern GTY ((length ("SIZEHASHTABLE"))) hash *cls_method_hash_list;
|
||||
|
||||
#define SIZEHASHTABLE 257
|
||||
|
||||
/* Objective-C/Objective-C++ @implementation list. */
|
||||
|
||||
struct imp_entry GTY(())
|
||||
{
|
||||
struct imp_entry *next;
|
||||
tree imp_context;
|
||||
tree imp_template;
|
||||
tree class_decl; /* _OBJC_CLASS_<my_name>; */
|
||||
tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
|
||||
BOOL_BITFIELD has_cxx_cdtors : 1;
|
||||
};
|
||||
|
||||
extern GTY(()) struct imp_entry *imp_list;
|
||||
extern GTY(()) int imp_count; /* `@implementation' */
|
||||
extern GTY(()) int cat_count; /* `@category' */
|
||||
|
||||
extern GTY(()) enum tree_code objc_inherit_code;
|
||||
extern GTY(()) int objc_public_flag;
|
||||
|
||||
/* Objective-C/Objective-C++ global tree enumeration. */
|
||||
|
||||
enum objc_tree_index
|
||||
{
|
||||
OCTI_STATIC_NST,
|
||||
OCTI_STATIC_NST_DECL,
|
||||
OCTI_SELF_ID,
|
||||
OCTI_UCMD_ID,
|
||||
|
||||
OCTI_SELF_DECL,
|
||||
OCTI_UMSG_DECL,
|
||||
OCTI_UMSG_FAST_DECL,
|
||||
OCTI_UMSG_SUPER_DECL,
|
||||
OCTI_UMSG_STRET_DECL,
|
||||
OCTI_UMSG_SUPER_STRET_DECL,
|
||||
OCTI_GET_CLASS_DECL,
|
||||
OCTI_GET_MCLASS_DECL,
|
||||
OCTI_SUPER_TYPE,
|
||||
OCTI_SEL_TYPE,
|
||||
OCTI_ID_TYPE,
|
||||
OCTI_CLS_TYPE,
|
||||
OCTI_NST_TYPE,
|
||||
OCTI_PROTO_TYPE,
|
||||
|
||||
OCTI_CLS_CHAIN,
|
||||
OCTI_ALIAS_CHAIN,
|
||||
OCTI_INTF_CHAIN,
|
||||
OCTI_PROTO_CHAIN,
|
||||
OCTI_IMPL_CHAIN,
|
||||
OCTI_CLS_REF_CHAIN,
|
||||
OCTI_SEL_REF_CHAIN,
|
||||
OCTI_IVAR_CHAIN,
|
||||
OCTI_CLS_NAMES_CHAIN,
|
||||
OCTI_METH_VAR_NAMES_CHAIN,
|
||||
OCTI_METH_VAR_TYPES_CHAIN,
|
||||
|
||||
OCTI_SYMBOLS_DECL,
|
||||
OCTI_NST_VAR_DECL,
|
||||
OCTI_CLS_VAR_DECL,
|
||||
OCTI_NST_METH_DECL,
|
||||
OCTI_CLS_METH_DECL,
|
||||
OCTI_CLS_DECL,
|
||||
OCTI_MCLS_DECL,
|
||||
OCTI_SEL_TABLE_DECL,
|
||||
OCTI_MODULES_DECL,
|
||||
OCTI_GNU_INIT_DECL,
|
||||
|
||||
OCTI_INTF_CTX,
|
||||
OCTI_IMPL_CTX,
|
||||
OCTI_METH_CTX,
|
||||
OCTI_IVAR_CTX,
|
||||
|
||||
OCTI_IMPL_TEMPL,
|
||||
OCTI_CLS_TEMPL,
|
||||
OCTI_CAT_TEMPL,
|
||||
OCTI_UPRIV_REC,
|
||||
OCTI_PROTO_TEMPL,
|
||||
OCTI_SEL_TEMPL,
|
||||
OCTI_UCLS_SUPER_REF,
|
||||
OCTI_UUCLS_SUPER_REF,
|
||||
OCTI_METH_TEMPL,
|
||||
OCTI_IVAR_TEMPL,
|
||||
OCTI_METH_LIST_TEMPL,
|
||||
OCTI_METH_PROTO_LIST_TEMPL,
|
||||
OCTI_IVAR_LIST_TEMPL,
|
||||
OCTI_SYMTAB_TEMPL,
|
||||
OCTI_MODULE_TEMPL,
|
||||
OCTI_SUPER_TEMPL,
|
||||
OCTI_OBJ_REF,
|
||||
OCTI_CLS_REF,
|
||||
OCTI_METH_PROTO_TEMPL,
|
||||
OCTI_FUNCTION1_TEMPL,
|
||||
OCTI_FUNCTION2_TEMPL,
|
||||
|
||||
OCTI_OBJ_ID,
|
||||
OCTI_CLS_ID,
|
||||
OCTI_ID_NAME,
|
||||
OCTI_CLASS_NAME,
|
||||
OCTI_CNST_STR_ID,
|
||||
OCTI_CNST_STR_TYPE,
|
||||
OCTI_CNST_STR_GLOB_ID,
|
||||
OCTI_STRING_CLASS_DECL,
|
||||
OCTI_INTERNAL_CNST_STR_TYPE,
|
||||
OCTI_SUPER_DECL,
|
||||
OCTI_UMSG_NONNIL_DECL,
|
||||
OCTI_UMSG_NONNIL_STRET_DECL,
|
||||
OCTI_STORAGE_CLS,
|
||||
OCTI_EXCEPTION_EXTRACT_DECL,
|
||||
OCTI_EXCEPTION_TRY_ENTER_DECL,
|
||||
OCTI_EXCEPTION_TRY_EXIT_DECL,
|
||||
OCTI_EXCEPTION_MATCH_DECL,
|
||||
OCTI_EXCEPTION_THROW_DECL,
|
||||
OCTI_SYNC_ENTER_DECL,
|
||||
OCTI_SYNC_EXIT_DECL,
|
||||
OCTI_SETJMP_DECL,
|
||||
OCTI_EXCDATA_TEMPL,
|
||||
OCTI_STACK_EXCEPTION_DATA_DECL,
|
||||
OCTI_LOCAL_EXCEPTION_DECL,
|
||||
OCTI_RETHROW_EXCEPTION_DECL,
|
||||
OCTI_EVAL_ONCE_DECL,
|
||||
OCTI_CATCH_TYPE,
|
||||
OCTI_EXECCLASS_DECL,
|
||||
|
||||
OCTI_ASSIGN_IVAR_DECL,
|
||||
OCTI_ASSIGN_IVAR_FAST_DECL,
|
||||
OCTI_ASSIGN_GLOBAL_DECL,
|
||||
OCTI_ASSIGN_STRONGCAST_DECL,
|
||||
|
||||
OCTI_MAX
|
||||
};
|
||||
|
||||
extern GTY(()) tree objc_global_trees[OCTI_MAX];
|
||||
|
||||
/* List of classes with list of their static instances. */
|
||||
#define objc_static_instances objc_global_trees[OCTI_STATIC_NST]
|
||||
|
||||
/* The declaration of the array administrating the static instances. */
|
||||
#define static_instances_decl objc_global_trees[OCTI_STATIC_NST_DECL]
|
||||
|
||||
/* Some commonly used instances of "identifier_node". */
|
||||
|
||||
#define self_id objc_global_trees[OCTI_SELF_ID]
|
||||
#define ucmd_id objc_global_trees[OCTI_UCMD_ID]
|
||||
|
||||
#define self_decl objc_global_trees[OCTI_SELF_DECL]
|
||||
#define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
|
||||
#define umsg_fast_decl objc_global_trees[OCTI_UMSG_FAST_DECL]
|
||||
#define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
|
||||
#define umsg_stret_decl objc_global_trees[OCTI_UMSG_STRET_DECL]
|
||||
#define umsg_super_stret_decl objc_global_trees[OCTI_UMSG_SUPER_STRET_DECL]
|
||||
#define objc_get_class_decl objc_global_trees[OCTI_GET_CLASS_DECL]
|
||||
#define objc_get_meta_class_decl \
|
||||
objc_global_trees[OCTI_GET_MCLASS_DECL]
|
||||
|
||||
#define objc_super_type objc_global_trees[OCTI_SUPER_TYPE]
|
||||
#define objc_selector_type objc_global_trees[OCTI_SEL_TYPE]
|
||||
#define objc_object_type objc_global_trees[OCTI_ID_TYPE]
|
||||
#define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
|
||||
#define objc_instance_type objc_global_trees[OCTI_NST_TYPE]
|
||||
#define objc_protocol_type objc_global_trees[OCTI_PROTO_TYPE]
|
||||
|
||||
/* Type checking macros. */
|
||||
|
||||
#define IS_ID(TYPE) \
|
||||
(TREE_CODE (TYPE) == POINTER_TYPE \
|
||||
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TYPE)) \
|
||||
== TREE_TYPE (objc_object_type)))
|
||||
#define IS_CLASS(TYPE) \
|
||||
(TREE_CODE (TYPE) == POINTER_TYPE \
|
||||
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TYPE)) \
|
||||
== TREE_TYPE (objc_class_type)))
|
||||
#define IS_PROTOCOL_QUALIFIED_UNTYPED(TYPE) \
|
||||
((IS_ID (TYPE) || IS_CLASS (TYPE)) \
|
||||
&& TYPE_HAS_OBJC_INFO (TREE_TYPE (TYPE)) \
|
||||
&& TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (TYPE)))
|
||||
#define IS_SUPER(TYPE) \
|
||||
(TREE_CODE (TYPE) == POINTER_TYPE \
|
||||
&& TREE_TYPE (TYPE) == objc_super_template)
|
||||
|
||||
#define class_chain objc_global_trees[OCTI_CLS_CHAIN]
|
||||
#define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
|
||||
#define interface_chain objc_global_trees[OCTI_INTF_CHAIN]
|
||||
#define protocol_chain objc_global_trees[OCTI_PROTO_CHAIN]
|
||||
#define implemented_classes objc_global_trees[OCTI_IMPL_CHAIN]
|
||||
|
||||
/* Chains to manage selectors that are referenced and defined in the
|
||||
module. */
|
||||
|
||||
#define cls_ref_chain objc_global_trees[OCTI_CLS_REF_CHAIN] /* Classes referenced. */
|
||||
#define sel_ref_chain objc_global_trees[OCTI_SEL_REF_CHAIN] /* Selectors referenced. */
|
||||
#define objc_ivar_chain objc_global_trees[OCTI_IVAR_CHAIN]
|
||||
|
||||
/* Chains to manage uniquing of strings. */
|
||||
|
||||
#define class_names_chain objc_global_trees[OCTI_CLS_NAMES_CHAIN]
|
||||
#define meth_var_names_chain objc_global_trees[OCTI_METH_VAR_NAMES_CHAIN]
|
||||
#define meth_var_types_chain objc_global_trees[OCTI_METH_VAR_TYPES_CHAIN]
|
||||
|
||||
|
||||
/* Backend data declarations. */
|
||||
|
||||
#define UOBJC_SYMBOLS_decl objc_global_trees[OCTI_SYMBOLS_DECL]
|
||||
#define UOBJC_INSTANCE_VARIABLES_decl objc_global_trees[OCTI_NST_VAR_DECL]
|
||||
#define UOBJC_CLASS_VARIABLES_decl objc_global_trees[OCTI_CLS_VAR_DECL]
|
||||
#define UOBJC_INSTANCE_METHODS_decl objc_global_trees[OCTI_NST_METH_DECL]
|
||||
#define UOBJC_CLASS_METHODS_decl objc_global_trees[OCTI_CLS_METH_DECL]
|
||||
#define UOBJC_CLASS_decl objc_global_trees[OCTI_CLS_DECL]
|
||||
#define UOBJC_METACLASS_decl objc_global_trees[OCTI_MCLS_DECL]
|
||||
#define UOBJC_SELECTOR_TABLE_decl objc_global_trees[OCTI_SEL_TABLE_DECL]
|
||||
#define UOBJC_MODULES_decl objc_global_trees[OCTI_MODULES_DECL]
|
||||
#define GNU_INIT_decl objc_global_trees[OCTI_GNU_INIT_DECL]
|
||||
|
||||
/* The following are used when compiling a class implementation.
|
||||
implementation_template will normally be an interface, however if
|
||||
none exists this will be equal to objc_implementation_context...it is
|
||||
set in start_class. */
|
||||
|
||||
#define objc_interface_context objc_global_trees[OCTI_INTF_CTX]
|
||||
#define objc_implementation_context objc_global_trees[OCTI_IMPL_CTX]
|
||||
#define objc_method_context objc_global_trees[OCTI_METH_CTX]
|
||||
#define objc_ivar_context objc_global_trees[OCTI_IVAR_CTX]
|
||||
|
||||
#define implementation_template objc_global_trees[OCTI_IMPL_TEMPL]
|
||||
#define objc_class_template objc_global_trees[OCTI_CLS_TEMPL]
|
||||
#define objc_category_template objc_global_trees[OCTI_CAT_TEMPL]
|
||||
#define uprivate_record objc_global_trees[OCTI_UPRIV_REC]
|
||||
#define objc_protocol_template objc_global_trees[OCTI_PROTO_TEMPL]
|
||||
#define objc_selector_template objc_global_trees[OCTI_SEL_TEMPL]
|
||||
#define ucls_super_ref objc_global_trees[OCTI_UCLS_SUPER_REF]
|
||||
#define uucls_super_ref objc_global_trees[OCTI_UUCLS_SUPER_REF]
|
||||
|
||||
#define umsg_nonnil_decl objc_global_trees[OCTI_UMSG_NONNIL_DECL]
|
||||
#define umsg_nonnil_stret_decl objc_global_trees[OCTI_UMSG_NONNIL_STRET_DECL]
|
||||
#define objc_storage_class objc_global_trees[OCTI_STORAGE_CLS]
|
||||
#define objc_exception_extract_decl \
|
||||
objc_global_trees[OCTI_EXCEPTION_EXTRACT_DECL]
|
||||
#define objc_exception_try_enter_decl \
|
||||
objc_global_trees[OCTI_EXCEPTION_TRY_ENTER_DECL]
|
||||
#define objc_exception_try_exit_decl \
|
||||
objc_global_trees[OCTI_EXCEPTION_TRY_EXIT_DECL]
|
||||
#define objc_exception_match_decl \
|
||||
objc_global_trees[OCTI_EXCEPTION_MATCH_DECL]
|
||||
#define objc_exception_throw_decl \
|
||||
objc_global_trees[OCTI_EXCEPTION_THROW_DECL]
|
||||
#define objc_sync_enter_decl objc_global_trees[OCTI_SYNC_ENTER_DECL]
|
||||
#define objc_sync_exit_decl objc_global_trees[OCTI_SYNC_EXIT_DECL]
|
||||
#define objc_exception_data_template \
|
||||
objc_global_trees[OCTI_EXCDATA_TEMPL]
|
||||
#define objc_setjmp_decl objc_global_trees[OCTI_SETJMP_DECL]
|
||||
#define objc_stack_exception_data \
|
||||
objc_global_trees[OCTI_STACK_EXCEPTION_DATA_DECL]
|
||||
#define objc_caught_exception objc_global_trees[OCTI_LOCAL_EXCEPTION_DECL]
|
||||
#define objc_rethrow_exception objc_global_trees[OCTI_RETHROW_EXCEPTION_DECL]
|
||||
#define objc_eval_once objc_global_trees[OCTI_EVAL_ONCE_DECL]
|
||||
#define objc_catch_type objc_global_trees[OCTI_CATCH_TYPE]
|
||||
|
||||
#define execclass_decl objc_global_trees[OCTI_EXECCLASS_DECL]
|
||||
|
||||
#define objc_assign_ivar_decl objc_global_trees[OCTI_ASSIGN_IVAR_DECL]
|
||||
#define objc_assign_ivar_fast_decl \
|
||||
objc_global_trees[OCTI_ASSIGN_IVAR_FAST_DECL]
|
||||
#define objc_assign_global_decl objc_global_trees[OCTI_ASSIGN_GLOBAL_DECL]
|
||||
#define objc_assign_strong_cast_decl \
|
||||
objc_global_trees[OCTI_ASSIGN_STRONGCAST_DECL]
|
||||
|
||||
#define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
|
||||
#define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
|
||||
#define objc_method_list_ptr objc_global_trees[OCTI_METH_LIST_TEMPL]
|
||||
#define objc_method_proto_list_ptr \
|
||||
objc_global_trees[OCTI_METH_PROTO_LIST_TEMPL]
|
||||
#define objc_ivar_list_ptr objc_global_trees[OCTI_IVAR_LIST_TEMPL]
|
||||
#define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
|
||||
#define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
|
||||
#define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
|
||||
#define objc_object_reference objc_global_trees[OCTI_OBJ_REF]
|
||||
#define objc_class_reference objc_global_trees[OCTI_CLS_REF]
|
||||
#define objc_method_prototype_template \
|
||||
objc_global_trees[OCTI_METH_PROTO_TEMPL]
|
||||
#define function1_template objc_global_trees[OCTI_FUNCTION1_TEMPL]
|
||||
#define function2_template objc_global_trees[OCTI_FUNCTION2_TEMPL]
|
||||
|
||||
#define objc_object_id objc_global_trees[OCTI_OBJ_ID]
|
||||
#define objc_class_id objc_global_trees[OCTI_CLS_ID]
|
||||
#define objc_object_name objc_global_trees[OCTI_ID_NAME]
|
||||
#define objc_class_name objc_global_trees[OCTI_CLASS_NAME]
|
||||
#define constant_string_id objc_global_trees[OCTI_CNST_STR_ID]
|
||||
#define constant_string_type objc_global_trees[OCTI_CNST_STR_TYPE]
|
||||
#define constant_string_global_id \
|
||||
objc_global_trees[OCTI_CNST_STR_GLOB_ID]
|
||||
#define string_class_decl objc_global_trees[OCTI_STRING_CLASS_DECL]
|
||||
#define internal_const_str_type objc_global_trees[OCTI_INTERNAL_CNST_STR_TYPE]
|
||||
#define UOBJC_SUPER_decl objc_global_trees[OCTI_SUPER_DECL]
|
||||
|
||||
#endif /* GCC_OBJC_ACT_H */
|
@ -1,133 +0,0 @@
|
||||
/* Language-dependent hooks for Objective-C.
|
||||
Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "c-tree.h"
|
||||
#include "c-common.h"
|
||||
#include "ggc.h"
|
||||
#include "objc-act.h"
|
||||
#include "langhooks.h"
|
||||
#include "langhooks-def.h"
|
||||
#include "diagnostic.h"
|
||||
#include "c-objc-common.h"
|
||||
|
||||
enum c_language_kind c_language = clk_objc;
|
||||
static void objc_init_ts (void);
|
||||
|
||||
/* Lang hooks common to C and ObjC are declared in c-objc-common.h;
|
||||
consequently, there should be very few hooks below. */
|
||||
|
||||
#undef LANG_HOOKS_NAME
|
||||
#define LANG_HOOKS_NAME "GNU Objective-C"
|
||||
#undef LANG_HOOKS_INIT
|
||||
#define LANG_HOOKS_INIT objc_init
|
||||
#undef LANG_HOOKS_DECL_PRINTABLE_NAME
|
||||
#define LANG_HOOKS_DECL_PRINTABLE_NAME objc_printable_name
|
||||
#undef LANG_HOOKS_GIMPLIFY_EXPR
|
||||
#define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
|
||||
#undef LANG_HOOKS_GET_CALLEE_FNDECL
|
||||
#define LANG_HOOKS_GET_CALLEE_FNDECL objc_get_callee_fndecl
|
||||
#undef LANG_HOOKS_INIT_TS
|
||||
#define LANG_HOOKS_INIT_TS objc_init_ts
|
||||
|
||||
/* Each front end provides its own lang hook initializer. */
|
||||
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
|
||||
/* Table indexed by tree code giving a string containing a character
|
||||
classifying the tree code. */
|
||||
|
||||
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
|
||||
|
||||
const enum tree_code_class tree_code_type[] = {
|
||||
#include "tree.def"
|
||||
tcc_exceptional,
|
||||
#include "c-common.def"
|
||||
tcc_exceptional,
|
||||
#include "objc-tree.def"
|
||||
};
|
||||
#undef DEFTREECODE
|
||||
|
||||
/* Table indexed by tree code giving number of expression
|
||||
operands beyond the fixed part of the node structure.
|
||||
Not used for types or decls. */
|
||||
|
||||
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
|
||||
|
||||
const unsigned char tree_code_length[] = {
|
||||
#include "tree.def"
|
||||
0,
|
||||
#include "c-common.def"
|
||||
0,
|
||||
#include "objc-tree.def"
|
||||
};
|
||||
#undef DEFTREECODE
|
||||
|
||||
/* Names of tree components.
|
||||
Used for printing out the tree and error messages. */
|
||||
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
|
||||
|
||||
const char * const tree_code_name[] = {
|
||||
#include "tree.def"
|
||||
"@@dummy",
|
||||
#include "c-common.def"
|
||||
"@@dummy",
|
||||
#include "objc-tree.def"
|
||||
};
|
||||
#undef DEFTREECODE
|
||||
|
||||
/* Lang hook routines common to C and ObjC appear in c-objc-common.c;
|
||||
there should be very few (if any) routines below. */
|
||||
|
||||
static void
|
||||
objc_init_ts (void)
|
||||
{
|
||||
tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_NON_COMMON] = 1;
|
||||
tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_NON_COMMON] = 1;
|
||||
tree_contains_struct[KEYWORD_DECL][TS_DECL_NON_COMMON] = 1;
|
||||
|
||||
tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_WITH_VIS] = 1;
|
||||
tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_WITH_VIS] = 1;
|
||||
tree_contains_struct[KEYWORD_DECL][TS_DECL_WITH_VIS] = 1;
|
||||
|
||||
tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_WRTL] = 1;
|
||||
tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_WRTL] = 1;
|
||||
tree_contains_struct[KEYWORD_DECL][TS_DECL_WRTL] = 1;
|
||||
|
||||
tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_MINIMAL] = 1;
|
||||
tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_MINIMAL] = 1;
|
||||
tree_contains_struct[KEYWORD_DECL][TS_DECL_MINIMAL] = 1;
|
||||
|
||||
tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_COMMON] = 1;
|
||||
tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_COMMON] = 1;
|
||||
tree_contains_struct[KEYWORD_DECL][TS_DECL_COMMON] = 1;
|
||||
}
|
||||
|
||||
void
|
||||
finish_file (void)
|
||||
{
|
||||
objc_finish_file ();
|
||||
}
|
||||
|
||||
#include "gtype-objc.h"
|
@ -1,47 +0,0 @@
|
||||
/* This file contains the definitions and documentation for the
|
||||
additional tree codes used in the Objective C front end (see tree.def
|
||||
for the standard codes).
|
||||
Copyright (C) 1990, 1997, 1998, 1999, 2000, 2001, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
|
||||
/* Objective-C types. */
|
||||
DEFTREECODE (CLASS_INTERFACE_TYPE, "class_interface_type", tcc_type, 0)
|
||||
DEFTREECODE (CLASS_IMPLEMENTATION_TYPE, "class_implementation_type",
|
||||
tcc_type, 0)
|
||||
DEFTREECODE (CATEGORY_INTERFACE_TYPE, "category_interface_type", tcc_type, 0)
|
||||
DEFTREECODE (CATEGORY_IMPLEMENTATION_TYPE,"category_implementation_type",
|
||||
tcc_type, 0)
|
||||
DEFTREECODE (PROTOCOL_INTERFACE_TYPE, "protocol_interface_type", tcc_type, 0)
|
||||
|
||||
/* Objective-C decls. */
|
||||
DEFTREECODE (KEYWORD_DECL, "keyword_decl", tcc_declaration, 0)
|
||||
DEFTREECODE (INSTANCE_METHOD_DECL, "instance_method_decl", tcc_declaration, 0)
|
||||
DEFTREECODE (CLASS_METHOD_DECL, "class_method_decl", tcc_declaration, 0)
|
||||
|
||||
/* Objective-C expressions. */
|
||||
DEFTREECODE (MESSAGE_SEND_EXPR, "message_send_expr", tcc_expression, 3)
|
||||
DEFTREECODE (CLASS_REFERENCE_EXPR, "class_reference_expr", tcc_expression, 1)
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
mode:c
|
||||
End:
|
||||
*/
|
File diff suppressed because it is too large
Load Diff
@ -1,376 +0,0 @@
|
||||
# Makefile for GNU Objective C runtime library.
|
||||
# Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004,
|
||||
# 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
#This file is part of GCC.
|
||||
|
||||
#GCC 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.
|
||||
|
||||
#GCC 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 GCC; see the file COPYING. If not, write to
|
||||
#the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
#Boston, MA 02110-1301, USA. */
|
||||
|
||||
#This was cribbed from the libchill, libiberty and libstdc++
|
||||
#Makefile.in files. Some of this stuff may be unnecessary and
|
||||
#worthless.
|
||||
|
||||
SHELL = @SHELL@
|
||||
MAKEOVERRIDES=
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
srcdir = @glibcpp_srcdir@
|
||||
VPATH = @glibcpp_srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
target_noncanonical = @target_noncanonical@
|
||||
gcc_version := $(shell cat $(srcdir)/../gcc/BASE-VER)
|
||||
host_subdir = @host_subdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
multi_basedir = @multi_basedir@
|
||||
toolexecdir = @toolexecdir@
|
||||
# Toolexecdir is used only by toolexeclibdir
|
||||
toolexeclibdir = @toolexeclibdir@
|
||||
|
||||
includedirname = @includedirname@
|
||||
libext = @libext@
|
||||
|
||||
extra_ldflags_libobjc = @extra_ldflags_libobjc@
|
||||
|
||||
top_builddir = .
|
||||
|
||||
libdir = $(exec_prefix)/lib
|
||||
libsubdir = $(libdir)/gcc/$(target_noncanonical)/$(gcc_version)
|
||||
|
||||
# Multilib support variables.
|
||||
MULTISRCTOP =
|
||||
MULTIBUILDTOP =
|
||||
MULTIDIRS =
|
||||
MULTISUBDIR =
|
||||
MULTIDO = true
|
||||
MULTICLEAN = true
|
||||
|
||||
# Not configured per top-level version, since that doesn't get passed
|
||||
# down at configure time, but overrridden by the top-level install
|
||||
# target.
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
AR = @AR@
|
||||
AR_FLAGS = rc
|
||||
|
||||
RANLIB = @RANLIB@
|
||||
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@
|
||||
WARN_CFLAGS = -W -Wall -Wwrite-strings -Wstrict-prototypes
|
||||
ALL_CFLAGS = -I. -I$(srcdir) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(WARN_CFLAGS) \
|
||||
-DIN_GCC -DIN_TARGET_LIBS -fno-strict-aliasing -fexceptions
|
||||
|
||||
# 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 = @VERSION@
|
||||
LIBOBJC_GC_VERSION = @VERSION@
|
||||
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
|
||||
|
||||
OBJC_GCFLAGS=-DOBJC_WITH_GC=1
|
||||
OBJC_THREAD_FILE=thr-objc
|
||||
OBJC_BOEHM_GC=@OBJC_BOEHM_GC@
|
||||
OBJC_BOEHM_GC_INCLUDES=@OBJC_BOEHM_GC_INCLUDES@
|
||||
|
||||
INCLUDES = -I$(srcdir)/objc -I$(srcdir)/$(MULTISRCTOP)../gcc \
|
||||
-I$(srcdir)/$(MULTISRCTOP)../gcc/config \
|
||||
-I$(MULTIBUILDTOP)../../$(host_subdir)/gcc \
|
||||
-I$(srcdir)/$(MULTISRCTOP)../include \
|
||||
$(OBJC_BOEHM_GC_INCLUDES)
|
||||
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .m .lo
|
||||
|
||||
.c.lo:
|
||||
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
|
||||
.m.lo:
|
||||
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
|
||||
# Flags to pass to a recursive make.
|
||||
FLAGS_TO_PASS = \
|
||||
"AR=$(AR)" \
|
||||
"AR_FLAGS=$(AR_FLAGS)" \
|
||||
"CC=$(CC)" \
|
||||
"CFLAGS=$(CFLAGS)" \
|
||||
"DESTDIR=$(DESTDIR)" \
|
||||
"LIBCFLAGS=$(LIBCFLAGS)" \
|
||||
"EXTRA_OFILES=$(EXTRA_OFILES)" \
|
||||
"HDEFINES=$(HDEFINES)" \
|
||||
"INSTALL=$(INSTALL)" \
|
||||
"INSTALL_DATA=$(INSTALL_DATA)" \
|
||||
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
|
||||
"LDFLAGS=$(LDFLAGS)" \
|
||||
"LIBTOOL=$(LIBTOOL)" \
|
||||
"LOADLIBES=$(LOADLIBES)" \
|
||||
"PICFLAG=$(PICFLAG)" \
|
||||
"RANLIB=$(RANLIB)" \
|
||||
"SHELL=$(SHELL)" \
|
||||
"prefix=$(prefix)" \
|
||||
"exec_prefix=$(exec_prefix)" \
|
||||
"libdir=$(libdir)" \
|
||||
"libsubdir=$(libsubdir)" \
|
||||
"tooldir=$(tooldir)"
|
||||
|
||||
all: libobjc$(libext).la $(OBJC_BOEHM_GC)
|
||||
: $(MAKE) ; exec $(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=all
|
||||
|
||||
# User-visible header files.
|
||||
|
||||
OBJC_H = hash.h objc-list.h sarray.h objc.h objc-api.h \
|
||||
NXConstStr.h Object.h Protocol.h encoding.h typedstream.h \
|
||||
thr.h objc-decls.h
|
||||
|
||||
# Modules that comprise the runtime library.
|
||||
|
||||
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 exception.lo
|
||||
|
||||
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 exception_gc.lo
|
||||
|
||||
runtime-info.h:
|
||||
echo "" > tmp-runtime.m
|
||||
echo "/* This file is automatically generated */" > $@
|
||||
$(CC) $(MULTIFLAGS) -print-objc-runtime-info -S tmp-runtime.m >> $@
|
||||
rm -f tmp-runtime.m tmp-runtime.s
|
||||
|
||||
archive_gc.lo: archive.c
|
||||
$(LIBTOOL_COMPILE) $(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.lo: encoding.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
gc.lo: gc.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
|
||||
gc_gc.lo: gc.c
|
||||
$(LIBTOOL_COMPILE) $(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.lo: init.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
linking.lo: linking.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
linking_gc.lo: linking.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -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.lo: nil_method.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) -o $@ $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
NXConstStr.lo: NXConstStr.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
NXConstStr_gc.lo: NXConstStr.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
|
||||
Object.lo: Object.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
Object_gc.lo: Object.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
|
||||
objects_gc.lo: objects.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) -o $@ $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
Protocol.lo: Protocol.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
Protocol_gc.lo: Protocol.m
|
||||
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
|
||||
$(OBJC_GCFLAGS) $(INCLUDES) $<
|
||||
|
||||
sarray_gc.lo: sarray.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
selector_gc.lo: selector.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
sendmsg.lo: sendmsg.c runtime-info.h
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
|
||||
sendmsg_gc.lo: sendmsg.c runtime-info.h
|
||||
$(LIBTOOL_COMPILE) $(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.lo: $(OBJC_THREAD_FILE).c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
$(INCLUDES) $<
|
||||
|
||||
exception.lo: exception.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) \
|
||||
-fexceptions $(INCLUDES) $<
|
||||
|
||||
exception_gc.lo: exception.c
|
||||
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
|
||||
-fexceptions $(INCLUDES) $<
|
||||
|
||||
doc: info dvi pdf html
|
||||
|
||||
# No install-html support
|
||||
.PHONY: install-html
|
||||
install-html:
|
||||
|
||||
libobjc$(libext).la: $(OBJS)
|
||||
$(LIBTOOL_LINK) $(CC) -o $@ $(OBJS) \
|
||||
-rpath $(toolexeclibdir) \
|
||||
-version-info $(LIBOBJC_VERSION) $(extra_ldflags_libobjc)
|
||||
|
||||
libobjc_gc$(libext).la: $(OBJS_GC)
|
||||
$(LIBTOOL_LINK) $(CC) -o $@ $(OBJS_GC) \
|
||||
-rpath $(toolexeclibdir) \
|
||||
-version-info $(LIBOBJC_GC_VERSION) $(extra_ldflags_libobjc)
|
||||
|
||||
#
|
||||
# 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
|
||||
libobjc.dll: libobjc_s.a libobjc_entry.o
|
||||
$(CC) -mdll -Wl,--base-file -Wl,libobjc.base \
|
||||
-o libobjc.dll libobjc_s.a libobjc_entry.o -lkernel32
|
||||
$(DLLTOOL) --dllname libobjc.dll --def $(srcdir)/libobjc.def \
|
||||
--base-file libobjc.base --output-exp libobjc.exp
|
||||
$(GCC_FOR_TARGET) -mdll -Wl,--base-file libobjc.base libobjc.exp \
|
||||
-o libobjc.dll libobjc_s.a libobjc_entry.o -lkernel32
|
||||
$(DLLTOOL) --dllname libobjc.dll --def $(srcdir)/libobjc.def \
|
||||
--base-file libobjc.base --output-exp libobjc.exp
|
||||
$(GCC_FOR_TARGET) libobjc.exp -mdll \
|
||||
-o libobjc.dll libobjc_s.a libobjc_entry.o -lkernel32
|
||||
$(DLLTOOL) --dllname libobjc.dll --def $(srcdir)/libobjc.def \
|
||||
--output-lib libobjc.a
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
info:
|
||||
dvi:
|
||||
pdf:
|
||||
html:
|
||||
|
||||
Makefile: Makefile.in config.status
|
||||
$(SHELL) config.status
|
||||
|
||||
config.status: configure
|
||||
rm -f config.cache
|
||||
CONFIG_SITE=no-such-file CC='$(CC)' AR='$(AR)' CFLAGS='$(CFLAGS)' \
|
||||
CPPFLAGS='$(CPPFLAGS)' $(SHELL) config.status --recheck
|
||||
|
||||
${srcdir}/configure: @MAINT@ configure.ac
|
||||
rm -f config.cache
|
||||
cd ${srcdir} && autoconf
|
||||
|
||||
install: install-libs install-headers
|
||||
|
||||
install-libs: installdirs
|
||||
$(SHELL) $(multi_basedir)/mkinstalldirs $(DESTDIR)$(toolexeclibdir)
|
||||
$(LIBTOOL_INSTALL) $(INSTALL) libobjc$(libext).la $(DESTDIR)$(toolexeclibdir);
|
||||
if [ "$(OBJC_BOEHM_GC)" ]; then \
|
||||
$(LIBTOOL_INSTALL) $(INSTALL) libobjc_gc$(libext).la \
|
||||
$(DESTDIR)$(toolexeclibdir);\
|
||||
fi
|
||||
$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO="$@"
|
||||
@-$(LIBTOOL) --mode=finish $(DESTDIR)$(toolexeclibdir)
|
||||
|
||||
# Copy Objective C headers to installation include directory.
|
||||
install-headers:
|
||||
$(SHELL) $(multi_basedir)/mkinstalldirs $(DESTDIR)$(libsubdir)/$(includedirname)/objc
|
||||
for file in $(OBJC_H); do \
|
||||
realfile=$(srcdir)/objc/$${file}; \
|
||||
$(INSTALL_DATA) $${realfile} $(DESTDIR)$(libsubdir)/$(includedirname)/objc; \
|
||||
done
|
||||
|
||||
check uninstall install-strip dist installcheck installdirs:
|
||||
|
||||
mostlyclean:
|
||||
-$(LIBTOOL_CLEAN) rm -f libobjc$(libext).la libobjc_gc$(libext).la *.lo
|
||||
-rm -f runtime-info.h tmp-runtime.s *.o *.lo libobjc* xforward \
|
||||
fflags *.aux *.cp *.dvi *.pdf *.fn *.info *.ky *.log *.pg \
|
||||
*.toc *.tp *.vr *.html libobj.exp
|
||||
@$(MULTICLEAN) multi-clean DO=mostlyclean
|
||||
|
||||
clean: mostlyclean
|
||||
rm -f config.log
|
||||
@$(MULTICLEAN) multi-clean DO=clean
|
||||
|
||||
distclean: clean
|
||||
@$(MULTICLEAN) multi-clean DO=distclean
|
||||
rm -f config.cache config.status Makefile configure
|
||||
|
||||
maintainer-clean realclean: distclean
|
||||
|
||||
.PHONY: mostlyclean clean distclean maintainer-clean all check uninstall \
|
||||
install-strip dist installcheck installdirs
|
||||
|
||||
# Don't export variables to the environment, in order to not confuse
|
||||
# configure.
|
||||
.NOEXPORT:
|
@ -1,42 +0,0 @@
|
||||
/* Implementation of the NXConstantString class for Objective-C.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Contributed by Pieter J. Schoenmakers <tiggr@es.ele.tue.nl>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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/NXConstStr.h"
|
||||
|
||||
@implementation NXConstantString
|
||||
|
||||
-(const char *) cString
|
||||
{
|
||||
return (c_string);
|
||||
} /* -cString */
|
||||
|
||||
-(unsigned int) length
|
||||
{
|
||||
return (len);
|
||||
} /* -length */
|
||||
|
||||
@end
|
@ -1,386 +0,0 @@
|
||||
/* The implementation of class Object for Objective-C.
|
||||
Copyright (C) 1993, 1994, 1995, 1997, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 <stdarg.h>
|
||||
#include "objc/Object.h"
|
||||
#include "objc/Protocol.h"
|
||||
#include "objc/objc-api.h"
|
||||
|
||||
extern int errno;
|
||||
|
||||
#define MAX_CLASS_NAME_LEN 256
|
||||
|
||||
@implementation Object
|
||||
|
||||
+ initialize
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
+ new
|
||||
{
|
||||
return [[self alloc] init];
|
||||
}
|
||||
|
||||
+ alloc
|
||||
{
|
||||
return class_create_instance(self);
|
||||
}
|
||||
|
||||
- free
|
||||
{
|
||||
return object_dispose(self);
|
||||
}
|
||||
|
||||
- copy
|
||||
{
|
||||
return [[self shallowCopy] deepen];
|
||||
}
|
||||
|
||||
- shallowCopy
|
||||
{
|
||||
return object_copy(self);
|
||||
}
|
||||
|
||||
- deepen
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- deepCopy
|
||||
{
|
||||
return [self copy];
|
||||
}
|
||||
|
||||
- (Class)class
|
||||
{
|
||||
return object_get_class(self);
|
||||
}
|
||||
|
||||
- (Class)superClass
|
||||
{
|
||||
return object_get_super_class(self);
|
||||
}
|
||||
|
||||
- (MetaClass)metaClass
|
||||
{
|
||||
return object_get_meta_class(self);
|
||||
}
|
||||
|
||||
- (const char *)name
|
||||
{
|
||||
return object_get_class_name(self);
|
||||
}
|
||||
|
||||
- self
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (unsigned int)hash
|
||||
{
|
||||
return (size_t)self;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:anObject
|
||||
{
|
||||
return self==anObject;
|
||||
}
|
||||
|
||||
- (int)compare:anotherObject;
|
||||
{
|
||||
if ([self isEqual:anotherObject])
|
||||
return 0;
|
||||
// Ordering objects by their address is pretty useless,
|
||||
// so subclasses should override this is some useful way.
|
||||
else if (self > anotherObject)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
- (BOOL)isMetaClass
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isClass
|
||||
{
|
||||
return object_is_class(self);
|
||||
}
|
||||
|
||||
- (BOOL)isInstance
|
||||
{
|
||||
return object_is_instance(self);
|
||||
}
|
||||
|
||||
- (BOOL)isKindOf:(Class)aClassObject
|
||||
{
|
||||
Class class;
|
||||
|
||||
for (class = self->isa; class!=Nil; class = class_get_super_class(class))
|
||||
if (class==aClassObject)
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isMemberOf:(Class)aClassObject
|
||||
{
|
||||
return self->isa==aClassObject;
|
||||
}
|
||||
|
||||
- (BOOL)isKindOfClassNamed:(const char *)aClassName
|
||||
{
|
||||
Class class;
|
||||
|
||||
if (aClassName!=NULL)
|
||||
for (class = self->isa; class!=Nil; class = class_get_super_class(class))
|
||||
if (!strcmp(class_get_class_name(class), aClassName))
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isMemberOfClassNamed:(const char *)aClassName
|
||||
{
|
||||
return ((aClassName!=NULL)
|
||||
&&!strcmp(class_get_class_name(self->isa), aClassName));
|
||||
}
|
||||
|
||||
+ (BOOL)instancesRespondTo:(SEL)aSel
|
||||
{
|
||||
return class_get_instance_method(self, aSel)!=METHOD_NULL;
|
||||
}
|
||||
|
||||
- (BOOL)respondsTo:(SEL)aSel
|
||||
{
|
||||
return ((object_is_instance(self)
|
||||
?class_get_instance_method(self->isa, aSel)
|
||||
:class_get_class_method(self->isa, aSel))!=METHOD_NULL);
|
||||
}
|
||||
|
||||
+ (IMP)instanceMethodFor:(SEL)aSel
|
||||
{
|
||||
return method_get_imp(class_get_instance_method(self, aSel));
|
||||
}
|
||||
|
||||
// Indicates if the receiving class or instance conforms to the given protocol
|
||||
// not usually overridden by subclasses
|
||||
//
|
||||
// Modified 9/5/94 to always search the class object's protocol list, rather
|
||||
// than the meta class.
|
||||
|
||||
+ (BOOL) conformsTo: (Protocol*)aProtocol
|
||||
{
|
||||
size_t i;
|
||||
struct objc_protocol_list* proto_list;
|
||||
id parent;
|
||||
|
||||
for (proto_list = ((Class)self)->protocols;
|
||||
proto_list; proto_list = proto_list->next)
|
||||
{
|
||||
for (i=0; i < proto_list->count; i++)
|
||||
{
|
||||
if ([proto_list->list[i] conformsTo: aProtocol])
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
if ((parent = [self superClass]))
|
||||
return [parent conformsTo: aProtocol];
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) conformsTo: (Protocol*)aProtocol
|
||||
{
|
||||
return [[self class] conformsTo:aProtocol];
|
||||
}
|
||||
|
||||
- (IMP)methodFor:(SEL)aSel
|
||||
{
|
||||
return (method_get_imp(object_is_instance(self)
|
||||
?class_get_instance_method(self->isa, aSel)
|
||||
:class_get_class_method(self->isa, aSel)));
|
||||
}
|
||||
|
||||
+ (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
|
||||
{
|
||||
return ((struct objc_method_description *)
|
||||
class_get_instance_method(self, aSel));
|
||||
}
|
||||
|
||||
- (struct objc_method_description *)descriptionForMethod:(SEL)aSel
|
||||
{
|
||||
return ((struct objc_method_description *)
|
||||
(object_is_instance(self)
|
||||
?class_get_instance_method(self->isa, aSel)
|
||||
:class_get_class_method(self->isa, aSel)));
|
||||
}
|
||||
|
||||
- perform:(SEL)aSel
|
||||
{
|
||||
IMP msg = objc_msg_lookup(self, aSel);
|
||||
if (!msg)
|
||||
return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
|
||||
return (*msg)(self, aSel);
|
||||
}
|
||||
|
||||
- perform:(SEL)aSel with:anObject
|
||||
{
|
||||
IMP msg = objc_msg_lookup(self, aSel);
|
||||
if (!msg)
|
||||
return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
|
||||
return (*msg)(self, aSel, anObject);
|
||||
}
|
||||
|
||||
- perform:(SEL)aSel with:anObject1 with:anObject2
|
||||
{
|
||||
IMP msg = objc_msg_lookup(self, aSel);
|
||||
if (!msg)
|
||||
return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
|
||||
return (*msg)(self, aSel, anObject1, anObject2);
|
||||
}
|
||||
|
||||
- (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
|
||||
{
|
||||
(void) argFrame; /* UNUSED */
|
||||
return (retval_t)[self doesNotRecognize: aSel];
|
||||
}
|
||||
|
||||
- (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
|
||||
{
|
||||
return objc_msg_sendv(self, aSel, argFrame);
|
||||
}
|
||||
|
||||
+ poseAs:(Class)aClassObject
|
||||
{
|
||||
return class_pose_as(self, aClassObject);
|
||||
}
|
||||
|
||||
- (Class)transmuteClassTo:(Class)aClassObject
|
||||
{
|
||||
if (object_is_instance(self))
|
||||
if (class_is_class(aClassObject))
|
||||
if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
|
||||
if ([self isKindOf:aClassObject])
|
||||
{
|
||||
Class old_isa = isa;
|
||||
isa = aClassObject;
|
||||
return old_isa;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- subclassResponsibility:(SEL)aSel
|
||||
{
|
||||
return [self error:"subclass should override %s", sel_get_name(aSel)];
|
||||
}
|
||||
|
||||
- notImplemented:(SEL)aSel
|
||||
{
|
||||
return [self error:"method %s not implemented", sel_get_name(aSel)];
|
||||
}
|
||||
|
||||
- shouldNotImplement:(SEL)aSel
|
||||
{
|
||||
return [self error:"%s should not implement %s",
|
||||
object_get_class_name(self), sel_get_name(aSel)];
|
||||
}
|
||||
|
||||
- doesNotRecognize:(SEL)aSel
|
||||
{
|
||||
return [self error:"%s does not recognize %s",
|
||||
object_get_class_name(self), sel_get_name(aSel)];
|
||||
}
|
||||
|
||||
- error:(const char *)aString, ...
|
||||
{
|
||||
#define FMT "error: %s (%s)\n%s\n"
|
||||
char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self))
|
||||
+((aString!=NULL)?strlen((char*)aString):0)+8)];
|
||||
va_list ap;
|
||||
|
||||
sprintf(fmt, FMT, object_get_class_name(self),
|
||||
object_is_instance(self)?"instance":"class",
|
||||
(aString!=NULL)?aString:"");
|
||||
va_start(ap, aString);
|
||||
objc_verror(self, OBJC_ERR_UNKNOWN, fmt, ap);
|
||||
va_end(ap);
|
||||
return nil;
|
||||
#undef FMT
|
||||
}
|
||||
|
||||
+ (int)version
|
||||
{
|
||||
return class_get_version(self);
|
||||
}
|
||||
|
||||
+ setVersion:(int)aVersion
|
||||
{
|
||||
class_set_version(self, aVersion);
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (int)streamVersion: (TypedStream*)aStream
|
||||
{
|
||||
if (aStream->mode == OBJC_READONLY)
|
||||
return objc_get_stream_class_version (aStream, self);
|
||||
else
|
||||
return class_get_version (self);
|
||||
}
|
||||
|
||||
// These are used to write or read the instance variables
|
||||
// declared in this particular part of the object. Subclasses
|
||||
// should extend these, by calling [super read/write: aStream]
|
||||
// before doing their own archiving. These methods are private, in
|
||||
// the sense that they should only be called from subclasses.
|
||||
|
||||
- read: (TypedStream*)aStream
|
||||
{
|
||||
(void) aStream; /* UNUSED */
|
||||
// [super read: aStream];
|
||||
return self;
|
||||
}
|
||||
|
||||
- write: (TypedStream*)aStream
|
||||
{
|
||||
(void) aStream; /* UNUSED */
|
||||
// [super write: aStream];
|
||||
return self;
|
||||
}
|
||||
|
||||
- awake
|
||||
{
|
||||
// [super awake];
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
@ -1,182 +0,0 @@
|
||||
/* This file contains the implementation of class Protocol.
|
||||
Copyright (C) 1993, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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/Protocol.h"
|
||||
#include "objc/objc-api.h"
|
||||
|
||||
/* Method description list */
|
||||
struct objc_method_description_list {
|
||||
int count;
|
||||
struct objc_method_description list[1];
|
||||
};
|
||||
|
||||
|
||||
@implementation Protocol
|
||||
{
|
||||
@private
|
||||
char *protocol_name;
|
||||
struct objc_protocol_list *protocol_list;
|
||||
struct objc_method_description_list *instance_methods, *class_methods;
|
||||
}
|
||||
|
||||
/* Obtaining attributes intrinsic to the protocol */
|
||||
|
||||
- (const char *)name
|
||||
{
|
||||
return protocol_name;
|
||||
}
|
||||
|
||||
/* Testing protocol conformance */
|
||||
|
||||
- (BOOL) conformsTo: (Protocol *)aProtocolObject
|
||||
{
|
||||
size_t i;
|
||||
struct objc_protocol_list* proto_list;
|
||||
|
||||
if (aProtocolObject == nil)
|
||||
return NO;
|
||||
|
||||
if (!strcmp(aProtocolObject->protocol_name, self->protocol_name))
|
||||
return YES;
|
||||
|
||||
for (proto_list = protocol_list; proto_list; proto_list = proto_list->next)
|
||||
{
|
||||
for (i=0; i < proto_list->count; i++)
|
||||
{
|
||||
if ([proto_list->list[i] conformsTo: aProtocolObject])
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* Looking up information specific to a protocol */
|
||||
|
||||
- (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel
|
||||
{
|
||||
int i;
|
||||
struct objc_protocol_list* proto_list;
|
||||
const char* name = sel_get_name (aSel);
|
||||
struct objc_method_description *result;
|
||||
|
||||
if (instance_methods)
|
||||
for (i = 0; i < instance_methods->count; i++)
|
||||
{
|
||||
if (!strcmp ((char*)instance_methods->list[i].name, name))
|
||||
return &(instance_methods->list[i]);
|
||||
}
|
||||
|
||||
for (proto_list = protocol_list; proto_list; proto_list = proto_list->next)
|
||||
{
|
||||
size_t j;
|
||||
for (j=0; j < proto_list->count; j++)
|
||||
{
|
||||
if ((result = [proto_list->list[j]
|
||||
descriptionForInstanceMethod: aSel]))
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel;
|
||||
{
|
||||
int i;
|
||||
struct objc_protocol_list* proto_list;
|
||||
const char* name = sel_get_name (aSel);
|
||||
struct objc_method_description *result;
|
||||
|
||||
if (class_methods)
|
||||
for (i = 0; i < class_methods->count; i++)
|
||||
{
|
||||
if (!strcmp ((char*)class_methods->list[i].name, name))
|
||||
return &(class_methods->list[i]);
|
||||
}
|
||||
|
||||
for (proto_list = protocol_list; proto_list; proto_list = proto_list->next)
|
||||
{
|
||||
size_t j;
|
||||
for (j=0; j < proto_list->count; j++)
|
||||
{
|
||||
if ((result = [proto_list->list[j]
|
||||
descriptionForClassMethod: aSel]))
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- (unsigned) hash
|
||||
{
|
||||
/* Compute a hash of the protocol_name; use the same hash algorithm
|
||||
* that we use for class names; protocol names and class names are
|
||||
* somewhat similar types of string spaces.
|
||||
*/
|
||||
int hash = 0, index;
|
||||
|
||||
for (index = 0; protocol_name[index] != '\0'; index++)
|
||||
{
|
||||
hash = (hash << 4) ^ (hash >> 28) ^ protocol_name[index];
|
||||
}
|
||||
|
||||
hash = (hash ^ (hash >> 10) ^ (hash >> 20));
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*
|
||||
* Equality between formal protocols is only formal (nothing to do
|
||||
* with actually checking the list of methods they have!). Two formal
|
||||
* Protocols are equal if and only if they have the same name.
|
||||
*
|
||||
* Please note (for comparisons with other implementations) that
|
||||
* checking the names is equivalent to checking that Protocol A
|
||||
* conforms to Protocol B and Protocol B conforms to Protocol A,
|
||||
* because this happens iff they have the same name. If they have
|
||||
* different names, A conforms to B if and only if A includes B, but
|
||||
* the situation where A includes B and B includes A is a circular
|
||||
* dependency between Protocols which is forbidden by the compiler, so
|
||||
* A conforms to B and B conforms to A with A and B having different
|
||||
* names is an impossible case.
|
||||
*/
|
||||
- (BOOL) isEqual: (id)obj
|
||||
{
|
||||
if (obj == self)
|
||||
return YES;
|
||||
|
||||
if ([obj isKindOf: [Protocol class]])
|
||||
{
|
||||
if (strcmp (protocol_name, ((Protocol *)obj)->protocol_name) == 0)
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
@end
|
||||
|
@ -1,104 +0,0 @@
|
||||
|
||||
GNU Objective C notes
|
||||
*********************
|
||||
|
||||
This document is to explain what has been done, and a little about how
|
||||
specific features differ from other implementations. The runtime has
|
||||
been completely rewritten in gcc 2.4. The earlier runtime had several
|
||||
severe bugs and was rather incomplete. The compiler has had several
|
||||
new features added as well.
|
||||
|
||||
This is not documentation for Objective C, it is usable to someone
|
||||
who knows Objective C from somewhere else.
|
||||
|
||||
|
||||
Runtime API functions
|
||||
=====================
|
||||
|
||||
The runtime is modeled after the NeXT Objective C runtime. That is,
|
||||
most functions have semantics as it is known from the NeXT. The
|
||||
names, however, have changed. All runtime API functions have names
|
||||
of lowercase letters and underscores as opposed to the
|
||||
`traditional' mixed case names.
|
||||
The runtime api functions are not documented as of now.
|
||||
Someone offered to write it, and did it, but we were not allowed to
|
||||
use it by his university (Very sad story). We have started writing
|
||||
the documentation over again. This will be announced in appropriate
|
||||
places when it becomes available.
|
||||
|
||||
|
||||
Protocols
|
||||
=========
|
||||
|
||||
Protocols are now fully supported. The semantics is exactly as on the
|
||||
NeXT. There is a flag to specify how protocols should be typechecked
|
||||
when adopted to classes. The normal typechecker requires that all
|
||||
methods in a given protocol must be implemented in the class that
|
||||
adopts it -- it is not enough to inherit them. The flag
|
||||
`-Wno-protocol' causes it to allow inherited methods, while
|
||||
`-Wprotocols' is the default which requires them defined.
|
||||
|
||||
|
||||
+load
|
||||
===========
|
||||
This method, if defined, is called for each class and category
|
||||
implementation when the class is loaded into the runtime. This method
|
||||
is not inherited, and is thus not called for a subclass that doesn't
|
||||
define it itself. Thus, each +load method is called exactly once by
|
||||
the runtime. The runtime invocation of this method is thread safe.
|
||||
|
||||
|
||||
+initialize
|
||||
===========
|
||||
|
||||
This method, if defined, is called before any other instance or class
|
||||
methods of that particular class. For the GNU runtime, this method is
|
||||
not inherited, and is thus not called as initializer for a subclass that
|
||||
doesn't define it itself. Thus, each +initialize method is called exactly
|
||||
once by the runtime (or never if no methods of that particular class is
|
||||
never called). It is wise to guard against multiple invocations anyway
|
||||
to remain portable with the NeXT runtime. The runtime invocation of
|
||||
this method is thread safe.
|
||||
|
||||
|
||||
Passivation/Activation/Typedstreams
|
||||
===================================
|
||||
|
||||
This is supported in the style of NeXT TypedStream's. Consult the
|
||||
headerfile Typedstreams.h for api functions. I (Kresten) have
|
||||
rewritten it in Objective C, but this implementation is not part of
|
||||
2.4, it is available from the GNU Objective C prerelease archive.
|
||||
There is one difference worth noting concerning objects stored with
|
||||
objc_write_object_reference (aka NXWriteObjectReference). When these
|
||||
are read back in, their object is not guaranteed to be available until
|
||||
the `-awake' method is called in the object that requests that object.
|
||||
To objc_read_object you must pass a pointer to an id, which is valid
|
||||
after exit from the function calling it (like e.g. an instance
|
||||
variable). In general, you should not use objects read in until the
|
||||
-awake method is called.
|
||||
|
||||
|
||||
Acknowledgements
|
||||
================
|
||||
|
||||
The GNU Objective C team: Geoffrey Knauth <gsk@marble.com> (manager),
|
||||
Tom Wood <wood@next.com> (compiler) and Kresten Krab Thorup
|
||||
<krab@iesd.auc.dk> (runtime) would like to thank a some people for
|
||||
participating in the development of the present GNU Objective C.
|
||||
|
||||
Paul Burchard <burchard@geom.umn.edu> and Andrew McCallum
|
||||
<mccallum@cs.rochester.edu> has been very helpful debugging the
|
||||
runtime. Eric Herring <herring@iesd.auc.dk> has been very helpful
|
||||
cleaning up after the documentation-copyright disaster and is now
|
||||
helping with the new documentation.
|
||||
|
||||
Steve Naroff <snaroff@next.com> and Richard Stallman
|
||||
<rms@gnu.ai.mit.edu> has been very helpful with implementation details
|
||||
in the compiler.
|
||||
|
||||
|
||||
Bug Reports
|
||||
===========
|
||||
|
||||
Please read the section `Submitting Bugreports' of the gcc manual
|
||||
before you submit any bugs.
|
@ -1,50 +0,0 @@
|
||||
==============================================================================
|
||||
README.threads - Wed Nov 29 15:16:24 EST 1995
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Limited documentation is available in the THREADS file.
|
||||
|
||||
This version has been tested on Sun Solaris, SGI Irix, and Windows NT.
|
||||
It should also work on any single threaded system.
|
||||
|
||||
Thanks go to the following people for help test and debug the library:
|
||||
|
||||
Scott Christley, scottc@ocbi.com
|
||||
Andrew McCallum, mccallum@cs.rochester.edu
|
||||
|
||||
galen
|
||||
gchunt@cs.rochester.edu
|
||||
|
||||
Any questions, bug reports, etc should be directed to:
|
||||
|
||||
Scott Christley, scottc@ocbi.com
|
||||
|
||||
Please do not bug Galen with email as he no longer supports the code.
|
||||
|
||||
==============================================================================
|
||||
Changes from prior releases (in revered chronological order):
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
* Fixed bug in copy part of sarray_realloc. I had an < which should
|
||||
have been <=. (Bug report from Scott).
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
* Support for DEC OSF/1 is definitely broken. My programs always
|
||||
seg-fault when I link with libpthreads.a.
|
||||
|
||||
* Thread id's are no longer int's, but are instead of type
|
||||
_objc_thread_t which is typedef'ed from a void *. An invalid thread
|
||||
id is denoted by NULL and not -1 as before.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
* Renamed thread-winnt.c to thread-win32.c to better reflect support
|
||||
for the API on both Windows NT and Windows 95 platforms.
|
||||
(Who knows, maybe even Win32s :-).
|
||||
|
||||
* Fixed bugs in Win32 support as per report from Scott Christley.
|
||||
|
||||
* Fixed bug in sarray_get as per report from Scott Christley.
|
||||
|
||||
|
@ -1,377 +0,0 @@
|
||||
This file describes in little detail the modifications to the
|
||||
Objective-C runtime needed to make it thread safe.
|
||||
|
||||
First off, kudos to Galen Hunt who is the author of this great work.
|
||||
|
||||
If you have an comments or just want to know where to
|
||||
send me money to express your undying gratitude for threading the
|
||||
Objective-C runtime you can reach Galen at:
|
||||
|
||||
gchunt@cs.rochester.edu
|
||||
|
||||
Any questions, comments, bug reports, etc. should send email either to the
|
||||
GCC bug account or to:
|
||||
|
||||
Scott Christley <scottc@net-community.com>
|
||||
|
||||
* Sarray Threading:
|
||||
|
||||
The most critical component of the Objective-C runtime is the sparse array
|
||||
structure (sarray). Sarrays store object selectors and implementations.
|
||||
Following in the tradition of the Objective-C runtime, my threading
|
||||
support assumes that fast message dispatching is far more important
|
||||
than *ANY* and *ALL* other operations. The message dispatching thus
|
||||
uses *NO* locks on any kind. In fact, if you look in sarray.h, you
|
||||
will notice that the message dispatching has not been modified.
|
||||
Instead, I have modified the sarray management functions so that all
|
||||
updates to the sarray data structure can be made in parallel will
|
||||
message dispatching.
|
||||
|
||||
To support concurrent message dispatching, no dynamically allocated
|
||||
sarray data structures are freed while more than one thread is
|
||||
operational. Sarray data structures that are no longer in use are
|
||||
kept in a linked list of garbage and are released whenever the program
|
||||
is operating with a single thread. The programmer can also flush the
|
||||
garbage list by calling sarray_remove_garbage when the programmer can
|
||||
ensure that no message dispatching is taking place concurrently. The
|
||||
amount of un-reclaimed sarray garbage should normally be extremely
|
||||
small in a real program as sarray structures are freed only when using
|
||||
the "poseAs" functionality and early in program initialization, which
|
||||
normally occurs while the program is single threaded.
|
||||
|
||||
******************************************************************************
|
||||
* Static Variables:
|
||||
|
||||
The following variables are either statically or globally defined. This list
|
||||
does not include variables which are internal to implementation dependent
|
||||
versions of thread-*.c.
|
||||
|
||||
The following threading designations are used:
|
||||
SAFE : Implicitly thread safe.
|
||||
SINGLE : Must only be used in single thread mode.
|
||||
MUTEX : Protected by single global mutex objc_runtime_mutex.
|
||||
UNUSED : Not used in the runtime.
|
||||
|
||||
Variable Name: Usage: Defined: Also used in:
|
||||
=========================== ====== ============ =====================
|
||||
__objc_class_hash MUTEX class.c
|
||||
__objc_class_links_resolved UNUSED class.c runtime.h
|
||||
__objc_class_number MUTEX class.c
|
||||
__objc_dangling_categories UNUSED init.c
|
||||
__objc_module_list MUTEX init.c
|
||||
__objc_selector_array MUTEX selector.c
|
||||
__objc_selector_hash MUTEX selector.c
|
||||
__objc_selector_max_index MUTEX selector.c sendmsg.c runtime.h
|
||||
__objc_selector_names MUTEX selector.c
|
||||
__objc_thread_exit_status SAFE thread.c
|
||||
__objc_uninstalled_dtable MUTEX sendmsg.c selector.c
|
||||
_objc_load_callback SAFE init.c objc-api.h
|
||||
_objc_lookup_class SAFE class.c objc-api.h
|
||||
_objc_object_alloc SINGLE objects.c objc-api.h
|
||||
_objc_object_copy SINGLE objects.c objc-api.h
|
||||
_objc_object_dispose SINGLE objects.c objc-api.h
|
||||
frwd_sel SAFE2 sendmsg.c
|
||||
idxsize MUTEX sarray.c sendmsg.c sarray.h
|
||||
initialize_sel SAFE2 sendmsg.c
|
||||
narrays MUTEX sarray.c sendmsg.c sarray.h
|
||||
nbuckets MUTEX sarray.c sendmsg.c sarray.h
|
||||
nindices MUTEX sarray.c sarray.h
|
||||
previous_constructors SAFE1 init.c
|
||||
proto_class SAFE1 init.c
|
||||
unclaimed_categories MUTEX init.c
|
||||
unclaimed_proto_list MUTEX init.c
|
||||
uninitialized_statics MUTEX init.c
|
||||
|
||||
Notes:
|
||||
1) Initialized once in unithread mode.
|
||||
2) Initialized value will always be same, guaranteed by lock on selector
|
||||
hash table.
|
||||
|
||||
|
||||
******************************************************************************
|
||||
* Frontend/Backend design:
|
||||
|
||||
The design of the Objective-C runtime thread and mutex functions utilizes a
|
||||
frontend/backend implementation.
|
||||
|
||||
The frontend, as characterized by the files thr.h and thr.c, is a set
|
||||
of platform independent structures and functions which represent the
|
||||
user interface. Objective-C programs should use these structures and
|
||||
functions for their thread and mutex work if they wish to maintain a
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
objc_thread_yield() -> __objc_thread_yield() -> system yield function
|
||||
|
||||
This has two extra function calls over calling the platform specific function
|
||||
explicitly, but the issue is whether only the overhead of a single function
|
||||
is necessary.
|
||||
|
||||
objc_thread_yield() -> system yield function
|
||||
|
||||
This breaks the public/private dichotomy between the frontend/backend
|
||||
for the sake of efficiency. It is possible to just use a preprocessor
|
||||
define so as to eliminate the extra function call:
|
||||
|
||||
#define objc_thread_yield() __objc_thread_yield()
|
||||
|
||||
This has the undesirable effect that if objc_thread_yield is actually
|
||||
turned into a function based upon future need; then ObjC programs which
|
||||
access the thread functions would need to be recompiled versus just
|
||||
being relinked.
|
||||
|
||||
******************************************************************************
|
||||
* Threads:
|
||||
|
||||
The thread system attempts to create multiple threads using whatever
|
||||
operating system or library thread support is available. It does
|
||||
assume that all system functions are thread safe. Notably this means
|
||||
that the system implementation of malloc and free must be thread safe.
|
||||
If a system has multiple processors, the threads are configured for
|
||||
full parallel processing.
|
||||
|
||||
* Backend initialization functions
|
||||
|
||||
__objc_init_thread_system(void), int
|
||||
Initialize the thread subsystem. Called once by __objc_exec_class.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
__objc_close_thread_system(void), int
|
||||
Closes the thread subsystem, not currently guaranteed to be called.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
*****
|
||||
* Frontend thread functions
|
||||
* User programs should use these functions.
|
||||
|
||||
objc_thread_detach(SEL selector, id object, id argument), objc_thread_t
|
||||
Creates and detaches a new thread. The new thread starts by
|
||||
sending the given selector with a single argument to the
|
||||
given object.
|
||||
|
||||
objc_thread_set_priority(int priority), int
|
||||
Sets a thread's relative priority within the program. Valid
|
||||
options are:
|
||||
|
||||
OBJC_THREAD_INTERACTIVE_PRIORITY
|
||||
OBJC_THREAD_BACKGROUND_PRIORITY
|
||||
OBJC_THREAD_LOW_PRIORITY
|
||||
|
||||
objc_thread_get_priority(void), int
|
||||
Query a thread's priority.
|
||||
|
||||
objc_thread_yield(void), void
|
||||
Yields processor to another thread with equal or higher
|
||||
priority. It is up to the system scheduler to determine if
|
||||
the processor is taken or not.
|
||||
|
||||
objc_thread_exit(void), int
|
||||
Terminates a thread. If this is the last thread executing
|
||||
then the program will terminate.
|
||||
|
||||
objc_thread_id(void), int
|
||||
Returns the current thread's id.
|
||||
|
||||
objc_thread_set_data(void *value), int
|
||||
Set a pointer to the thread's local storage. Local storage is
|
||||
thread specific.
|
||||
|
||||
objc_thread_get_data(void), void *
|
||||
Returns the pointer to the thread's local storage.
|
||||
|
||||
*****
|
||||
* Backend thread functions
|
||||
* User programs should *NOT* directly call these functions.
|
||||
|
||||
__objc_thread_detach(void (*func)(void *arg), void *arg), objc_thread_t
|
||||
Spawns a new thread executing func, called by objc_thread_detach.
|
||||
Return NULL if error otherwise return thread id.
|
||||
|
||||
__objc_thread_set_priority(int priority), int
|
||||
Set the thread's priority, called by objc_thread_set_priority.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
__objc_thread_get_priority(void), int
|
||||
Query a thread's priority, called by objc_thread_get_priority.
|
||||
Return -1 if error otherwise return the priority.
|
||||
|
||||
__objc_thread_yield(void), void
|
||||
Yields the processor, called by objc_thread_yield.
|
||||
|
||||
__objc_thread_exit(void), int
|
||||
Terminates the thread, called by objc_thread_exit.
|
||||
Return -1 if error otherwise function does not return.
|
||||
|
||||
__objc_thread_id(void), objc_thread_t
|
||||
Returns the current thread's id, called by objc_thread_id.
|
||||
Return -1 if error otherwise return thread id.
|
||||
|
||||
__objc_thread_set_data(void *value), int
|
||||
Set pointer for thread local storage, called by objc_thread_set_data.
|
||||
Returns -1 if error otherwise return 0.
|
||||
|
||||
__objc_thread_get_data(void), void *
|
||||
Returns the pointer to the thread's local storage.
|
||||
Returns NULL if error, called by objc_thread_get_data.
|
||||
|
||||
|
||||
******************************************************************************
|
||||
* Mutexes:
|
||||
|
||||
Mutexes can be locked recursively. Each locked mutex remembers
|
||||
its owner (by thread id) and how many times it has been locked. The
|
||||
last unlock on a mutex removes the system lock and allows other
|
||||
threads to access the mutex.
|
||||
|
||||
*****
|
||||
* Frontend mutex functions
|
||||
* User programs should use these functions.
|
||||
|
||||
objc_mutex_allocate(void), objc_mutex_t
|
||||
Allocates a new mutex. Mutex is initially unlocked.
|
||||
Return NULL if error otherwise return mutex pointer.
|
||||
|
||||
objc_mutex_deallocate(objc_mutex_t mutex), int
|
||||
Free a mutex. Before freeing the mutex, makes sure that no
|
||||
one else is using it.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
objc_mutex_lock(objc_mutex_t mutex), int
|
||||
Locks a mutex. As mentioned earlier, the same thread may call
|
||||
this routine repeatedly.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
objc_mutex_trylock(objc_mutex_t mutex), int
|
||||
Attempts to lock a mutex. If lock on mutex can be acquired
|
||||
then function operates exactly as objc_mutex_lock.
|
||||
Return -1 if failed to acquire lock otherwise return 0.
|
||||
|
||||
objc_mutex_unlock(objc_mutex_t mutex), int
|
||||
Unlocks the mutex by one level. Other threads may not acquire
|
||||
the mutex until this thread has released all locks on it.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
*****
|
||||
* Backend mutex functions
|
||||
* User programs should *NOT* directly call these functions.
|
||||
|
||||
__objc_mutex_allocate(objc_mutex_t mutex), int
|
||||
Allocates a new mutex, called by objc_mutex_allocate.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
__objc_mutex_deallocate(objc_mutex_t mutex), int
|
||||
Free a mutex, called by objc_mutex_deallocate.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
__objc_mutex_lock(objc_mutex_t mutex), int
|
||||
Locks a mutex, called by objc_mutex_lock.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
__objc_mutex_trylock(objc_mutex_t mutex), int
|
||||
Attempts to lock a mutex, called by objc_mutex_trylock.
|
||||
Return -1 if failed to acquire lock or error otherwise return 0.
|
||||
|
||||
__objc_mutex_unlock(objc_mutex_t mutex), int
|
||||
Unlocks the mutex, called by objc_mutex_unlock.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
******************************************************************************
|
||||
* Condition Mutexes:
|
||||
|
||||
Mutexes can be locked recursively. Each locked mutex remembers
|
||||
its owner (by thread id) and how many times it has been locked. The
|
||||
last unlock on a mutex removes the system lock and allows other
|
||||
threads to access the mutex.
|
||||
|
||||
*
|
||||
* Frontend condition mutex functions
|
||||
* User programs should use these functions.
|
||||
*
|
||||
|
||||
objc_condition_allocate(void), objc_condition_t
|
||||
Allocate a condition mutex.
|
||||
Return NULL if error otherwise return condition pointer.
|
||||
|
||||
objc_condition_deallocate(objc_condition_t condition), int
|
||||
Deallocate a condition. Note that this includes an implicit
|
||||
condition_broadcast to insure that waiting threads have the
|
||||
opportunity to wake. It is legal to dealloc a condition only
|
||||
if no other thread is/will be using it. Does NOT check for
|
||||
other threads waiting but just wakes them up.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int
|
||||
Wait on the condition unlocking the mutex until objc_condition_signal()
|
||||
or objc_condition_broadcast() are called for the same condition. The
|
||||
given mutex *must* have the depth 1 so that it can be unlocked
|
||||
here, for someone else can lock it and signal/broadcast the condition.
|
||||
The mutex is used to lock access to the shared data that make up the
|
||||
"condition" predicate.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
objc_condition_broadcast(objc_condition_t condition), int
|
||||
Wake up all threads waiting on this condition. It is recommended that
|
||||
the called would lock the same mutex as the threads in
|
||||
objc_condition_wait before changing the "condition predicate"
|
||||
and make this call and unlock it right away after this call.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
objc_condition_signal(objc_condition_t condition), int
|
||||
Wake up one thread waiting on this condition.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
*
|
||||
* Backend condition mutex functions
|
||||
* User programs should *NOT* directly call these functions.
|
||||
*
|
||||
|
||||
__objc_condition_allocate(objc_condition_t condition), int
|
||||
Allocate a condition mutex, called by objc_condition_allocate.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
__objc_condition_deallocate(objc_condition_t condition), int
|
||||
Deallocate a condition, called by objc_condition_deallocate.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int
|
||||
Wait on the condition, called by objc_condition_wait.
|
||||
Return -1 if error otherwise return 0 when condition is met.
|
||||
|
||||
__objc_condition_broadcast(objc_condition_t condition), int
|
||||
Wake up all threads waiting on this condition.
|
||||
Called by objc_condition_broadcast.
|
||||
Return -1 if error otherwise return 0.
|
||||
|
||||
__objc_condition_signal(objc_condition_t condition), int
|
||||
Wake up one thread waiting on this condition.
|
||||
Called by objc_condition_signal.
|
||||
Return -1 if error otherwise return 0.
|
@ -1,23 +0,0 @@
|
||||
This readme refers to the file thr-mach.c.
|
||||
|
||||
Under mach, thread priorities are kinda strange-- any given thread has
|
||||
a MAXIMUM priority and a BASE priority. The BASE priority is the
|
||||
current priority of the thread and the MAXIMUM is the maximum possible
|
||||
priority the thread can assume. The developer can lower, but never
|
||||
raise the maximum priority.
|
||||
|
||||
The gcc concept of thread priorities is that they run at one of three
|
||||
levels; interactive, background, and low.
|
||||
|
||||
Under mach, this is translated to:
|
||||
|
||||
interactive -- set priority to maximum
|
||||
background -- set priority to 2/3 of maximum
|
||||
low -- set priority to 1/3 of maximum
|
||||
|
||||
This means that it is possible for a thread with the priority of
|
||||
interactive to actually run at a lower priority than another thread
|
||||
with a background, or even low, priority if the developer has modified
|
||||
the maximum priority.
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
dnl Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2004
|
||||
dnl 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.
|
||||
|
||||
m4_include(../config/acx.m4)
|
||||
m4_include(../config/no-executables.m4)
|
||||
|
||||
m4_include(../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(yes,no,[
|
||||
AC_DEFUN([AM_PROG_LIBTOOL],)
|
||||
AC_DEFUN([AC_LIBTOOL_DLOPEN],)
|
||||
AC_DEFUN([AC_LIBLTDL_CONVENIENCE],)
|
||||
AC_SUBST(LIBTOOL)
|
||||
])
|
158
contrib/libobjc/aclocal.m4
vendored
158
contrib/libobjc/aclocal.m4
vendored
@ -1,158 +0,0 @@
|
||||
# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
# 2005 Free Software Foundation, Inc.
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
|
||||
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
|
||||
#
|
||||
# Of course, Automake must honor this variable whenever it calls a
|
||||
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||
# depending on how configure is run. This is pretty annoying, since
|
||||
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||
# source directory, any form will work fine, but in subdirectories a
|
||||
# relative path needs to be adjusted first.
|
||||
#
|
||||
# $ac_aux_dir/missing
|
||||
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||
# $top_srcdir/$ac_aux_dir/missing
|
||||
# fails if $ac_aux_dir is absolute,
|
||||
# fails when called from a subdirectory in a VPATH build with
|
||||
# a relative $ac_aux_dir
|
||||
#
|
||||
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||
# harmless because $srcdir is `.', but things will broke when you
|
||||
# start a VPATH build or use an absolute $srcdir.
|
||||
#
|
||||
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||
# and then we would define $MISSING as
|
||||
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||
# This will work as long as MISSING is not called from configure, because
|
||||
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||
# However there are other variables, like CC, which are often used in
|
||||
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||
#
|
||||
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||
# configured tree to be moved without reconfiguration.
|
||||
|
||||
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
||||
[dnl Rely on autoconf to set up CDPATH properly.
|
||||
AC_PREREQ([2.50])dnl
|
||||
# expand $ac_aux_dir to an absolute path
|
||||
am_aux_dir=`cd $ac_aux_dir && pwd`
|
||||
])
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 7
|
||||
|
||||
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||
# -------------------------------------
|
||||
# Define a conditional.
|
||||
AC_DEFUN([AM_CONDITIONAL],
|
||||
[AC_PREREQ(2.52)dnl
|
||||
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||
AC_SUBST([$1_TRUE])
|
||||
AC_SUBST([$1_FALSE])
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
$1_FALSE='#'
|
||||
else
|
||||
$1_TRUE='#'
|
||||
$1_FALSE=
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||
AC_MSG_ERROR([[conditional "$1" was never defined.
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
|
||||
# From Jim Meyering
|
||||
|
||||
# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 4
|
||||
|
||||
AC_DEFUN([AM_MAINTAINER_MODE],
|
||||
[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
|
||||
dnl maintainer-mode is disabled by default
|
||||
AC_ARG_ENABLE(maintainer-mode,
|
||||
[ --enable-maintainer-mode enable make rules and dependencies not useful
|
||||
(and sometimes confusing) to the casual installer],
|
||||
USE_MAINTAINER_MODE=$enableval,
|
||||
USE_MAINTAINER_MODE=no)
|
||||
AC_MSG_RESULT([$USE_MAINTAINER_MODE])
|
||||
AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
|
||||
MAINT=$MAINTAINER_MODE_TRUE
|
||||
AC_SUBST(MAINT)dnl
|
||||
]
|
||||
)
|
||||
|
||||
AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 3
|
||||
|
||||
# AM_PROG_CC_C_O
|
||||
# --------------
|
||||
# Like AC_PROG_CC_C_O, but changed for automake.
|
||||
AC_DEFUN([AM_PROG_CC_C_O],
|
||||
[AC_REQUIRE([AC_PROG_CC_C_O])dnl
|
||||
AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
# FIXME: we rely on the cache variable name because
|
||||
# there is no other way.
|
||||
set dummy $CC
|
||||
ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
|
||||
if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then
|
||||
# Losing compiler, so override with the script.
|
||||
# FIXME: It is wrong to rewrite CC.
|
||||
# But if we don't then we get into trouble of one sort or another.
|
||||
# A longer-term fix would be to have automake use am__CC in this case,
|
||||
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
|
||||
CC="$am_aux_dir/compile $CC"
|
||||
fi
|
||||
])
|
||||
|
||||
m4_include([../config/multi.m4])
|
||||
m4_include([acinclude.m4])
|
File diff suppressed because it is too large
Load Diff
@ -1,703 +0,0 @@
|
||||
/* GNU Objective C Runtime class related functions
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 2001, 2002
|
||||
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 GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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. */
|
||||
|
||||
/*
|
||||
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 "objc/runtime.h" /* the kitchen sink */
|
||||
#include "objc/sarray.h"
|
||||
|
||||
#include "objc/objc.h"
|
||||
#include "objc/objc-api.h"
|
||||
#include "objc/thr.h"
|
||||
|
||||
/* 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 (void)
|
||||
{
|
||||
/* 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 (void)
|
||||
{
|
||||
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 (void)
|
||||
{
|
||||
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. */
|
||||
BOOL __objc_class_links_resolved = NO; /* !T:UNUSED */
|
||||
|
||||
|
||||
void
|
||||
__objc_init_class_tables (void)
|
||||
{
|
||||
/* Allocate the class hash table. */
|
||||
|
||||
if (__class_table_lock)
|
||||
return;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
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. */
|
||||
void
|
||||
__objc_add_class_to_hash (Class class)
|
||||
{
|
||||
Class h_class;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
/* Make sure the table is there. */
|
||||
assert (__class_table_lock);
|
||||
|
||||
/* 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 = class_table_get_safe (class->name);
|
||||
if (! h_class)
|
||||
{
|
||||
/* The class isn't in the hash table. Add the class and assign a class
|
||||
number. */
|
||||
static unsigned int class_number = 1;
|
||||
|
||||
CLS_SETNUMBER (class, class_number);
|
||||
CLS_SETNUMBER (class->class_pointer, class_number);
|
||||
|
||||
++class_number;
|
||||
class_table_insert (class->name, class);
|
||||
}
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
Class
|
||||
objc_lookup_class (const char *name)
|
||||
{
|
||||
Class class;
|
||||
|
||||
class = class_table_get_safe (name);
|
||||
|
||||
if (class)
|
||||
return class;
|
||||
|
||||
if (_objc_lookup_class)
|
||||
return (*_objc_lookup_class) (name);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
Class
|
||||
objc_get_class (const char *name)
|
||||
{
|
||||
Class class;
|
||||
|
||||
class = class_table_get_safe (name);
|
||||
|
||||
if (class)
|
||||
return class;
|
||||
|
||||
if (_objc_lookup_class)
|
||||
class = (*_objc_lookup_class) (name);
|
||||
|
||||
if (class)
|
||||
return class;
|
||||
|
||||
objc_error (nil, OBJC_ERR_BAD_CLASS,
|
||||
"objc runtime: cannot find class %s\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MetaClass
|
||||
objc_get_meta_class (const char *name)
|
||||
{
|
||||
return objc_get_class (name)->class_pointer;
|
||||
}
|
||||
|
||||
/* This function provides a way to enumerate all the classes in the
|
||||
executable. Pass *ENUM_STATE == NULL to start the enumeration. The
|
||||
function will return 0 when there are no more classes.
|
||||
For example:
|
||||
id class;
|
||||
void *es = NULL;
|
||||
while ((class = objc_next_class (&es)))
|
||||
... do something with class;
|
||||
*/
|
||||
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);
|
||||
|
||||
class = class_table_next ((struct class_table_enumerator **) enum_state);
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
|
||||
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. */
|
||||
void
|
||||
__objc_resolve_class_links (void)
|
||||
{
|
||||
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. */
|
||||
while ((class1 = class_table_next (&es)))
|
||||
{
|
||||
/* 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. */
|
||||
class1->class_pointer->class_pointer = object_class->class_pointer;
|
||||
|
||||
if (! CLS_ISRESOLV (class1))
|
||||
{
|
||||
CLS_SETRESOLV (class1);
|
||||
CLS_SETRESOLV (class1->class_pointer);
|
||||
|
||||
if (class1->super_class)
|
||||
{
|
||||
Class a_super_class
|
||||
= objc_get_class ((char *) class1->super_class);
|
||||
|
||||
assert (a_super_class);
|
||||
|
||||
DEBUG_PRINTF ("making class connections for: %s\n",
|
||||
class1->name);
|
||||
|
||||
/* 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. */
|
||||
if (a_super_class->class_pointer)
|
||||
{
|
||||
class1->class_pointer->sibling_class
|
||||
= a_super_class->class_pointer->subclass_list;
|
||||
a_super_class->class_pointer->subclass_list
|
||||
= class1->class_pointer;
|
||||
}
|
||||
}
|
||||
else /* A root class, make its meta object be a subclass of
|
||||
Object. */
|
||||
{
|
||||
class1->class_pointer->sibling_class
|
||||
= object_class->subclass_list;
|
||||
object_class->subclass_list = class1->class_pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign superclass links. */
|
||||
es = NULL;
|
||||
while ((class1 = class_table_next (&es)))
|
||||
{
|
||||
Class sub_class;
|
||||
for (sub_class = class1->subclass_list; sub_class;
|
||||
sub_class = sub_class->sibling_class)
|
||||
{
|
||||
sub_class->super_class = class1;
|
||||
if (CLS_ISCLASS (sub_class))
|
||||
sub_class->class_pointer->super_class = class1->class_pointer;
|
||||
}
|
||||
}
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define CLASSOF(c) ((c)->class_pointer)
|
||||
|
||||
Class
|
||||
class_pose_as (Class impostor, Class super_class)
|
||||
{
|
||||
if (! CLS_ISRESOLV (impostor))
|
||||
__objc_resolve_class_links ();
|
||||
|
||||
/* Preconditions */
|
||||
assert (impostor);
|
||||
assert (super_class);
|
||||
assert (impostor->super_class == super_class);
|
||||
assert (CLS_ISCLASS (impostor));
|
||||
assert (CLS_ISCLASS (super_class));
|
||||
assert (impostor->instance_size == super_class->instance_size);
|
||||
|
||||
{
|
||||
Class *subclass = &(super_class->subclass_list);
|
||||
|
||||
/* Move subclasses of super_class to impostor. */
|
||||
while (*subclass)
|
||||
{
|
||||
Class nextSub = (*subclass)->sibling_class;
|
||||
|
||||
if (*subclass != impostor)
|
||||
{
|
||||
Class sub = *subclass;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
*subclass = nextSub;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
impostor->sibling_class = 0;
|
||||
CLASSOF (impostor)->sibling_class = 0;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
class_table_replace (super_class, impostor);
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
|
||||
/* Next, we update the dispatch tables... */
|
||||
__objc_update_dispatch_table_for_class (CLASSOF (impostor));
|
||||
__objc_update_dispatch_table_for_class (impostor);
|
||||
|
||||
return impostor;
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if the compiler has a thread header that is non single. */
|
||||
#undef HAVE_GTHR_DEFAULT
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <sched.h> header file. */
|
||||
#undef HAVE_SCHED_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
#undef NO_MINUS_C_MINUS_O
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define if the compiler is configured for setjmp/longjmp exceptions. */
|
||||
#undef SJLJ_EXCEPTIONS
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
6595
contrib/libobjc/configure
vendored
6595
contrib/libobjc/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -1,296 +0,0 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004
|
||||
# 2005, 2006 Free Software Foundation, Inc.
|
||||
# Originally contributed by Dave Love (d.love@dl.ac.uk).
|
||||
#
|
||||
#This file is part of GCC.
|
||||
#
|
||||
#GCC 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.
|
||||
#
|
||||
#GCC 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 GCC; see the file COPYING. If not, write to
|
||||
#the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
#02110-1301, USA.
|
||||
|
||||
AC_PREREQ(2.59)
|
||||
AC_INIT(package-unused, version-unused,, libobjc)
|
||||
AC_CONFIG_SRCDIR([objc/objc.h])
|
||||
GCC_TOPLEV_SUBDIRS
|
||||
|
||||
# We need the following definitions because AC_PROG_LIBTOOL relies on them
|
||||
PACKAGE=libobjc
|
||||
# Version is pulled out to make it a bit easier to change using sed.
|
||||
VERSION=2:0:0
|
||||
AC_SUBST(VERSION)
|
||||
|
||||
# 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
|
||||
|
||||
# -------
|
||||
# Options
|
||||
# -------
|
||||
|
||||
# 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])
|
||||
|
||||
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])
|
||||
AC_MSG_RESULT($version_specific_libs)
|
||||
|
||||
AC_ARG_ENABLE(objc-gc,
|
||||
[ --enable-objc-gc enable the use of Boehm's garbage collector with
|
||||
the GNU Objective-C runtime.],
|
||||
[case $enable_objc_gc in
|
||||
no)
|
||||
OBJC_BOEHM_GC=''
|
||||
OBJC_BOEHM_GC_INCLUDES=''
|
||||
;;
|
||||
*)
|
||||
OBJC_BOEHM_GC=libobjc_gc.la
|
||||
OBJC_BOEHM_GC_INCLUDES='-I$(top_srcdir)/../boehm-gc/include -I../boehm-gc/include'
|
||||
;;
|
||||
esac],
|
||||
[OBJC_BOEHM_GC=''; OBJC_BOEHM_GC_INCLUDES=''])
|
||||
AC_SUBST(OBJC_BOEHM_GC)
|
||||
AC_SUBST(OBJC_BOEHM_GC_INCLUDES)
|
||||
|
||||
# -----------
|
||||
# Directories
|
||||
# -----------
|
||||
|
||||
# Find the rest of the source tree framework.
|
||||
AM_ENABLE_MULTILIB(, ..)
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
ACX_NONCANONICAL_TARGET
|
||||
|
||||
# Export source directory.
|
||||
# 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.
|
||||
case $srcdir in
|
||||
[\\/$]* | ?:[\\/]*) glibcpp_srcdir=${srcdir} ;;
|
||||
*) glibcpp_srcdir=`cd "$srcdir" && ${PWDCMD-pwd} || echo "$srcdir"` ;;
|
||||
esac
|
||||
AC_SUBST(glibcpp_srcdir)
|
||||
|
||||
# Calculate toolexeclibdir
|
||||
# Also toolexecdir, though it's only used in toolexeclibdir
|
||||
case ${version_specific_libs} in
|
||||
yes)
|
||||
# Need the gcc compiler version to know where to install libraries
|
||||
# and header files if --enable-version-specific-runtime-libs option
|
||||
# is selected.
|
||||
toolexecdir='$(libdir)/gcc/$(target_noncanonical)'
|
||||
toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
|
||||
;;
|
||||
no)
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
# Install a library built with a cross compiler in tooldir, not libdir.
|
||||
toolexecdir='$(exec_prefix)/$(target_noncanonical)'
|
||||
toolexeclibdir='$(toolexecdir)/lib'
|
||||
else
|
||||
toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)'
|
||||
toolexeclibdir='$(libdir)'
|
||||
fi
|
||||
multi_os_directory=`$CC -print-multi-os-directory`
|
||||
case $multi_os_directory in
|
||||
.) ;; # Avoid trailing /.
|
||||
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(toolexecdir)
|
||||
AC_SUBST(toolexeclibdir)
|
||||
|
||||
# Figure out if we want to name the include directory and the
|
||||
# library name changes differently.
|
||||
includedirname=include
|
||||
libext=
|
||||
case "${host}" in
|
||||
*-darwin*)
|
||||
# Darwin is the only target so far that needs a different include directory.
|
||||
includedirname=include-gnu-runtime
|
||||
libext=-gnu
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(includedirname)
|
||||
AC_SUBST(libext)
|
||||
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
|
||||
# --------
|
||||
# Programs
|
||||
# --------
|
||||
|
||||
GCC_NO_EXECUTABLES
|
||||
|
||||
# We must force CC to /not/ be a precious variable; otherwise
|
||||
# the wrong, non-multilib-adjusted value will be used in multilibs.
|
||||
# As a side effect, we have to subst CFLAGS ourselves.
|
||||
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
|
||||
m4_define([_AC_ARG_VAR_PRECIOUS],[])
|
||||
AC_PROG_CC
|
||||
m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
|
||||
|
||||
# extra LD Flags which are required for targets
|
||||
case "${host}" in
|
||||
*-darwin*)
|
||||
# Darwin needs -single_module when linking libobjc
|
||||
extra_ldflags_libobjc=-Wl,-single_module
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(extra_ldflags_libobjc)
|
||||
|
||||
AC_SUBST(CFLAGS)
|
||||
|
||||
AC_CHECK_TOOL(AS, as)
|
||||
AC_CHECK_TOOL(AR, ar)
|
||||
AC_CHECK_TOOL(RANLIB, ranlib, :)
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
# Enable Win32 DLL on MS Windows - FIXME
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
AM_PROG_CC_C_O
|
||||
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
# -------
|
||||
# Headers
|
||||
# -------
|
||||
|
||||
# Sanity check for the cross-compilation case:
|
||||
AC_CHECK_HEADER(stdio.h,:,
|
||||
[AC_MSG_ERROR([Can't find stdio.h.
|
||||
You must have a usable C system for the target already installed, at least
|
||||
including headers and, preferably, the library, before you can configure
|
||||
the Objective C runtime system. If necessary, install gcc now with
|
||||
\`LANGUAGES=c', then the target library, then build with \`LANGUAGES=objc'.])])
|
||||
|
||||
AC_HEADER_STDC
|
||||
|
||||
AC_CHECK_HEADERS(sched.h)
|
||||
|
||||
# -----------
|
||||
# Miscellanea
|
||||
# -----------
|
||||
|
||||
AC_MSG_CHECKING([for thread model used by GCC])
|
||||
target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
|
||||
AC_MSG_RESULT([$target_thread_file])
|
||||
|
||||
if test $target_thread_file != single; then
|
||||
AC_DEFINE(HAVE_GTHR_DEFAULT, 1,
|
||||
[Define if the compiler has a thread header that is non single.])
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING([for exception model to use])
|
||||
AC_LANG_PUSH(C)
|
||||
AC_ARG_ENABLE(sjlj-exceptions,
|
||||
AS_HELP_STRING([--enable-sjlj-exceptions],
|
||||
[force use of builtin_setjmp for exceptions]),
|
||||
[:],
|
||||
[dnl Botheration. Now we've got to detect the exception model.
|
||||
dnl Link tests against libgcc.a are problematic since -- at least
|
||||
dnl as of this writing -- we've not been given proper -L bits for
|
||||
dnl single-tree newlib and libgloss.
|
||||
dnl
|
||||
dnl This is what AC_TRY_COMPILE would do if it didn't delete the
|
||||
dnl conftest files before we got a change to grep them first.
|
||||
cat > conftest.$ac_ext << EOF
|
||||
[#]line __oline__ "configure"
|
||||
@interface Frob
|
||||
@end
|
||||
@implementation Frob
|
||||
@end
|
||||
int proc();
|
||||
int foo()
|
||||
{
|
||||
@try {
|
||||
return proc();
|
||||
}
|
||||
@catch (Frob* ex) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
old_CFLAGS="$CFLAGS"
|
||||
dnl work around that we don't have Objective-C support in autoconf
|
||||
CFLAGS="-x objective-c -fgnu-runtime -fobjc-exceptions -S"
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1 ; then
|
||||
enable_sjlj_exceptions=yes
|
||||
elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then
|
||||
enable_sjlj_exceptions=no
|
||||
fi
|
||||
fi
|
||||
CFLAGS="$old_CFLAGS"
|
||||
rm -f conftest*])
|
||||
if test x$enable_sjlj_exceptions = xyes; then
|
||||
AC_DEFINE(SJLJ_EXCEPTIONS, 1,
|
||||
[Define if the compiler is configured for setjmp/longjmp exceptions.])
|
||||
ac_exception_model_name=sjlj
|
||||
elif test x$enable_sjlj_exceptions = xno; then
|
||||
ac_exception_model_name="call frame"
|
||||
else
|
||||
AC_MSG_ERROR([unable to detect exception model])
|
||||
fi
|
||||
AC_LANG_POP(C)
|
||||
AC_MSG_RESULT($ac_exception_model_name)
|
||||
|
||||
# ------
|
||||
# Output
|
||||
# ------
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
|
||||
AC_CONFIG_COMMANDS([default],
|
||||
[[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
|
||||
LD="${ORIGINAL_LD_FOR_MULTILIBS}"
|
||||
. ${multi_basedir}/config-ml.in
|
||||
fi
|
||||
fi]],
|
||||
[[srcdir=${srcdir}
|
||||
host=${host}
|
||||
target=${target}
|
||||
with_target_subdir=${with_target_subdir}
|
||||
with_multisubdir=${with_multisubdir}
|
||||
ac_configure_args="--enable-multilib ${ac_configure_args}"
|
||||
multi_basedir=${multi_basedir}
|
||||
CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
ORIGINAL_LD_FOR_MULTILIBS="${ORIGINAL_LD_FOR_MULTILIBS}"
|
||||
]])
|
||||
|
||||
AC_OUTPUT
|
File diff suppressed because it is too large
Load Diff
@ -1,376 +0,0 @@
|
||||
/* The implementation of exception handling primitives for Objective-C.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 <stdlib.h>
|
||||
#include "config.h"
|
||||
#include "objc/objc-api.h"
|
||||
#include "unwind.h"
|
||||
#include "unwind-pe.h"
|
||||
|
||||
|
||||
/* This is the exception class we report -- "GNUCOBJC". */
|
||||
#define __objc_exception_class \
|
||||
((((((((_Unwind_Exception_Class) 'G' \
|
||||
<< 8 | (_Unwind_Exception_Class) 'N') \
|
||||
<< 8 | (_Unwind_Exception_Class) 'U') \
|
||||
<< 8 | (_Unwind_Exception_Class) 'C') \
|
||||
<< 8 | (_Unwind_Exception_Class) 'O') \
|
||||
<< 8 | (_Unwind_Exception_Class) 'B') \
|
||||
<< 8 | (_Unwind_Exception_Class) 'J') \
|
||||
<< 8 | (_Unwind_Exception_Class) 'C')
|
||||
|
||||
/* This is the object that is passed around by the Objective C runtime
|
||||
to represent the exception in flight. */
|
||||
|
||||
struct ObjcException
|
||||
{
|
||||
/* This bit is needed in order to interact with the unwind runtime. */
|
||||
struct _Unwind_Exception base;
|
||||
|
||||
/* The actual object we want to throw. */
|
||||
id value;
|
||||
|
||||
/* Cache some internal unwind data between phase 1 and phase 2. */
|
||||
_Unwind_Ptr landingPad;
|
||||
int handlerSwitchValue;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct lsda_header_info
|
||||
{
|
||||
_Unwind_Ptr Start;
|
||||
_Unwind_Ptr LPStart;
|
||||
_Unwind_Ptr ttype_base;
|
||||
const unsigned char *TType;
|
||||
const unsigned char *action_table;
|
||||
unsigned char ttype_encoding;
|
||||
unsigned char call_site_encoding;
|
||||
};
|
||||
|
||||
static const unsigned char *
|
||||
parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p,
|
||||
struct lsda_header_info *info)
|
||||
{
|
||||
_Unwind_Word tmp;
|
||||
unsigned char lpstart_encoding;
|
||||
|
||||
info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
|
||||
|
||||
/* Find @LPStart, the base to which landing pad offsets are relative. */
|
||||
lpstart_encoding = *p++;
|
||||
if (lpstart_encoding != DW_EH_PE_omit)
|
||||
p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
|
||||
else
|
||||
info->LPStart = info->Start;
|
||||
|
||||
/* Find @TType, the base of the handler and exception spec type data. */
|
||||
info->ttype_encoding = *p++;
|
||||
if (info->ttype_encoding != DW_EH_PE_omit)
|
||||
{
|
||||
p = read_uleb128 (p, &tmp);
|
||||
info->TType = p + tmp;
|
||||
}
|
||||
else
|
||||
info->TType = 0;
|
||||
|
||||
/* The encoding and length of the call-site table; the action table
|
||||
immediately follows. */
|
||||
info->call_site_encoding = *p++;
|
||||
p = read_uleb128 (p, &tmp);
|
||||
info->action_table = p + tmp;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static Class
|
||||
get_ttype_entry (struct lsda_header_info *info, _Unwind_Word i)
|
||||
{
|
||||
_Unwind_Ptr ptr;
|
||||
|
||||
i *= size_of_encoded_value (info->ttype_encoding);
|
||||
read_encoded_value_with_base (info->ttype_encoding, info->ttype_base,
|
||||
info->TType - i, &ptr);
|
||||
|
||||
/* NULL ptr means catch-all. */
|
||||
if (ptr)
|
||||
return objc_get_class ((const char *) ptr);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Like unto the method of the same name on Object, but takes an id. */
|
||||
/* ??? Does this bork the meta-type system? Can/should we look up an
|
||||
isKindOf method on the id? */
|
||||
|
||||
static int
|
||||
isKindOf (id value, Class target)
|
||||
{
|
||||
Class c;
|
||||
|
||||
/* NULL target is catch-all. */
|
||||
if (target == 0)
|
||||
return 1;
|
||||
|
||||
for (c = value->class_pointer; c; c = class_get_super_class (c))
|
||||
if (c == target)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Using a different personality function name causes link failures
|
||||
when trying to mix code using different exception handling models. */
|
||||
#ifdef SJLJ_EXCEPTIONS
|
||||
#define PERSONALITY_FUNCTION __gnu_objc_personality_sj0
|
||||
#define __builtin_eh_return_data_regno(x) x
|
||||
#else
|
||||
#define PERSONALITY_FUNCTION __gnu_objc_personality_v0
|
||||
#endif
|
||||
|
||||
_Unwind_Reason_Code
|
||||
PERSONALITY_FUNCTION (int version,
|
||||
_Unwind_Action actions,
|
||||
_Unwind_Exception_Class exception_class,
|
||||
struct _Unwind_Exception *ue_header,
|
||||
struct _Unwind_Context *context)
|
||||
{
|
||||
struct ObjcException *xh = (struct ObjcException *) ue_header;
|
||||
|
||||
struct lsda_header_info info;
|
||||
const unsigned char *language_specific_data;
|
||||
const unsigned char *action_record;
|
||||
const unsigned char *p;
|
||||
_Unwind_Ptr landing_pad, ip;
|
||||
int handler_switch_value;
|
||||
int saw_cleanup = 0, saw_handler;
|
||||
void *return_object;
|
||||
|
||||
/* Interface version check. */
|
||||
if (version != 1)
|
||||
return _URC_FATAL_PHASE1_ERROR;
|
||||
|
||||
/* Shortcut for phase 2 found handler for domestic exception. */
|
||||
if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME)
|
||||
&& exception_class == __objc_exception_class)
|
||||
{
|
||||
handler_switch_value = xh->handlerSwitchValue;
|
||||
landing_pad = xh->landingPad;
|
||||
goto install_context;
|
||||
}
|
||||
|
||||
language_specific_data = (const unsigned char *)
|
||||
_Unwind_GetLanguageSpecificData (context);
|
||||
|
||||
/* If no LSDA, then there are no handlers or cleanups. */
|
||||
if (! language_specific_data)
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
|
||||
/* Parse the LSDA header. */
|
||||
p = parse_lsda_header (context, language_specific_data, &info);
|
||||
info.ttype_base = base_of_encoded_value (info.ttype_encoding, context);
|
||||
ip = _Unwind_GetIP (context) - 1;
|
||||
landing_pad = 0;
|
||||
action_record = 0;
|
||||
handler_switch_value = 0;
|
||||
|
||||
#ifdef SJLJ_EXCEPTIONS
|
||||
/* The given "IP" is an index into the call-site table, with two
|
||||
exceptions -- -1 means no-action, and 0 means terminate. But
|
||||
since we're using uleb128 values, we've not got random access
|
||||
to the array. */
|
||||
if ((int) ip < 0)
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
else
|
||||
{
|
||||
_Unwind_Word cs_lp, cs_action;
|
||||
do
|
||||
{
|
||||
p = read_uleb128 (p, &cs_lp);
|
||||
p = read_uleb128 (p, &cs_action);
|
||||
}
|
||||
while (--ip);
|
||||
|
||||
/* Can never have null landing pad for sjlj -- that would have
|
||||
been indicated by a -1 call site index. */
|
||||
landing_pad = cs_lp + 1;
|
||||
if (cs_action)
|
||||
action_record = info.action_table + cs_action - 1;
|
||||
goto found_something;
|
||||
}
|
||||
#else
|
||||
/* Search the call-site table for the action associated with this IP. */
|
||||
while (p < info.action_table)
|
||||
{
|
||||
_Unwind_Ptr cs_start, cs_len, cs_lp;
|
||||
_Unwind_Word cs_action;
|
||||
|
||||
/* Note that all call-site encodings are "absolute" displacements. */
|
||||
p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
|
||||
p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
|
||||
p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
|
||||
p = read_uleb128 (p, &cs_action);
|
||||
|
||||
/* The table is sorted, so if we've passed the ip, stop. */
|
||||
if (ip < info.Start + cs_start)
|
||||
p = info.action_table;
|
||||
else if (ip < info.Start + cs_start + cs_len)
|
||||
{
|
||||
if (cs_lp)
|
||||
landing_pad = info.LPStart + cs_lp;
|
||||
if (cs_action)
|
||||
action_record = info.action_table + cs_action - 1;
|
||||
goto found_something;
|
||||
}
|
||||
}
|
||||
#endif /* SJLJ_EXCEPTIONS */
|
||||
|
||||
/* If ip is not present in the table, C++ would call terminate. */
|
||||
/* ??? As with Java, it's perhaps better to tweek the LSDA to
|
||||
that no-action is mapped to no-entry. */
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
|
||||
found_something:
|
||||
saw_cleanup = 0;
|
||||
saw_handler = 0;
|
||||
|
||||
if (landing_pad == 0)
|
||||
{
|
||||
/* If ip is present, and has a null landing pad, there are
|
||||
no cleanups or handlers to be run. */
|
||||
}
|
||||
else if (action_record == 0)
|
||||
{
|
||||
/* If ip is present, has a non-null landing pad, and a null
|
||||
action table offset, then there are only cleanups present.
|
||||
Cleanups use a zero switch value, as set above. */
|
||||
saw_cleanup = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise we have a catch handler. */
|
||||
_Unwind_Sword ar_filter, ar_disp;
|
||||
|
||||
while (1)
|
||||
{
|
||||
p = action_record;
|
||||
p = read_sleb128 (p, &ar_filter);
|
||||
read_sleb128 (p, &ar_disp);
|
||||
|
||||
if (ar_filter == 0)
|
||||
{
|
||||
/* Zero filter values are cleanups. */
|
||||
saw_cleanup = 1;
|
||||
}
|
||||
|
||||
/* During forced unwinding, we only run cleanups. With a
|
||||
foreign exception class, we have no class info to match. */
|
||||
else if ((actions & _UA_FORCE_UNWIND)
|
||||
|| exception_class != __objc_exception_class)
|
||||
;
|
||||
|
||||
else if (ar_filter > 0)
|
||||
{
|
||||
/* Positive filter values are handlers. */
|
||||
|
||||
Class catch_type = get_ttype_entry (&info, ar_filter);
|
||||
|
||||
if (isKindOf (xh->value, catch_type))
|
||||
{
|
||||
handler_switch_value = ar_filter;
|
||||
saw_handler = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Negative filter values are exception specifications,
|
||||
which Objective-C does not use. */
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (ar_disp == 0)
|
||||
break;
|
||||
action_record = p + ar_disp;
|
||||
}
|
||||
}
|
||||
|
||||
if (! saw_handler && ! saw_cleanup)
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
|
||||
if (actions & _UA_SEARCH_PHASE)
|
||||
{
|
||||
if (!saw_handler)
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
|
||||
/* For domestic exceptions, we cache data from phase 1 for phase 2. */
|
||||
if (exception_class == __objc_exception_class)
|
||||
{
|
||||
xh->handlerSwitchValue = handler_switch_value;
|
||||
xh->landingPad = landing_pad;
|
||||
}
|
||||
return _URC_HANDLER_FOUND;
|
||||
}
|
||||
|
||||
install_context:
|
||||
if (saw_cleanup == 0)
|
||||
{
|
||||
return_object = xh->value;
|
||||
if (!(actions & _UA_SEARCH_PHASE))
|
||||
_Unwind_DeleteException(&xh->base);
|
||||
}
|
||||
|
||||
_Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
|
||||
__builtin_extend_pointer (saw_cleanup ? xh : return_object));
|
||||
_Unwind_SetGR (context, __builtin_eh_return_data_regno (1),
|
||||
handler_switch_value);
|
||||
_Unwind_SetIP (context, landing_pad);
|
||||
return _URC_INSTALL_CONTEXT;
|
||||
}
|
||||
|
||||
static void
|
||||
__objc_exception_cleanup (_Unwind_Reason_Code code __attribute__((unused)),
|
||||
struct _Unwind_Exception *exc)
|
||||
{
|
||||
free (exc);
|
||||
}
|
||||
|
||||
void
|
||||
objc_exception_throw (id value)
|
||||
{
|
||||
struct ObjcException *header = calloc (1, sizeof (*header));
|
||||
header->base.exception_class = __objc_exception_class;
|
||||
header->base.exception_cleanup = __objc_exception_cleanup;
|
||||
header->value = value;
|
||||
|
||||
#ifdef SJLJ_EXCEPTIONS
|
||||
_Unwind_SjLj_RaiseException (&header->base);
|
||||
#else
|
||||
_Unwind_RaiseException (&header->base);
|
||||
#endif
|
||||
|
||||
/* Some sort of unwinding error. */
|
||||
abort ();
|
||||
}
|
@ -1,454 +0,0 @@
|
||||
/* Basic data types for Objective C.
|
||||
Copyright (C) 1998, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
Contributed by Ovidiu Predescu.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 "tconfig.h"
|
||||
#include "objc/objc.h"
|
||||
#include "objc/encoding.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if OBJC_WITH_GC
|
||||
|
||||
#include <gc.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* gc_typed.h uses the following but doesn't declare them */
|
||||
typedef GC_word word;
|
||||
typedef GC_signed_word signed_word;
|
||||
#define BITS_PER_WORD (CHAR_BIT * sizeof (word))
|
||||
|
||||
#include <gc_typed.h>
|
||||
|
||||
/* The following functions set up in `mask` the corresponding pointers.
|
||||
The offset is incremented with the size of the type. */
|
||||
|
||||
#define ROUND(V, A) \
|
||||
({ typeof (V) __v = (V); typeof (A) __a = (A); \
|
||||
__a * ((__v+__a - 1)/__a); })
|
||||
|
||||
#define SET_BIT_FOR_OFFSET(mask, offset) \
|
||||
GC_set_bit (mask, offset / sizeof (void *))
|
||||
|
||||
/* Some prototypes */
|
||||
static void
|
||||
__objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset);
|
||||
static void
|
||||
__objc_gc_setup_union (GC_bitmap mask, const char *type, int offset);
|
||||
|
||||
|
||||
static void
|
||||
__objc_gc_setup_array (GC_bitmap mask, const char *type, int offset)
|
||||
{
|
||||
int i, len = atoi (type + 1);
|
||||
|
||||
while (isdigit (*++type))
|
||||
/* do nothing */; /* skip the size of the array */
|
||||
|
||||
switch (*type) {
|
||||
case _C_ARY_B:
|
||||
for (i = 0; i < len; i++)
|
||||
__objc_gc_setup_array (mask, type, offset);
|
||||
break;
|
||||
|
||||
case _C_STRUCT_B:
|
||||
for (i = 0; i < len; i++)
|
||||
__objc_gc_setup_struct (mask, type, offset);
|
||||
break;
|
||||
|
||||
case _C_UNION_B:
|
||||
for (i = 0; i < len; i++)
|
||||
__objc_gc_setup_union (mask, type, offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset)
|
||||
{
|
||||
struct objc_struct_layout layout;
|
||||
unsigned int position;
|
||||
const char *mtype;
|
||||
|
||||
objc_layout_structure (type, &layout);
|
||||
|
||||
while (objc_layout_structure_next_member (&layout))
|
||||
{
|
||||
BOOL gc_invisible = NO;
|
||||
|
||||
objc_layout_structure_get_info (&layout, &position, NULL, &mtype);
|
||||
|
||||
/* Skip the variable name */
|
||||
if (*mtype == '"')
|
||||
{
|
||||
for (mtype++; *mtype++ != '"';)
|
||||
/* do nothing */;
|
||||
}
|
||||
|
||||
if (*mtype == _C_GCINVISIBLE)
|
||||
{
|
||||
gc_invisible = YES;
|
||||
mtype++;
|
||||
}
|
||||
|
||||
/* Add to position the offset of this structure */
|
||||
position += offset;
|
||||
|
||||
switch (*mtype) {
|
||||
case _C_ID:
|
||||
case _C_CLASS:
|
||||
case _C_SEL:
|
||||
case _C_PTR:
|
||||
case _C_CHARPTR:
|
||||
case _C_ATOM:
|
||||
if (! gc_invisible)
|
||||
SET_BIT_FOR_OFFSET (mask, position);
|
||||
break;
|
||||
|
||||
case _C_ARY_B:
|
||||
__objc_gc_setup_array (mask, mtype, position);
|
||||
break;
|
||||
|
||||
case _C_STRUCT_B:
|
||||
__objc_gc_setup_struct (mask, mtype, position);
|
||||
break;
|
||||
|
||||
case _C_UNION_B:
|
||||
__objc_gc_setup_union (mask, mtype, position);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__objc_gc_setup_union (GC_bitmap mask, const char *type, int offset)
|
||||
{
|
||||
/* Sub-optimal, quick implementation: assume the union is made of
|
||||
pointers, set up the mask accordingly. */
|
||||
|
||||
int i, size, align;
|
||||
|
||||
/* Skip the variable name */
|
||||
if (*type == '"')
|
||||
{
|
||||
for (type++; *type++ != '"';)
|
||||
/* do nothing */;
|
||||
}
|
||||
|
||||
size = objc_sizeof_type (type);
|
||||
align = objc_alignof_type (type);
|
||||
|
||||
offset = ROUND (offset, align);
|
||||
for (i = 0; i < size; i += sizeof (void *))
|
||||
{
|
||||
SET_BIT_FOR_OFFSET (mask, offset);
|
||||
offset += sizeof (void *);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Iterates over the types in the structure that represents the class
|
||||
encoding and sets the bits in mask according to each ivar type. */
|
||||
static void
|
||||
__objc_gc_type_description_from_type (GC_bitmap mask, const char *type)
|
||||
{
|
||||
struct objc_struct_layout layout;
|
||||
unsigned int offset, align;
|
||||
const char *ivar_type;
|
||||
|
||||
objc_layout_structure (type, &layout);
|
||||
|
||||
while (objc_layout_structure_next_member (&layout))
|
||||
{
|
||||
BOOL gc_invisible = NO;
|
||||
|
||||
objc_layout_structure_get_info (&layout, &offset, &align, &ivar_type);
|
||||
|
||||
/* Skip the variable name */
|
||||
if (*ivar_type == '"')
|
||||
{
|
||||
for (ivar_type++; *ivar_type++ != '"';)
|
||||
/* do nothing */;
|
||||
}
|
||||
|
||||
if (*ivar_type == _C_GCINVISIBLE)
|
||||
{
|
||||
gc_invisible = YES;
|
||||
ivar_type++;
|
||||
}
|
||||
|
||||
switch (*ivar_type) {
|
||||
case _C_ID:
|
||||
case _C_CLASS:
|
||||
case _C_SEL:
|
||||
case _C_PTR:
|
||||
case _C_CHARPTR:
|
||||
if (! gc_invisible)
|
||||
SET_BIT_FOR_OFFSET (mask, offset);
|
||||
break;
|
||||
|
||||
case _C_ARY_B:
|
||||
__objc_gc_setup_array (mask, ivar_type, offset);
|
||||
break;
|
||||
|
||||
case _C_STRUCT_B:
|
||||
__objc_gc_setup_struct (mask, ivar_type, offset);
|
||||
break;
|
||||
|
||||
case _C_UNION_B:
|
||||
__objc_gc_setup_union (mask, ivar_type, offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Computes in *type the full type encoding of this class including
|
||||
its super classes. '*size' gives the total number of bytes allocated
|
||||
into *type, '*current' the number of bytes used so far by the
|
||||
encoding. */
|
||||
static void
|
||||
__objc_class_structure_encoding (Class class, char **type, int *size,
|
||||
int *current)
|
||||
{
|
||||
int i, ivar_count;
|
||||
struct objc_ivar_list *ivars;
|
||||
|
||||
if (! class)
|
||||
{
|
||||
strcat (*type, "{");
|
||||
(*current)++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add the type encodings of the super classes */
|
||||
__objc_class_structure_encoding (class->super_class, type, size, current);
|
||||
|
||||
ivars = class->ivars;
|
||||
if (! ivars)
|
||||
return;
|
||||
|
||||
ivar_count = ivars->ivar_count;
|
||||
|
||||
for (i = 0; i < ivar_count; i++)
|
||||
{
|
||||
struct objc_ivar *ivar = &(ivars->ivar_list[i]);
|
||||
const char *ivar_type = ivar->ivar_type;
|
||||
int len = strlen (ivar_type);
|
||||
|
||||
if (*current + len + 1 >= *size)
|
||||
{
|
||||
/* Increase the size of the encoding string so that it
|
||||
contains this ivar's type. */
|
||||
*size = ROUND (*current + len + 1, 10);
|
||||
*type = objc_realloc (*type, *size);
|
||||
}
|
||||
strcat (*type + *current, ivar_type);
|
||||
*current += len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Allocates the memory that will hold the type description for class
|
||||
and calls the __objc_class_structure_encoding that generates this
|
||||
value. */
|
||||
void
|
||||
__objc_generate_gc_type_description (Class class)
|
||||
{
|
||||
GC_bitmap mask;
|
||||
int bits_no, size;
|
||||
int type_size = 10, current;
|
||||
char *class_structure_type;
|
||||
|
||||
if (! CLS_ISCLASS (class))
|
||||
return;
|
||||
|
||||
/* We have to create a mask in which each bit counts for a pointer member.
|
||||
We take into consideration all the non-pointer instance variables and we
|
||||
round them up to the alignment. */
|
||||
|
||||
/* The number of bits in the mask is the size of an instance in bytes divided
|
||||
by the size of a pointer. */
|
||||
bits_no = (ROUND (class_get_instance_size (class), sizeof (void *))
|
||||
/ sizeof (void *));
|
||||
size = ROUND (bits_no, BITS_PER_WORD) / BITS_PER_WORD;
|
||||
mask = objc_atomic_malloc (size * sizeof (int));
|
||||
memset (mask, 0, size * sizeof (int));
|
||||
|
||||
class_structure_type = objc_atomic_malloc (type_size);
|
||||
*class_structure_type = current = 0;
|
||||
__objc_class_structure_encoding (class, &class_structure_type,
|
||||
&type_size, ¤t);
|
||||
if (current + 1 == type_size)
|
||||
class_structure_type = objc_realloc (class_structure_type, ++type_size);
|
||||
strcat (class_structure_type + current, "}");
|
||||
#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);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf (" mask for '%s', type '%s' (bits %d, mask size %d) is:",
|
||||
class_structure_type, class->name, bits_no, size);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < size; i++)
|
||||
printf (" %lx", mask[i]);
|
||||
}
|
||||
puts ("");
|
||||
#endif
|
||||
|
||||
class->gc_object_type = (void *) GC_make_descriptor (mask, bits_no);
|
||||
}
|
||||
|
||||
|
||||
/* Returns YES if type denotes a pointer type, NO otherwise */
|
||||
static inline BOOL
|
||||
__objc_ivar_pointer (const char *type)
|
||||
{
|
||||
type = objc_skip_type_qualifiers (type);
|
||||
|
||||
return (*type == _C_ID
|
||||
|| *type == _C_CLASS
|
||||
|| *type == _C_SEL
|
||||
|| *type == _C_PTR
|
||||
|| *type == _C_CHARPTR
|
||||
|| *type == _C_ATOM);
|
||||
}
|
||||
|
||||
|
||||
/* Mark the instance variable whose name is given by ivarname as a
|
||||
weak pointer (a pointer hidden to the garbage collector) if
|
||||
gc_invisible is true. If gc_invisible is false it unmarks the
|
||||
instance variable and makes it a normal pointer, visible to the
|
||||
garbage collector.
|
||||
|
||||
This operation only makes sense on instance variables that are
|
||||
pointers. */
|
||||
void
|
||||
class_ivar_set_gcinvisible (Class class, const char *ivarname,
|
||||
BOOL gc_invisible)
|
||||
{
|
||||
int i, ivar_count;
|
||||
struct objc_ivar_list *ivars;
|
||||
|
||||
if (! class || ! ivarname)
|
||||
return;
|
||||
|
||||
ivars = class->ivars;
|
||||
if (! ivars)
|
||||
return;
|
||||
|
||||
ivar_count = ivars->ivar_count;
|
||||
|
||||
for (i = 0; i < ivar_count; i++)
|
||||
{
|
||||
struct objc_ivar *ivar = &(ivars->ivar_list[i]);
|
||||
const char *type;
|
||||
|
||||
if (! ivar->ivar_name || strcmp (ivar->ivar_name, ivarname))
|
||||
continue;
|
||||
|
||||
assert (ivar->ivar_type);
|
||||
type = ivar->ivar_type;
|
||||
|
||||
/* Skip the variable name */
|
||||
if (*type == '"')
|
||||
{
|
||||
for (type++; *type++ != '"';)
|
||||
/* do nothing */;
|
||||
}
|
||||
|
||||
if (*type == _C_GCINVISIBLE)
|
||||
{
|
||||
char *new_type;
|
||||
size_t len;
|
||||
|
||||
if (gc_invisible || ! __objc_ivar_pointer (type))
|
||||
return; /* The type of the variable already matches the
|
||||
requested gc_invisible type */
|
||||
|
||||
/* The variable is gc_invisible so we make it gc visible. */
|
||||
new_type = objc_atomic_malloc (strlen(ivar->ivar_type));
|
||||
len = (type - ivar->ivar_type);
|
||||
memcpy (new_type, ivar->ivar_type, len);
|
||||
new_type[len] = 0;
|
||||
strcat (new_type, type + 1);
|
||||
ivar->ivar_type = new_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *new_type;
|
||||
size_t len;
|
||||
|
||||
if (! gc_invisible || ! __objc_ivar_pointer (type))
|
||||
return; /* The type of the variable already matches the
|
||||
requested gc_invisible type */
|
||||
|
||||
/* The variable is gc visible so we make it gc_invisible. */
|
||||
new_type = objc_malloc (strlen(ivar->ivar_type) + 2);
|
||||
len = (type - ivar->ivar_type);
|
||||
memcpy (new_type, ivar->ivar_type, len);
|
||||
new_type[len] = 0;
|
||||
strcat (new_type, "!");
|
||||
strcat (new_type, type);
|
||||
ivar->ivar_type = new_type;
|
||||
}
|
||||
|
||||
__objc_generate_gc_type_description (class);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Search the instance variable in the superclasses */
|
||||
class_ivar_set_gcinvisible (class->super_class, ivarname, gc_invisible);
|
||||
}
|
||||
|
||||
#else /* !OBJC_WITH_GC */
|
||||
|
||||
void
|
||||
__objc_generate_gc_type_description (Class class __attribute__ ((__unused__)))
|
||||
{
|
||||
}
|
||||
|
||||
void class_ivar_set_gcinvisible (Class class __attribute__ ((__unused__)),
|
||||
const char *ivarname __attribute__ ((__unused__)),
|
||||
BOOL gc_invisible __attribute__ ((__unused__)))
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* OBJC_WITH_GC */
|
@ -1,283 +0,0 @@
|
||||
/* Hash tables for Objective C internal structures
|
||||
Copyright (C) 1993, 1996, 1997, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 "assert.h"
|
||||
|
||||
#include "objc/hash.h"
|
||||
|
||||
#include "objc/runtime.h" /* for DEBUG_PRINTF */
|
||||
|
||||
/* These two macros determine when a hash table is full and
|
||||
by how much it should be expanded respectively.
|
||||
|
||||
These equations are percentages. */
|
||||
#define FULLNESS(cache) \
|
||||
((((cache)->size * 75) / 100) <= (cache)->used)
|
||||
#define EXPANSION(cache) \
|
||||
((cache)->size * 2)
|
||||
|
||||
cache_ptr
|
||||
objc_hash_new (unsigned int size, hash_func_type hash_func,
|
||||
compare_func_type compare_func)
|
||||
{
|
||||
cache_ptr cache;
|
||||
|
||||
/* Pass me a value greater than 0 and a power of 2. */
|
||||
assert (size);
|
||||
assert (! (size & (size - 1)));
|
||||
|
||||
/* Allocate the cache structure. calloc insures
|
||||
its initialization for default values. */
|
||||
cache = (cache_ptr) objc_calloc (1, sizeof (struct cache));
|
||||
assert (cache);
|
||||
|
||||
/* Allocate the array of buckets for the cache.
|
||||
calloc initializes all of the pointers to NULL. */
|
||||
cache->node_table
|
||||
= (node_ptr *) objc_calloc (size, sizeof (node_ptr));
|
||||
assert (cache->node_table);
|
||||
|
||||
cache->size = size;
|
||||
|
||||
/* This should work for all processor architectures? */
|
||||
cache->mask = (size - 1);
|
||||
|
||||
/* Store the hashing function so that codes can be computed. */
|
||||
cache->hash_func = hash_func;
|
||||
|
||||
/* Store the function that compares hash keys to
|
||||
determine if they are equal. */
|
||||
cache->compare_func = compare_func;
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
objc_hash_delete (cache_ptr cache)
|
||||
{
|
||||
node_ptr node;
|
||||
node_ptr next_node;
|
||||
unsigned int i;
|
||||
|
||||
/* Purge all key/value pairs from the table. */
|
||||
/* Step through the nodes one by one and remove every node WITHOUT
|
||||
using objc_hash_next. this makes objc_hash_delete much more efficient. */
|
||||
for (i = 0;i < cache->size;i++) {
|
||||
if ((node = cache->node_table[i])) {
|
||||
/* an entry in the hash table has been found, now step through the
|
||||
nodes next in the list and free them. */
|
||||
while ((next_node = node->next)) {
|
||||
objc_hash_remove (cache,node->key);
|
||||
node = next_node;
|
||||
}
|
||||
|
||||
objc_hash_remove (cache,node->key);
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the array of nodes and the cache itself. */
|
||||
objc_free(cache->node_table);
|
||||
objc_free(cache);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
objc_hash_add (cache_ptr *cachep, const void *key, void *value)
|
||||
{
|
||||
size_t indx = (*(*cachep)->hash_func)(*cachep, key);
|
||||
node_ptr node = (node_ptr) objc_calloc (1, sizeof (struct cache_node));
|
||||
|
||||
|
||||
assert (node);
|
||||
|
||||
/* Initialize the new node. */
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
node->next = (*cachep)->node_table[indx];
|
||||
|
||||
/* Debugging.
|
||||
Check the list for another key. */
|
||||
#ifdef DEBUG
|
||||
{ node_ptr node1 = (*cachep)->node_table[indx];
|
||||
|
||||
while (node1) {
|
||||
|
||||
assert (node1->key != key);
|
||||
node1 = node1->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Install the node as the first element on the list. */
|
||||
(*cachep)->node_table[indx] = node;
|
||||
|
||||
/* Bump the number of entries in the cache. */
|
||||
++(*cachep)->used;
|
||||
|
||||
/* Check the hash table's fullness. We're going
|
||||
to expand if it is above the fullness level. */
|
||||
if (FULLNESS (*cachep)) {
|
||||
|
||||
/* The hash table has reached its fullness level. Time to
|
||||
expand it.
|
||||
|
||||
I'm using a slow method here but is built on other
|
||||
primitive functions thereby increasing its
|
||||
correctness. */
|
||||
node_ptr node1 = NULL;
|
||||
cache_ptr new = objc_hash_new (EXPANSION (*cachep),
|
||||
(*cachep)->hash_func,
|
||||
(*cachep)->compare_func);
|
||||
|
||||
DEBUG_PRINTF ("Expanding cache %#x from %d to %d\n",
|
||||
(int) *cachep, (*cachep)->size, new->size);
|
||||
|
||||
/* Copy the nodes from the first hash table to the new one. */
|
||||
while ((node1 = objc_hash_next (*cachep, node1)))
|
||||
objc_hash_add (&new, node1->key, node1->value);
|
||||
|
||||
/* Trash the old cache. */
|
||||
objc_hash_delete (*cachep);
|
||||
|
||||
/* Return a pointer to the new hash table. */
|
||||
*cachep = new;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
objc_hash_remove (cache_ptr cache, const void *key)
|
||||
{
|
||||
size_t indx = (*cache->hash_func)(cache, key);
|
||||
node_ptr node = cache->node_table[indx];
|
||||
|
||||
|
||||
/* We assume there is an entry in the table. Error if it is not. */
|
||||
assert (node);
|
||||
|
||||
/* Special case. First element is the key/value pair to be removed. */
|
||||
if ((*cache->compare_func)(node->key, key)) {
|
||||
cache->node_table[indx] = node->next;
|
||||
objc_free(node);
|
||||
} else {
|
||||
|
||||
/* Otherwise, find the hash entry. */
|
||||
node_ptr prev = node;
|
||||
BOOL removed = NO;
|
||||
|
||||
do {
|
||||
|
||||
if ((*cache->compare_func)(node->key, key)) {
|
||||
prev->next = node->next, removed = YES;
|
||||
objc_free(node);
|
||||
} else
|
||||
prev = node, node = node->next;
|
||||
} while (! removed && node);
|
||||
assert (removed);
|
||||
}
|
||||
|
||||
/* Decrement the number of entries in the hash table. */
|
||||
--cache->used;
|
||||
}
|
||||
|
||||
|
||||
node_ptr
|
||||
objc_hash_next (cache_ptr cache, node_ptr node)
|
||||
{
|
||||
/* If the scan is being started then reset the last node
|
||||
visitied pointer and bucket index. */
|
||||
if (! node)
|
||||
cache->last_bucket = 0;
|
||||
|
||||
/* If there is a node visited last then check for another
|
||||
entry in the same bucket; Otherwise step to the next bucket. */
|
||||
if (node) {
|
||||
if (node->next)
|
||||
/* There is a node which follows the last node
|
||||
returned. Step to that node and retun it. */
|
||||
return node->next;
|
||||
else
|
||||
++cache->last_bucket;
|
||||
}
|
||||
|
||||
/* If the list isn't exhausted then search the buckets for
|
||||
other nodes. */
|
||||
if (cache->last_bucket < cache->size) {
|
||||
/* Scan the remainder of the buckets looking for an entry
|
||||
at the head of the list. Return the first item found. */
|
||||
while (cache->last_bucket < cache->size)
|
||||
if (cache->node_table[cache->last_bucket])
|
||||
return cache->node_table[cache->last_bucket];
|
||||
else
|
||||
++cache->last_bucket;
|
||||
|
||||
/* No further nodes were found in the hash table. */
|
||||
return NULL;
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Given KEY, return corresponding value for it in CACHE.
|
||||
Return NULL if the KEY is not recorded. */
|
||||
|
||||
void *
|
||||
objc_hash_value_for_key (cache_ptr cache, const void *key)
|
||||
{
|
||||
node_ptr node = cache->node_table[(*cache->hash_func)(cache, key)];
|
||||
void *retval = NULL;
|
||||
|
||||
if (node)
|
||||
do {
|
||||
if ((*cache->compare_func)(node->key, key)) {
|
||||
retval = node->value;
|
||||
break;
|
||||
} else
|
||||
node = node->next;
|
||||
} while (! retval && node);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Given KEY, return YES if it exists in the CACHE.
|
||||
Return NO if it does not */
|
||||
|
||||
BOOL
|
||||
objc_hash_is_key_in_hash (cache_ptr cache, const void *key)
|
||||
{
|
||||
node_ptr node = cache->node_table[(*cache->hash_func)(cache, key)];
|
||||
|
||||
if (node)
|
||||
do {
|
||||
if ((*cache->compare_func)(node->key, key))
|
||||
return YES;
|
||||
else
|
||||
node = node->next;
|
||||
} while (node);
|
||||
|
||||
return NO;
|
||||
}
|
@ -1,894 +0,0 @@
|
||||
/* GNU Objective C Runtime initialization
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup
|
||||
+load support contributed by Ovidiu Predescu <ovidiu@net-community.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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/runtime.h"
|
||||
|
||||
/* The version number of this runtime. This must match the number
|
||||
defined in gcc (objc-act.c). */
|
||||
#define OBJC_VERSION 8
|
||||
#define PROTOCOL_VERSION 2
|
||||
|
||||
/* This list contains all modules currently loaded into the runtime. */
|
||||
static struct objc_list *__objc_module_list = 0; /* !T:MUTEX */
|
||||
|
||||
/* This list contains all proto_list's not yet assigned class links. */
|
||||
static struct objc_list *unclaimed_proto_list = 0; /* !T:MUTEX */
|
||||
|
||||
/* List of unresolved static instances. */
|
||||
static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
|
||||
|
||||
/* Global runtime "write" mutex. */
|
||||
objc_mutex_t __objc_runtime_mutex = 0;
|
||||
|
||||
/* Number of threads that are alive. */
|
||||
int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
|
||||
|
||||
/* Check compiler vs runtime version. */
|
||||
static void init_check_module_version (Module_t);
|
||||
|
||||
/* Assign isa links to protos. */
|
||||
static void __objc_init_protocols (struct objc_protocol_list *protos);
|
||||
|
||||
/* Add protocol to class. */
|
||||
static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
|
||||
|
||||
/* This is a hook which is called by __objc_exec_class every time a
|
||||
class or a category is loaded into the runtime. This may e.g. help
|
||||
a dynamic loader determine the classes that have been loaded when
|
||||
an object file is dynamically linked in. */
|
||||
void (*_objc_load_callback) (Class class, Category *category); /* !T:SAFE */
|
||||
|
||||
/* Is all categories/classes resolved? */
|
||||
BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
|
||||
|
||||
extern SEL
|
||||
__sel_register_typed_name (const char *name, const char *types,
|
||||
struct objc_selector *orig, BOOL is_const);
|
||||
|
||||
/* Sends +load to all classes and categories in certain situations. */
|
||||
static void objc_send_load (void);
|
||||
|
||||
/* Inserts all the classes defined in module in a tree of classes that
|
||||
resembles the class hierarchy. This tree is traversed in preorder
|
||||
and the classes in its nodes receive the +load message if these
|
||||
methods were not executed before. The algorithm ensures that when
|
||||
the +load method of a class is executed all the superclasses have
|
||||
been already received the +load message. */
|
||||
static void __objc_create_classes_tree (Module_t module);
|
||||
|
||||
static void __objc_call_callback (Module_t module);
|
||||
|
||||
/* A special version that works only before the classes are completely
|
||||
installed in the runtime. */
|
||||
static BOOL class_is_subclass_of_class (Class class, Class superclass);
|
||||
|
||||
typedef struct objc_class_tree {
|
||||
Class class;
|
||||
struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
|
||||
} objc_class_tree;
|
||||
|
||||
/* This is a linked list of objc_class_tree trees. The head of these
|
||||
trees are root classes (their super class is Nil). These different
|
||||
trees represent different class hierarchies. */
|
||||
static struct objc_list *__objc_class_tree_list = NULL;
|
||||
|
||||
/* Keeps the +load methods who have been already executed. This hash
|
||||
should not be destroyed during the execution of the program. */
|
||||
static cache_ptr __objc_load_methods = NULL;
|
||||
|
||||
/* This function is used when building the class tree used to send
|
||||
ordinately the +load message to all classes needing it. The tree
|
||||
is really needed so that superclasses will get the message before
|
||||
subclasses.
|
||||
|
||||
This tree will contain classes which are being loaded (or have just
|
||||
being loaded), and whose super_class pointers have not yet been
|
||||
resolved. This implies that their super_class pointers point to a
|
||||
string with the name of the superclass; when the first message is
|
||||
sent to the class (/an object of that class) the class links will
|
||||
be resolved, which will replace the super_class pointers with
|
||||
pointers to the actual superclasses.
|
||||
|
||||
Unfortunately, the tree might also contain classes which had been
|
||||
loaded previously, and whose class links have already been
|
||||
resolved.
|
||||
|
||||
This function returns the superclass of a class in both cases, and
|
||||
can be used to build the determine the class relationships while
|
||||
building the tree.
|
||||
*/
|
||||
static Class class_superclass_of_class (Class class)
|
||||
{
|
||||
char *super_class_name;
|
||||
|
||||
/* If the class links have been resolved, use the resolved
|
||||
* links. */
|
||||
if (CLS_ISRESOLV (class))
|
||||
return class->super_class;
|
||||
|
||||
/* Else, 'class' has not yet been resolved. This means that its
|
||||
* super_class pointer is really the name of the super class (rather
|
||||
* than a pointer to the actual superclass). */
|
||||
super_class_name = (char *)class->super_class;
|
||||
|
||||
/* Return Nil for a root class. */
|
||||
if (super_class_name == NULL)
|
||||
return Nil;
|
||||
|
||||
/* Lookup the superclass of non-root classes. */
|
||||
return objc_lookup_class (super_class_name);
|
||||
}
|
||||
|
||||
|
||||
/* Creates a tree of classes whose topmost class is directly inherited
|
||||
from `upper' and the bottom class in this tree is
|
||||
`bottom_class'. The classes in this tree are super classes of
|
||||
`bottom_class'. `subclasses' member of each tree node point to the
|
||||
next subclass tree node. */
|
||||
|
||||
static objc_class_tree *
|
||||
create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
|
||||
{
|
||||
Class superclass = bottom_class->super_class ?
|
||||
objc_lookup_class ((char *) bottom_class->super_class)
|
||||
: Nil;
|
||||
|
||||
objc_class_tree *tree, *prev;
|
||||
|
||||
DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
|
||||
DEBUG_PRINTF ("bottom_class = %s, upper = %s\n",
|
||||
(bottom_class ? bottom_class->name : NULL),
|
||||
(upper ? upper->name : NULL));
|
||||
|
||||
tree = prev = objc_calloc (1, sizeof (objc_class_tree));
|
||||
prev->class = bottom_class;
|
||||
|
||||
while (superclass != upper)
|
||||
{
|
||||
tree = objc_calloc (1, sizeof (objc_class_tree));
|
||||
tree->class = superclass;
|
||||
tree->subclasses = list_cons (prev, tree->subclasses);
|
||||
superclass = class_superclass_of_class (superclass);
|
||||
prev = tree;
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
/* Insert the `class' into the proper place in the `tree' class
|
||||
hierarchy. This function returns a new tree if the class has been
|
||||
successfully inserted into the tree or NULL if the class is not
|
||||
part of the classes hierarchy described by `tree'. This function is
|
||||
private to objc_tree_insert_class (), you should not call it
|
||||
directly. */
|
||||
|
||||
static objc_class_tree *
|
||||
__objc_tree_insert_class (objc_class_tree *tree, Class class)
|
||||
{
|
||||
DEBUG_PRINTF ("__objc_tree_insert_class: tree = %x, class = %s\n",
|
||||
tree, class->name);
|
||||
|
||||
if (tree == NULL)
|
||||
return create_tree_of_subclasses_inherited_from (class, NULL);
|
||||
else if (class == tree->class)
|
||||
{
|
||||
/* `class' has been already inserted */
|
||||
DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
|
||||
return tree;
|
||||
}
|
||||
else if (class_superclass_of_class (class) == tree->class)
|
||||
{
|
||||
/* If class is a direct subclass of tree->class then add class to the
|
||||
list of subclasses. First check to see if it wasn't already
|
||||
inserted. */
|
||||
struct objc_list *list = tree->subclasses;
|
||||
objc_class_tree *node;
|
||||
|
||||
while (list)
|
||||
{
|
||||
/* Class has been already inserted; do nothing just return
|
||||
the tree. */
|
||||
if (((objc_class_tree *) list->head)->class == class)
|
||||
{
|
||||
DEBUG_PRINTF ("2. class %s was previously inserted\n",
|
||||
class->name);
|
||||
return tree;
|
||||
}
|
||||
list = list->tail;
|
||||
}
|
||||
|
||||
/* Create a new node class and insert it into the list of subclasses */
|
||||
node = objc_calloc (1, sizeof (objc_class_tree));
|
||||
node->class = class;
|
||||
tree->subclasses = list_cons (node, tree->subclasses);
|
||||
DEBUG_PRINTF ("3. class %s inserted\n", class->name);
|
||||
return tree;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The class is not a direct subclass of tree->class. Search for
|
||||
class's superclasses in the list of subclasses. */
|
||||
struct objc_list *subclasses = tree->subclasses;
|
||||
|
||||
/* Precondition: the class must be a subclass of tree->class;
|
||||
otherwise return NULL to indicate our caller that it must
|
||||
take the next tree. */
|
||||
if (! class_is_subclass_of_class (class, tree->class))
|
||||
return NULL;
|
||||
|
||||
for (; subclasses != NULL; subclasses = subclasses->tail)
|
||||
{
|
||||
Class aClass = ((objc_class_tree *) (subclasses->head))->class;
|
||||
|
||||
if (class_is_subclass_of_class (class, aClass))
|
||||
{
|
||||
/* If we found one of class's superclasses we insert the
|
||||
class into its subtree and return the original tree
|
||||
since nothing has been changed. */
|
||||
subclasses->head
|
||||
= __objc_tree_insert_class (subclasses->head, class);
|
||||
DEBUG_PRINTF ("4. class %s inserted\n", class->name);
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
|
||||
/* We haven't found a subclass of `class' in the `subclasses'
|
||||
list. Create a new tree of classes whose topmost class is a
|
||||
direct subclass of tree->class. */
|
||||
{
|
||||
objc_class_tree *new_tree
|
||||
= create_tree_of_subclasses_inherited_from (class, tree->class);
|
||||
tree->subclasses = list_cons (new_tree, tree->subclasses);
|
||||
DEBUG_PRINTF ("5. class %s inserted\n", class->name);
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This function inserts `class' in the right tree hierarchy classes. */
|
||||
|
||||
static void
|
||||
objc_tree_insert_class (Class class)
|
||||
{
|
||||
struct objc_list *list_node;
|
||||
objc_class_tree *tree;
|
||||
|
||||
list_node = __objc_class_tree_list;
|
||||
while (list_node)
|
||||
{
|
||||
tree = __objc_tree_insert_class (list_node->head, class);
|
||||
if (tree)
|
||||
{
|
||||
list_node->head = tree;
|
||||
break;
|
||||
}
|
||||
else
|
||||
list_node = list_node->tail;
|
||||
}
|
||||
|
||||
/* If the list was finished but the class hasn't been inserted,
|
||||
insert it here. */
|
||||
if (! list_node)
|
||||
{
|
||||
__objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
|
||||
__objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
|
||||
}
|
||||
}
|
||||
|
||||
/* Traverse tree in preorder. Used to send +load. */
|
||||
|
||||
static void
|
||||
objc_preorder_traverse (objc_class_tree *tree,
|
||||
int level,
|
||||
void (*function) (objc_class_tree *, int))
|
||||
{
|
||||
struct objc_list *node;
|
||||
|
||||
(*function) (tree, level);
|
||||
for (node = tree->subclasses; node; node = node->tail)
|
||||
objc_preorder_traverse (node->head, level + 1, function);
|
||||
}
|
||||
|
||||
/* Traverse tree in postorder. Used to destroy a tree. */
|
||||
|
||||
static void
|
||||
objc_postorder_traverse (objc_class_tree *tree,
|
||||
int level,
|
||||
void (*function) (objc_class_tree *, int))
|
||||
{
|
||||
struct objc_list *node;
|
||||
|
||||
for (node = tree->subclasses; node; node = node->tail)
|
||||
objc_postorder_traverse (node->head, level + 1, function);
|
||||
(*function) (tree, level);
|
||||
}
|
||||
|
||||
/* Used to print a tree class hierarchy. */
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
__objc_tree_print (objc_class_tree *tree, int level)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < level; i++)
|
||||
printf (" ");
|
||||
printf ("%s\n", tree->class->name);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Walks on a linked list of methods in the reverse order and executes
|
||||
all the methods corresponding to `op' selector. Walking in the
|
||||
reverse order assures the +load of class is executed first and then
|
||||
+load of categories because of the way in which categories are
|
||||
added to the class methods. */
|
||||
|
||||
static void
|
||||
__objc_send_message_in_list (MethodList_t method_list, Class class, SEL op)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (! method_list)
|
||||
return;
|
||||
|
||||
/* First execute the `op' message in the following method lists */
|
||||
__objc_send_message_in_list (method_list->method_next, class, op);
|
||||
|
||||
/* Search the method list. */
|
||||
for (i = 0; i < method_list->method_count; i++)
|
||||
{
|
||||
Method_t mth = &method_list->method_list[i];
|
||||
|
||||
if (mth->method_name && sel_eq (mth->method_name, op)
|
||||
&& ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
|
||||
{
|
||||
/* Add this method into the +load hash table */
|
||||
objc_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__objc_send_load (objc_class_tree *tree,
|
||||
int level __attribute__ ((__unused__)))
|
||||
{
|
||||
static SEL load_sel = 0;
|
||||
Class class = tree->class;
|
||||
MethodList_t method_list = class->class_pointer->methods;
|
||||
|
||||
if (! load_sel)
|
||||
load_sel = sel_register_name ("load");
|
||||
|
||||
__objc_send_message_in_list (method_list, class, load_sel);
|
||||
}
|
||||
|
||||
static void
|
||||
__objc_destroy_class_tree_node (objc_class_tree *tree,
|
||||
int level __attribute__ ((__unused__)))
|
||||
{
|
||||
objc_free (tree);
|
||||
}
|
||||
|
||||
/* This is used to check if the relationship between two classes
|
||||
before the runtime completely installs the classes. */
|
||||
|
||||
static BOOL
|
||||
class_is_subclass_of_class (Class class, Class superclass)
|
||||
{
|
||||
for (; class != Nil;)
|
||||
{
|
||||
if (class == superclass)
|
||||
return YES;
|
||||
class = class_superclass_of_class (class);
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* This list contains all the classes in the runtime system for whom
|
||||
their superclasses are not yet known to the runtime. */
|
||||
static struct objc_list *unresolved_classes = 0;
|
||||
|
||||
/* Extern function used to reference the Object and NXConstantString
|
||||
classes. */
|
||||
|
||||
extern void __objc_force_linking (void);
|
||||
|
||||
void
|
||||
__objc_force_linking (void)
|
||||
{
|
||||
extern void __objc_linking (void);
|
||||
__objc_linking ();
|
||||
}
|
||||
|
||||
/* Run through the statics list, removing modules as soon as all its
|
||||
statics have been initialized. */
|
||||
|
||||
static void
|
||||
objc_init_statics (void)
|
||||
{
|
||||
struct objc_list **cell = &uninitialized_statics;
|
||||
struct objc_static_instances **statics_in_module;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
while (*cell)
|
||||
{
|
||||
int module_initialized = 1;
|
||||
|
||||
for (statics_in_module = (*cell)->head;
|
||||
*statics_in_module; statics_in_module++)
|
||||
{
|
||||
struct objc_static_instances *statics = *statics_in_module;
|
||||
Class class = objc_lookup_class (statics->class_name);
|
||||
|
||||
if (! class)
|
||||
module_initialized = 0;
|
||||
/* Actually, the static's class_pointer will be NULL when we
|
||||
haven't been here before. However, the comparison is to be
|
||||
reminded of taking into account class posing and to think about
|
||||
possible semantics... */
|
||||
else if (class != statics->instances[0]->class_pointer)
|
||||
{
|
||||
id *inst;
|
||||
|
||||
for (inst = &statics->instances[0]; *inst; inst++)
|
||||
{
|
||||
(*inst)->class_pointer = class;
|
||||
|
||||
/* ??? Make sure the object will not be freed. With
|
||||
refcounting, invoke `-retain'. Without refcounting, do
|
||||
nothing and hope that `-free' will never be invoked. */
|
||||
|
||||
/* ??? Send the object an `-initStatic' or something to
|
||||
that effect now or later on? What are the semantics of
|
||||
statically allocated instances, besides the trivial
|
||||
NXConstantString, anyway? */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (module_initialized)
|
||||
{
|
||||
/* Remove this module from the uninitialized list. */
|
||||
struct objc_list *this = *cell;
|
||||
*cell = this->tail;
|
||||
objc_free (this);
|
||||
}
|
||||
else
|
||||
cell = &(*cell)->tail;
|
||||
}
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
} /* objc_init_statics */
|
||||
|
||||
/* This function is called by constructor functions generated for each
|
||||
module compiled. (_GLOBAL_$I$...) The purpose of this function is
|
||||
to gather the module pointers so that they may be processed by the
|
||||
initialization routines as soon as possible. */
|
||||
|
||||
void
|
||||
__objc_exec_class (Module_t module)
|
||||
{
|
||||
/* Have we processed any constructors previously? This flag is used to
|
||||
indicate that some global data structures need to be built. */
|
||||
static BOOL previous_constructors = 0;
|
||||
|
||||
static struct objc_list *unclaimed_categories = 0;
|
||||
|
||||
/* The symbol table (defined in objc-api.h) generated by gcc */
|
||||
Symtab_t symtab = module->symtab;
|
||||
|
||||
/* The statics in this module */
|
||||
struct objc_static_instances **statics
|
||||
= symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
|
||||
|
||||
/* Entry used to traverse hash lists */
|
||||
struct objc_list **cell;
|
||||
|
||||
/* The table of selector references for this module */
|
||||
SEL selectors = symtab->refs;
|
||||
|
||||
/* dummy counter */
|
||||
int i;
|
||||
|
||||
DEBUG_PRINTF ("received module: %s\n", module->name);
|
||||
|
||||
/* check gcc version */
|
||||
init_check_module_version (module);
|
||||
|
||||
/* On the first call of this routine, initialize some data structures. */
|
||||
if (! previous_constructors)
|
||||
{
|
||||
/* Initialize thread-safe system */
|
||||
__objc_init_thread_system ();
|
||||
__objc_runtime_threads_alive = 1;
|
||||
__objc_runtime_mutex = objc_mutex_allocate ();
|
||||
|
||||
__objc_init_selector_tables ();
|
||||
__objc_init_class_tables ();
|
||||
__objc_init_dispatch_tables ();
|
||||
__objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
|
||||
__objc_load_methods = objc_hash_new (128,
|
||||
(hash_func_type)objc_hash_ptr,
|
||||
objc_compare_ptrs);
|
||||
previous_constructors = 1;
|
||||
}
|
||||
|
||||
/* Save the module pointer for later processing. (not currently used) */
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
__objc_module_list = list_cons (module, __objc_module_list);
|
||||
|
||||
/* Replace referenced selectors from names to SEL's. */
|
||||
if (selectors)
|
||||
{
|
||||
for (i = 0; selectors[i].sel_id; ++i)
|
||||
{
|
||||
const char *name, *type;
|
||||
name = (char *) selectors[i].sel_id;
|
||||
type = (char *) selectors[i].sel_types;
|
||||
/* Constructors are constant static data so we can safely store
|
||||
pointers to them in the runtime structures. is_const == YES */
|
||||
__sel_register_typed_name (name, type,
|
||||
(struct objc_selector *) &(selectors[i]),
|
||||
YES);
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the classes in the load module and gather selector information. */
|
||||
DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
|
||||
for (i = 0; i < symtab->cls_def_cnt; ++i)
|
||||
{
|
||||
Class class = (Class) symtab->defs[i];
|
||||
const char *superclass = (char *) class->super_class;
|
||||
|
||||
/* Make sure we have what we think. */
|
||||
assert (CLS_ISCLASS (class));
|
||||
assert (CLS_ISMETA (class->class_pointer));
|
||||
DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
|
||||
|
||||
/* Initialize the subclass list to be NULL.
|
||||
In some cases it isn't and this crashes the program. */
|
||||
class->subclass_list = NULL;
|
||||
|
||||
/* Store the class in the class table and assign class numbers. */
|
||||
__objc_add_class_to_hash (class);
|
||||
|
||||
/* Register all of the selectors in the class and meta class. */
|
||||
__objc_register_selectors_from_class (class);
|
||||
__objc_register_selectors_from_class ((Class) class->class_pointer);
|
||||
|
||||
/* Install the fake dispatch tables */
|
||||
__objc_install_premature_dtable (class);
|
||||
__objc_install_premature_dtable (class->class_pointer);
|
||||
|
||||
/* Register the instance methods as class methods, this is
|
||||
only done for root classes. */
|
||||
__objc_register_instance_methods_to_class (class);
|
||||
|
||||
if (class->protocols)
|
||||
__objc_init_protocols (class->protocols);
|
||||
|
||||
/* Check to see if the superclass is known in this point. If it's not
|
||||
add the class to the unresolved_classes list. */
|
||||
if (superclass && ! objc_lookup_class (superclass))
|
||||
unresolved_classes = list_cons (class, unresolved_classes);
|
||||
}
|
||||
|
||||
/* Process category information from the module. */
|
||||
for (i = 0; i < symtab->cat_def_cnt; ++i)
|
||||
{
|
||||
Category_t category = symtab->defs[i + symtab->cls_def_cnt];
|
||||
Class class = objc_lookup_class (category->class_name);
|
||||
|
||||
/* If the class for the category exists then append its methods. */
|
||||
if (class)
|
||||
{
|
||||
|
||||
DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
|
||||
module->name,
|
||||
class->name);
|
||||
|
||||
/* Do instance methods. */
|
||||
if (category->instance_methods)
|
||||
class_add_method_list (class, category->instance_methods);
|
||||
|
||||
/* Do class methods. */
|
||||
if (category->class_methods)
|
||||
class_add_method_list ((Class) class->class_pointer,
|
||||
category->class_methods);
|
||||
|
||||
if (category->protocols)
|
||||
{
|
||||
__objc_init_protocols (category->protocols);
|
||||
__objc_class_add_protocols (class, category->protocols);
|
||||
}
|
||||
|
||||
/* Register the instance methods as class methods, this is
|
||||
only done for root classes. */
|
||||
__objc_register_instance_methods_to_class (class);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The object to which the category methods belong can't be found.
|
||||
Save the information. */
|
||||
unclaimed_categories = list_cons (category, unclaimed_categories);
|
||||
}
|
||||
}
|
||||
|
||||
if (statics)
|
||||
uninitialized_statics = list_cons (statics, uninitialized_statics);
|
||||
if (uninitialized_statics)
|
||||
objc_init_statics ();
|
||||
|
||||
/* Scan the unclaimed category hash. Attempt to attach any unclaimed
|
||||
categories to objects. */
|
||||
for (cell = &unclaimed_categories; *cell; )
|
||||
{
|
||||
Category_t category = (*cell)->head;
|
||||
Class class = objc_lookup_class (category->class_name);
|
||||
|
||||
if (class)
|
||||
{
|
||||
DEBUG_PRINTF ("attaching stored categories to object: %s\n",
|
||||
class->name);
|
||||
|
||||
list_remove_head (cell);
|
||||
|
||||
if (category->instance_methods)
|
||||
class_add_method_list (class, category->instance_methods);
|
||||
|
||||
if (category->class_methods)
|
||||
class_add_method_list ((Class) class->class_pointer,
|
||||
category->class_methods);
|
||||
|
||||
if (category->protocols)
|
||||
{
|
||||
__objc_init_protocols (category->protocols);
|
||||
__objc_class_add_protocols (class, category->protocols);
|
||||
}
|
||||
|
||||
/* Register the instance methods as class methods, this is
|
||||
only done for root classes. */
|
||||
__objc_register_instance_methods_to_class (class);
|
||||
}
|
||||
else
|
||||
cell = &(*cell)->tail;
|
||||
}
|
||||
|
||||
if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
|
||||
{
|
||||
list_mapcar (unclaimed_proto_list,
|
||||
(void (*) (void *))__objc_init_protocols);
|
||||
list_free (unclaimed_proto_list);
|
||||
unclaimed_proto_list = 0;
|
||||
}
|
||||
|
||||
objc_send_load ();
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
objc_send_load (void)
|
||||
{
|
||||
if (! __objc_module_list)
|
||||
return;
|
||||
|
||||
/* Try to find out if all the classes loaded so far also have their
|
||||
superclasses known to the runtime. We suppose that the objects
|
||||
that are allocated in the +load method are in general of a class
|
||||
declared in the same module. */
|
||||
if (unresolved_classes)
|
||||
{
|
||||
Class class = unresolved_classes->head;
|
||||
|
||||
while (objc_lookup_class ((char *) class->super_class))
|
||||
{
|
||||
list_remove_head (&unresolved_classes);
|
||||
if (unresolved_classes)
|
||||
class = unresolved_classes->head;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we still have classes for whom we don't have yet their
|
||||
super classes known to the runtime we don't send the +load
|
||||
messages. */
|
||||
if (unresolved_classes)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Special check to allow creating and sending messages to constant
|
||||
strings in +load methods. If these classes are not yet known,
|
||||
even if all the other classes are known, delay sending of +load. */
|
||||
if (! objc_lookup_class ("NXConstantString") ||
|
||||
! objc_lookup_class ("Object"))
|
||||
return;
|
||||
|
||||
/* Iterate over all modules in the __objc_module_list and call on
|
||||
them the __objc_create_classes_tree function. This function
|
||||
creates a tree of classes that resembles the class hierarchy. */
|
||||
list_mapcar (__objc_module_list,
|
||||
(void (*) (void *)) __objc_create_classes_tree);
|
||||
|
||||
while (__objc_class_tree_list)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
objc_preorder_traverse (__objc_class_tree_list->head,
|
||||
0, __objc_tree_print);
|
||||
#endif
|
||||
objc_preorder_traverse (__objc_class_tree_list->head,
|
||||
0, __objc_send_load);
|
||||
objc_postorder_traverse (__objc_class_tree_list->head,
|
||||
0, __objc_destroy_class_tree_node);
|
||||
list_remove_head (&__objc_class_tree_list);
|
||||
}
|
||||
|
||||
list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
|
||||
list_free (__objc_module_list);
|
||||
__objc_module_list = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
__objc_create_classes_tree (Module_t module)
|
||||
{
|
||||
/* The runtime mutex is locked in this point */
|
||||
|
||||
Symtab_t symtab = module->symtab;
|
||||
int i;
|
||||
|
||||
/* Iterate thru classes defined in this module and insert them in
|
||||
the classes tree hierarchy. */
|
||||
for (i = 0; i < symtab->cls_def_cnt; i++)
|
||||
{
|
||||
Class class = (Class) symtab->defs[i];
|
||||
|
||||
objc_tree_insert_class (class);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__objc_call_callback (Module_t module)
|
||||
{
|
||||
/* The runtime mutex is locked in this point. */
|
||||
|
||||
Symtab_t symtab = module->symtab;
|
||||
int i;
|
||||
|
||||
/* Iterate thru classes defined in this module and call the callback
|
||||
for each one. */
|
||||
for (i = 0; i < symtab->cls_def_cnt; i++)
|
||||
{
|
||||
Class class = (Class) symtab->defs[i];
|
||||
|
||||
/* Call the _objc_load_callback for this class. */
|
||||
if (_objc_load_callback)
|
||||
_objc_load_callback (class, 0);
|
||||
}
|
||||
|
||||
/* Call the _objc_load_callback for categories. Don't register the
|
||||
instance methods as class methods for categories to root classes
|
||||
since they were already added in the class. */
|
||||
for (i = 0; i < symtab->cat_def_cnt; i++)
|
||||
{
|
||||
Category_t category = symtab->defs[i + symtab->cls_def_cnt];
|
||||
Class class = objc_lookup_class (category->class_name);
|
||||
|
||||
if (_objc_load_callback)
|
||||
_objc_load_callback (class, category);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity check the version of gcc used to compile `module'. */
|
||||
|
||||
static void
|
||||
init_check_module_version (Module_t module)
|
||||
{
|
||||
if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
|
||||
{
|
||||
int code;
|
||||
|
||||
if (module->version > OBJC_VERSION)
|
||||
code = OBJC_ERR_OBJC_VERSION;
|
||||
else if (module->version < OBJC_VERSION)
|
||||
code = OBJC_ERR_GCC_VERSION;
|
||||
else
|
||||
code = OBJC_ERR_MODULE_SIZE;
|
||||
|
||||
objc_error (nil, code, "Module %s version %d doesn't match runtime %d\n",
|
||||
module->name, (int)module->version, OBJC_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__objc_init_protocols (struct objc_protocol_list *protos)
|
||||
{
|
||||
size_t i;
|
||||
static Class proto_class = 0;
|
||||
|
||||
if (! protos)
|
||||
return;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
if (! proto_class)
|
||||
proto_class = objc_lookup_class ("Protocol");
|
||||
|
||||
if (! proto_class)
|
||||
{
|
||||
unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
assert (protos->next == 0); /* only single ones allowed */
|
||||
#endif
|
||||
|
||||
for (i = 0; i < protos->count; i++)
|
||||
{
|
||||
struct objc_protocol *aProto = protos->list[i];
|
||||
if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
|
||||
{
|
||||
/* assign class pointer */
|
||||
aProto->class_pointer = proto_class;
|
||||
|
||||
/* init super protocols */
|
||||
__objc_init_protocols (aProto->protocol_list);
|
||||
}
|
||||
else if (protos->list[i]->class_pointer != proto_class)
|
||||
{
|
||||
objc_error (nil, OBJC_ERR_PROTOCOL_VERSION,
|
||||
"Version %d doesn't match runtime protocol version %d\n",
|
||||
(int) ((char *) protos->list[i]->class_pointer
|
||||
- (char *) 0),
|
||||
PROTOCOL_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
__objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
|
||||
{
|
||||
/* Well... */
|
||||
if (! protos)
|
||||
return;
|
||||
|
||||
/* Add it... */
|
||||
protos->next = class->protocols;
|
||||
class->protocols = protos;
|
||||
}
|
@ -1,170 +0,0 @@
|
||||
; GNU Objective C Runtime DLL Export Definitions
|
||||
; Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
; Contributed by Scott Christley <scottc@net-community.com>
|
||||
;
|
||||
; This file is part of GCC.
|
||||
;
|
||||
; GCC 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.
|
||||
;
|
||||
; GCC 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
|
||||
; GCC; see the file COPYING. If not, write to the Free Software
|
||||
; Foundation, 51 Franklin Street, Fifth Floor,
|
||||
; Boston, MA 02110-1301, USA.
|
||||
|
||||
LIBRARY libobjc
|
||||
EXPORTS
|
||||
search_for_method_in_list
|
||||
objc_get_uninstalled_dtable
|
||||
objc_hash_is_key_in_hash
|
||||
hash_is_key_in_hash
|
||||
objc_verror
|
||||
_objc_load_callback
|
||||
objc_malloc
|
||||
objc_atomic_malloc
|
||||
objc_valloc
|
||||
objc_realloc
|
||||
objc_calloc
|
||||
objc_free
|
||||
__objc_init_thread_system
|
||||
objc_mutex_allocate
|
||||
objc_mutex_deallocate
|
||||
objc_mutex_lock
|
||||
objc_mutex_trylock
|
||||
objc_mutex_unlock
|
||||
objc_thread_detach
|
||||
objc_thread_exit
|
||||
objc_thread_get_data
|
||||
objc_thread_get_priority
|
||||
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
|
||||
objc_error
|
||||
__objc_object_alloc
|
||||
__objc_object_copy
|
||||
__objc_object_dispose
|
||||
class_create_instance
|
||||
object_copy
|
||||
object_dispose
|
||||
__objc_init_selector_tables
|
||||
__objc_register_selectors_from_class
|
||||
__sel_register_typed_name
|
||||
sel_get_any_typed_uid
|
||||
sel_get_any_uid
|
||||
sel_get_name
|
||||
sel_get_type
|
||||
sel_get_typed_uid
|
||||
sel_get_uid
|
||||
sel_is_mapped
|
||||
sel_register_name
|
||||
sel_register_typed_name
|
||||
sel_types_match
|
||||
method_get_first_argument
|
||||
method_get_next_argument
|
||||
method_get_nth_argument
|
||||
method_get_number_of_arguments
|
||||
method_get_sizeof_arguments
|
||||
objc_aligned_size
|
||||
objc_alignof_type
|
||||
objc_get_type_qualifiers
|
||||
objc_promoted_size
|
||||
objc_sizeof_type
|
||||
objc_skip_argspec
|
||||
objc_skip_offset
|
||||
objc_skip_type_qualifiers
|
||||
objc_skip_typespec
|
||||
__objc_read_nbyte_uint
|
||||
__objc_read_nbyte_ulong
|
||||
__objc_write_class
|
||||
__objc_write_object
|
||||
__objc_write_selector
|
||||
objc_close_typed_stream
|
||||
objc_end_of_typed_stream
|
||||
objc_flush_typed_stream
|
||||
objc_get_stream_class_version
|
||||
objc_open_typed_stream
|
||||
objc_open_typed_stream_for_file
|
||||
objc_read_array
|
||||
objc_read_char
|
||||
objc_read_int
|
||||
objc_read_long
|
||||
objc_read_object
|
||||
objc_read_selector
|
||||
objc_read_short
|
||||
objc_read_string
|
||||
objc_read_type
|
||||
objc_read_types
|
||||
objc_read_unsigned_char
|
||||
objc_read_unsigned_int
|
||||
objc_read_unsigned_long
|
||||
objc_read_unsigned_short
|
||||
objc_write_array
|
||||
objc_write_char
|
||||
objc_write_int
|
||||
objc_write_long
|
||||
objc_write_object
|
||||
objc_write_object_reference
|
||||
objc_write_root_object
|
||||
objc_write_selector
|
||||
objc_write_short
|
||||
objc_write_string
|
||||
objc_write_string_atomic
|
||||
objc_write_type
|
||||
objc_write_types
|
||||
objc_write_unsigned_char
|
||||
objc_write_unsigned_int
|
||||
objc_write_unsigned_long
|
||||
objc_write_unsigned_short
|
||||
__objc_exec_class
|
||||
__objc_init_dispatch_tables
|
||||
__objc_install_premature_dtable
|
||||
__objc_print_dtable_stats
|
||||
__objc_responds_to
|
||||
__objc_update_dispatch_table_for_class
|
||||
class_add_method_list
|
||||
class_get_class_method
|
||||
class_get_instance_method
|
||||
get_imp
|
||||
nil_method
|
||||
objc_msg_lookup
|
||||
objc_msg_lookup_super
|
||||
objc_msg_sendv
|
||||
__objc_add_class_to_hash
|
||||
__objc_init_class_tables
|
||||
__objc_resolve_class_links
|
||||
class_pose_as
|
||||
objc_get_class
|
||||
objc_get_meta_class
|
||||
objc_lookup_class
|
||||
objc_next_class
|
||||
sarray_at_put
|
||||
sarray_at_put_safe
|
||||
sarray_free
|
||||
sarray_lazy_copy
|
||||
sarray_new
|
||||
sarray_realloc
|
||||
sarray_remove_garbage
|
||||
objc_hash_add
|
||||
hash_add
|
||||
objc_hash_delete
|
||||
hash_delete
|
||||
objc_hash_new
|
||||
hash_new
|
||||
objc_hash_next
|
||||
hash_next
|
||||
objc_hash_remove
|
||||
hash_remove
|
||||
objc_hash_value_for_key
|
||||
hash_value_for_key
|
@ -1,55 +0,0 @@
|
||||
/* GNU Objective C Runtime DLL Entry
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Contributed by Scott Christley <scottc@net-community.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 <windows.h>
|
||||
|
||||
/*
|
||||
DLL entry function for Objective-C Runtime library
|
||||
This function gets called everytime a process/thread attaches to DLL
|
||||
*/
|
||||
WINBOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call,
|
||||
LPVOID lpReserved)
|
||||
{
|
||||
switch(ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
This section terminates the list of imports under GCC. If you do not
|
||||
include this then you will have problems when linking with DLLs.
|
||||
*/
|
||||
asm (".section .idata$3\n" ".long 0,0,0,0,0,0,0,0");
|
@ -1,40 +0,0 @@
|
||||
/* Force linking of classes required by Objective C runtime.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Contributed by Ovidiu Predescu (ovidiu@net-community.com).
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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/Object.h>
|
||||
#include <objc/NXConstStr.h>
|
||||
|
||||
/* Generate references to Object and NXConstanstString classes since they are
|
||||
needed by the runtime system to run correctly. */
|
||||
|
||||
|
||||
void __objc_linking (void)
|
||||
{
|
||||
[Object name];
|
||||
[NXConstantString name];
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
# GNU Objective C Runtime Makefile for compiling with djgpp
|
||||
# Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# GCC 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.
|
||||
#
|
||||
# GCC 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
|
||||
# GCC; see the file COPYING. If not, write to the Free Software
|
||||
# Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
# This Makefile is configured for GnuMAKE
|
||||
|
||||
GCC_FOR_TARGET=gcc
|
||||
|
||||
.SUFFIXES: .o .m
|
||||
|
||||
OPTIMIZE = -O2
|
||||
|
||||
# Always search these dirs when compiling.
|
||||
SUBDIR_INCLUDES = -I. -I.. -I../config
|
||||
|
||||
.c.o:
|
||||
$(GCC_FOR_TARGET) $(OPTIMIZE) \
|
||||
-c $(GCC_CFLAGS) $(SUBDIR_INCLUDES) $<
|
||||
|
||||
.m.o:
|
||||
$(GCC_FOR_TARGET) $(OPTIMIZE) -fgnu-runtime \
|
||||
-c $(GCC_CFLAGS) $(SUBDIR_INCLUDES) $<
|
||||
|
||||
OBJC_O = hash.o sarray.o class.o sendmsg.o init.o archive.o \
|
||||
selector.o objects.o misc.o object.o protocol.o encoding.o thread.o
|
||||
|
||||
libobjc.a: $(OBJC_O)
|
||||
-rm -f libobjc.a
|
||||
ar rc libobjc.a $(OBJC_O)
|
||||
ranlib libobjc.a
|
||||
|
||||
OBJC_H = hash.h objc-list.h sarray.h objc.h \
|
||||
objc-api.h \
|
||||
object.h protocol.h mutex.h \
|
||||
typedstream.h thread.h
|
||||
|
||||
mostlyclean:
|
||||
-rm -f *.o libobjc.a xforward fflags
|
||||
clean: mostlyclean
|
||||
distclean: mostlyclean
|
||||
extraclean: mostlyclean
|
@ -1,185 +0,0 @@
|
||||
/* GNU Objective C Runtime Miscellaneous
|
||||
Copyright (C) 1993, 1994, 1995, 1996, 1997, 2002
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 __USE_FIXED_PROTOTYPES__
|
||||
#include <stdlib.h>
|
||||
#include "objc/runtime.h"
|
||||
|
||||
/*
|
||||
** Error handler function
|
||||
** NULL so that default is to just print to stderr
|
||||
*/
|
||||
static objc_error_handler _objc_error_handler = NULL;
|
||||
|
||||
/* Trigger an objc error */
|
||||
void
|
||||
objc_error (id object, int code, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
objc_verror (object, code, fmt, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
/* Trigger an objc error */
|
||||
void
|
||||
objc_verror (id object, int code, const char *fmt, va_list ap)
|
||||
{
|
||||
BOOL result = NO;
|
||||
|
||||
/* Call the error handler if its there
|
||||
Otherwise print to stderr */
|
||||
if (_objc_error_handler)
|
||||
result = (*_objc_error_handler) (object, code, fmt, ap);
|
||||
else
|
||||
vfprintf (stderr, fmt, ap);
|
||||
|
||||
/* Continue if the error handler says its ok
|
||||
Otherwise abort the program */
|
||||
if (result)
|
||||
return;
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Set the error handler */
|
||||
objc_error_handler
|
||||
objc_set_error_handler (objc_error_handler func)
|
||||
{
|
||||
objc_error_handler temp = _objc_error_handler;
|
||||
_objc_error_handler = func;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/*
|
||||
** Standard functions for memory allocation and disposal.
|
||||
** Users should use these functions in their ObjC programs so
|
||||
** that they work properly with garbage collectors as well as
|
||||
** can take advantage of the exception/error handling available.
|
||||
*/
|
||||
|
||||
void *
|
||||
objc_malloc (size_t size)
|
||||
{
|
||||
void *res = (void *) (*_objc_malloc) (size);
|
||||
if (! res)
|
||||
objc_error (nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
void *
|
||||
objc_atomic_malloc (size_t size)
|
||||
{
|
||||
void *res = (void *) (*_objc_atomic_malloc) (size);
|
||||
if (! res)
|
||||
objc_error (nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
void *
|
||||
objc_valloc (size_t size)
|
||||
{
|
||||
void *res = (void *) (*_objc_valloc) (size);
|
||||
if (! res)
|
||||
objc_error (nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
void *
|
||||
objc_realloc (void *mem, size_t size)
|
||||
{
|
||||
void *res = (void *) (*_objc_realloc) (mem, size);
|
||||
if (! res)
|
||||
objc_error (nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
void *
|
||||
objc_calloc (size_t nelem, size_t size)
|
||||
{
|
||||
void *res = (void *) (*_objc_calloc) (nelem, size);
|
||||
if (! res)
|
||||
objc_error (nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
objc_free (void *mem)
|
||||
{
|
||||
(*_objc_free) (mem);
|
||||
}
|
||||
|
||||
/*
|
||||
** Hook functions for memory allocation and disposal.
|
||||
** This makes it easy to substitute garbage collection systems
|
||||
** such as Boehm's GC by assigning these function pointers
|
||||
** to the GC's allocation routines. By default these point
|
||||
** to the ANSI standard malloc, realloc, free, etc.
|
||||
**
|
||||
** Users should call the normal objc routines above for
|
||||
** memory allocation and disposal within their programs.
|
||||
*/
|
||||
|
||||
#if OBJC_WITH_GC
|
||||
#include <gc.h>
|
||||
|
||||
static void *
|
||||
GC_calloc (size_t nelem, size_t size)
|
||||
{
|
||||
void *p = GC_malloc (nelem * size);
|
||||
if (! p)
|
||||
objc_error (nil, OBJC_ERR_MEMORY, "Virtual memory exhausted!\n");
|
||||
|
||||
memset (p, 0, nelem * size);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void
|
||||
noFree (void *p)
|
||||
{
|
||||
}
|
||||
|
||||
void *(*_objc_malloc) (size_t) = GC_malloc;
|
||||
void *(*_objc_atomic_malloc) (size_t) = GC_malloc_atomic;
|
||||
void *(*_objc_valloc) (size_t) = GC_malloc;
|
||||
void *(*_objc_realloc) (void *, size_t) = GC_realloc;
|
||||
void *(*_objc_calloc) (size_t, size_t) = GC_calloc;
|
||||
void (*_objc_free) (void *) = noFree;
|
||||
|
||||
#else /* !OBJC_WITH_GC */
|
||||
|
||||
void *(*_objc_malloc) (size_t) = malloc;
|
||||
void *(*_objc_atomic_malloc) (size_t) = malloc;
|
||||
void *(*_objc_valloc) (size_t) = malloc;
|
||||
void *(*_objc_realloc) (void *, size_t) = realloc;
|
||||
void *(*_objc_calloc) (size_t, size_t) = calloc;
|
||||
void (*_objc_free) (void *) = free;
|
||||
|
||||
|
||||
#endif /* !OBJC_WITH_GC */
|
@ -1,55 +0,0 @@
|
||||
/* GNU Objective C Runtime nil receiver function
|
||||
Copyright (C) 1993, 1995, 1996, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
/* This is the nil method, the function that is called when the receiver
|
||||
of a method is nil */
|
||||
|
||||
#include "objc/runtime.h"
|
||||
|
||||
/* When the receiver of a method invocation is nil, the runtime
|
||||
returns nil_method() as the method implementation. This function
|
||||
will be casted to whatever function was supposed to be executed to
|
||||
execute that method (that function will take an id, followed by a
|
||||
SEL, followed by who knows what arguments, depends on the method),
|
||||
and executed.
|
||||
|
||||
For this reason, nil_method() should be a function which can be
|
||||
called in place of any function taking an 'id' argument followed by
|
||||
a 'SEL' argument, followed by zero, or one, or any number of
|
||||
arguments (both a fixed number, or a variable number !).
|
||||
|
||||
There is no "proper" implementation of such a nil_method function
|
||||
in C, however in all existing implementations it does not matter
|
||||
when extra arguments are present, so we can simply create a function
|
||||
taking a receiver and a selector, and all other arguments will be
|
||||
ignored. :-)
|
||||
*/
|
||||
|
||||
id
|
||||
nil_method (id receiver, SEL op __attribute__ ((__unused__)))
|
||||
{
|
||||
return receiver;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/* Interface for the NXConstantString class for Objective-C.
|
||||
Copyright (C) 1995, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Pieter J. Schoenmakers <tiggr@es.ele.tue.nl>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
#ifndef __nxconstantstring_INCLUDE_GNU
|
||||
#define __nxconstantstring_INCLUDE_GNU
|
||||
|
||||
#include "Object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@interface NXConstantString: Object
|
||||
{
|
||||
char *c_string;
|
||||
unsigned int len;
|
||||
}
|
||||
|
||||
-(const char *) cString;
|
||||
-(unsigned int) length;
|
||||
|
||||
@end
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,132 +0,0 @@
|
||||
/* Interface for the Object class for Objective-C.
|
||||
Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
#ifndef __object_INCLUDE_GNU
|
||||
#define __object_INCLUDE_GNU
|
||||
|
||||
#include "objc.h"
|
||||
#include "typedstream.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* All classes are derived from Object. As such,
|
||||
* this is the overhead tacked onto those objects.
|
||||
*/
|
||||
@interface Object
|
||||
{
|
||||
Class isa; /* A pointer to the instance's class structure */
|
||||
}
|
||||
|
||||
/* Initializing classes and instances */
|
||||
+ initialize;
|
||||
- init;
|
||||
|
||||
/* Creating, freeing, and copying instances */
|
||||
+ new;
|
||||
+ alloc;
|
||||
- free;
|
||||
- copy;
|
||||
- shallowCopy;
|
||||
- deepen;
|
||||
- deepCopy;
|
||||
|
||||
/* Identifying classes */
|
||||
- (Class)class;
|
||||
- (Class)superClass;
|
||||
- (MetaClass)metaClass;
|
||||
- (const char *)name;
|
||||
|
||||
/* Identifying and comparing objects */
|
||||
- self;
|
||||
- (unsigned int)hash;
|
||||
- (BOOL)isEqual:anObject;
|
||||
- (int)compare:anotherObject;
|
||||
|
||||
/* Testing object type */
|
||||
- (BOOL)isMetaClass;
|
||||
- (BOOL)isClass;
|
||||
- (BOOL)isInstance;
|
||||
|
||||
/* Testing inheritance relationships */
|
||||
- (BOOL)isKindOf:(Class)aClassObject;
|
||||
- (BOOL)isMemberOf:(Class)aClassObject;
|
||||
- (BOOL)isKindOfClassNamed:(const char *)aClassName;
|
||||
- (BOOL)isMemberOfClassNamed:(const char *)aClassName;
|
||||
|
||||
/* Testing class functionality */
|
||||
+ (BOOL)instancesRespondTo:(SEL)aSel;
|
||||
- (BOOL)respondsTo:(SEL)aSel;
|
||||
|
||||
/* Testing protocol conformance */
|
||||
- (BOOL)conformsTo:(Protocol*)aProtocol;
|
||||
|
||||
/* Introspection */
|
||||
+ (IMP)instanceMethodFor:(SEL)aSel;
|
||||
- (IMP)methodFor:(SEL)aSel;
|
||||
+ (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel;
|
||||
- (struct objc_method_description *)descriptionForMethod:(SEL)aSel;
|
||||
|
||||
/* Sending messages determined at run time */
|
||||
- perform:(SEL)aSel;
|
||||
- perform:(SEL)aSel with:anObject;
|
||||
- perform:(SEL)aSel with:anObject1 with:anObject2;
|
||||
|
||||
/* Forwarding */
|
||||
- (retval_t)forward:(SEL)aSel :(arglist_t)argFrame;
|
||||
- (retval_t)performv:(SEL)aSel :(arglist_t)argFrame;
|
||||
|
||||
/* Posing */
|
||||
+ poseAs:(Class)aClassObject;
|
||||
- (Class)transmuteClassTo:(Class)aClassObject;
|
||||
|
||||
/* Enforcing intentions */
|
||||
- subclassResponsibility:(SEL)aSel;
|
||||
- notImplemented:(SEL)aSel;
|
||||
- shouldNotImplement:(SEL)aSel;
|
||||
|
||||
/* Error handling */
|
||||
- doesNotRecognize:(SEL)aSel;
|
||||
- error:(const char *)aString, ...;
|
||||
|
||||
/* Archiving */
|
||||
+ (int)version;
|
||||
+ setVersion:(int)aVersion;
|
||||
+ (int)streamVersion: (TypedStream*)aStream;
|
||||
|
||||
- read: (TypedStream*)aStream;
|
||||
- write: (TypedStream*)aStream;
|
||||
- awake;
|
||||
|
||||
@end
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,63 +0,0 @@
|
||||
/* Declare the class Protocol for Objective C programs.
|
||||
Copyright (C) 1993, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
#ifndef __Protocol_INCLUDE_GNU
|
||||
#define __Protocol_INCLUDE_GNU
|
||||
|
||||
#include "Object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@interface Protocol : Object
|
||||
{
|
||||
@private
|
||||
char *protocol_name;
|
||||
struct objc_protocol_list *protocol_list;
|
||||
struct objc_method_description_list *instance_methods, *class_methods;
|
||||
}
|
||||
|
||||
/* Obtaining attributes intrinsic to the protocol */
|
||||
|
||||
- (const char *)name;
|
||||
|
||||
/* Testing protocol conformance */
|
||||
|
||||
- (BOOL) conformsTo: (Protocol *)aProtocolObject;
|
||||
|
||||
/* Looking up information specific to a protocol */
|
||||
|
||||
- (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel;
|
||||
- (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel;
|
||||
|
||||
@end
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* not __Protocol_INCLUDE_GNU */
|
@ -1,107 +0,0 @@
|
||||
/* Encoding of types for Objective C.
|
||||
Copyright (C) 1993, 1997, 2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
Author: Kresten Krab Thorup
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
#ifndef __encoding_INCLUDE_GNU
|
||||
#define __encoding_INCLUDE_GNU
|
||||
|
||||
#include "objc-api.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define _C_CONST 'r'
|
||||
#define _C_IN 'n'
|
||||
#define _C_INOUT 'N'
|
||||
#define _C_OUT 'o'
|
||||
#define _C_BYCOPY 'O'
|
||||
#define _C_BYREF 'R'
|
||||
#define _C_ONEWAY 'V'
|
||||
#define _C_GCINVISIBLE '!'
|
||||
|
||||
#define _F_CONST 0x01
|
||||
#define _F_IN 0x01
|
||||
#define _F_OUT 0x02
|
||||
#define _F_INOUT 0x03
|
||||
#define _F_BYCOPY 0x04
|
||||
#define _F_BYREF 0x08
|
||||
#define _F_ONEWAY 0x10
|
||||
#define _F_GCINVISIBLE 0x20
|
||||
|
||||
int objc_aligned_size (const char *type);
|
||||
int objc_sizeof_type (const char *type);
|
||||
int objc_alignof_type (const char *type);
|
||||
int objc_aligned_size (const char *type);
|
||||
int objc_promoted_size (const char *type);
|
||||
|
||||
const char *objc_skip_type_qualifiers (const char *type);
|
||||
const char *objc_skip_typespec (const char *type);
|
||||
const char *objc_skip_offset (const char *type);
|
||||
const char *objc_skip_argspec (const char *type);
|
||||
int method_get_number_of_arguments (struct objc_method *);
|
||||
int method_get_sizeof_arguments (struct objc_method *);
|
||||
|
||||
char *method_get_first_argument (struct objc_method *,
|
||||
arglist_t argframe,
|
||||
const char **type);
|
||||
char *method_get_next_argument (arglist_t argframe,
|
||||
const char **type);
|
||||
char *method_get_nth_argument (struct objc_method *m,
|
||||
arglist_t argframe,
|
||||
int arg,
|
||||
const char **type);
|
||||
|
||||
unsigned objc_get_type_qualifiers (const char *type);
|
||||
|
||||
|
||||
struct objc_struct_layout
|
||||
{
|
||||
const char *original_type;
|
||||
const char *type;
|
||||
const char *prev_type;
|
||||
unsigned int record_size;
|
||||
unsigned int record_align;
|
||||
};
|
||||
|
||||
void objc_layout_structure (const char *type,
|
||||
struct objc_struct_layout *layout);
|
||||
BOOL objc_layout_structure_next_member (struct objc_struct_layout *layout);
|
||||
void objc_layout_finish_structure (struct objc_struct_layout *layout,
|
||||
unsigned int *size,
|
||||
unsigned int *align);
|
||||
void objc_layout_structure_get_info (struct objc_struct_layout *layout,
|
||||
unsigned int *offset,
|
||||
unsigned int *align,
|
||||
const char **type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __encoding_INCLUDE_GNU */
|
@ -1,216 +0,0 @@
|
||||
/* Hash tables for Objective C method dispatch.
|
||||
Copyright (C) 1993, 1995, 1996, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
|
||||
#ifndef __hash_INCLUDE_GNU
|
||||
#define __hash_INCLUDE_GNU
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "objc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* This data structure is used to hold items
|
||||
* stored in a hash table. Each node holds
|
||||
* a key/value pair.
|
||||
*
|
||||
* Items in the cache are really of type void *.
|
||||
*/
|
||||
typedef struct cache_node
|
||||
{
|
||||
struct cache_node *next; /* Pointer to next entry on the list.
|
||||
NULL indicates end of list. */
|
||||
const void *key; /* Key used to locate the value. Used
|
||||
to locate value when more than one
|
||||
key computes the same hash
|
||||
value. */
|
||||
void *value; /* Value stored for the key. */
|
||||
} *node_ptr;
|
||||
|
||||
|
||||
/*
|
||||
* This data type is the function that computes a hash code given a key.
|
||||
* Therefore, the key can be a pointer to anything and the function specific
|
||||
* to the key type.
|
||||
*
|
||||
* Unfortunately there is a mutual data structure reference problem with this
|
||||
* typedef. Therefore, to remove compiler warnings the functions passed to
|
||||
* objc_hash_new will have to be casted to this type.
|
||||
*/
|
||||
typedef unsigned int (*hash_func_type) (void *, const void *);
|
||||
|
||||
/*
|
||||
* This data type is the function that compares two hash keys and returns an
|
||||
* integer greater than, equal to, or less than 0, according as the first
|
||||
* parameter is lexicographically greater than, equal to, or less than the
|
||||
* second.
|
||||
*/
|
||||
|
||||
typedef int (*compare_func_type) (const void *, const void *);
|
||||
|
||||
|
||||
/*
|
||||
* This data structure is the cache.
|
||||
*
|
||||
* It must be passed to all of the hashing routines
|
||||
* (except for new).
|
||||
*/
|
||||
typedef struct cache
|
||||
{
|
||||
/* Variables used to implement the hash itself. */
|
||||
node_ptr *node_table; /* Pointer to an array of hash nodes. */
|
||||
/* Variables used to track the size of the hash table so to determine
|
||||
when to resize it. */
|
||||
unsigned int size; /* Number of buckets allocated for the hash table
|
||||
(number of array entries allocated for
|
||||
"node_table"). Must be a power of two. */
|
||||
unsigned int used; /* Current number of entries in the hash table. */
|
||||
unsigned int mask; /* Precomputed mask. */
|
||||
|
||||
/* Variables used to implement indexing through the hash table. */
|
||||
|
||||
unsigned int last_bucket; /* Tracks which entry in the array where
|
||||
the last value was returned. */
|
||||
/* Function used to compute a hash code given a key.
|
||||
This function is specified when the hash table is created. */
|
||||
hash_func_type hash_func;
|
||||
/* Function used to compare two hash keys to see if they are equal. */
|
||||
compare_func_type compare_func;
|
||||
} *cache_ptr;
|
||||
|
||||
|
||||
/* Two important hash tables. */
|
||||
extern cache_ptr module_hash_table, class_hash_table;
|
||||
|
||||
/* Allocate and initialize a hash table. */
|
||||
|
||||
cache_ptr objc_hash_new (unsigned int size,
|
||||
hash_func_type hash_func,
|
||||
compare_func_type compare_func);
|
||||
|
||||
/* Deallocate all of the hash nodes and the cache itself. */
|
||||
|
||||
void objc_hash_delete (cache_ptr cache);
|
||||
|
||||
/* Add the key/value pair to the hash table. If the
|
||||
hash table reaches a level of fullness then it will be resized.
|
||||
|
||||
assert if the key is already in the hash. */
|
||||
|
||||
void objc_hash_add (cache_ptr *cachep, const void *key, void *value);
|
||||
|
||||
/* Remove the key/value pair from the hash table.
|
||||
assert if the key isn't in the table. */
|
||||
|
||||
void objc_hash_remove (cache_ptr cache, const void *key);
|
||||
|
||||
/* Used to index through the hash table. Start with NULL
|
||||
to get the first entry.
|
||||
|
||||
Successive calls pass the value returned previously.
|
||||
** Don't modify the hash during this operation ***
|
||||
|
||||
Cache nodes are returned such that key or value can
|
||||
be extracted. */
|
||||
|
||||
node_ptr objc_hash_next (cache_ptr cache, node_ptr node);
|
||||
|
||||
/* Used to return a value from a hash table using a given key. */
|
||||
|
||||
void *objc_hash_value_for_key (cache_ptr cache, const void *key);
|
||||
|
||||
/* Used to determine if the given key exists in the hash table */
|
||||
|
||||
BOOL objc_hash_is_key_in_hash (cache_ptr cache, const void *key);
|
||||
|
||||
/************************************************
|
||||
|
||||
Useful hashing functions.
|
||||
|
||||
Declared inline for your pleasure.
|
||||
|
||||
************************************************/
|
||||
|
||||
/* Calculate a hash code by performing some
|
||||
manipulation of the key pointer. (Use the lowest bits
|
||||
except for those likely to be 0 due to alignment.) */
|
||||
|
||||
static inline unsigned int
|
||||
objc_hash_ptr (cache_ptr cache, const void *key)
|
||||
{
|
||||
return ((size_t)key / sizeof (void *)) & cache->mask;
|
||||
}
|
||||
|
||||
|
||||
/* Calculate a hash code by iterating over a NULL
|
||||
terminate string. */
|
||||
static inline unsigned int
|
||||
objc_hash_string (cache_ptr cache, const void *key)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
unsigned int ctr = 0;
|
||||
const char *ckey = (const char *) key;
|
||||
|
||||
while (*ckey) {
|
||||
ret ^= *ckey++ << ctr;
|
||||
ctr = (ctr + 1) % sizeof (void *);
|
||||
}
|
||||
|
||||
return ret & cache->mask;
|
||||
}
|
||||
|
||||
|
||||
/* Compare two pointers for equality. */
|
||||
static inline int
|
||||
objc_compare_ptrs (const void *k1, const void *k2)
|
||||
{
|
||||
return (k1 == k2);
|
||||
}
|
||||
|
||||
|
||||
/* Compare two strings. */
|
||||
static inline int
|
||||
objc_compare_strings (const void *k1, const void *k2)
|
||||
{
|
||||
if (k1 == k2)
|
||||
return 1;
|
||||
else if (k1 == 0 || k2 == 0)
|
||||
return 0;
|
||||
else
|
||||
return ! strcmp ((const char *) k1, (const char *) k2);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#endif /* not __hash_INCLUDE_GNU */
|
@ -1,626 +0,0 @@
|
||||
/* GNU Objective-C Runtime API.
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
#ifndef __objc_api_INCLUDE_GNU
|
||||
#define __objc_api_INCLUDE_GNU
|
||||
|
||||
#include "objc.h"
|
||||
#include "hash.h"
|
||||
#include "thr.h"
|
||||
#include "objc-decls.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* For functions which return Method_t */
|
||||
#define METHOD_NULL (Method_t)0
|
||||
/* Boolean typedefs */
|
||||
/*
|
||||
** Method descriptor returned by introspective Object methods.
|
||||
** This is really just the first part of the more complete objc_method
|
||||
** structure defined below and used internally by the runtime.
|
||||
*/
|
||||
struct objc_method_description
|
||||
{
|
||||
SEL name; /* this is a selector, not a string */
|
||||
char *types; /* type encoding */
|
||||
};
|
||||
|
||||
/* Filer types used to describe Ivars and Methods. */
|
||||
#define _C_ID '@'
|
||||
#define _C_CLASS '#'
|
||||
#define _C_SEL ':'
|
||||
#define _C_CHR 'c'
|
||||
#define _C_UCHR 'C'
|
||||
#define _C_SHT 's'
|
||||
#define _C_USHT 'S'
|
||||
#define _C_INT 'i'
|
||||
#define _C_UINT 'I'
|
||||
#define _C_LNG 'l'
|
||||
#define _C_ULNG 'L'
|
||||
#define _C_LNG_LNG 'q'
|
||||
#define _C_ULNG_LNG 'Q'
|
||||
#define _C_FLT 'f'
|
||||
#define _C_DBL 'd'
|
||||
#define _C_BFLD 'b'
|
||||
#define _C_BOOL 'B'
|
||||
#define _C_VOID 'v'
|
||||
#define _C_UNDEF '?'
|
||||
#define _C_PTR '^'
|
||||
#define _C_CHARPTR '*'
|
||||
#define _C_ATOM '%'
|
||||
#define _C_ARY_B '['
|
||||
#define _C_ARY_E ']'
|
||||
#define _C_UNION_B '('
|
||||
#define _C_UNION_E ')'
|
||||
#define _C_STRUCT_B '{'
|
||||
#define _C_STRUCT_E '}'
|
||||
#define _C_VECTOR '!'
|
||||
#define _C_COMPLEX 'j'
|
||||
|
||||
|
||||
/*
|
||||
** Error handling
|
||||
**
|
||||
** Call objc_error() or objc_verror() to record an error; this error
|
||||
** routine will generally exit the program but not necessarily if the
|
||||
** user has installed his own error handler.
|
||||
**
|
||||
** Call objc_set_error_handler to assign your own function for
|
||||
** handling errors. The function should return YES if it is ok
|
||||
** to continue execution, or return NO or just abort if the
|
||||
** program should be stopped. The default error handler is just to
|
||||
** print a message on stderr.
|
||||
**
|
||||
** The error handler function should be of type objc_error_handler
|
||||
** The first parameter is an object instance of relevance.
|
||||
** The second parameter is an error code.
|
||||
** The third parameter is a format string in the printf style.
|
||||
** The fourth parameter is a variable list of arguments.
|
||||
*/
|
||||
extern void objc_error(id object, int code, const char* fmt, ...);
|
||||
extern void objc_verror(id object, int code, const char* fmt, va_list ap);
|
||||
typedef BOOL (*objc_error_handler)(id, int code, const char *fmt, va_list ap);
|
||||
extern objc_error_handler objc_set_error_handler(objc_error_handler func);
|
||||
|
||||
/*
|
||||
** Error codes
|
||||
** These are used by the runtime library, and your
|
||||
** error handling may use them to determine if the error is
|
||||
** hard or soft thus whether execution can continue or abort.
|
||||
*/
|
||||
#define OBJC_ERR_UNKNOWN 0 /* Generic error */
|
||||
|
||||
#define OBJC_ERR_OBJC_VERSION 1 /* Incorrect runtime version */
|
||||
#define OBJC_ERR_GCC_VERSION 2 /* Incorrect compiler version */
|
||||
#define OBJC_ERR_MODULE_SIZE 3 /* Bad module size */
|
||||
#define OBJC_ERR_PROTOCOL_VERSION 4 /* Incorrect protocol version */
|
||||
|
||||
#define OBJC_ERR_MEMORY 10 /* Out of memory */
|
||||
|
||||
#define OBJC_ERR_RECURSE_ROOT 20 /* Attempt to archive the root
|
||||
object more than once. */
|
||||
#define OBJC_ERR_BAD_DATA 21 /* Didn't read expected data */
|
||||
#define OBJC_ERR_BAD_KEY 22 /* Bad key for object */
|
||||
#define OBJC_ERR_BAD_CLASS 23 /* Unknown class */
|
||||
#define OBJC_ERR_BAD_TYPE 24 /* Bad type specification */
|
||||
#define OBJC_ERR_NO_READ 25 /* Cannot read stream */
|
||||
#define OBJC_ERR_NO_WRITE 26 /* Cannot write stream */
|
||||
#define OBJC_ERR_STREAM_VERSION 27 /* Incorrect stream version */
|
||||
#define OBJC_ERR_BAD_OPCODE 28 /* Bad opcode */
|
||||
|
||||
#define OBJC_ERR_UNIMPLEMENTED 30 /* Method is not implemented */
|
||||
|
||||
#define OBJC_ERR_BAD_STATE 40 /* Bad thread state */
|
||||
|
||||
/*
|
||||
** Set this variable nonzero to print a line describing each
|
||||
** message that is sent. (this is currently disabled)
|
||||
*/
|
||||
extern BOOL objc_trace;
|
||||
|
||||
|
||||
/* For every class which happens to have statically allocated instances in
|
||||
this module, one OBJC_STATIC_INSTANCES is allocated by the compiler.
|
||||
INSTANCES is NULL terminated and points to all statically allocated
|
||||
instances of this class. */
|
||||
struct objc_static_instances
|
||||
{
|
||||
char *class_name;
|
||||
#ifdef __cplusplus
|
||||
id instances[1];
|
||||
#else
|
||||
id instances[0];
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
** Whereas a Module (defined further down) is the root (typically) of a file,
|
||||
** a Symtab is the root of the class and category definitions within the
|
||||
** module.
|
||||
**
|
||||
** A Symtab contains a variable length array of pointers to classes and
|
||||
** categories defined in the module.
|
||||
*/
|
||||
typedef struct objc_symtab {
|
||||
unsigned long sel_ref_cnt; /* Unknown. */
|
||||
SEL refs; /* Unknown. */
|
||||
unsigned short cls_def_cnt; /* Number of classes compiled
|
||||
(defined) in the module. */
|
||||
unsigned short cat_def_cnt; /* Number of categories
|
||||
compiled (defined) in the
|
||||
module. */
|
||||
|
||||
void *defs[1]; /* Variable array of pointers.
|
||||
cls_def_cnt of type Class
|
||||
followed by cat_def_cnt of
|
||||
type Category_t, followed
|
||||
by a NULL terminated array
|
||||
of objc_static_instances. */
|
||||
} Symtab, *Symtab_t;
|
||||
|
||||
|
||||
/*
|
||||
** The compiler generates one of these structures for each module that
|
||||
** composes the executable (eg main.m).
|
||||
**
|
||||
** This data structure is the root of the definition tree for the module.
|
||||
**
|
||||
** A collect program runs between ld stages and creates a ObjC ctor array.
|
||||
** That array holds a pointer to each module structure of the executable.
|
||||
*/
|
||||
typedef struct objc_module {
|
||||
unsigned long version; /* Compiler revision. */
|
||||
unsigned long size; /* sizeof(Module). */
|
||||
const char* name; /* Name of the file where the
|
||||
module was generated. The
|
||||
name includes the path. */
|
||||
|
||||
Symtab_t symtab; /* Pointer to the Symtab of
|
||||
the module. The Symtab
|
||||
holds an array of
|
||||
pointers to
|
||||
the classes and categories
|
||||
defined in the module. */
|
||||
} Module, *Module_t;
|
||||
|
||||
|
||||
/*
|
||||
** The compiler generates one of these structures for a class that has
|
||||
** instance variables defined in its specification.
|
||||
*/
|
||||
typedef struct objc_ivar {
|
||||
const char* ivar_name; /* Name of the instance
|
||||
variable as entered in the
|
||||
class definition. */
|
||||
const char* ivar_type; /* Description of the Ivar's
|
||||
type. Useful for
|
||||
debuggers. */
|
||||
int ivar_offset; /* Byte offset from the base
|
||||
address of the instance
|
||||
structure to the variable. */
|
||||
} *Ivar_t;
|
||||
|
||||
typedef struct objc_ivar_list {
|
||||
int ivar_count; /* Number of structures (Ivar)
|
||||
contained in the list. One
|
||||
structure per instance
|
||||
variable defined in the
|
||||
class. */
|
||||
struct objc_ivar ivar_list[1]; /* Variable length
|
||||
structure. */
|
||||
} IvarList, *IvarList_t;
|
||||
|
||||
|
||||
/*
|
||||
** The compiler generates one (or more) of these structures for a class that
|
||||
** has methods defined in its specification.
|
||||
**
|
||||
** The implementation of a class can be broken into separate pieces in a file
|
||||
** and categories can break them across modules. To handle this problem is a
|
||||
** singly linked list of methods.
|
||||
*/
|
||||
typedef struct objc_method {
|
||||
SEL method_name; /* This variable is the method's
|
||||
name. It is a char*.
|
||||
The unique integer passed to
|
||||
objc_msg_send is a char* too.
|
||||
It is compared against
|
||||
method_name using strcmp. */
|
||||
const char* method_types; /* Description of the method's
|
||||
parameter list. Useful for
|
||||
debuggers. */
|
||||
IMP method_imp; /* Address of the method in the
|
||||
executable. */
|
||||
} Method, *Method_t;
|
||||
|
||||
typedef struct objc_method_list {
|
||||
struct objc_method_list* method_next; /* This variable is used to link
|
||||
a method list to another. It
|
||||
is a singly linked list. */
|
||||
int method_count; /* Number of methods defined in
|
||||
this structure. */
|
||||
Method method_list[1]; /* Variable length
|
||||
structure. */
|
||||
} MethodList, *MethodList_t;
|
||||
|
||||
struct objc_protocol_list {
|
||||
struct objc_protocol_list *next;
|
||||
size_t count;
|
||||
Protocol *list[1];
|
||||
};
|
||||
|
||||
/*
|
||||
** This is used to assure consistent access to the info field of
|
||||
** classes
|
||||
*/
|
||||
#ifndef HOST_BITS_PER_LONG
|
||||
#define HOST_BITS_PER_LONG (sizeof(long)*8)
|
||||
#endif
|
||||
|
||||
#define __CLS_INFO(cls) ((cls)->info)
|
||||
#define __CLS_ISINFO(cls, mask) ((__CLS_INFO(cls)&mask)==mask)
|
||||
#define __CLS_SETINFO(cls, mask) (__CLS_INFO(cls) |= mask)
|
||||
|
||||
/* The structure is of type MetaClass */
|
||||
#define _CLS_META 0x2L
|
||||
#define CLS_ISMETA(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_META))
|
||||
|
||||
|
||||
/* The structure is of type Class */
|
||||
#define _CLS_CLASS 0x1L
|
||||
#define CLS_ISCLASS(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_CLASS))
|
||||
|
||||
/*
|
||||
** The class is initialized within the runtime. This means that
|
||||
** it has had correct super and sublinks assigned
|
||||
*/
|
||||
#define _CLS_RESOLV 0x8L
|
||||
#define CLS_ISRESOLV(cls) __CLS_ISINFO(cls, _CLS_RESOLV)
|
||||
#define CLS_SETRESOLV(cls) __CLS_SETINFO(cls, _CLS_RESOLV)
|
||||
|
||||
/*
|
||||
** The class has been send a +initialize message or a such is not
|
||||
** defined for this class
|
||||
*/
|
||||
#define _CLS_INITIALIZED 0x04L
|
||||
#define CLS_ISINITIALIZED(cls) __CLS_ISINFO(cls, _CLS_INITIALIZED)
|
||||
#define CLS_SETINITIALIZED(cls) __CLS_SETINFO(cls, _CLS_INITIALIZED)
|
||||
|
||||
/*
|
||||
** The class number of this class. This must be the same for both the
|
||||
** class and its meta class object
|
||||
*/
|
||||
#define CLS_GETNUMBER(cls) (__CLS_INFO(cls) >> (HOST_BITS_PER_LONG/2))
|
||||
#define CLS_SETNUMBER(cls, num) \
|
||||
({ (cls)->info <<= (HOST_BITS_PER_LONG/2); \
|
||||
(cls)->info >>= (HOST_BITS_PER_LONG/2); \
|
||||
__CLS_SETINFO(cls, (((unsigned long)num) << (HOST_BITS_PER_LONG/2))); })
|
||||
|
||||
/*
|
||||
** The compiler generates one of these structures for each category. A class
|
||||
** may have many categories and contain both instance and factory methods.
|
||||
*/
|
||||
typedef struct objc_category {
|
||||
const char* category_name; /* Name of the category. Name
|
||||
contained in the () of the
|
||||
category definition. */
|
||||
const char* class_name; /* Name of the class to which
|
||||
the category belongs. */
|
||||
MethodList_t instance_methods; /* Linked list of instance
|
||||
methods defined in the
|
||||
category. NULL indicates no
|
||||
instance methods defined. */
|
||||
MethodList_t class_methods; /* Linked list of factory
|
||||
methods defined in the
|
||||
category. NULL indicates no
|
||||
class methods defined. */
|
||||
struct objc_protocol_list *protocols; /* List of Protocols
|
||||
conformed to */
|
||||
} Category, *Category_t;
|
||||
|
||||
/*
|
||||
** Structure used when a message is send to a class's super class. The
|
||||
** compiler generates one of these structures and passes it to
|
||||
** objc_msg_super.
|
||||
*/
|
||||
typedef struct objc_super {
|
||||
id self; /* Id of the object sending
|
||||
the message. */
|
||||
#ifdef __cplusplus
|
||||
Class super_class;
|
||||
#else
|
||||
Class class; /* Object's super class. */
|
||||
#endif
|
||||
} Super, *Super_t;
|
||||
|
||||
IMP objc_msg_lookup_super(Super_t super, SEL sel);
|
||||
|
||||
retval_t objc_msg_sendv(id, SEL, arglist_t);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** This is a hook which is called by objc_lookup_class and
|
||||
** objc_get_class if the runtime is not able to find the class.
|
||||
** This may e.g. try to load in the class using dynamic loading.
|
||||
** The function is guaranteed to be passed a non-NULL name string.
|
||||
*/
|
||||
objc_EXPORT Class (*_objc_lookup_class)(const char *name);
|
||||
|
||||
/*
|
||||
** This is a hook which is called by __objc_exec_class every time a class
|
||||
** or a category is loaded into the runtime. This may e.g. help a
|
||||
** dynamic loader determine the classes that have been loaded when
|
||||
** an object file is dynamically linked in.
|
||||
*/
|
||||
objc_EXPORT void (*_objc_load_callback)(Class _class, Category* category);
|
||||
|
||||
/*
|
||||
** Hook functions for allocating, copying and disposing of instances
|
||||
*/
|
||||
objc_EXPORT id (*_objc_object_alloc)(Class _class);
|
||||
objc_EXPORT id (*_objc_object_copy)(id object);
|
||||
objc_EXPORT id (*_objc_object_dispose)(id object);
|
||||
|
||||
/*
|
||||
** Standard functions for memory allocation and disposal.
|
||||
** Users should use these functions in their ObjC programs so
|
||||
** that they work properly with garbage collectors as well as
|
||||
** can take advantage of the exception/error handling available.
|
||||
*/
|
||||
void *
|
||||
objc_malloc(size_t size);
|
||||
|
||||
void *
|
||||
objc_atomic_malloc(size_t size);
|
||||
|
||||
void *
|
||||
objc_valloc(size_t size);
|
||||
|
||||
void *
|
||||
objc_realloc(void *mem, size_t size);
|
||||
|
||||
void *
|
||||
objc_calloc(size_t nelem, size_t size);
|
||||
|
||||
void
|
||||
objc_free(void *mem);
|
||||
|
||||
/*
|
||||
** Hook functions for memory allocation and disposal.
|
||||
** This makes it easy to substitute garbage collection systems
|
||||
** such as Boehm's GC by assigning these function pointers
|
||||
** to the GC's allocation routines. By default these point
|
||||
** to the ANSI standard malloc, realloc, free, etc.
|
||||
**
|
||||
** Users should call the normal objc routines above for
|
||||
** memory allocation and disposal within their programs.
|
||||
*/
|
||||
objc_EXPORT void *(*_objc_malloc)(size_t);
|
||||
objc_EXPORT void *(*_objc_atomic_malloc)(size_t);
|
||||
objc_EXPORT void *(*_objc_valloc)(size_t);
|
||||
objc_EXPORT void *(*_objc_realloc)(void *, size_t);
|
||||
objc_EXPORT void *(*_objc_calloc)(size_t, size_t);
|
||||
objc_EXPORT 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.
|
||||
*/
|
||||
objc_EXPORT 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);
|
||||
|
||||
Class class_pose_as(Class impostor, Class superclass);
|
||||
|
||||
Class objc_get_class(const char *name);
|
||||
|
||||
Class objc_lookup_class(const char *name);
|
||||
|
||||
Class objc_next_class(void **enum_state);
|
||||
|
||||
const char *sel_get_name(SEL selector);
|
||||
|
||||
const char *sel_get_type(SEL selector);
|
||||
|
||||
SEL sel_get_uid(const char *name);
|
||||
|
||||
SEL sel_get_any_uid(const char *name);
|
||||
|
||||
SEL sel_get_any_typed_uid(const char *name);
|
||||
|
||||
SEL sel_get_typed_uid(const char *name, const char*);
|
||||
|
||||
SEL sel_register_name(const char *name);
|
||||
|
||||
SEL sel_register_typed_name(const char *name, const char*type);
|
||||
|
||||
|
||||
BOOL sel_is_mapped (SEL aSel);
|
||||
|
||||
extern id class_create_instance(Class _class);
|
||||
|
||||
static inline const char *
|
||||
class_get_class_name(Class _class)
|
||||
{
|
||||
return CLS_ISCLASS(_class)?_class->name:((_class==Nil)?"Nil":0);
|
||||
}
|
||||
|
||||
static inline long
|
||||
class_get_instance_size(Class _class)
|
||||
{
|
||||
return CLS_ISCLASS(_class)?_class->instance_size:0;
|
||||
}
|
||||
|
||||
static inline MetaClass
|
||||
class_get_meta_class(Class _class)
|
||||
{
|
||||
return CLS_ISCLASS(_class)?_class->class_pointer:Nil;
|
||||
}
|
||||
|
||||
static inline Class
|
||||
class_get_super_class(Class _class)
|
||||
{
|
||||
return CLS_ISCLASS(_class)?_class->super_class:Nil;
|
||||
}
|
||||
|
||||
static inline int
|
||||
class_get_version(Class _class)
|
||||
{
|
||||
return CLS_ISCLASS(_class)?_class->version:-1;
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
class_is_class(Class _class)
|
||||
{
|
||||
return CLS_ISCLASS(_class);
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
class_is_meta_class(Class _class)
|
||||
{
|
||||
return CLS_ISMETA(_class);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
class_set_version(Class _class, long version)
|
||||
{
|
||||
if (CLS_ISCLASS(_class))
|
||||
_class->version = version;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
class_get_gc_object_type (Class _class)
|
||||
{
|
||||
return CLS_ISCLASS(_class) ? _class->gc_object_type : NULL;
|
||||
}
|
||||
|
||||
/* Mark the instance variable as innaccessible to the garbage collector */
|
||||
extern void class_ivar_set_gcinvisible (Class _class,
|
||||
const char* ivarname,
|
||||
BOOL gcInvisible);
|
||||
|
||||
static inline IMP
|
||||
method_get_imp(Method_t method)
|
||||
{
|
||||
return (method!=METHOD_NULL)?method->method_imp:(IMP)0;
|
||||
}
|
||||
|
||||
IMP get_imp (Class _class, SEL sel);
|
||||
|
||||
/* Redefine on NeXTSTEP so as not to conflict with system function */
|
||||
#ifdef __NeXT__
|
||||
#define object_copy gnu_object_copy
|
||||
#define object_dispose gnu_object_dispose
|
||||
#endif
|
||||
|
||||
id object_copy(id object);
|
||||
|
||||
id object_dispose(id object);
|
||||
|
||||
static inline Class
|
||||
object_get_class(id object)
|
||||
{
|
||||
return ((object!=nil)
|
||||
? (CLS_ISCLASS(object->class_pointer)
|
||||
? object->class_pointer
|
||||
: (CLS_ISMETA(object->class_pointer)
|
||||
? (Class)object
|
||||
: Nil))
|
||||
: Nil);
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
object_get_class_name(id object)
|
||||
{
|
||||
return ((object!=nil)?(CLS_ISCLASS(object->class_pointer)
|
||||
?object->class_pointer->name
|
||||
:((Class)object)->name)
|
||||
:"Nil");
|
||||
}
|
||||
|
||||
static inline MetaClass
|
||||
object_get_meta_class(id object)
|
||||
{
|
||||
return ((object!=nil)?(CLS_ISCLASS(object->class_pointer)
|
||||
?object->class_pointer->class_pointer
|
||||
:(CLS_ISMETA(object->class_pointer)
|
||||
?object->class_pointer
|
||||
:Nil))
|
||||
:Nil);
|
||||
}
|
||||
|
||||
static inline Class
|
||||
object_get_super_class
|
||||
(id object)
|
||||
{
|
||||
return ((object!=nil)?(CLS_ISCLASS(object->class_pointer)
|
||||
?object->class_pointer->super_class
|
||||
:(CLS_ISMETA(object->class_pointer)
|
||||
?((Class)object)->super_class
|
||||
:Nil))
|
||||
:Nil);
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
object_is_class (id 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_meta_class (id object)
|
||||
{
|
||||
return ((object != nil)
|
||||
&& !object_is_instance (object)
|
||||
&& !object_is_class (object));
|
||||
}
|
||||
|
||||
struct sarray*
|
||||
objc_get_uninstalled_dtable(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* not __objc_api_INCLUDE_GNU */
|
||||
|
||||
|
||||
|
@ -1,47 +0,0 @@
|
||||
/* GNU Objective-C Extern helpers for Win32.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
#ifndef __objc_decls_INCLUDE_GNU
|
||||
#define __objc_decls_INCLUDE_GNU
|
||||
|
||||
#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32)
|
||||
|
||||
# ifdef DLL_EXPORT /* defined by libtool (if required) */
|
||||
# define objc_EXPORT __declspec(dllexport)
|
||||
# define objc_DECLARE __declspec(dllexport)
|
||||
#else
|
||||
# define objc_EXPORT extern __declspec(dllimport)
|
||||
# define objc_DECLARE extern __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
# define objc_EXPORT extern
|
||||
# define objc_DECLARE
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __objc_decls_INCLUDE_GNU */
|
@ -1,156 +0,0 @@
|
||||
/* Generic single linked list to keep various information
|
||||
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
#ifndef __GNU_OBJC_LIST_H
|
||||
#define __GNU_OBJC_LIST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct objc_list {
|
||||
void *head;
|
||||
struct objc_list *tail;
|
||||
};
|
||||
|
||||
/* Return a cons cell produced from (head . tail) */
|
||||
|
||||
static inline struct objc_list*
|
||||
list_cons(void* head, struct objc_list* tail)
|
||||
{
|
||||
struct objc_list* cell;
|
||||
|
||||
cell = (struct objc_list*)objc_malloc(sizeof(struct objc_list));
|
||||
cell->head = head;
|
||||
cell->tail = tail;
|
||||
return cell;
|
||||
}
|
||||
|
||||
/* Return the length of a list, list_length(NULL) returns zero */
|
||||
|
||||
static inline int
|
||||
list_length(struct objc_list* list)
|
||||
{
|
||||
int i = 0;
|
||||
while(list)
|
||||
{
|
||||
i += 1;
|
||||
list = list->tail;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Return the Nth element of LIST, where N count from zero. If N
|
||||
larger than the list length, NULL is returned */
|
||||
|
||||
static inline void*
|
||||
list_nth(int indx, struct objc_list* list)
|
||||
{
|
||||
while(indx-- != 0)
|
||||
{
|
||||
if(list->tail)
|
||||
list = list->tail;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return list->head;
|
||||
}
|
||||
|
||||
/* Remove the element at the head by replacing it by its successor */
|
||||
|
||||
static inline void
|
||||
list_remove_head(struct objc_list** list)
|
||||
{
|
||||
if ((*list)->tail)
|
||||
{
|
||||
struct objc_list* tail = (*list)->tail; /* fetch next */
|
||||
*(*list) = *tail; /* copy next to list head */
|
||||
objc_free(tail); /* free next */
|
||||
}
|
||||
else /* only one element in list */
|
||||
{
|
||||
objc_free(*list);
|
||||
(*list) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Remove the element with `car' set to ELEMENT */
|
||||
|
||||
static inline void
|
||||
list_remove_elem(struct objc_list** list, void* elem)
|
||||
{
|
||||
while (*list) {
|
||||
if ((*list)->head == elem)
|
||||
list_remove_head(list);
|
||||
list = &((*list)->tail);
|
||||
}
|
||||
}
|
||||
|
||||
/* Map FUNCTION over all elements in LIST */
|
||||
|
||||
static inline void
|
||||
list_mapcar(struct objc_list* list, void(*function)(void*))
|
||||
{
|
||||
while(list)
|
||||
{
|
||||
(*function)(list->head);
|
||||
list = list->tail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return element that has ELEM as car */
|
||||
|
||||
static inline struct objc_list**
|
||||
list_find(struct objc_list** list, void* elem)
|
||||
{
|
||||
while(*list)
|
||||
{
|
||||
if ((*list)->head == elem)
|
||||
return list;
|
||||
list = &((*list)->tail);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Free list (backwards recursive) */
|
||||
|
||||
static void
|
||||
list_free(struct objc_list* list)
|
||||
{
|
||||
if(list)
|
||||
{
|
||||
list_free(list->tail);
|
||||
objc_free(list);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* not __GNU_OBJC_LIST_H */
|
@ -1,165 +0,0 @@
|
||||
/* Basic data types for Objective C.
|
||||
Copyright (C) 1993, 1995, 1996, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
#ifndef __objc_INCLUDE_GNU
|
||||
#define __objc_INCLUDE_GNU
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
** Definition of the boolean type.
|
||||
*/
|
||||
#ifdef __vxworks
|
||||
typedef int BOOL;
|
||||
#else
|
||||
typedef unsigned char BOOL;
|
||||
#endif
|
||||
#define YES (BOOL)1
|
||||
#define NO (BOOL)0
|
||||
|
||||
/*
|
||||
** Definition of a selector. Selectors themselves are not unique, but
|
||||
** the sel_id is a unique identifier.
|
||||
*/
|
||||
typedef const struct objc_selector
|
||||
{
|
||||
void *sel_id;
|
||||
const char *sel_types;
|
||||
} *SEL;
|
||||
|
||||
inline static BOOL
|
||||
sel_eq (SEL s1, SEL s2)
|
||||
{
|
||||
if (s1 == 0 || s2 == 0)
|
||||
return s1 == s2;
|
||||
else
|
||||
return s1->sel_id == s2->sel_id;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** ObjC uses this typedef for untyped instances.
|
||||
*/
|
||||
typedef struct objc_object {
|
||||
struct objc_class* class_pointer;
|
||||
} *id;
|
||||
|
||||
/*
|
||||
** Definition of method type. When retrieving the implementation of a
|
||||
** method, this is type of the pointer returned. The idea of the
|
||||
** definition of IMP is to represent a 'pointer to a general function
|
||||
** taking an id, a SEL, followed by other unspecified arguments'. You
|
||||
** must always cast an IMP to a pointer to a function taking the
|
||||
** appropriate, specific types for that function, before calling it -
|
||||
** to make sure the appropriate arguments are passed to it. The code
|
||||
** generated by the compiler to perform method calls automatically
|
||||
** does this cast inside method calls.
|
||||
*/
|
||||
typedef id (*IMP)(id, SEL, ...);
|
||||
|
||||
/*
|
||||
** More simple types...
|
||||
*/
|
||||
#define nil (id)0 /* id of Nil instance */
|
||||
#define Nil (Class)0 /* id of Nil class */
|
||||
typedef char *STR; /* String alias */
|
||||
|
||||
/*
|
||||
** The compiler generates one of these structures for each class.
|
||||
**
|
||||
** This structure is the definition for classes.
|
||||
**
|
||||
** This structure is generated by the compiler in the executable and used by
|
||||
** the run-time during normal messaging operations. Therefore some members
|
||||
** change type. The compiler generates "char* const" and places a string in
|
||||
** the following member variables: super_class.
|
||||
*/
|
||||
typedef struct objc_class *MetaClass;
|
||||
typedef struct objc_class *Class;
|
||||
struct objc_class {
|
||||
MetaClass class_pointer; /* Pointer to the class's
|
||||
meta class. */
|
||||
struct objc_class* super_class; /* Pointer to the super
|
||||
class. NULL for class
|
||||
Object. */
|
||||
const char* name; /* Name of the class. */
|
||||
long version; /* Unknown. */
|
||||
unsigned long info; /* Bit mask. See class masks
|
||||
defined above. */
|
||||
long instance_size; /* Size in bytes of the class.
|
||||
The sum of the class
|
||||
definition and all super
|
||||
class definitions. */
|
||||
struct objc_ivar_list* ivars; /* Pointer to a structure that
|
||||
describes the instance
|
||||
variables in the class
|
||||
definition. NULL indicates
|
||||
no instance variables. Does
|
||||
not include super class
|
||||
variables. */
|
||||
struct objc_method_list* methods; /* Linked list of instance
|
||||
methods defined for the
|
||||
class. */
|
||||
struct sarray * dtable; /* Pointer to instance
|
||||
method dispatch table. */
|
||||
struct objc_class* subclass_list; /* Subclasses */
|
||||
struct objc_class* sibling_class;
|
||||
|
||||
struct objc_protocol_list *protocols; /* Protocols conformed to */
|
||||
void* gc_object_type;
|
||||
};
|
||||
|
||||
#ifndef __OBJC__
|
||||
typedef struct objc_protocol {
|
||||
struct objc_class* class_pointer;
|
||||
char *protocol_name;
|
||||
struct objc_protocol_list *protocol_list;
|
||||
struct objc_method_description_list *instance_methods, *class_methods;
|
||||
} Protocol;
|
||||
|
||||
#else /* __OBJC__ */
|
||||
@class Protocol;
|
||||
#endif
|
||||
|
||||
typedef void* retval_t; /* return value */
|
||||
typedef void(*apply_t)(void); /* function pointer */
|
||||
typedef union arglist {
|
||||
char *arg_ptr;
|
||||
char arg_regs[sizeof (char*)];
|
||||
} *arglist_t; /* argument frame */
|
||||
|
||||
|
||||
IMP objc_msg_lookup(id receiver, SEL op);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* not __objc_INCLUDE_GNU */
|
@ -1,96 +0,0 @@
|
||||
/* GNU Objective C Runtime internal declarations
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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. */
|
||||
|
||||
#ifndef __objc_runtime_INCLUDE_GNU
|
||||
#define __objc_runtime_INCLUDE_GNU
|
||||
|
||||
#include <stdarg.h> /* for varargs and va_list's */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <stddef.h> /* so noone else will get system versions */
|
||||
#include <assert.h>
|
||||
|
||||
#include "objc.h" /* core data types */
|
||||
#include "objc-api.h" /* runtime api functions */
|
||||
|
||||
#include "thr.h" /* thread and mutex support */
|
||||
|
||||
#include "hash.h" /* hash structures */
|
||||
#include "objc-list.h" /* linear lists */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern void __objc_add_class_to_hash(Class); /* (objc-class.c) */
|
||||
extern void __objc_init_selector_tables(void); /* (objc-sel.c) */
|
||||
extern void __objc_init_class_tables(void); /* (objc-class.c) */
|
||||
extern void __objc_init_dispatch_tables(void); /* (objc-dispatch.c) */
|
||||
extern void __objc_install_premature_dtable(Class); /* (objc-dispatch.c) */
|
||||
extern void __objc_resolve_class_links(void); /* (objc-class.c) */
|
||||
extern void __objc_register_selectors_from_class(Class); /* (objc-sel.c) */
|
||||
extern void __objc_register_selectors_from_list (MethodList_t); /* (selector.c) */
|
||||
extern void __objc_update_dispatch_table_for_class (Class);/* (objc-msg.c) */
|
||||
|
||||
extern int __objc_init_thread_system(void); /* thread.c */
|
||||
extern int __objc_fini_thread_system(void); /* thread.c */
|
||||
extern void __objc_print_dtable_stats(void); /* sendmsg.c */
|
||||
|
||||
extern void class_add_method_list(Class, MethodList_t);
|
||||
|
||||
/* Registering instance methods as class methods for root classes */
|
||||
extern void __objc_register_instance_methods_to_class(Class);
|
||||
extern Method_t search_for_method_in_list(MethodList_t list, SEL op);
|
||||
|
||||
/* True when class links has been resolved */
|
||||
extern BOOL __objc_class_links_resolved;
|
||||
|
||||
/* Number of selectors stored in each of the selector tables */
|
||||
extern unsigned int __objc_selector_max_index;
|
||||
|
||||
/* Mutex locking __objc_selector_max_index and its arrays. */
|
||||
extern objc_mutex_t __objc_runtime_mutex;
|
||||
|
||||
/* Number of threads which are alive. */
|
||||
extern int __objc_runtime_threads_alive;
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_PRINTF(format, args...) printf (format, ## args)
|
||||
#else
|
||||
#define DEBUG_PRINTF(format, args...)
|
||||
#endif
|
||||
|
||||
BOOL __objc_responds_to (id object, SEL sel); /* for internal use only! */
|
||||
SEL __sel_register_typed_name (const char*, const char*,
|
||||
struct objc_selector*, BOOL is_const);
|
||||
extern void __objc_generate_gc_type_description (Class);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* not __objc_runtime_INCLUDE_GNU */
|
@ -1,244 +0,0 @@
|
||||
/* Sparse Arrays for Objective C dispatch tables
|
||||
Copyright (C) 1993, 1995, 1996, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
#ifndef __sarray_INCLUDE_GNU
|
||||
#define __sarray_INCLUDE_GNU
|
||||
|
||||
#include "thr.h"
|
||||
|
||||
#define OBJC_SPARSE2 /* 2-level sparse array */
|
||||
/* #define OBJC_SPARSE3 */ /* 3-level sparse array */
|
||||
|
||||
#ifdef OBJC_SPARSE2
|
||||
extern const char* __objc_sparse2_id;
|
||||
#endif
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
extern const char* __objc_sparse3_id;
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern int nbuckets; /* for stats */
|
||||
extern int nindices;
|
||||
extern int narrays;
|
||||
extern int idxsize;
|
||||
|
||||
/* An unsigned integer of same size as a pointer */
|
||||
#define SIZET_BITS (sizeof(size_t)*8)
|
||||
|
||||
#if defined(__sparc__) || defined(OBJC_SPARSE2)
|
||||
#define PRECOMPUTE_SELECTORS
|
||||
#endif
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
|
||||
/* Buckets are 8 words each */
|
||||
#define BUCKET_BITS 3
|
||||
#define BUCKET_SIZE (1<<BUCKET_BITS)
|
||||
#define BUCKET_MASK (BUCKET_SIZE-1)
|
||||
|
||||
/* Indices are 16 words each */
|
||||
#define INDEX_BITS 4
|
||||
#define INDEX_SIZE (1<<INDEX_BITS)
|
||||
#define INDEX_MASK (INDEX_SIZE-1)
|
||||
|
||||
#define INDEX_CAPACITY (BUCKET_SIZE*INDEX_SIZE)
|
||||
|
||||
#else /* OBJC_SPARSE2 */
|
||||
|
||||
/* Buckets are 32 words each */
|
||||
#define BUCKET_BITS 5
|
||||
#define BUCKET_SIZE (1<<BUCKET_BITS)
|
||||
#define BUCKET_MASK (BUCKET_SIZE-1)
|
||||
|
||||
#endif /* OBJC_SPARSE2 */
|
||||
|
||||
typedef size_t sidx;
|
||||
|
||||
#ifdef PRECOMPUTE_SELECTORS
|
||||
|
||||
struct soffset {
|
||||
#ifdef OBJC_SPARSE3
|
||||
unsigned int unused : SIZET_BITS/4;
|
||||
unsigned int eoffset : SIZET_BITS/4;
|
||||
unsigned int boffset : SIZET_BITS/4;
|
||||
unsigned int ioffset : SIZET_BITS/4;
|
||||
#else /* OBJC_SPARSE2 */
|
||||
#ifdef __sparc__
|
||||
unsigned long boffset : (SIZET_BITS - 2) - BUCKET_BITS;
|
||||
unsigned int eoffset : BUCKET_BITS;
|
||||
unsigned int unused : 2;
|
||||
#else
|
||||
unsigned int boffset : SIZET_BITS/2;
|
||||
unsigned int eoffset : SIZET_BITS/2;
|
||||
#endif
|
||||
#endif /* OBJC_SPARSE2 */
|
||||
};
|
||||
|
||||
union sofftype {
|
||||
struct soffset off;
|
||||
sidx idx;
|
||||
};
|
||||
|
||||
#endif /* not PRECOMPUTE_SELECTORS */
|
||||
|
||||
union sversion {
|
||||
int version;
|
||||
void *next_free;
|
||||
};
|
||||
|
||||
struct sbucket {
|
||||
void* elems[BUCKET_SIZE]; /* elements stored in array */
|
||||
union sversion version; /* used for copy-on-write */
|
||||
};
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
|
||||
struct sindex {
|
||||
struct sbucket* buckets[INDEX_SIZE];
|
||||
union sversion version; /* used for copy-on-write */
|
||||
};
|
||||
|
||||
#endif /* OBJC_SPARSE3 */
|
||||
|
||||
struct sarray {
|
||||
#ifdef OBJC_SPARSE3
|
||||
struct sindex** indices;
|
||||
struct sindex* empty_index;
|
||||
#else /* OBJC_SPARSE2 */
|
||||
struct sbucket** buckets;
|
||||
#endif /* OBJC_SPARSE2 */
|
||||
struct sbucket* empty_bucket;
|
||||
union sversion version; /* used for copy-on-write */
|
||||
short ref_count;
|
||||
struct sarray* is_copy_of;
|
||||
size_t capacity;
|
||||
};
|
||||
|
||||
struct sarray* sarray_new(int, void* default_element);
|
||||
void sarray_free(struct sarray*);
|
||||
struct sarray* sarray_lazy_copy(struct sarray*);
|
||||
void sarray_realloc(struct sarray*, int new_size);
|
||||
void sarray_at_put(struct sarray*, sidx indx, void* elem);
|
||||
void sarray_at_put_safe(struct sarray*, sidx indx, void* elem);
|
||||
|
||||
struct sarray* sarray_hard_copy(struct sarray*); /* ... like the name? */
|
||||
void sarray_remove_garbage(void);
|
||||
|
||||
|
||||
#ifdef PRECOMPUTE_SELECTORS
|
||||
/* Transform soffset values to ints and vica verca */
|
||||
static inline unsigned int
|
||||
soffset_decode(sidx indx)
|
||||
{
|
||||
union sofftype x;
|
||||
x.idx = indx;
|
||||
#ifdef OBJC_SPARSE3
|
||||
return x.off.eoffset
|
||||
+ (x.off.boffset*BUCKET_SIZE)
|
||||
+ (x.off.ioffset*INDEX_CAPACITY);
|
||||
#else /* OBJC_SPARSE2 */
|
||||
return x.off.eoffset + (x.off.boffset*BUCKET_SIZE);
|
||||
#endif /* OBJC_SPARSE2 */
|
||||
}
|
||||
|
||||
static inline sidx
|
||||
soffset_encode(size_t offset)
|
||||
{
|
||||
union sofftype x;
|
||||
x.off.eoffset = offset%BUCKET_SIZE;
|
||||
#ifdef OBJC_SPARSE3
|
||||
x.off.boffset = (offset/BUCKET_SIZE)%INDEX_SIZE;
|
||||
x.off.ioffset = offset/INDEX_CAPACITY;
|
||||
#else /* OBJC_SPARSE2 */
|
||||
x.off.boffset = offset/BUCKET_SIZE;
|
||||
#endif
|
||||
return (sidx)x.idx;
|
||||
}
|
||||
|
||||
#else /* not PRECOMPUTE_SELECTORS */
|
||||
|
||||
static inline size_t
|
||||
soffset_decode(sidx indx)
|
||||
{
|
||||
return indx;
|
||||
}
|
||||
|
||||
static inline sidx
|
||||
soffset_encode(size_t offset)
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
#endif /* not PRECOMPUTE_SELECTORS */
|
||||
|
||||
/* Get element from the Sparse array `array' at offset `indx' */
|
||||
|
||||
static inline void* sarray_get(struct sarray* array, sidx indx)
|
||||
{
|
||||
#ifdef PRECOMPUTE_SELECTORS
|
||||
union sofftype x;
|
||||
x.idx = indx;
|
||||
#ifdef OBJC_SPARSE3
|
||||
return
|
||||
array->
|
||||
indices[x.off.ioffset]->
|
||||
buckets[x.off.boffset]->
|
||||
elems[x.off.eoffset];
|
||||
#else /* OBJC_SPARSE2 */
|
||||
return array->buckets[x.off.boffset]->elems[x.off.eoffset];
|
||||
#endif /* OBJC_SPARSE2 */
|
||||
#else /* not PRECOMPUTE_SELECTORS */
|
||||
#ifdef OBJC_SPARSE3
|
||||
return array->
|
||||
indices[indx/INDEX_CAPACITY]->
|
||||
buckets[(indx/BUCKET_SIZE)%INDEX_SIZE]->
|
||||
elems[indx%BUCKET_SIZE];
|
||||
#else /* OBJC_SPARSE2 */
|
||||
return array->buckets[indx/BUCKET_SIZE]->elems[indx%BUCKET_SIZE];
|
||||
#endif /* not OBJC_SPARSE3 */
|
||||
#endif /* not PRECOMPUTE_SELECTORS */
|
||||
}
|
||||
|
||||
static inline void* sarray_get_safe(struct sarray* array, sidx indx)
|
||||
{
|
||||
if(soffset_decode(indx) < array->capacity)
|
||||
return sarray_get(array, indx);
|
||||
else
|
||||
return (array->empty_bucket->elems[0]);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __sarray_INCLUDE_GNU */
|
@ -1,153 +0,0 @@
|
||||
/* Thread and mutex controls for Objective C.
|
||||
Copyright (C) 1996, 1997, 2002, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
|
||||
#ifndef __thread_INCLUDE_GNU
|
||||
#define __thread_INCLUDE_GNU
|
||||
|
||||
#include "objc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*************************************************************************
|
||||
* Universal static variables:
|
||||
*/
|
||||
extern int __objc_thread_exit_status; /* Global exit status. */
|
||||
|
||||
/********
|
||||
* Thread safe implementation types and functions.
|
||||
*/
|
||||
|
||||
/* Thread priorities */
|
||||
#define OBJC_THREAD_INTERACTIVE_PRIORITY 2
|
||||
#define OBJC_THREAD_BACKGROUND_PRIORITY 1
|
||||
#define OBJC_THREAD_LOW_PRIORITY 0
|
||||
|
||||
/* A thread */
|
||||
typedef void * objc_thread_t;
|
||||
|
||||
/* This structure represents a single mutual exclusion lock. */
|
||||
struct objc_mutex
|
||||
{
|
||||
volatile objc_thread_t owner; /* Id of thread that owns. */
|
||||
volatile int depth; /* # of acquires. */
|
||||
void * backend; /* Specific to backend */
|
||||
};
|
||||
typedef struct objc_mutex *objc_mutex_t;
|
||||
|
||||
/* This structure represents a single condition mutex */
|
||||
struct objc_condition
|
||||
{
|
||||
void * backend; /* Specific to backend */
|
||||
};
|
||||
typedef struct objc_condition *objc_condition_t;
|
||||
|
||||
/* Frontend mutex functions */
|
||||
objc_mutex_t objc_mutex_allocate (void);
|
||||
int objc_mutex_deallocate (objc_mutex_t mutex);
|
||||
int objc_mutex_lock (objc_mutex_t mutex);
|
||||
int objc_mutex_unlock (objc_mutex_t mutex);
|
||||
int objc_mutex_trylock (objc_mutex_t mutex);
|
||||
|
||||
/* Frontend condition mutex functions */
|
||||
objc_condition_t objc_condition_allocate (void);
|
||||
int objc_condition_deallocate (objc_condition_t condition);
|
||||
int objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex);
|
||||
int objc_condition_signal (objc_condition_t condition);
|
||||
int objc_condition_broadcast (objc_condition_t condition);
|
||||
|
||||
/* Frontend thread functions */
|
||||
objc_thread_t objc_thread_detach (SEL selector, id object, id argument);
|
||||
void objc_thread_yield (void);
|
||||
int objc_thread_exit (void);
|
||||
int objc_thread_set_priority (int priority);
|
||||
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
|
||||
runtime initially becomes multi threaded.
|
||||
The hook function is only called once, meaning only when the
|
||||
2nd thread is spawned, not for each and every thread.
|
||||
|
||||
It returns the previous hook function or NULL if there is none.
|
||||
|
||||
A program outside of the runtime could set this to some function so
|
||||
it can be informed; for example, the GNUstep Base Library sets it
|
||||
so it can implement the NSBecomingMultiThreaded notification.
|
||||
*/
|
||||
typedef void (*objc_thread_callback) (void);
|
||||
objc_thread_callback objc_set_thread_callback (objc_thread_callback func);
|
||||
|
||||
/* Backend initialization functions */
|
||||
int __objc_init_thread_system (void);
|
||||
int __objc_fini_thread_system (void);
|
||||
|
||||
/* Backend mutex functions */
|
||||
int __objc_mutex_allocate (objc_mutex_t mutex);
|
||||
int __objc_mutex_deallocate (objc_mutex_t mutex);
|
||||
int __objc_mutex_lock (objc_mutex_t mutex);
|
||||
int __objc_mutex_trylock (objc_mutex_t mutex);
|
||||
int __objc_mutex_unlock (objc_mutex_t mutex);
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
int __objc_condition_allocate (objc_condition_t condition);
|
||||
int __objc_condition_deallocate (objc_condition_t condition);
|
||||
int __objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex);
|
||||
int __objc_condition_broadcast (objc_condition_t condition);
|
||||
int __objc_condition_signal (objc_condition_t condition);
|
||||
|
||||
/* Backend thread functions */
|
||||
objc_thread_t __objc_thread_detach (void (*func) (void *arg), void *arg);
|
||||
int __objc_thread_set_priority (int priority);
|
||||
int __objc_thread_get_priority (void);
|
||||
void __objc_thread_yield (void);
|
||||
int __objc_thread_exit (void);
|
||||
objc_thread_t __objc_thread_id (void);
|
||||
int __objc_thread_set_data (void *value);
|
||||
void * __objc_thread_get_data (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* not __thread_INCLUDE_GNU */
|
@ -1,141 +0,0 @@
|
||||
/* GNU Objective-C Typed Streams interface.
|
||||
Copyright (C) 1993, 1995, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
#ifndef __typedstream_INCLUDE_GNU
|
||||
#define __typedstream_INCLUDE_GNU
|
||||
|
||||
#include "objc.h"
|
||||
#include "hash.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef int (*objc_typed_read_func)(void*, char*, int);
|
||||
typedef int (*objc_typed_write_func)(void*, const char*, int);
|
||||
typedef int (*objc_typed_flush_func)(void*);
|
||||
typedef int (*objc_typed_eof_func)(void*);
|
||||
|
||||
#define OBJC_READONLY 0x01
|
||||
#define OBJC_WRITEONLY 0x02
|
||||
|
||||
#define OBJC_MANAGED_STREAM 0x01
|
||||
#define OBJC_FILE_STREAM 0x02
|
||||
#define OBJC_MEMORY_STREAM 0x04
|
||||
|
||||
#define OBJC_TYPED_STREAM_VERSION 0x01
|
||||
|
||||
typedef struct objc_typed_stream {
|
||||
void* physical;
|
||||
cache_ptr object_table; /* read/written objects */
|
||||
cache_ptr stream_table; /* other read/written but shared things.. */
|
||||
cache_ptr class_table; /* class version mapping */
|
||||
cache_ptr object_refs; /* forward references */
|
||||
int mode; /* OBJC_READONLY or OBJC_WRITEONLY */
|
||||
int type; /* MANAGED, FILE, MEMORY etc bit string */
|
||||
int version; /* version used when writing */
|
||||
int writing_root_p;
|
||||
objc_typed_read_func read;
|
||||
objc_typed_write_func write;
|
||||
objc_typed_eof_func eof;
|
||||
objc_typed_flush_func flush;
|
||||
} TypedStream;
|
||||
|
||||
/* opcode masks */
|
||||
#define _B_VALUE 0x1fU
|
||||
#define _B_CODE 0xe0U
|
||||
#define _B_SIGN 0x10U
|
||||
#define _B_NUMBER 0x0fU
|
||||
|
||||
/* standard opcodes */
|
||||
#define _B_INVALID 0x00U
|
||||
#define _B_SINT 0x20U
|
||||
#define _B_NINT 0x40U
|
||||
#define _B_SSTR 0x60U
|
||||
#define _B_NSTR 0x80U
|
||||
#define _B_RCOMM 0xa0U
|
||||
#define _B_UCOMM 0xc0U
|
||||
#define _B_EXT 0xe0U
|
||||
|
||||
/* eXtension opcodes */
|
||||
#define _BX_OBJECT 0x00U
|
||||
#define _BX_CLASS 0x01U
|
||||
#define _BX_SEL 0x02U
|
||||
#define _BX_OBJREF 0x03U
|
||||
#define _BX_OBJROOT 0x04U
|
||||
#define _BX_EXT 0x1fU
|
||||
|
||||
/*
|
||||
** Read and write objects as specified by TYPE. All the `last'
|
||||
** arguments are pointers to the objects to read/write.
|
||||
*/
|
||||
|
||||
int objc_write_type (TypedStream* stream, const char* type, const void* data);
|
||||
int objc_read_type (TypedStream* stream, const char* type, void* data);
|
||||
|
||||
int objc_write_types (TypedStream* stream, const char* type, ...);
|
||||
int objc_read_types (TypedStream* stream, const char* type, ...);
|
||||
|
||||
int objc_write_object_reference (TypedStream* stream, id object);
|
||||
int objc_write_root_object (TypedStream* stream, id object);
|
||||
|
||||
long objc_get_stream_class_version (TypedStream* stream, Class class_type);
|
||||
|
||||
|
||||
/*
|
||||
** Convenience functions
|
||||
*/
|
||||
|
||||
int objc_write_array (TypedStream* stream, const char* type,
|
||||
int count, const void* data);
|
||||
int objc_read_array (TypedStream* stream, const char* type,
|
||||
int count, void* data);
|
||||
|
||||
int objc_write_object (TypedStream* stream, id object);
|
||||
int objc_read_object (TypedStream* stream, id* object);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Open a typed stream for reading or writing. MODE may be either of
|
||||
** OBJC_READONLY or OBJC_WRITEONLY.
|
||||
*/
|
||||
|
||||
TypedStream* objc_open_typed_stream (FILE* physical, int mode);
|
||||
TypedStream* objc_open_typed_stream_for_file (const char* file_name, int mode);
|
||||
|
||||
void objc_close_typed_stream (TypedStream* stream);
|
||||
|
||||
BOOL objc_end_of_typed_stream (TypedStream* stream);
|
||||
void objc_flush_typed_stream (TypedStream* stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* not __typedstream_INCLUDE_GNU */
|
@ -1,103 +0,0 @@
|
||||
/* GNU Objective C Runtime class related functions
|
||||
Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 "tconfig.h" /* include defs of bzero for target */
|
||||
#include "objc/objc.h"
|
||||
#include "objc/runtime.h" /* the kitchen sink */
|
||||
|
||||
#if OBJC_WITH_GC
|
||||
# include <gc.h>
|
||||
#endif
|
||||
|
||||
id __objc_object_alloc (Class);
|
||||
id __objc_object_dispose (id);
|
||||
id __objc_object_copy (id);
|
||||
|
||||
id (*_objc_object_alloc) (Class) = __objc_object_alloc; /* !T:SINGLE */
|
||||
id (*_objc_object_dispose) (id) = __objc_object_dispose; /* !T:SINGLE */
|
||||
id (*_objc_object_copy) (id) = __objc_object_copy; /* !T:SINGLE */
|
||||
|
||||
id
|
||||
class_create_instance (Class class)
|
||||
{
|
||||
id new = nil;
|
||||
|
||||
#if OBJC_WITH_GC
|
||||
if (CLS_ISCLASS (class))
|
||||
new = (id) GC_malloc_explicitly_typed (class->instance_size,
|
||||
class->gc_object_type);
|
||||
#else
|
||||
if (CLS_ISCLASS (class))
|
||||
new = (*_objc_object_alloc) (class);
|
||||
#endif
|
||||
|
||||
if (new != nil)
|
||||
{
|
||||
memset (new, 0, class->instance_size);
|
||||
new->class_pointer = class;
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
id
|
||||
object_copy (id object)
|
||||
{
|
||||
if ((object != nil) && CLS_ISCLASS (object->class_pointer))
|
||||
return (*_objc_object_copy) (object);
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
id
|
||||
object_dispose (id object)
|
||||
{
|
||||
if ((object != nil) && CLS_ISCLASS (object->class_pointer))
|
||||
{
|
||||
if (_objc_object_dispose)
|
||||
(*_objc_object_dispose) (object);
|
||||
else
|
||||
objc_free (object);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
id __objc_object_alloc (Class class)
|
||||
{
|
||||
return (id) objc_malloc (class->instance_size);
|
||||
}
|
||||
|
||||
id __objc_object_dispose (id object)
|
||||
{
|
||||
objc_free (object);
|
||||
return 0;
|
||||
}
|
||||
|
||||
id __objc_object_copy (id object)
|
||||
{
|
||||
id copy = class_create_instance (object->class_pointer);
|
||||
memcpy (copy, object, object->class_pointer->instance_size);
|
||||
return copy;
|
||||
}
|
@ -1,518 +0,0 @@
|
||||
/* Sparse Arrays for Objective C dispatch tables
|
||||
Copyright (C) 1993, 1995, 1996, 2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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/sarray.h"
|
||||
#include "objc/runtime.h"
|
||||
#include <stdio.h>
|
||||
#include "assert.h"
|
||||
|
||||
int nbuckets = 0; /* !T:MUTEX */
|
||||
int nindices = 0; /* !T:MUTEX */
|
||||
int narrays = 0; /* !T:MUTEX */
|
||||
int idxsize = 0; /* !T:MUTEX */
|
||||
|
||||
static void *first_free_data = NULL; /* !T:MUTEX */
|
||||
|
||||
#ifdef OBJC_SPARSE2
|
||||
const char *__objc_sparse2_id = "2 level sparse indices";
|
||||
#endif
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
const char *__objc_sparse3_id = "3 level sparse indices";
|
||||
#endif
|
||||
|
||||
/* This function removes any structures left over from free operations
|
||||
that were not safe in a multi-threaded environment. */
|
||||
void
|
||||
sarray_remove_garbage (void)
|
||||
{
|
||||
void **vp;
|
||||
void *np;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
vp = first_free_data;
|
||||
first_free_data = NULL;
|
||||
|
||||
while (vp) {
|
||||
np = *vp;
|
||||
objc_free (vp);
|
||||
vp = np;
|
||||
}
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
/* Free a block of dynamically allocated memory. If we are in multi-threaded
|
||||
mode, it is ok to free it. If not, we add it to the garbage heap to be
|
||||
freed later. */
|
||||
|
||||
static void
|
||||
sarray_free_garbage (void *vp)
|
||||
{
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
if (__objc_runtime_threads_alive == 1) {
|
||||
objc_free (vp);
|
||||
if (first_free_data)
|
||||
sarray_remove_garbage ();
|
||||
}
|
||||
else {
|
||||
*(void **)vp = first_free_data;
|
||||
first_free_data = vp;
|
||||
}
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
/* sarray_at_put : copies data in such a way as to be thread reader safe. */
|
||||
void
|
||||
sarray_at_put (struct sarray *array, sidx index, void *element)
|
||||
{
|
||||
#ifdef OBJC_SPARSE3
|
||||
struct sindex **the_index;
|
||||
struct sindex *new_index;
|
||||
#endif
|
||||
struct sbucket **the_bucket;
|
||||
struct sbucket *new_bucket;
|
||||
#ifdef OBJC_SPARSE3
|
||||
size_t ioffset;
|
||||
#endif
|
||||
size_t boffset;
|
||||
size_t eoffset;
|
||||
#ifdef PRECOMPUTE_SELECTORS
|
||||
union sofftype xx;
|
||||
xx.idx = index;
|
||||
#ifdef OBJC_SPARSE3
|
||||
ioffset = xx.off.ioffset;
|
||||
#endif
|
||||
boffset = xx.off.boffset;
|
||||
eoffset = xx.off.eoffset;
|
||||
#else /* not PRECOMPUTE_SELECTORS */
|
||||
#ifdef OBJC_SPARSE3
|
||||
ioffset = index/INDEX_CAPACITY;
|
||||
boffset = (index/BUCKET_SIZE)%INDEX_SIZE;
|
||||
eoffset = index%BUCKET_SIZE;
|
||||
#else
|
||||
boffset = index/BUCKET_SIZE;
|
||||
eoffset = index%BUCKET_SIZE;
|
||||
#endif
|
||||
#endif /* not PRECOMPUTE_SELECTORS */
|
||||
|
||||
assert (soffset_decode (index) < array->capacity); /* Range check */
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
the_index = &(array->indices[ioffset]);
|
||||
the_bucket = &((*the_index)->buckets[boffset]);
|
||||
#else
|
||||
the_bucket = &(array->buckets[boffset]);
|
||||
#endif
|
||||
|
||||
if ((*the_bucket)->elems[eoffset] == element)
|
||||
return; /* great! we just avoided a lazy copy */
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
|
||||
/* First, perform lazy copy/allocation of index if needed */
|
||||
|
||||
if ((*the_index) == array->empty_index) {
|
||||
|
||||
/* The index was previously empty, allocate a new */
|
||||
new_index = (struct sindex *) objc_malloc (sizeof (struct sindex));
|
||||
memcpy (new_index, array->empty_index, sizeof (struct sindex));
|
||||
new_index->version.version = array->version.version;
|
||||
*the_index = new_index; /* Prepared for install. */
|
||||
the_bucket = &((*the_index)->buckets[boffset]);
|
||||
|
||||
nindices += 1;
|
||||
} else if ((*the_index)->version.version != array->version.version) {
|
||||
|
||||
/* This index must be lazy copied */
|
||||
struct sindex *old_index = *the_index;
|
||||
new_index = (struct sindex *) objc_malloc (sizeof (struct sindex));
|
||||
memcpy (new_index, old_index, sizeof (struct sindex));
|
||||
new_index->version.version = array->version.version;
|
||||
*the_index = new_index; /* Prepared for install. */
|
||||
the_bucket = &((*the_index)->buckets[boffset]);
|
||||
|
||||
nindices += 1;
|
||||
}
|
||||
|
||||
#endif /* OBJC_SPARSE3 */
|
||||
|
||||
/* next, perform lazy allocation/copy of the bucket if needed */
|
||||
|
||||
if ((*the_bucket) == array->empty_bucket) {
|
||||
|
||||
/* The bucket was previously empty (or something like that), */
|
||||
/* allocate a new. This is the effect of `lazy' allocation */
|
||||
new_bucket = (struct sbucket *) objc_malloc (sizeof (struct sbucket));
|
||||
memcpy ((void *) new_bucket, (const void *) array->empty_bucket,
|
||||
sizeof (struct sbucket));
|
||||
new_bucket->version.version = array->version.version;
|
||||
*the_bucket = new_bucket; /* Prepared for install. */
|
||||
|
||||
nbuckets += 1;
|
||||
|
||||
} else if ((*the_bucket)->version.version != array->version.version) {
|
||||
|
||||
/* Perform lazy copy. */
|
||||
struct sbucket *old_bucket = *the_bucket;
|
||||
new_bucket = (struct sbucket *) objc_malloc (sizeof (struct sbucket));
|
||||
memcpy (new_bucket, old_bucket, sizeof (struct sbucket));
|
||||
new_bucket->version.version = array->version.version;
|
||||
*the_bucket = new_bucket; /* Prepared for install. */
|
||||
|
||||
nbuckets += 1;
|
||||
|
||||
}
|
||||
(*the_bucket)->elems[eoffset] = element;
|
||||
}
|
||||
|
||||
void
|
||||
sarray_at_put_safe (struct sarray *array, sidx index, void *element)
|
||||
{
|
||||
if (soffset_decode (index) >= array->capacity)
|
||||
sarray_realloc (array, soffset_decode (index) + 1);
|
||||
sarray_at_put (array, index, element);
|
||||
}
|
||||
|
||||
struct sarray *
|
||||
sarray_new (int size, void *default_element)
|
||||
{
|
||||
struct sarray *arr;
|
||||
#ifdef OBJC_SPARSE3
|
||||
size_t num_indices = ((size - 1)/(INDEX_CAPACITY)) + 1;
|
||||
struct sindex **new_indices;
|
||||
#else /* OBJC_SPARSE2 */
|
||||
size_t num_indices = ((size - 1)/BUCKET_SIZE) + 1;
|
||||
struct sbucket **new_buckets;
|
||||
#endif
|
||||
size_t counter;
|
||||
|
||||
assert (size > 0);
|
||||
|
||||
/* Allocate core array */
|
||||
arr = (struct sarray *) objc_malloc (sizeof (struct sarray));
|
||||
arr->version.version = 0;
|
||||
|
||||
/* Initialize members */
|
||||
#ifdef OBJC_SPARSE3
|
||||
arr->capacity = num_indices*INDEX_CAPACITY;
|
||||
new_indices = (struct sindex **)
|
||||
objc_malloc (sizeof (struct sindex *) * num_indices);
|
||||
|
||||
arr->empty_index = (struct sindex *) objc_malloc (sizeof (struct sindex));
|
||||
arr->empty_index->version.version = 0;
|
||||
|
||||
narrays += 1;
|
||||
idxsize += num_indices;
|
||||
nindices += 1;
|
||||
|
||||
#else /* OBJC_SPARSE2 */
|
||||
arr->capacity = num_indices*BUCKET_SIZE;
|
||||
new_buckets = (struct sbucket **)
|
||||
objc_malloc (sizeof (struct sbucket *) * num_indices);
|
||||
|
||||
narrays += 1;
|
||||
idxsize += num_indices;
|
||||
|
||||
#endif
|
||||
|
||||
arr->empty_bucket = (struct sbucket *) objc_malloc (sizeof (struct sbucket));
|
||||
arr->empty_bucket->version.version = 0;
|
||||
|
||||
nbuckets += 1;
|
||||
|
||||
arr->ref_count = 1;
|
||||
arr->is_copy_of = (struct sarray *) 0;
|
||||
|
||||
for (counter = 0; counter < BUCKET_SIZE; counter++)
|
||||
arr->empty_bucket->elems[counter] = default_element;
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
for (counter = 0; counter < INDEX_SIZE; counter++)
|
||||
arr->empty_index->buckets[counter] = arr->empty_bucket;
|
||||
|
||||
for (counter = 0; counter < num_indices; counter++)
|
||||
new_indices[counter] = arr->empty_index;
|
||||
|
||||
#else /* OBJC_SPARSE2 */
|
||||
|
||||
for (counter = 0; counter < num_indices; counter++)
|
||||
new_buckets[counter] = arr->empty_bucket;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
arr->indices = new_indices;
|
||||
#else /* OBJC_SPARSE2 */
|
||||
arr->buckets = new_buckets;
|
||||
#endif
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
/* Reallocate the sparse array to hold `newsize' entries
|
||||
Note: We really allocate and then free. We have to do this to ensure that
|
||||
any concurrent readers notice the update. */
|
||||
|
||||
void
|
||||
sarray_realloc (struct sarray *array, int newsize)
|
||||
{
|
||||
#ifdef OBJC_SPARSE3
|
||||
size_t old_max_index = (array->capacity - 1)/INDEX_CAPACITY;
|
||||
size_t new_max_index = ((newsize - 1)/INDEX_CAPACITY);
|
||||
size_t rounded_size = (new_max_index + 1) * INDEX_CAPACITY;
|
||||
|
||||
struct sindex **new_indices;
|
||||
struct sindex **old_indices;
|
||||
|
||||
#else /* OBJC_SPARSE2 */
|
||||
size_t old_max_index = (array->capacity - 1)/BUCKET_SIZE;
|
||||
size_t new_max_index = ((newsize - 1)/BUCKET_SIZE);
|
||||
size_t rounded_size = (new_max_index + 1) * BUCKET_SIZE;
|
||||
|
||||
struct sbucket **new_buckets;
|
||||
struct sbucket **old_buckets;
|
||||
|
||||
#endif
|
||||
|
||||
size_t counter;
|
||||
|
||||
assert (newsize > 0);
|
||||
|
||||
/* The size is the same, just ignore the request */
|
||||
if (rounded_size <= array->capacity)
|
||||
return;
|
||||
|
||||
assert (array->ref_count == 1); /* stop if lazy copied... */
|
||||
|
||||
/* We are asked to extend the array -- allocate new bucket table, */
|
||||
/* and insert empty_bucket in newly allocated places. */
|
||||
if (rounded_size > array->capacity)
|
||||
{
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
new_max_index += 4;
|
||||
rounded_size = (new_max_index + 1) * INDEX_CAPACITY;
|
||||
|
||||
#else /* OBJC_SPARSE2 */
|
||||
new_max_index += 4;
|
||||
rounded_size = (new_max_index + 1) * BUCKET_SIZE;
|
||||
#endif
|
||||
|
||||
/* update capacity */
|
||||
array->capacity = rounded_size;
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
/* alloc to force re-read by any concurrent readers. */
|
||||
old_indices = array->indices;
|
||||
new_indices = (struct sindex **)
|
||||
objc_malloc ((new_max_index + 1) * sizeof (struct sindex *));
|
||||
#else /* OBJC_SPARSE2 */
|
||||
old_buckets = array->buckets;
|
||||
new_buckets = (struct sbucket **)
|
||||
objc_malloc ((new_max_index + 1) * sizeof (struct sbucket *));
|
||||
#endif
|
||||
|
||||
/* copy buckets below old_max_index (they are still valid) */
|
||||
for (counter = 0; counter <= old_max_index; counter++ ) {
|
||||
#ifdef OBJC_SPARSE3
|
||||
new_indices[counter] = old_indices[counter];
|
||||
#else /* OBJC_SPARSE2 */
|
||||
new_buckets[counter] = old_buckets[counter];
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
/* reset entries above old_max_index to empty_bucket */
|
||||
for (counter = old_max_index + 1; counter <= new_max_index; counter++)
|
||||
new_indices[counter] = array->empty_index;
|
||||
#else /* OBJC_SPARSE2 */
|
||||
/* reset entries above old_max_index to empty_bucket */
|
||||
for (counter = old_max_index + 1; counter <= new_max_index; counter++)
|
||||
new_buckets[counter] = array->empty_bucket;
|
||||
#endif
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
/* install the new indices */
|
||||
array->indices = new_indices;
|
||||
#else /* OBJC_SPARSE2 */
|
||||
array->buckets = new_buckets;
|
||||
#endif
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
/* free the old indices */
|
||||
sarray_free_garbage (old_indices);
|
||||
#else /* OBJC_SPARSE2 */
|
||||
sarray_free_garbage (old_buckets);
|
||||
#endif
|
||||
|
||||
idxsize += (new_max_index-old_max_index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Free a sparse array allocated with sarray_new */
|
||||
|
||||
void
|
||||
sarray_free (struct sarray *array) {
|
||||
#ifdef OBJC_SPARSE3
|
||||
size_t old_max_index = (array->capacity - 1)/INDEX_CAPACITY;
|
||||
struct sindex **old_indices;
|
||||
#else
|
||||
size_t old_max_index = (array->capacity - 1)/BUCKET_SIZE;
|
||||
struct sbucket **old_buckets;
|
||||
#endif
|
||||
size_t counter = 0;
|
||||
|
||||
assert (array->ref_count != 0); /* Freed multiple times!!! */
|
||||
|
||||
if (--(array->ref_count) != 0) /* There exists copies of me */
|
||||
return;
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
old_indices = array->indices;
|
||||
#else
|
||||
old_buckets = array->buckets;
|
||||
#endif
|
||||
|
||||
/* Free all entries that do not point to empty_bucket */
|
||||
for (counter = 0; counter <= old_max_index; counter++ ) {
|
||||
#ifdef OBJC_SPARSE3
|
||||
struct sindex *idx = old_indices[counter];
|
||||
if ((idx != array->empty_index) &&
|
||||
(idx->version.version == array->version.version)) {
|
||||
int c2;
|
||||
for (c2 = 0; c2 < INDEX_SIZE; c2++) {
|
||||
struct sbucket *bkt = idx->buckets[c2];
|
||||
if ((bkt != array->empty_bucket) &&
|
||||
(bkt->version.version == array->version.version))
|
||||
{
|
||||
sarray_free_garbage (bkt);
|
||||
nbuckets -= 1;
|
||||
}
|
||||
}
|
||||
sarray_free_garbage (idx);
|
||||
nindices -= 1;
|
||||
}
|
||||
#else /* OBJC_SPARSE2 */
|
||||
struct sbucket *bkt = array->buckets[counter];
|
||||
if ((bkt != array->empty_bucket) &&
|
||||
(bkt->version.version == array->version.version))
|
||||
{
|
||||
sarray_free_garbage (bkt);
|
||||
nbuckets -= 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
/* free empty_index */
|
||||
if (array->empty_index->version.version == array->version.version) {
|
||||
sarray_free_garbage (array->empty_index);
|
||||
nindices -= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* free empty_bucket */
|
||||
if (array->empty_bucket->version.version == array->version.version) {
|
||||
sarray_free_garbage (array->empty_bucket);
|
||||
nbuckets -= 1;
|
||||
}
|
||||
idxsize -= (old_max_index + 1);
|
||||
narrays -= 1;
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
/* free bucket table */
|
||||
sarray_free_garbage (array->indices);
|
||||
|
||||
#else
|
||||
/* free bucket table */
|
||||
sarray_free_garbage (array->buckets);
|
||||
|
||||
#endif
|
||||
|
||||
/* If this is a copy of another array, we free it (which might just
|
||||
* decrement its reference count so it will be freed when no longer in use).
|
||||
*/
|
||||
if (array->is_copy_of)
|
||||
sarray_free (array->is_copy_of);
|
||||
|
||||
/* free array */
|
||||
sarray_free_garbage (array);
|
||||
}
|
||||
|
||||
/* This is a lazy copy. Only the core of the structure is actually */
|
||||
/* copied. */
|
||||
|
||||
struct sarray *
|
||||
sarray_lazy_copy (struct sarray *oarr)
|
||||
{
|
||||
struct sarray *arr;
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
size_t num_indices = ((oarr->capacity - 1)/INDEX_CAPACITY) + 1;
|
||||
struct sindex **new_indices;
|
||||
#else /* OBJC_SPARSE2 */
|
||||
size_t num_indices = ((oarr->capacity - 1)/BUCKET_SIZE) + 1;
|
||||
struct sbucket **new_buckets;
|
||||
#endif
|
||||
|
||||
/* Allocate core array */
|
||||
arr = (struct sarray *) objc_malloc (sizeof (struct sarray)); /* !!! */
|
||||
arr->version.version = oarr->version.version + 1;
|
||||
#ifdef OBJC_SPARSE3
|
||||
arr->empty_index = oarr->empty_index;
|
||||
#endif
|
||||
arr->empty_bucket = oarr->empty_bucket;
|
||||
arr->ref_count = 1;
|
||||
oarr->ref_count += 1;
|
||||
arr->is_copy_of = oarr;
|
||||
arr->capacity = oarr->capacity;
|
||||
|
||||
#ifdef OBJC_SPARSE3
|
||||
/* Copy bucket table */
|
||||
new_indices = (struct sindex **)
|
||||
objc_malloc (sizeof (struct sindex *) * num_indices);
|
||||
memcpy (new_indices, oarr->indices, sizeof (struct sindex *) * num_indices);
|
||||
arr->indices = new_indices;
|
||||
#else
|
||||
/* Copy bucket table */
|
||||
new_buckets = (struct sbucket **)
|
||||
objc_malloc (sizeof (struct sbucket *) * num_indices);
|
||||
memcpy (new_buckets, oarr->buckets, sizeof (struct sbucket *) * num_indices);
|
||||
arr->buckets = new_buckets;
|
||||
#endif
|
||||
|
||||
idxsize += num_indices;
|
||||
narrays += 1;
|
||||
|
||||
return arr;
|
||||
}
|
@ -1,490 +0,0 @@
|
||||
/* GNU Objective C Runtime selector related functions
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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/runtime.h"
|
||||
#include "objc/sarray.h"
|
||||
#include "objc/encoding.h"
|
||||
|
||||
/* Initial selector hash table size. Value doesn't matter much */
|
||||
#define SELECTOR_HASH_SIZE 128
|
||||
|
||||
/* Tables mapping selector names to uid and opposite */
|
||||
static struct sarray *__objc_selector_array = 0; /* uid -> sel !T:MUTEX */
|
||||
static struct sarray *__objc_selector_names = 0; /* uid -> name !T:MUTEX */
|
||||
static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */
|
||||
|
||||
/* Number of selectors stored in each of the above tables */
|
||||
unsigned int __objc_selector_max_index = 0; /* !T:MUTEX */
|
||||
|
||||
void __objc_init_selector_tables (void)
|
||||
{
|
||||
__objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0);
|
||||
__objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0);
|
||||
__objc_selector_hash
|
||||
= objc_hash_new (SELECTOR_HASH_SIZE,
|
||||
(hash_func_type) objc_hash_string,
|
||||
(compare_func_type) objc_compare_strings);
|
||||
}
|
||||
|
||||
/* This routine is given a class and records all of the methods in its class
|
||||
structure in the record table. */
|
||||
void
|
||||
__objc_register_selectors_from_class (Class class)
|
||||
{
|
||||
MethodList_t method_list;
|
||||
|
||||
method_list = class->methods;
|
||||
while (method_list)
|
||||
{
|
||||
__objc_register_selectors_from_list (method_list);
|
||||
method_list = method_list->method_next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This routine is given a list of methods and records each of the methods in
|
||||
the record table. This is the routine that does the actual recording
|
||||
work.
|
||||
|
||||
The name and type pointers in the method list must be permanent and
|
||||
immutable.
|
||||
*/
|
||||
void
|
||||
__objc_register_selectors_from_list (MethodList_t method_list)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
while (i < method_list->method_count)
|
||||
{
|
||||
Method_t method = &method_list->method_list[i];
|
||||
if (method->method_name)
|
||||
{
|
||||
method->method_name
|
||||
= __sel_register_typed_name ((const char *) method->method_name,
|
||||
method->method_types, 0, YES);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
|
||||
/* Register instance methods as class methods for root classes */
|
||||
void __objc_register_instance_methods_to_class (Class class)
|
||||
{
|
||||
MethodList_t method_list;
|
||||
MethodList_t class_method_list;
|
||||
int max_methods_no = 16;
|
||||
MethodList_t new_list;
|
||||
Method_t curr_method;
|
||||
|
||||
/* Only if a root class. */
|
||||
if (class->super_class)
|
||||
return;
|
||||
|
||||
/* Allocate a method list to hold the new class methods */
|
||||
new_list = objc_calloc (sizeof (struct objc_method_list)
|
||||
+ sizeof (struct objc_method[max_methods_no]), 1);
|
||||
method_list = class->methods;
|
||||
class_method_list = class->class_pointer->methods;
|
||||
curr_method = &new_list->method_list[0];
|
||||
|
||||
/* Iterate through the method lists for the class */
|
||||
while (method_list)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Iterate through the methods from this method list */
|
||||
for (i = 0; i < method_list->method_count; i++)
|
||||
{
|
||||
Method_t mth = &method_list->method_list[i];
|
||||
if (mth->method_name
|
||||
&& ! search_for_method_in_list (class_method_list,
|
||||
mth->method_name))
|
||||
{
|
||||
/* This instance method isn't a class method.
|
||||
Add it into the new_list. */
|
||||
*curr_method = *mth;
|
||||
|
||||
/* Reallocate the method list if necessary */
|
||||
if (++new_list->method_count == max_methods_no)
|
||||
new_list =
|
||||
objc_realloc (new_list, sizeof (struct objc_method_list)
|
||||
+ sizeof (struct
|
||||
objc_method[max_methods_no += 16]));
|
||||
curr_method = &new_list->method_list[new_list->method_count];
|
||||
}
|
||||
}
|
||||
|
||||
method_list = method_list->method_next;
|
||||
}
|
||||
|
||||
/* If we created any new class methods
|
||||
then attach the method list to the class */
|
||||
if (new_list->method_count)
|
||||
{
|
||||
new_list =
|
||||
objc_realloc (new_list, sizeof (struct objc_method_list)
|
||||
+ sizeof (struct objc_method[new_list->method_count]));
|
||||
new_list->method_next = class->class_pointer->methods;
|
||||
class->class_pointer->methods = new_list;
|
||||
}
|
||||
else
|
||||
objc_free(new_list);
|
||||
|
||||
__objc_update_dispatch_table_for_class (class->class_pointer);
|
||||
}
|
||||
|
||||
|
||||
/* Returns YES iff t1 and t2 have same method types, but we ignore
|
||||
the argframe layout */
|
||||
BOOL
|
||||
sel_types_match (const char *t1, const char *t2)
|
||||
{
|
||||
if (! t1 || ! t2)
|
||||
return NO;
|
||||
while (*t1 && *t2)
|
||||
{
|
||||
if (*t1 == '+') t1++;
|
||||
if (*t2 == '+') t2++;
|
||||
while (isdigit ((unsigned char) *t1)) t1++;
|
||||
while (isdigit ((unsigned char) *t2)) t2++;
|
||||
/* xxx Remove these next two lines when qualifiers are put in
|
||||
all selectors, not just Protocol selectors. */
|
||||
t1 = objc_skip_type_qualifiers (t1);
|
||||
t2 = objc_skip_type_qualifiers (t2);
|
||||
if (! *t1 && ! *t2)
|
||||
return YES;
|
||||
if (*t1 != *t2)
|
||||
return NO;
|
||||
t1++;
|
||||
t2++;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* return selector representing name */
|
||||
SEL
|
||||
sel_get_typed_uid (const char *name, const char *types)
|
||||
{
|
||||
struct objc_list *l;
|
||||
sidx i;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
|
||||
if (i == 0)
|
||||
{
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
|
||||
l; l = l->tail)
|
||||
{
|
||||
SEL s = (SEL) l->head;
|
||||
if (types == 0 || s->sel_types == 0)
|
||||
{
|
||||
if (s->sel_types == types)
|
||||
{
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
else if (sel_types_match (s->sel_types, types))
|
||||
{
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return selector representing name; prefer a selector with non-NULL type */
|
||||
SEL
|
||||
sel_get_any_typed_uid (const char *name)
|
||||
{
|
||||
struct objc_list *l;
|
||||
sidx i;
|
||||
SEL s = NULL;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
|
||||
if (i == 0)
|
||||
{
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
|
||||
l; l = l->tail)
|
||||
{
|
||||
s = (SEL) l->head;
|
||||
if (s->sel_types)
|
||||
{
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* return selector representing name */
|
||||
SEL
|
||||
sel_get_any_uid (const char *name)
|
||||
{
|
||||
struct objc_list *l;
|
||||
sidx i;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
|
||||
if (soffset_decode (i) == 0)
|
||||
{
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
|
||||
if (l == 0)
|
||||
return 0;
|
||||
|
||||
return (SEL) l->head;
|
||||
}
|
||||
|
||||
/* return selector representing name */
|
||||
SEL
|
||||
sel_get_uid (const char *name)
|
||||
{
|
||||
return sel_register_typed_name (name, 0);
|
||||
}
|
||||
|
||||
/* Get name of selector. If selector is unknown, the empty string ""
|
||||
is returned */
|
||||
const char *sel_get_name (SEL selector)
|
||||
{
|
||||
const char *ret;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
if ((soffset_decode ((sidx)selector->sel_id) > 0)
|
||||
&& (soffset_decode ((sidx)selector->sel_id) <= __objc_selector_max_index))
|
||||
ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id);
|
||||
else
|
||||
ret = 0;
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL
|
||||
sel_is_mapped (SEL selector)
|
||||
{
|
||||
unsigned int idx = soffset_decode ((sidx)selector->sel_id);
|
||||
return ((idx > 0) && (idx <= __objc_selector_max_index));
|
||||
}
|
||||
|
||||
|
||||
const char *sel_get_type (SEL selector)
|
||||
{
|
||||
if (selector)
|
||||
return selector->sel_types;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The uninstalled dispatch table */
|
||||
extern struct sarray *__objc_uninstalled_dtable;
|
||||
|
||||
/* __sel_register_typed_name allocates lots of struct objc_selector:s
|
||||
of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the number
|
||||
of malloc calls and memory lost to malloc overhead, we allocate
|
||||
objc_selector:s in blocks here. This is only called from
|
||||
__sel_register_typed_name, and __sel_register_typed_name may only be
|
||||
called when __objc_runtime_mutex is locked.
|
||||
|
||||
Note that the objc_selector:s allocated from __sel_register_typed_name
|
||||
are never freed.
|
||||
|
||||
62 because 62 * sizeof (struct objc_selector) = 496 (992). This should
|
||||
let malloc add some overhead and use a nice, round 512 (1024) byte chunk.
|
||||
*/
|
||||
#define SELECTOR_POOL_SIZE 62
|
||||
static struct objc_selector *selector_pool;
|
||||
static int selector_pool_left;
|
||||
|
||||
static struct objc_selector *
|
||||
pool_alloc_selector(void)
|
||||
{
|
||||
if (!selector_pool_left)
|
||||
{
|
||||
selector_pool = objc_malloc (sizeof (struct objc_selector)
|
||||
* SELECTOR_POOL_SIZE);
|
||||
selector_pool_left = SELECTOR_POOL_SIZE;
|
||||
}
|
||||
return &selector_pool[--selector_pool_left];
|
||||
}
|
||||
|
||||
/* Store the passed selector name in the selector record and return its
|
||||
selector value (value returned by sel_get_uid).
|
||||
Assumes that the calling function has locked down __objc_runtime_mutex. */
|
||||
/* is_const parameter tells us if the name and types parameters
|
||||
are really constant or not. If YES then they are constant and
|
||||
we can just store the pointers. If NO then we need to copy
|
||||
name and types because the pointers may disappear later on. */
|
||||
SEL
|
||||
__sel_register_typed_name (const char *name, const char *types,
|
||||
struct objc_selector *orig, BOOL is_const)
|
||||
{
|
||||
struct objc_selector *j;
|
||||
sidx i;
|
||||
struct objc_list *l;
|
||||
|
||||
i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
|
||||
if (soffset_decode (i) != 0)
|
||||
{
|
||||
for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
|
||||
l; l = l->tail)
|
||||
{
|
||||
SEL s = (SEL) l->head;
|
||||
if (types == 0 || s->sel_types == 0)
|
||||
{
|
||||
if (s->sel_types == types)
|
||||
{
|
||||
if (orig)
|
||||
{
|
||||
orig->sel_id = (void *) i;
|
||||
return orig;
|
||||
}
|
||||
else
|
||||
return s;
|
||||
}
|
||||
}
|
||||
else if (! strcmp (s->sel_types, types))
|
||||
{
|
||||
if (orig)
|
||||
{
|
||||
orig->sel_id = (void *) i;
|
||||
return orig;
|
||||
}
|
||||
else
|
||||
return s;
|
||||
}
|
||||
}
|
||||
if (orig)
|
||||
j = orig;
|
||||
else
|
||||
j = pool_alloc_selector ();
|
||||
|
||||
j->sel_id = (void *) i;
|
||||
/* Can we use the pointer or must copy types? Don't copy if NULL */
|
||||
if ((is_const) || (types == 0))
|
||||
j->sel_types = (const char *) types;
|
||||
else {
|
||||
j->sel_types = (char *) objc_malloc (strlen (types) + 1);
|
||||
strcpy ((char *) j->sel_types, types);
|
||||
}
|
||||
l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
__objc_selector_max_index += 1;
|
||||
i = soffset_encode (__objc_selector_max_index);
|
||||
if (orig)
|
||||
j = orig;
|
||||
else
|
||||
j = pool_alloc_selector ();
|
||||
|
||||
j->sel_id = (void *) i;
|
||||
/* Can we use the pointer or must copy types? Don't copy if NULL */
|
||||
if ((is_const) || (types == 0))
|
||||
j->sel_types = (const char *) types;
|
||||
else {
|
||||
j->sel_types = (char *) objc_malloc (strlen (types) + 1);
|
||||
strcpy ((char *) j->sel_types, types);
|
||||
}
|
||||
l = 0;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types,
|
||||
(long) soffset_decode (i));
|
||||
|
||||
{
|
||||
int is_new = (l == 0);
|
||||
const char *new_name;
|
||||
|
||||
/* Can we use the pointer or must copy name? Don't copy if NULL */
|
||||
if ((is_const) || (name == 0))
|
||||
new_name = name;
|
||||
else {
|
||||
new_name = (char *) objc_malloc (strlen (name) + 1);
|
||||
strcpy ((char *) new_name, name);
|
||||
}
|
||||
|
||||
l = list_cons ((void *) j, l);
|
||||
sarray_at_put_safe (__objc_selector_names, i, (void *) new_name);
|
||||
sarray_at_put_safe (__objc_selector_array, i, (void *) l);
|
||||
if (is_new)
|
||||
objc_hash_add (&__objc_selector_hash, (void *) new_name, (void *) i);
|
||||
}
|
||||
|
||||
sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
|
||||
|
||||
return (SEL) j;
|
||||
}
|
||||
|
||||
SEL
|
||||
sel_register_name (const char *name)
|
||||
{
|
||||
SEL ret;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
/* Assume that name is not constant static memory and needs to be
|
||||
copied before put into a runtime structure. is_const == NO */
|
||||
ret = __sel_register_typed_name (name, 0, 0, NO);
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEL
|
||||
sel_register_typed_name (const char *name, const char *type)
|
||||
{
|
||||
SEL ret;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
/* Assume that name and type are not constant static memory and need to
|
||||
be copied before put into a runtime structure. is_const == NO */
|
||||
ret = __sel_register_typed_name (name, type, 0, NO);
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,701 +0,0 @@
|
||||
/* GNU Objective C Runtime message lookup
|
||||
Copyright (C) 1993, 1995, 1996, 1997, 1998,
|
||||
2001, 2002, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Kresten Krab Thorup
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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. */
|
||||
|
||||
/* FIXME: This file has no business including tm.h. */
|
||||
/* FIXME: This should be using libffi instead of __builtin_apply
|
||||
and friends. */
|
||||
|
||||
#include "tconfig.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "objc/runtime.h"
|
||||
#include "objc/sarray.h"
|
||||
#include "objc/encoding.h"
|
||||
#include "runtime-info.h"
|
||||
|
||||
/* 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
|
||||
#define INVISIBLE_STRUCT_RETURN 1
|
||||
#else
|
||||
#define INVISIBLE_STRUCT_RETURN 0
|
||||
#endif
|
||||
|
||||
/* 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);
|
||||
|
||||
static void __objc_install_dispatch_table_for_class (Class);
|
||||
|
||||
/* Forward declare some functions */
|
||||
static void __objc_init_install_dtable (id, SEL);
|
||||
|
||||
/* Various forwarding functions that are used based upon the
|
||||
return type for the selector.
|
||||
__objc_block_forward for structures.
|
||||
__objc_double_forward for floats/doubles.
|
||||
__objc_word_forward for pointers or types that fit in registers.
|
||||
*/
|
||||
static double __objc_double_forward (id, SEL, ...);
|
||||
static id __objc_word_forward (id, SEL, ...);
|
||||
typedef struct { id many[8]; } __big;
|
||||
#if INVISIBLE_STRUCT_RETURN
|
||||
static __big
|
||||
#else
|
||||
static id
|
||||
#endif
|
||||
__objc_block_forward (id, SEL, ...);
|
||||
static Method_t search_for_method_in_hierarchy (Class class, SEL sel);
|
||||
Method_t search_for_method_in_list (MethodList_t list, SEL op);
|
||||
id nil_method (id, SEL);
|
||||
|
||||
/* Given a selector, return the proper forwarding implementation. */
|
||||
inline
|
||||
IMP
|
||||
__objc_get_forward_imp (SEL sel)
|
||||
{
|
||||
/* If a custom forwarding hook was registered, try getting a forwarding
|
||||
* function from it. */
|
||||
if (__objc_msg_forward)
|
||||
{
|
||||
IMP result;
|
||||
if ((result = __objc_msg_forward (sel)) != NULL)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* In all other cases, use the default forwarding functions built using
|
||||
* __builtin_apply and friends. */
|
||||
{
|
||||
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. */
|
||||
inline
|
||||
IMP
|
||||
get_imp (Class class, SEL sel)
|
||||
{
|
||||
/* In a vanilla implementation we would first check if the dispatch
|
||||
table is installed. Here instead, to get more speed in the
|
||||
standard case (that the dispatch table is installed) we first try
|
||||
to get the imp using brute force. Only if that fails, we do what
|
||||
we should have been doing from the very beginning, that is, check
|
||||
if the dispatch table needs to be installed, install it if it's
|
||||
not installed, and retrieve the imp from the table if it's
|
||||
installed. */
|
||||
void *res = sarray_get_safe (class->dtable, (size_t) sel->sel_id);
|
||||
if (res == 0)
|
||||
{
|
||||
/* Not a valid method */
|
||||
if (class->dtable == __objc_uninstalled_dtable)
|
||||
{
|
||||
/* The dispatch table needs to be installed. */
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
/* Double-checked locking pattern: Check
|
||||
__objc_uninstalled_dtable again in case another thread
|
||||
installed the dtable while we were waiting for the lock
|
||||
to be released. */
|
||||
if (class->dtable == __objc_uninstalled_dtable)
|
||||
{
|
||||
__objc_install_dispatch_table_for_class (class);
|
||||
}
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
/* Call ourselves with the installed dispatch table
|
||||
and get the real method */
|
||||
res = get_imp (class, sel);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The dispatch table has been installed. */
|
||||
|
||||
/* Get the method from the dispatch table (we try to get it
|
||||
again in case another thread has installed the dtable just
|
||||
after we invoked sarray_get_safe, but before we checked
|
||||
class->dtable == __objc_uninstalled_dtable).
|
||||
*/
|
||||
res = sarray_get_safe (class->dtable, (size_t) sel->sel_id);
|
||||
if (res == 0)
|
||||
{
|
||||
/* The dispatch table has been installed, and the method
|
||||
is not in the dispatch table. So the method just
|
||||
doesn't exist for the class. Return the forwarding
|
||||
implementation. */
|
||||
res = __objc_get_forward_imp (sel);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Query if an object can respond to a selector, returns YES if the
|
||||
object implements the selector otherwise NO. Does not check if the
|
||||
method can be forwarded. */
|
||||
inline
|
||||
BOOL
|
||||
__objc_responds_to (id object, SEL sel)
|
||||
{
|
||||
void *res;
|
||||
|
||||
/* Install dispatch table if need be */
|
||||
if (object->class_pointer->dtable == __objc_uninstalled_dtable)
|
||||
{
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
if (object->class_pointer->dtable == __objc_uninstalled_dtable)
|
||||
{
|
||||
__objc_install_dispatch_table_for_class (object->class_pointer);
|
||||
}
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
/* Get the method from the dispatch table */
|
||||
res = sarray_get_safe (object->class_pointer->dtable, (size_t) sel->sel_id);
|
||||
return (res != 0);
|
||||
}
|
||||
|
||||
/* This is the lookup function. All entries in the table are either a
|
||||
valid method *or* zero. If zero then either the dispatch table
|
||||
needs to be installed or it doesn't exist and forwarding is attempted. */
|
||||
inline
|
||||
IMP
|
||||
objc_msg_lookup (id receiver, SEL op)
|
||||
{
|
||||
IMP result;
|
||||
if (receiver)
|
||||
{
|
||||
result = sarray_get_safe (receiver->class_pointer->dtable,
|
||||
(sidx)op->sel_id);
|
||||
if (result == 0)
|
||||
{
|
||||
/* Not a valid method */
|
||||
if (receiver->class_pointer->dtable == __objc_uninstalled_dtable)
|
||||
{
|
||||
/* The dispatch table needs to be installed.
|
||||
This happens on the very first method call to the class. */
|
||||
__objc_init_install_dtable (receiver, op);
|
||||
|
||||
/* Get real method for this in newly installed dtable */
|
||||
result = get_imp (receiver->class_pointer, op);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The dispatch table has been installed. Check again
|
||||
if the method exists (just in case the dispatch table
|
||||
has been installed by another thread after we did the
|
||||
previous check that the method exists).
|
||||
*/
|
||||
result = sarray_get_safe (receiver->class_pointer->dtable,
|
||||
(sidx)op->sel_id);
|
||||
if (result == 0)
|
||||
{
|
||||
/* If the method still just doesn't exist for the
|
||||
class, attempt to forward the method. */
|
||||
result = __objc_get_forward_imp (op);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return (IMP)nil_method;
|
||||
}
|
||||
|
||||
IMP
|
||||
objc_msg_lookup_super (Super_t super, SEL sel)
|
||||
{
|
||||
if (super->self)
|
||||
return get_imp (super->class, sel);
|
||||
else
|
||||
return (IMP)nil_method;
|
||||
}
|
||||
|
||||
int method_get_sizeof_arguments (Method *);
|
||||
|
||||
retval_t
|
||||
objc_msg_sendv (id object, SEL op, arglist_t arg_frame)
|
||||
{
|
||||
Method *m = class_get_instance_method (object->class_pointer, op);
|
||||
const char *type;
|
||||
*((id *) method_get_first_argument (m, arg_frame, &type)) = object;
|
||||
*((SEL *) method_get_next_argument (arg_frame, &type)) = op;
|
||||
return __builtin_apply ((apply_t) m->method_imp,
|
||||
arg_frame,
|
||||
method_get_sizeof_arguments (m));
|
||||
}
|
||||
|
||||
void
|
||||
__objc_init_dispatch_tables ()
|
||||
{
|
||||
__objc_uninstalled_dtable = sarray_new (200, 0);
|
||||
}
|
||||
|
||||
/* This function is called by objc_msg_lookup when the
|
||||
dispatch table needs to be installed; thus it is called once
|
||||
for each class, namely when the very first message is sent to it. */
|
||||
static void
|
||||
__objc_init_install_dtable (id receiver, SEL op __attribute__ ((__unused__)))
|
||||
{
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
/* This may happen, if the programmer has taken the address of a
|
||||
method before the dtable was initialized... too bad for him! */
|
||||
if (receiver->class_pointer->dtable != __objc_uninstalled_dtable)
|
||||
{
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CLS_ISCLASS (receiver->class_pointer))
|
||||
{
|
||||
/* receiver is an ordinary object */
|
||||
assert (CLS_ISCLASS (receiver->class_pointer));
|
||||
|
||||
/* install instance methods table */
|
||||
__objc_install_dispatch_table_for_class (receiver->class_pointer);
|
||||
|
||||
/* call +initialize -- this will in turn install the factory
|
||||
dispatch table if not already done :-) */
|
||||
__objc_send_initialize (receiver->class_pointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* receiver is a class object */
|
||||
assert (CLS_ISCLASS ((Class)receiver));
|
||||
assert (CLS_ISMETA (receiver->class_pointer));
|
||||
|
||||
/* Install real dtable for factory methods */
|
||||
__objc_install_dispatch_table_for_class (receiver->class_pointer);
|
||||
|
||||
__objc_send_initialize ((Class)receiver);
|
||||
}
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
/* Install dummy table for class which causes the first message to
|
||||
that class (or instances hereof) to be initialized properly */
|
||||
void
|
||||
__objc_install_premature_dtable (Class class)
|
||||
{
|
||||
assert (__objc_uninstalled_dtable);
|
||||
class->dtable = __objc_uninstalled_dtable;
|
||||
}
|
||||
|
||||
/* Send +initialize to class if not already done */
|
||||
static void
|
||||
__objc_send_initialize (Class class)
|
||||
{
|
||||
/* This *must* be a class object */
|
||||
assert (CLS_ISCLASS (class));
|
||||
assert (! CLS_ISMETA (class));
|
||||
|
||||
if (! CLS_ISINITIALIZED (class))
|
||||
{
|
||||
CLS_SETINITIALIZED (class);
|
||||
CLS_SETINITIALIZED (class->class_pointer);
|
||||
|
||||
/* Create the garbage collector type memory description */
|
||||
__objc_generate_gc_type_description (class);
|
||||
|
||||
if (class->super_class)
|
||||
__objc_send_initialize (class->super_class);
|
||||
|
||||
{
|
||||
SEL op = sel_register_name ("initialize");
|
||||
IMP imp = 0;
|
||||
MethodList_t method_list = class->class_pointer->methods;
|
||||
|
||||
while (method_list) {
|
||||
int i;
|
||||
Method_t method;
|
||||
|
||||
for (i = 0; i < method_list->method_count; i++) {
|
||||
method = &(method_list->method_list[i]);
|
||||
if (method->method_name
|
||||
&& method->method_name->sel_id == op->sel_id) {
|
||||
imp = method->method_imp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (imp)
|
||||
break;
|
||||
|
||||
method_list = method_list->method_next;
|
||||
|
||||
}
|
||||
if (imp)
|
||||
(*imp) ((id) class, op);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Walk on the methods list of class and install the methods in the reverse
|
||||
order of the lists. Since methods added by categories are before the methods
|
||||
of class in the methods list, this allows categories to substitute methods
|
||||
declared in class. However if more than one category replaces the same
|
||||
method nothing is guaranteed about what method will be used.
|
||||
Assumes that __objc_runtime_mutex is locked down. */
|
||||
static void
|
||||
__objc_install_methods_in_dtable (Class class, MethodList_t method_list)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (! method_list)
|
||||
return;
|
||||
|
||||
if (method_list->method_next)
|
||||
__objc_install_methods_in_dtable (class, method_list->method_next);
|
||||
|
||||
for (i = 0; i < method_list->method_count; i++)
|
||||
{
|
||||
Method_t method = &(method_list->method_list[i]);
|
||||
sarray_at_put_safe (class->dtable,
|
||||
(sidx) method->method_name->sel_id,
|
||||
method->method_imp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Assumes that __objc_runtime_mutex is locked down. */
|
||||
static void
|
||||
__objc_install_dispatch_table_for_class (Class class)
|
||||
{
|
||||
Class super;
|
||||
|
||||
/* If the class has not yet had its class links resolved, we must
|
||||
re-compute all class links */
|
||||
if (! CLS_ISRESOLV (class))
|
||||
__objc_resolve_class_links ();
|
||||
|
||||
super = class->super_class;
|
||||
|
||||
if (super != 0 && (super->dtable == __objc_uninstalled_dtable))
|
||||
__objc_install_dispatch_table_for_class (super);
|
||||
|
||||
/* Allocate dtable if necessary */
|
||||
if (super == 0)
|
||||
{
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
class->dtable = sarray_new (__objc_selector_max_index, 0);
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
else
|
||||
class->dtable = sarray_lazy_copy (super->dtable);
|
||||
|
||||
__objc_install_methods_in_dtable (class, class->methods);
|
||||
}
|
||||
|
||||
void
|
||||
__objc_update_dispatch_table_for_class (Class class)
|
||||
{
|
||||
Class next;
|
||||
struct sarray *arr;
|
||||
|
||||
/* not yet installed -- skip it */
|
||||
if (class->dtable == __objc_uninstalled_dtable)
|
||||
return;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
arr = class->dtable;
|
||||
__objc_install_premature_dtable (class); /* someone might require it... */
|
||||
sarray_free (arr); /* release memory */
|
||||
|
||||
/* could have been lazy... */
|
||||
__objc_install_dispatch_table_for_class (class);
|
||||
|
||||
if (class->subclass_list) /* Traverse subclasses */
|
||||
for (next = class->subclass_list; next; next = next->sibling_class)
|
||||
__objc_update_dispatch_table_for_class (next);
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
|
||||
/* This function adds a method list to a class. This function is
|
||||
typically called by another function specific to the run-time. As
|
||||
such this function does not worry about thread safe issues.
|
||||
|
||||
This one is only called for categories. Class objects have their
|
||||
methods installed right away, and their selectors are made into
|
||||
SEL's by the function __objc_register_selectors_from_class. */
|
||||
void
|
||||
class_add_method_list (Class class, MethodList_t list)
|
||||
{
|
||||
/* Passing of a linked list is not allowed. Do multiple calls. */
|
||||
assert (! list->method_next);
|
||||
|
||||
__objc_register_selectors_from_list(list);
|
||||
|
||||
/* Add the methods to the class's method list. */
|
||||
list->method_next = class->methods;
|
||||
class->methods = list;
|
||||
|
||||
/* Update the dispatch table of class */
|
||||
__objc_update_dispatch_table_for_class (class);
|
||||
}
|
||||
|
||||
Method_t
|
||||
class_get_instance_method (Class class, SEL op)
|
||||
{
|
||||
return search_for_method_in_hierarchy (class, op);
|
||||
}
|
||||
|
||||
Method_t
|
||||
class_get_class_method (MetaClass class, SEL op)
|
||||
{
|
||||
return search_for_method_in_hierarchy (class, op);
|
||||
}
|
||||
|
||||
|
||||
/* Search for a method starting from the current class up its hierarchy.
|
||||
Return a pointer to the method's method structure if found. NULL
|
||||
otherwise. */
|
||||
|
||||
static Method_t
|
||||
search_for_method_in_hierarchy (Class cls, SEL sel)
|
||||
{
|
||||
Method_t method = NULL;
|
||||
Class class;
|
||||
|
||||
if (! sel_is_mapped (sel))
|
||||
return NULL;
|
||||
|
||||
/* Scan the method list of the class. If the method isn't found in the
|
||||
list then step to its super class. */
|
||||
for (class = cls; ((! method) && class); class = class->super_class)
|
||||
method = search_for_method_in_list (class->methods, sel);
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Given a linked list of method and a method's name. Search for the named
|
||||
method's method structure. Return a pointer to the method's method
|
||||
structure if found. NULL otherwise. */
|
||||
Method_t
|
||||
search_for_method_in_list (MethodList_t list, SEL op)
|
||||
{
|
||||
MethodList_t method_list = list;
|
||||
|
||||
if (! sel_is_mapped (op))
|
||||
return NULL;
|
||||
|
||||
/* If not found then we'll search the list. */
|
||||
while (method_list)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Search the method list. */
|
||||
for (i = 0; i < method_list->method_count; ++i)
|
||||
{
|
||||
Method_t method = &method_list->method_list[i];
|
||||
|
||||
if (method->method_name)
|
||||
if (method->method_name->sel_id == op->sel_id)
|
||||
return method;
|
||||
}
|
||||
|
||||
/* The method wasn't found. Follow the link to the next list of
|
||||
methods. */
|
||||
method_list = method_list->method_next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static retval_t __objc_forward (id object, SEL sel, arglist_t args);
|
||||
|
||||
/* Forwarding pointers/integers through the normal registers */
|
||||
static id
|
||||
__objc_word_forward (id rcv, SEL op, ...)
|
||||
{
|
||||
void *args, *res;
|
||||
|
||||
args = __builtin_apply_args ();
|
||||
res = __objc_forward (rcv, op, args);
|
||||
if (res)
|
||||
__builtin_return (res);
|
||||
else
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Specific routine for forwarding floats/double because of
|
||||
architectural differences on some processors. i386s for
|
||||
example which uses a floating point stack versus general
|
||||
registers for floating point numbers. This forward routine
|
||||
makes sure that GCC restores the proper return values */
|
||||
static double
|
||||
__objc_double_forward (id rcv, SEL op, ...)
|
||||
{
|
||||
void *args, *res;
|
||||
|
||||
args = __builtin_apply_args ();
|
||||
res = __objc_forward (rcv, op, args);
|
||||
__builtin_return (res);
|
||||
}
|
||||
|
||||
#if INVISIBLE_STRUCT_RETURN
|
||||
static __big
|
||||
#else
|
||||
static id
|
||||
#endif
|
||||
__objc_block_forward (id rcv, SEL op, ...)
|
||||
{
|
||||
void *args, *res;
|
||||
|
||||
args = __builtin_apply_args ();
|
||||
res = __objc_forward (rcv, op, args);
|
||||
if (res)
|
||||
__builtin_return (res);
|
||||
else
|
||||
#if INVISIBLE_STRUCT_RETURN
|
||||
return (__big) {{0, 0, 0, 0, 0, 0, 0, 0}};
|
||||
#else
|
||||
return nil;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* This function is installed in the dispatch table for all methods which are
|
||||
not implemented. Thus, it is called when a selector is not recognized. */
|
||||
static retval_t
|
||||
__objc_forward (id object, SEL sel, arglist_t args)
|
||||
{
|
||||
IMP imp;
|
||||
static SEL frwd_sel = 0; /* !T:SAFE2 */
|
||||
SEL err_sel;
|
||||
|
||||
/* first try if the object understands forward:: */
|
||||
if (! frwd_sel)
|
||||
frwd_sel = sel_get_any_uid ("forward::");
|
||||
|
||||
if (__objc_responds_to (object, frwd_sel))
|
||||
{
|
||||
imp = get_imp (object->class_pointer, frwd_sel);
|
||||
return (*imp) (object, frwd_sel, sel, args);
|
||||
}
|
||||
|
||||
/* If the object recognizes the doesNotRecognize: method then we're going
|
||||
to send it. */
|
||||
err_sel = sel_get_any_uid ("doesNotRecognize:");
|
||||
if (__objc_responds_to (object, err_sel))
|
||||
{
|
||||
imp = get_imp (object->class_pointer, err_sel);
|
||||
return (*imp) (object, err_sel, sel);
|
||||
}
|
||||
|
||||
/* The object doesn't recognize the method. Check for responding to
|
||||
error:. If it does then sent it. */
|
||||
{
|
||||
char msg[256 + strlen ((const char *) sel_get_name (sel))
|
||||
+ strlen ((const char *) object->class_pointer->name)];
|
||||
|
||||
sprintf (msg, "(%s) %s does not recognize %s",
|
||||
(CLS_ISMETA (object->class_pointer)
|
||||
? "class"
|
||||
: "instance" ),
|
||||
object->class_pointer->name, sel_get_name (sel));
|
||||
|
||||
err_sel = sel_get_any_uid ("error:");
|
||||
if (__objc_responds_to (object, err_sel))
|
||||
{
|
||||
imp = get_imp (object->class_pointer, err_sel);
|
||||
return (*imp) (object, sel_get_any_uid ("error:"), msg);
|
||||
}
|
||||
|
||||
/* The object doesn't respond to doesNotRecognize: or error:; Therefore,
|
||||
a default action is taken. */
|
||||
objc_error (object, OBJC_ERR_UNIMPLEMENTED, "%s\n", msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__objc_print_dtable_stats ()
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
#ifdef OBJC_SPARSE2
|
||||
printf ("memory usage: (%s)\n", "2-level sparse arrays");
|
||||
#else
|
||||
printf ("memory usage: (%s)\n", "3-level sparse arrays");
|
||||
#endif
|
||||
|
||||
printf ("arrays: %d = %ld bytes\n", narrays,
|
||||
(long) narrays * sizeof (struct sarray));
|
||||
total += narrays * sizeof (struct sarray);
|
||||
printf ("buckets: %d = %ld bytes\n", nbuckets,
|
||||
(long) nbuckets * sizeof (struct sbucket));
|
||||
total += nbuckets * sizeof (struct sbucket);
|
||||
|
||||
printf ("idxtables: %d = %ld bytes\n",
|
||||
idxsize, (long) idxsize * sizeof (void *));
|
||||
total += idxsize * sizeof (void *);
|
||||
printf ("-----------------------------------\n");
|
||||
printf ("total: %d bytes\n", total);
|
||||
printf ("===================================\n");
|
||||
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
}
|
||||
|
||||
/* Returns the uninstalled dispatch table indicator.
|
||||
If a class' dispatch table points to __objc_uninstalled_dtable
|
||||
then that means it needs its dispatch table to be installed. */
|
||||
inline
|
||||
struct sarray *
|
||||
objc_get_uninstalled_dtable ()
|
||||
{
|
||||
return __objc_uninstalled_dtable;
|
||||
}
|
@ -1,281 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Interface
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 <pthread.h>
|
||||
#include "objc/thr.h"
|
||||
#include "objc/runtime.h"
|
||||
|
||||
/* Key structure for maintaining thread specific storage */
|
||||
static pthread_key_t _objc_thread_storage;
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__objc_init_thread_system(void)
|
||||
{
|
||||
/* Initialize the thread storage key */
|
||||
return pthread_keycreate(&_objc_thread_storage, NULL);
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__objc_close_thread_system(void)
|
||||
{
|
||||
/* Destroy the thread storage key */
|
||||
/* Not implemented yet */
|
||||
/* return pthread_key_delete(&_objc_thread_storage); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__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, pthread_attr_default,
|
||||
(void *)func, arg) == 0)
|
||||
{
|
||||
/* ??? May not work! (64bit) */
|
||||
thread_id = *(objc_thread_t *)&new_thread_handle;
|
||||
pthread_detach(&new_thread_handle); /* Fully detach thread. */
|
||||
}
|
||||
else
|
||||
thread_id = NULL;
|
||||
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
__objc_thread_set_priority(int priority)
|
||||
{
|
||||
int sys_priority = 0;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
case OBJC_THREAD_INTERACTIVE_PRIORITY:
|
||||
sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
|
||||
break;
|
||||
default:
|
||||
case OBJC_THREAD_BACKGROUND_PRIORITY:
|
||||
sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
|
||||
break;
|
||||
case OBJC_THREAD_LOW_PRIORITY:
|
||||
sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Change the priority. */
|
||||
if (pthread_setprio(pthread_self(), sys_priority) >= 0)
|
||||
return 0;
|
||||
else
|
||||
/* Failed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__objc_thread_get_priority(void)
|
||||
{
|
||||
int sys_priority;
|
||||
|
||||
if ((sys_priority = pthread_getprio(pthread_self())) >= 0) {
|
||||
if (sys_priority >= PRI_FG_MIN_NP && sys_priority <= PRI_FG_MAX_NP)
|
||||
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||
if (sys_priority >= PRI_BG_MIN_NP && sys_priority <= PRI_BG_MAX_NP)
|
||||
return OBJC_THREAD_BACKGROUND_PRIORITY;
|
||||
return OBJC_THREAD_LOW_PRIORITY;
|
||||
}
|
||||
|
||||
/* Failed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
void
|
||||
__objc_thread_yield(void)
|
||||
{
|
||||
pthread_yield();
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__objc_thread_exit(void)
|
||||
{
|
||||
/* exit the thread */
|
||||
pthread_exit(&__objc_thread_exit_status);
|
||||
|
||||
/* Failed if we reached here */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__objc_thread_id(void)
|
||||
{
|
||||
pthread_t self = pthread_self();
|
||||
|
||||
return (objc_thread_t) pthread_getunique_np (&self);
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__objc_thread_set_data(void *value)
|
||||
{
|
||||
return pthread_setspecific(_objc_thread_storage, value);
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__objc_thread_get_data(void)
|
||||
{
|
||||
void *value = NULL;
|
||||
|
||||
if ( !(pthread_getspecific(_objc_thread_storage, &value)) )
|
||||
return value;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__objc_mutex_allocate(objc_mutex_t mutex)
|
||||
{
|
||||
if (pthread_mutex_init((pthread_mutex_t *)(&(mutex->backend)),
|
||||
pthread_mutexattr_default))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a mutex. */
|
||||
int
|
||||
__objc_mutex_deallocate(objc_mutex_t mutex)
|
||||
{
|
||||
if (pthread_mutex_destroy((pthread_mutex_t *)(&(mutex->backend))))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_lock(objc_mutex_t mutex)
|
||||
{
|
||||
return pthread_mutex_lock((pthread_mutex_t *)(&(mutex->backend)));
|
||||
}
|
||||
|
||||
/* Try to grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_trylock(objc_mutex_t mutex)
|
||||
{
|
||||
if (pthread_mutex_trylock((pthread_mutex_t *)(&(mutex->backend))) != 1)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__objc_mutex_unlock(objc_mutex_t mutex)
|
||||
{
|
||||
return pthread_mutex_unlock((pthread_mutex_t *)(&(mutex->backend)));
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__objc_condition_allocate(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
|
||||
/*
|
||||
if (pthread_cond_init((pthread_cond_t *)(&(condition->backend)), NULL))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
*/
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__objc_condition_deallocate(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
|
||||
/*
|
||||
return pthread_cond_destroy((pthread_cond_t *)(&(condition->backend)));
|
||||
*/
|
||||
}
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
|
||||
/*
|
||||
return pthread_cond_wait((pthread_cond_t *)(&(condition->backend)),
|
||||
(pthread_mutex_t *)(&(mutex->backend)));
|
||||
*/
|
||||
}
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__objc_condition_broadcast(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
|
||||
/*
|
||||
return pthread_cond_broadcast((pthread_cond_t *)(&(condition->backend)));
|
||||
*/
|
||||
}
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__objc_condition_signal(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
|
||||
/*
|
||||
return pthread_cond_signal((pthread_cond_t *)(&(condition->backend)));
|
||||
*/
|
||||
}
|
||||
|
||||
/* End of File */
|
@ -1,281 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Interface
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 <pthread.h>
|
||||
#include "objc/thr.h"
|
||||
#include "objc/runtime.h"
|
||||
|
||||
/* Key structure for maintaining thread specific storage */
|
||||
static pthread_key_t _objc_thread_storage;
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__objc_init_thread_system(void)
|
||||
{
|
||||
/* Initialize the thread storage key */
|
||||
return pthread_keycreate(&_objc_thread_storage, NULL);
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__objc_close_thread_system(void)
|
||||
{
|
||||
/* Destroy the thread storage key */
|
||||
/* Not implemented yet */
|
||||
/* return pthread_key_delete(&_objc_thread_storage); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__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, pthread_attr_default,
|
||||
(void *)func, arg) == 0)
|
||||
{
|
||||
/* ??? May not work! (64bit) */
|
||||
thread_id = *(objc_thread_t *)&new_thread_handle;
|
||||
pthread_detach(&new_thread_handle); /* Fully detach thread. */
|
||||
}
|
||||
else
|
||||
thread_id = NULL;
|
||||
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
__objc_thread_set_priority(int priority)
|
||||
{
|
||||
int sys_priority = 0;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
case OBJC_THREAD_INTERACTIVE_PRIORITY:
|
||||
sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
|
||||
break;
|
||||
default:
|
||||
case OBJC_THREAD_BACKGROUND_PRIORITY:
|
||||
sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
|
||||
break;
|
||||
case OBJC_THREAD_LOW_PRIORITY:
|
||||
sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Change the priority. */
|
||||
if (pthread_setprio(pthread_self(), sys_priority) >= 0)
|
||||
return 0;
|
||||
else
|
||||
/* Failed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__objc_thread_get_priority(void)
|
||||
{
|
||||
int sys_priority;
|
||||
|
||||
if ((sys_priority = pthread_getprio(pthread_self())) >= 0) {
|
||||
if (sys_priority >= PRI_FG_MIN_NP && sys_priority <= PRI_FG_MAX_NP)
|
||||
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||
if (sys_priority >= PRI_BG_MIN_NP && sys_priority <= PRI_BG_MAX_NP)
|
||||
return OBJC_THREAD_BACKGROUND_PRIORITY;
|
||||
return OBJC_THREAD_LOW_PRIORITY;
|
||||
}
|
||||
|
||||
/* Failed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
void
|
||||
__objc_thread_yield(void)
|
||||
{
|
||||
pthread_yield();
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__objc_thread_exit(void)
|
||||
{
|
||||
/* exit the thread */
|
||||
pthread_exit(&__objc_thread_exit_status);
|
||||
|
||||
/* Failed if we reached here */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__objc_thread_id(void)
|
||||
{
|
||||
pthread_t self = pthread_self();
|
||||
|
||||
return (objc_thread_t) pthread_getunique_np (&self);
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__objc_thread_set_data(void *value)
|
||||
{
|
||||
return pthread_setspecific(_objc_thread_storage, value);
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__objc_thread_get_data(void)
|
||||
{
|
||||
void *value = NULL;
|
||||
|
||||
if ( !(pthread_getspecific(_objc_thread_storage, &value)) )
|
||||
return value;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__objc_mutex_allocate(objc_mutex_t mutex)
|
||||
{
|
||||
if (pthread_mutex_init((pthread_mutex_t *)(&(mutex->backend)),
|
||||
pthread_mutexattr_default))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a mutex. */
|
||||
int
|
||||
__objc_mutex_deallocate(objc_mutex_t mutex)
|
||||
{
|
||||
if (pthread_mutex_destroy((pthread_mutex_t *)(&(mutex->backend))))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_lock(objc_mutex_t mutex)
|
||||
{
|
||||
return pthread_mutex_lock((pthread_mutex_t *)(&(mutex->backend)));
|
||||
}
|
||||
|
||||
/* Try to grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_trylock(objc_mutex_t mutex)
|
||||
{
|
||||
if (pthread_mutex_trylock((pthread_mutex_t *)(&(mutex->backend))) != 1)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__objc_mutex_unlock(objc_mutex_t mutex)
|
||||
{
|
||||
return pthread_mutex_unlock((pthread_mutex_t *)(&(mutex->backend)));
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__objc_condition_allocate(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
|
||||
/*
|
||||
if (pthread_cond_init((pthread_cond_t *)(&(condition->backend)), NULL))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
*/
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__objc_condition_deallocate(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
|
||||
/*
|
||||
return pthread_cond_destroy((pthread_cond_t *)(&(condition->backend)));
|
||||
*/
|
||||
}
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
|
||||
/*
|
||||
return pthread_cond_wait((pthread_cond_t *)(&(condition->backend)),
|
||||
(pthread_mutex_t *)(&(mutex->backend)));
|
||||
*/
|
||||
}
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__objc_condition_broadcast(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
|
||||
/*
|
||||
return pthread_cond_broadcast((pthread_cond_t *)(&(condition->backend)));
|
||||
*/
|
||||
}
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__objc_condition_signal(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
|
||||
/*
|
||||
return pthread_cond_signal((pthread_cond_t *)(&(condition->backend)));
|
||||
*/
|
||||
}
|
||||
|
||||
/* End of File */
|
@ -1,235 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Interface - SGI IRIX Implementation
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysmp.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <ulocks.h>
|
||||
#include "objc/thr.h"
|
||||
#include "objc/runtime.h"
|
||||
|
||||
/* Key structure for maintaining thread specific storage */
|
||||
static void * __objc_shared_arena_handle = NULL;
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__objc_init_thread_system(void)
|
||||
{
|
||||
/* Name of IRIX arena. */
|
||||
char arena_name[64];
|
||||
|
||||
DEBUG_PRINTF("__objc_init_thread_system\n");
|
||||
|
||||
/* Construct a temporary name for arena. */
|
||||
sprintf(arena_name, "/usr/tmp/objc_%05u", (unsigned)getpid());
|
||||
|
||||
/* Up to 256 threads. Arena only for threads. */
|
||||
usconfig(CONF_INITUSERS, 256);
|
||||
usconfig(CONF_ARENATYPE, US_SHAREDONLY);
|
||||
|
||||
/* Initialize the arena */
|
||||
if (!(__objc_shared_arena_handle = usinit(arena_name)))
|
||||
/* Failed */
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__objc_close_thread_system(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__objc_thread_detach(void (*func)(void *arg), void *arg)
|
||||
{
|
||||
objc_thread_t thread_id;
|
||||
int sys_id;
|
||||
|
||||
if ((sys_id = sproc((void *)func, PR_SALL, arg)) >= 0)
|
||||
thread_id = (objc_thread_t)sys_id;
|
||||
else
|
||||
thread_id = NULL;
|
||||
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
__objc_thread_set_priority(int priority)
|
||||
{
|
||||
/* Not implemented yet */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__objc_thread_get_priority(void)
|
||||
{
|
||||
/* Not implemented yet */
|
||||
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
void
|
||||
__objc_thread_yield(void)
|
||||
{
|
||||
sginap(0);
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__objc_thread_exit(void)
|
||||
{
|
||||
/* IRIX only has exit. */
|
||||
exit(__objc_thread_exit_status);
|
||||
|
||||
/* Failed if we reached here */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__objc_thread_id(void)
|
||||
{
|
||||
/* Threads are processes. */
|
||||
return (objc_thread_t)get_pid();
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__objc_thread_set_data(void *value)
|
||||
{
|
||||
*((void **)&PRDA->usr_prda) = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__objc_thread_get_data(void)
|
||||
{
|
||||
return *((void **)&PRDA->usr_prda);
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__objc_mutex_allocate(objc_mutex_t mutex)
|
||||
{
|
||||
if (!( (ulock_t)(mutex->backend) = usnewlock(__objc_shared_arena_handle) ))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a mutex. */
|
||||
int
|
||||
__objc_mutex_deallocate(objc_mutex_t mutex)
|
||||
{
|
||||
usfreelock((ulock_t)(mutex->backend), __objc_shared_arena_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_lock(objc_mutex_t mutex)
|
||||
{
|
||||
if (ussetlock((ulock_t)(mutex->backend)) == 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_trylock(objc_mutex_t mutex)
|
||||
{
|
||||
if (ustestlock((ulock_t)(mutex->backend)) == 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__objc_mutex_unlock(objc_mutex_t mutex)
|
||||
{
|
||||
usunsetlock((ulock_t)(mutex->backend));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__objc_condition_allocate(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__objc_condition_deallocate(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__objc_condition_broadcast(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__objc_condition_signal(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* End of File */
|
@ -1,313 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Implementation
|
||||
Copyright (C) 1996, 1997, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
Modified for Mach threads by Bill Bumgarner <bbum@friday.com>
|
||||
Condition functions added by Mircea Oancea <mircea@first.elcom.pub.ro>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 <mach/mach.h>
|
||||
#include <mach/cthreads.h>
|
||||
#include "objc/thr.h"
|
||||
#include "objc/runtime.h"
|
||||
|
||||
/*
|
||||
Obtain the maximum thread priority that can set for t. Under the
|
||||
mach threading model, it is possible for the developer to adjust the
|
||||
maximum priority downward only-- cannot be raised without superuser
|
||||
privileges. Once lowered, it cannot be raised.
|
||||
*/
|
||||
static int
|
||||
__mach_get_max_thread_priority (cthread_t t, int *base)
|
||||
{
|
||||
thread_t threadP;
|
||||
kern_return_t error;
|
||||
struct thread_sched_info info;
|
||||
unsigned int info_count=THREAD_SCHED_INFO_COUNT;
|
||||
|
||||
if (t == NULL)
|
||||
return -1;
|
||||
|
||||
threadP = cthread_thread (t); /* get thread underlying */
|
||||
|
||||
error = thread_info (threadP, THREAD_SCHED_INFO,
|
||||
(thread_info_t) &info, &info_count);
|
||||
|
||||
if (error != KERN_SUCCESS)
|
||||
return -1;
|
||||
|
||||
if (base != NULL)
|
||||
*base = info.base_priority;
|
||||
|
||||
return info.max_priority;
|
||||
}
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__objc_init_thread_system (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__objc_close_thread_system (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__objc_thread_detach (void (*func) (void *arg), void *arg)
|
||||
{
|
||||
objc_thread_t thread_id;
|
||||
cthread_t new_thread_handle;
|
||||
|
||||
/* create thread */
|
||||
new_thread_handle = cthread_fork ((cthread_fn_t) func, arg);
|
||||
|
||||
if (new_thread_handle)
|
||||
{
|
||||
/* this is not terribly portable */
|
||||
thread_id = *(objc_thread_t *) &new_thread_handle;
|
||||
cthread_detach (new_thread_handle);
|
||||
}
|
||||
else
|
||||
thread_id = NULL;
|
||||
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
__objc_thread_set_priority (int priority)
|
||||
{
|
||||
objc_thread_t *t = objc_thread_id ();
|
||||
cthread_t cT = (cthread_t) t;
|
||||
int maxPriority = __mach_get_max_thread_priority (cT, NULL);
|
||||
int sys_priority = 0;
|
||||
|
||||
if (maxPriority == -1)
|
||||
return -1;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
case OBJC_THREAD_INTERACTIVE_PRIORITY:
|
||||
sys_priority = maxPriority;
|
||||
break;
|
||||
case OBJC_THREAD_BACKGROUND_PRIORITY:
|
||||
sys_priority = (maxPriority * 2) / 3;
|
||||
break;
|
||||
case OBJC_THREAD_LOW_PRIORITY:
|
||||
sys_priority = maxPriority / 3;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sys_priority == 0)
|
||||
return -1;
|
||||
|
||||
/* Change the priority */
|
||||
if (cthread_priority (cT, sys_priority, 0) == KERN_SUCCESS)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__objc_thread_get_priority (void)
|
||||
{
|
||||
objc_thread_t *t = objc_thread_id ();
|
||||
cthread_t cT = (cthread_t) t; /* see objc_thread_id () */
|
||||
int basePriority;
|
||||
int maxPriority;
|
||||
int sys_priority = 0;
|
||||
|
||||
int interactiveT, backgroundT, lowT; /* thresholds */
|
||||
|
||||
maxPriority = __mach_get_max_thread_priority (cT, &basePriority);
|
||||
|
||||
if (maxPriority == -1)
|
||||
return -1;
|
||||
|
||||
if (basePriority > ( (maxPriority * 2) / 3))
|
||||
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||
|
||||
if (basePriority > ( maxPriority / 3))
|
||||
return OBJC_THREAD_BACKGROUND_PRIORITY;
|
||||
|
||||
return OBJC_THREAD_LOW_PRIORITY;
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
void
|
||||
__objc_thread_yield (void)
|
||||
{
|
||||
cthread_yield ();
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__objc_thread_exit (void)
|
||||
{
|
||||
/* exit the thread */
|
||||
cthread_exit (&__objc_thread_exit_status);
|
||||
|
||||
/* Failed if we reached here */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__objc_thread_id (void)
|
||||
{
|
||||
cthread_t self = cthread_self ();
|
||||
|
||||
return *(objc_thread_t *) &self;
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__objc_thread_set_data (void *value)
|
||||
{
|
||||
cthread_set_data (cthread_self (), (any_t) value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__objc_thread_get_data (void)
|
||||
{
|
||||
return (void *) cthread_data (cthread_self ());
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__objc_mutex_allocate (objc_mutex_t mutex)
|
||||
{
|
||||
int err = 0;
|
||||
mutex->backend = objc_malloc (sizeof (struct mutex));
|
||||
|
||||
err = mutex_init ((mutex_t) (mutex->backend));
|
||||
|
||||
if (err != 0)
|
||||
{
|
||||
objc_free (mutex->backend);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a mutex. */
|
||||
int
|
||||
__objc_mutex_deallocate (objc_mutex_t mutex)
|
||||
{
|
||||
mutex_clear ((mutex_t) (mutex->backend));
|
||||
|
||||
objc_free (mutex->backend);
|
||||
mutex->backend = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_lock (objc_mutex_t mutex)
|
||||
{
|
||||
mutex_lock ((mutex_t) (mutex->backend));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_trylock (objc_mutex_t mutex)
|
||||
{
|
||||
if (mutex_try_lock ((mutex_t) (mutex->backend)) == 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__objc_mutex_unlock (objc_mutex_t mutex)
|
||||
{
|
||||
mutex_unlock ((mutex_t) (mutex->backend));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__objc_condition_allocate (objc_condition_t condition)
|
||||
{
|
||||
condition->backend = objc_malloc (sizeof (struct condition));
|
||||
condition_init ((condition_t) (condition->backend));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__objc_condition_deallocate (objc_condition_t condition)
|
||||
{
|
||||
condition_clear ((condition_t) (condition->backend));
|
||||
objc_free (condition->backend);
|
||||
condition->backend = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
condition_wait ((condition_t) (condition->backend),
|
||||
(mutex_t) (mutex->backend));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__objc_condition_broadcast (objc_condition_t condition)
|
||||
{
|
||||
condition_broadcast ((condition_t) (condition->backend));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__objc_condition_signal (objc_condition_t condition)
|
||||
{
|
||||
condition_signal ((condition_t) (condition->backend));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End of File */
|
@ -1,192 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Interface.
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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
|
||||
/* The line below is needed for declarations of functions such as
|
||||
pthread_mutexattr_settype, without which gthr-posix.h may fail to
|
||||
compile within libobjc. Unfortunately, this breaks compilation on
|
||||
Tru64 UNIX V4.0F, so disable it there. */
|
||||
#ifndef __osf__
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
#include "config.h"
|
||||
#include "tconfig.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "defaults.h"
|
||||
#include "objc/thr.h"
|
||||
#include "objc/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 */
|
@ -1,267 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Interface - OS/2 emx Implementation
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Thomas Baier (baier@ci.tuwien.ac.at)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 "objc/runtime.h"
|
||||
|
||||
#define INCL_DOSSEMAPHORES
|
||||
#define INCL_DOSPROCESS
|
||||
|
||||
/*
|
||||
* conflicts with objc.h: SEL, BOOL, id
|
||||
* solution: prefixing those with _OS2_ before including <os2.h>
|
||||
*/
|
||||
#define SEL _OS2_SEL
|
||||
#define BOOL _OS2_BOOL
|
||||
#define id _OS2_id
|
||||
#include <os2.h>
|
||||
#undef id
|
||||
#undef SEL
|
||||
#undef BOOL
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__objc_init_thread_system(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__objc_close_thread_system(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__objc_thread_detach(void (*func)(void *arg), void *arg)
|
||||
{
|
||||
int thread_id = 0;
|
||||
|
||||
if ((thread_id = _beginthread (func,NULL,32768,arg)) < 0)
|
||||
thread_id = 0;
|
||||
|
||||
return (objc_thread_t)thread_id;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
__objc_thread_set_priority(int priority)
|
||||
{
|
||||
ULONG sys_class = 0;
|
||||
ULONG sys_priority = 0;
|
||||
|
||||
/* OBJC_THREAD_INTERACTIVE_PRIORITY -> PRTYC_FOREGROUNDSERVER
|
||||
* OBJC_THREAD_BACKGROUND_PRIORITY -> PRTYC_REGULAR
|
||||
* OBJC_THREAD_LOW_PRIORITY -> PRTYC_IDLETIME */
|
||||
|
||||
switch (priority) {
|
||||
case OBJC_THREAD_INTERACTIVE_PRIORITY:
|
||||
sys_class = PRTYC_REGULAR;
|
||||
sys_priority = 10;
|
||||
break;
|
||||
default:
|
||||
case OBJC_THREAD_BACKGROUND_PRIORITY:
|
||||
sys_class = PRTYC_IDLETIME;
|
||||
sys_priority = 25;
|
||||
break;
|
||||
case OBJC_THREAD_LOW_PRIORITY:
|
||||
sys_class = PRTYC_IDLETIME;
|
||||
sys_priority = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Change priority */
|
||||
if (!DosSetPriority (PRTYS_THREAD,sys_class,sys_priority,*_threadid))
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__objc_thread_get_priority(void)
|
||||
{
|
||||
PTIB ptib;
|
||||
PPIB ppib;
|
||||
|
||||
/* get information about current thread */
|
||||
DosGetInfoBlocks (&ptib,&ppib);
|
||||
|
||||
switch (ptib->tib_ptib2->tib2_ulpri)
|
||||
{
|
||||
case PRTYC_IDLETIME:
|
||||
case PRTYC_REGULAR:
|
||||
case PRTYC_TIMECRITICAL:
|
||||
case PRTYC_FOREGROUNDSERVER:
|
||||
default:
|
||||
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
void
|
||||
__objc_thread_yield(void)
|
||||
{
|
||||
DosSleep (0);
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__objc_thread_exit(void)
|
||||
{
|
||||
/* terminate the thread, NEVER use DosExit () */
|
||||
_endthread ();
|
||||
|
||||
/* Failed if we reached here */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__objc_thread_id(void)
|
||||
{
|
||||
return (objc_thread_t) *_threadid;
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__objc_thread_set_data(void *value)
|
||||
{
|
||||
*_threadstore () = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__objc_thread_get_data(void)
|
||||
{
|
||||
return *_threadstore ();
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__objc_mutex_allocate(objc_mutex_t mutex)
|
||||
{
|
||||
if (DosCreateMutexSem (NULL, (HMTX)(&(mutex->backend)),0L,0) > 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a mutex. */
|
||||
int
|
||||
__objc_mutex_deallocate(objc_mutex_t mutex)
|
||||
{
|
||||
DosCloseMutexSem ((HMTX)(mutex->backend));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_lock(objc_mutex_t mutex)
|
||||
{
|
||||
if (DosRequestMutexSem ((HMTX)(mutex->backend),-1L) != 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_trylock(objc_mutex_t mutex)
|
||||
{
|
||||
if (DosRequestMutexSem ((HMTX)(mutex->backend),0L) != 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__objc_mutex_unlock(objc_mutex_t mutex)
|
||||
{
|
||||
if (DosReleaseMutexSem((HMTX)(mutex->backend)) != 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__objc_condition_allocate(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__objc_condition_deallocate(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__objc_condition_broadcast(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__objc_condition_signal(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* End of File */
|
@ -1,318 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Interface for POSIX compliant threads
|
||||
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 GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 "objc/runtime.h"
|
||||
#include <pthread.h>
|
||||
|
||||
/* Key structure for maintaining thread specific storage */
|
||||
static pthread_key_t _objc_thread_storage;
|
||||
static pthread_attr_t _objc_thread_attribs;
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__objc_init_thread_system(void)
|
||||
{
|
||||
/* Initialize the thread storage key */
|
||||
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)
|
||||
{
|
||||
if (pthread_key_delete(_objc_thread_storage) == 0)
|
||||
{
|
||||
if (pthread_attr_destroy(&_objc_thread_attribs) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__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, &_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.
|
||||
*
|
||||
* Be aware that the default schedpolicy often disallows thread priorities.
|
||||
*/
|
||||
int
|
||||
__objc_thread_set_priority(int priority)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__objc_thread_get_priority(void)
|
||||
{
|
||||
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. */
|
||||
void
|
||||
__objc_thread_yield(void)
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__objc_thread_exit(void)
|
||||
{
|
||||
/* exit the thread */
|
||||
pthread_exit(&__objc_thread_exit_status);
|
||||
|
||||
/* Failed if we reached here */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__objc_thread_id(void)
|
||||
{
|
||||
pthread_t self = pthread_self();
|
||||
|
||||
return *(objc_thread_t *)&self;
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__objc_thread_set_data(void *value)
|
||||
{
|
||||
if (pthread_setspecific(_objc_thread_storage, value) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__objc_thread_get_data(void)
|
||||
{
|
||||
return pthread_getspecific(_objc_thread_storage);
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__objc_mutex_allocate(objc_mutex_t mutex)
|
||||
{
|
||||
mutex->backend = objc_malloc(sizeof(pthread_mutex_t));
|
||||
|
||||
if (pthread_mutex_init((pthread_mutex_t *)mutex->backend, NULL))
|
||||
{
|
||||
objc_free(mutex->backend);
|
||||
mutex->backend = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a 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;
|
||||
|
||||
objc_free(mutex->backend);
|
||||
mutex->backend = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_lock(objc_mutex_t mutex)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (pthread_mutex_unlock((pthread_mutex_t *)mutex->backend) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__objc_condition_allocate(objc_condition_t condition)
|
||||
{
|
||||
condition->backend = objc_malloc(sizeof(pthread_cond_t));
|
||||
|
||||
if (pthread_cond_init((pthread_cond_t *)condition->backend, NULL))
|
||||
{
|
||||
objc_free(condition->backend);
|
||||
condition->backend = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__objc_condition_deallocate(objc_condition_t condition)
|
||||
{
|
||||
if (pthread_cond_destroy((pthread_cond_t *)condition->backend))
|
||||
return -1;
|
||||
|
||||
objc_free(condition->backend);
|
||||
condition->backend = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (pthread_cond_signal((pthread_cond_t *)condition->backend) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
@ -1,218 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Implementation for PCThreads under GNU/Linux.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Scott Christley <scottc@net-community.com>
|
||||
Condition functions added by: Mircea Oancea <mircea@first.elcom.pub.ro>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 <pcthread.h>
|
||||
#include "objc/thr.h"
|
||||
#include "objc/runtime.h"
|
||||
|
||||
/* Key structure for maintaining thread specific storage */
|
||||
static pthread_key_t _objc_thread_storage;
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__objc_init_thread_system(void)
|
||||
{
|
||||
/* Initialize the thread storage key */
|
||||
return pthread_key_create(&_objc_thread_storage, NULL);
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__objc_close_thread_system(void)
|
||||
{
|
||||
/* Destroy the thread storage key */
|
||||
/* Not implemented yet */
|
||||
/* return pthread_key_delete(&_objc_thread_storage); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__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;
|
||||
else
|
||||
thread_id = NULL;
|
||||
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
__objc_thread_set_priority(int priority)
|
||||
{
|
||||
/* Not implemented yet */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__objc_thread_get_priority(void)
|
||||
{
|
||||
/* Not implemented yet */
|
||||
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
void
|
||||
__objc_thread_yield(void)
|
||||
{
|
||||
pthread_yield(NULL);
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__objc_thread_exit(void)
|
||||
{
|
||||
/* exit the thread */
|
||||
pthread_exit(&__objc_thread_exit_status);
|
||||
|
||||
/* Failed if we reached here */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__objc_thread_id(void)
|
||||
{
|
||||
pthread_t self = pthread_self();
|
||||
|
||||
return *(objc_thread_t *)&self;
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__objc_thread_set_data(void *value)
|
||||
{
|
||||
return pthread_setspecific(_objc_thread_storage, value);
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__objc_thread_get_data(void)
|
||||
{
|
||||
void *value = NULL;
|
||||
|
||||
if ( !(pthread_getspecific(_objc_thread_storage, &value)) )
|
||||
return value;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__objc_mutex_allocate(objc_mutex_t mutex)
|
||||
{
|
||||
if (pthread_mutex_init((pthread_mutex_t *)(&(mutex->backend)), NULL))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a mutex. */
|
||||
int
|
||||
__objc_mutex_deallocate(objc_mutex_t mutex)
|
||||
{
|
||||
if (pthread_mutex_destroy((pthread_mutex_t *)(&(mutex->backend))))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_lock(objc_mutex_t mutex)
|
||||
{
|
||||
return pthread_mutex_lock((pthread_mutex_t *)(&(mutex->backend)));
|
||||
}
|
||||
|
||||
/* 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)));
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__objc_mutex_unlock(objc_mutex_t mutex)
|
||||
{
|
||||
return pthread_mutex_unlock((pthread_mutex_t *)(&(mutex->backend)));
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__objc_condition_allocate(objc_condition_t condition)
|
||||
{
|
||||
if (pthread_cond_init((pthread_cond_t *)(&(condition->backend)), NULL))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__objc_condition_deallocate(objc_condition_t condition)
|
||||
{
|
||||
return pthread_cond_destroy((pthread_cond_t *)(&(condition->backend)));
|
||||
}
|
||||
|
||||
/* Wait on the 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)));
|
||||
}
|
||||
|
||||
/* 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)));
|
||||
}
|
||||
|
||||
/* 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)));
|
||||
}
|
||||
|
||||
/* End of File */
|
@ -1,194 +0,0 @@
|
||||
/* 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 GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 "objc/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 */
|
@ -1,192 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Implementation
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 "objc/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 */
|
@ -1,259 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Interface
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
Conditions added by Mircea Oancea (mircea@first.elcom.pub.ro)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 "objc/runtime.h"
|
||||
|
||||
#include <thread.h>
|
||||
#include <synch.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* Key structure for maintaining thread specific storage */
|
||||
static thread_key_t __objc_thread_data_key;
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__objc_init_thread_system(void)
|
||||
{
|
||||
/* Initialize the thread storage key */
|
||||
if (thr_keycreate(&__objc_thread_data_key, NULL) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__objc_close_thread_system(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__objc_thread_detach(void (*func)(void *arg), void *arg)
|
||||
{
|
||||
objc_thread_t thread_id;
|
||||
thread_t new_thread_id = 0;
|
||||
|
||||
if (thr_create(NULL, 0, (void *)func, arg,
|
||||
THR_DETACHED | THR_NEW_LWP,
|
||||
&new_thread_id) == 0)
|
||||
thread_id = *(objc_thread_t *)&new_thread_id;
|
||||
else
|
||||
thread_id = NULL;
|
||||
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
__objc_thread_set_priority(int priority)
|
||||
{
|
||||
int sys_priority = 0;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
case OBJC_THREAD_INTERACTIVE_PRIORITY:
|
||||
sys_priority = 300;
|
||||
break;
|
||||
default:
|
||||
case OBJC_THREAD_BACKGROUND_PRIORITY:
|
||||
sys_priority = 200;
|
||||
break;
|
||||
case OBJC_THREAD_LOW_PRIORITY:
|
||||
sys_priority = 1000;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Change priority */
|
||||
if (thr_setprio(thr_self(), sys_priority) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__objc_thread_get_priority(void)
|
||||
{
|
||||
int sys_priority;
|
||||
|
||||
if (thr_getprio(thr_self(), &sys_priority) == 0)
|
||||
{
|
||||
if (sys_priority >= 250)
|
||||
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||
else if (sys_priority >= 150)
|
||||
return OBJC_THREAD_BACKGROUND_PRIORITY;
|
||||
return OBJC_THREAD_LOW_PRIORITY;
|
||||
}
|
||||
|
||||
/* Couldn't get priority. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
void
|
||||
__objc_thread_yield(void)
|
||||
{
|
||||
thr_yield();
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__objc_thread_exit(void)
|
||||
{
|
||||
/* exit the thread */
|
||||
thr_exit(&__objc_thread_exit_status);
|
||||
|
||||
/* Failed if we reached here */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__objc_thread_id(void)
|
||||
{
|
||||
return (objc_thread_t)thr_self();
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__objc_thread_set_data(void *value)
|
||||
{
|
||||
if (thr_setspecific(__objc_thread_data_key, value) == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__objc_thread_get_data(void)
|
||||
{
|
||||
void *value = NULL;
|
||||
|
||||
if (thr_getspecific(__objc_thread_data_key, &value) == 0)
|
||||
return value;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__objc_mutex_allocate(objc_mutex_t mutex)
|
||||
{
|
||||
if (mutex_init( (mutex_t *)(&(mutex->backend)), USYNC_THREAD, 0))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Deallocate a mutex. */
|
||||
int
|
||||
__objc_mutex_deallocate(objc_mutex_t mutex)
|
||||
{
|
||||
mutex_destroy((mutex_t *)(&(mutex->backend)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_lock(objc_mutex_t mutex)
|
||||
{
|
||||
if (mutex_lock((mutex_t *)(&(mutex->backend))) != 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_trylock(objc_mutex_t mutex)
|
||||
{
|
||||
if (mutex_trylock((mutex_t *)(&(mutex->backend))) != 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__objc_mutex_unlock(objc_mutex_t mutex)
|
||||
{
|
||||
if (mutex_unlock((mutex_t *)(&(mutex->backend))) != 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__objc_condition_allocate(objc_condition_t condition)
|
||||
{
|
||||
return cond_init((cond_t *)(&(condition->backend)), USYNC_THREAD, NULL);
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__objc_condition_deallocate(objc_condition_t condition)
|
||||
{
|
||||
return cond_destroy((cond_t *)(&(condition->backend)));
|
||||
}
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
return cond_wait((cond_t *)(&(condition->backend)),
|
||||
(mutex_t *)(&(mutex->backend)));
|
||||
}
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__objc_condition_broadcast(objc_condition_t condition)
|
||||
{
|
||||
return cond_broadcast((cond_t *)(&(condition->backend)));
|
||||
}
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__objc_condition_signal(objc_condition_t condition)
|
||||
{
|
||||
return cond_signal((cond_t *)(&(condition->backend)));
|
||||
}
|
||||
|
||||
/* End of File */
|
@ -1,192 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Implementation
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 "objc/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 */
|
@ -1,272 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Interface - Win32 Implementation
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 "objc/runtime.h"
|
||||
|
||||
#ifndef __OBJC__
|
||||
#define __OBJC__
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
/* Key structure for maintaining thread specific storage */
|
||||
static DWORD __objc_data_tls = (DWORD)-1;
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__objc_init_thread_system(void)
|
||||
{
|
||||
/* Initialize the thread storage key */
|
||||
if ((__objc_data_tls = TlsAlloc()) != (DWORD)-1)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__objc_close_thread_system(void)
|
||||
{
|
||||
if (__objc_data_tls != (DWORD)-1)
|
||||
TlsFree(__objc_data_tls);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__objc_thread_detach(void (*func)(void *arg), void *arg)
|
||||
{
|
||||
DWORD thread_id = 0;
|
||||
HANDLE win32_handle;
|
||||
|
||||
if (!(win32_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func,
|
||||
arg, 0, &thread_id)))
|
||||
thread_id = 0;
|
||||
|
||||
return (objc_thread_t)thread_id;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
__objc_thread_set_priority(int priority)
|
||||
{
|
||||
int sys_priority = 0;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
case OBJC_THREAD_INTERACTIVE_PRIORITY:
|
||||
sys_priority = THREAD_PRIORITY_NORMAL;
|
||||
break;
|
||||
default:
|
||||
case OBJC_THREAD_BACKGROUND_PRIORITY:
|
||||
sys_priority = THREAD_PRIORITY_BELOW_NORMAL;
|
||||
break;
|
||||
case OBJC_THREAD_LOW_PRIORITY:
|
||||
sys_priority = THREAD_PRIORITY_LOWEST;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Change priority */
|
||||
if (SetThreadPriority(GetCurrentThread(), sys_priority))
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__objc_thread_get_priority(void)
|
||||
{
|
||||
int sys_priority;
|
||||
|
||||
sys_priority = GetThreadPriority(GetCurrentThread());
|
||||
|
||||
switch (sys_priority)
|
||||
{
|
||||
case THREAD_PRIORITY_HIGHEST:
|
||||
case THREAD_PRIORITY_TIME_CRITICAL:
|
||||
case THREAD_PRIORITY_ABOVE_NORMAL:
|
||||
case THREAD_PRIORITY_NORMAL:
|
||||
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||
|
||||
default:
|
||||
case THREAD_PRIORITY_BELOW_NORMAL:
|
||||
return OBJC_THREAD_BACKGROUND_PRIORITY;
|
||||
|
||||
case THREAD_PRIORITY_IDLE:
|
||||
case THREAD_PRIORITY_LOWEST:
|
||||
return OBJC_THREAD_LOW_PRIORITY;
|
||||
}
|
||||
|
||||
/* Couldn't get priority. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
void
|
||||
__objc_thread_yield(void)
|
||||
{
|
||||
Sleep(0);
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__objc_thread_exit(void)
|
||||
{
|
||||
/* exit the thread */
|
||||
ExitThread(__objc_thread_exit_status);
|
||||
|
||||
/* Failed if we reached here */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__objc_thread_id(void)
|
||||
{
|
||||
return (objc_thread_t)GetCurrentThreadId();
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__objc_thread_set_data(void *value)
|
||||
{
|
||||
if (TlsSetValue(__objc_data_tls, value))
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__objc_thread_get_data(void)
|
||||
{
|
||||
return TlsGetValue(__objc_data_tls); /* Return thread data. */
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__objc_mutex_allocate(objc_mutex_t mutex)
|
||||
{
|
||||
if ((mutex->backend = (void *)CreateMutex(NULL, 0, NULL)) == NULL)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a mutex. */
|
||||
int
|
||||
__objc_mutex_deallocate(objc_mutex_t mutex)
|
||||
{
|
||||
CloseHandle((HANDLE)(mutex->backend));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_lock(objc_mutex_t mutex)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = WaitForSingleObject((HANDLE)(mutex->backend), INFINITE);
|
||||
if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to grab a lock on a mutex. */
|
||||
int
|
||||
__objc_mutex_trylock(objc_mutex_t mutex)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = WaitForSingleObject((HANDLE)(mutex->backend), 0);
|
||||
if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__objc_mutex_unlock(objc_mutex_t mutex)
|
||||
{
|
||||
if (ReleaseMutex((HANDLE)(mutex->backend)) == 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__objc_condition_allocate(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__objc_condition_deallocate(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__objc_condition_broadcast(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__objc_condition_signal(objc_condition_t condition)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* End of File */
|
@ -1,563 +0,0 @@
|
||||
/* GNU Objective C Runtime Thread Interface
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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
|
||||
GCC; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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 <stdlib.h>
|
||||
#include "objc/runtime.h"
|
||||
|
||||
/* Global exit status. */
|
||||
int __objc_thread_exit_status = 0;
|
||||
|
||||
/* Flag which lets us know if we ever became multi threaded */
|
||||
int __objc_is_multi_threaded = 0;
|
||||
|
||||
/* The hook function called when the runtime becomes multi threaded */
|
||||
objc_thread_callback _objc_became_multi_threaded = NULL;
|
||||
|
||||
/*
|
||||
Use this to set the hook function that will be called when the
|
||||
runtime initially becomes multi threaded.
|
||||
The hook function is only called once, meaning only when the
|
||||
2nd thread is spawned, not for each and every thread.
|
||||
|
||||
It returns the previous hook function or NULL if there is none.
|
||||
|
||||
A program outside of the runtime could set this to some function so
|
||||
it can be informed; for example, the GNUstep Base Library sets it
|
||||
so it can implement the NSBecomingMultiThreaded notification.
|
||||
*/
|
||||
objc_thread_callback objc_set_thread_callback (objc_thread_callback func)
|
||||
{
|
||||
objc_thread_callback temp = _objc_became_multi_threaded;
|
||||
_objc_became_multi_threaded = func;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/*
|
||||
Private functions
|
||||
|
||||
These functions are utilized by the frontend, but they are not
|
||||
considered part of the public interface.
|
||||
*/
|
||||
|
||||
/*
|
||||
First function called in a thread, starts everything else.
|
||||
|
||||
This function is passed to the backend by objc_thread_detach
|
||||
as the starting function for a new thread.
|
||||
*/
|
||||
struct __objc_thread_start_state
|
||||
{
|
||||
SEL selector;
|
||||
id object;
|
||||
id argument;
|
||||
};
|
||||
|
||||
static void __attribute__((noreturn))
|
||||
__objc_thread_detach_function (struct __objc_thread_start_state *istate)
|
||||
{
|
||||
/* Valid state? */
|
||||
if (istate) {
|
||||
id (*imp) (id, SEL, id);
|
||||
SEL selector = istate->selector;
|
||||
id object = istate->object;
|
||||
id argument = istate->argument;
|
||||
|
||||
/* Don't need anymore so free it */
|
||||
objc_free (istate);
|
||||
|
||||
/* Clear out the thread local storage */
|
||||
objc_thread_set_data (NULL);
|
||||
|
||||
/* Check to see if we just became multi threaded */
|
||||
if (! __objc_is_multi_threaded)
|
||||
{
|
||||
__objc_is_multi_threaded = 1;
|
||||
|
||||
/* Call the hook function */
|
||||
if (_objc_became_multi_threaded != NULL)
|
||||
(*_objc_became_multi_threaded) ();
|
||||
}
|
||||
|
||||
/* Call the method */
|
||||
if ((imp = (id (*) (id, SEL, id))objc_msg_lookup (object, selector)))
|
||||
(*imp) (object, selector, argument);
|
||||
else
|
||||
objc_error (object, OBJC_ERR_UNIMPLEMENTED,
|
||||
"objc_thread_detach called with bad selector.\n");
|
||||
}
|
||||
else
|
||||
objc_error (nil, OBJC_ERR_BAD_STATE,
|
||||
"objc_thread_detach called with NULL state.\n");
|
||||
|
||||
/* Exit the thread */
|
||||
objc_thread_exit ();
|
||||
}
|
||||
|
||||
/*
|
||||
Frontend functions
|
||||
|
||||
These functions constitute the public interface to the Objective-C thread
|
||||
and mutex functionality.
|
||||
*/
|
||||
|
||||
/* Frontend thread functions */
|
||||
|
||||
/*
|
||||
Detach a new thread of execution and return its id. Returns NULL if fails.
|
||||
Thread is started by sending message with selector to object. Message
|
||||
takes a single argument.
|
||||
*/
|
||||
objc_thread_t
|
||||
objc_thread_detach (SEL selector, id object, id argument)
|
||||
{
|
||||
struct __objc_thread_start_state *istate;
|
||||
objc_thread_t thread_id = NULL;
|
||||
|
||||
/* Allocate the state structure */
|
||||
if (! (istate = (struct __objc_thread_start_state *)
|
||||
objc_malloc (sizeof (*istate))))
|
||||
return NULL;
|
||||
|
||||
/* Initialize the state structure */
|
||||
istate->selector = selector;
|
||||
istate->object = object;
|
||||
istate->argument = argument;
|
||||
|
||||
/* lock access */
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
|
||||
/* Call the backend to spawn the thread */
|
||||
if ((thread_id = __objc_thread_detach ((void *)__objc_thread_detach_function,
|
||||
istate)) == NULL)
|
||||
{
|
||||
/* failed! */
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
objc_free (istate);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Increment our thread counter */
|
||||
__objc_runtime_threads_alive++;
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
objc_thread_set_priority (int priority)
|
||||
{
|
||||
/* Call the backend */
|
||||
return __objc_thread_set_priority (priority);
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
objc_thread_get_priority (void)
|
||||
{
|
||||
/* Call the backend */
|
||||
return __objc_thread_get_priority ();
|
||||
}
|
||||
|
||||
/*
|
||||
Yield our process time to another thread. Any BUSY waiting that is done
|
||||
by a thread should use this function to make sure that other threads can
|
||||
make progress even on a lazy uniprocessor system.
|
||||
*/
|
||||
void
|
||||
objc_thread_yield (void)
|
||||
{
|
||||
/* Call the backend */
|
||||
__objc_thread_yield ();
|
||||
}
|
||||
|
||||
/*
|
||||
Terminate the current tread. Doesn't return.
|
||||
Actually, if it failed returns -1.
|
||||
*/
|
||||
int
|
||||
objc_thread_exit (void)
|
||||
{
|
||||
/* Decrement our counter of the number of threads alive */
|
||||
objc_mutex_lock (__objc_runtime_mutex);
|
||||
__objc_runtime_threads_alive--;
|
||||
objc_mutex_unlock (__objc_runtime_mutex);
|
||||
|
||||
/* Call the backend to terminate the thread */
|
||||
return __objc_thread_exit ();
|
||||
}
|
||||
|
||||
/*
|
||||
Returns an integer value which uniquely describes a thread. Must not be
|
||||
NULL which is reserved as a marker for "no thread".
|
||||
*/
|
||||
objc_thread_t
|
||||
objc_thread_id (void)
|
||||
{
|
||||
/* Call the backend */
|
||||
return __objc_thread_id ();
|
||||
}
|
||||
|
||||
/*
|
||||
Sets the thread's local storage pointer.
|
||||
Returns 0 if successful or -1 if failed.
|
||||
*/
|
||||
int
|
||||
objc_thread_set_data (void *value)
|
||||
{
|
||||
/* Call the backend */
|
||||
return __objc_thread_set_data (value);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the thread's local storage pointer. Returns NULL on failure.
|
||||
*/
|
||||
void *
|
||||
objc_thread_get_data (void)
|
||||
{
|
||||
/* Call the backend */
|
||||
return __objc_thread_get_data ();
|
||||
}
|
||||
|
||||
/* Frontend mutex functions */
|
||||
|
||||
/*
|
||||
Allocate a mutex. Return the mutex pointer if successful or NULL if the
|
||||
allocation failed for any reason.
|
||||
*/
|
||||
objc_mutex_t
|
||||
objc_mutex_allocate (void)
|
||||
{
|
||||
objc_mutex_t mutex;
|
||||
|
||||
/* Allocate the mutex structure */
|
||||
if (! (mutex = (objc_mutex_t)objc_malloc (sizeof (struct objc_mutex))))
|
||||
return NULL;
|
||||
|
||||
/* Call backend to create the mutex */
|
||||
if (__objc_mutex_allocate (mutex))
|
||||
{
|
||||
/* failed! */
|
||||
objc_free (mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize mutex */
|
||||
mutex->owner = NULL;
|
||||
mutex->depth = 0;
|
||||
return mutex;
|
||||
}
|
||||
|
||||
/*
|
||||
Deallocate a mutex. Note that this includes an implicit mutex_lock to
|
||||
insure that no one else is using the lock. It is legal to deallocate
|
||||
a lock if we have a lock on it, but illegal to deallocate a lock held
|
||||
by anyone else.
|
||||
Returns the number of locks on the thread. (1 for deallocate).
|
||||
*/
|
||||
int
|
||||
objc_mutex_deallocate (objc_mutex_t mutex)
|
||||
{
|
||||
int depth;
|
||||
|
||||
/* Valid mutex? */
|
||||
if (! mutex)
|
||||
return -1;
|
||||
|
||||
/* Acquire lock on mutex */
|
||||
depth = objc_mutex_lock (mutex);
|
||||
|
||||
/* Call backend to destroy mutex */
|
||||
if (__objc_mutex_deallocate (mutex))
|
||||
return -1;
|
||||
|
||||
/* Free the mutex structure */
|
||||
objc_free (mutex);
|
||||
|
||||
/* Return last depth */
|
||||
return depth;
|
||||
}
|
||||
|
||||
/*
|
||||
Grab a lock on a mutex. If this thread already has a lock on this mutex
|
||||
then we increment the lock count. If another thread has a lock on the
|
||||
mutex we block and wait for the thread to release the lock.
|
||||
Returns the lock count on the mutex held by this thread.
|
||||
*/
|
||||
int
|
||||
objc_mutex_lock (objc_mutex_t mutex)
|
||||
{
|
||||
objc_thread_t thread_id;
|
||||
int status;
|
||||
|
||||
/* Valid mutex? */
|
||||
if (! mutex)
|
||||
return -1;
|
||||
|
||||
/* If we already own the lock then increment depth */
|
||||
thread_id = __objc_thread_id ();
|
||||
if (mutex->owner == thread_id)
|
||||
return ++mutex->depth;
|
||||
|
||||
/* Call the backend to lock the mutex */
|
||||
status = __objc_mutex_lock (mutex);
|
||||
|
||||
/* Failed? */
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Successfully locked the thread */
|
||||
mutex->owner = thread_id;
|
||||
return mutex->depth = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Try to grab a lock on a mutex. If this thread already has a lock on
|
||||
this mutex then we increment the lock count and return it. If another
|
||||
thread has a lock on the mutex returns -1.
|
||||
*/
|
||||
int
|
||||
objc_mutex_trylock (objc_mutex_t mutex)
|
||||
{
|
||||
objc_thread_t thread_id;
|
||||
int status;
|
||||
|
||||
/* Valid mutex? */
|
||||
if (! mutex)
|
||||
return -1;
|
||||
|
||||
/* If we already own the lock then increment depth */
|
||||
thread_id = __objc_thread_id ();
|
||||
if (mutex->owner == thread_id)
|
||||
return ++mutex->depth;
|
||||
|
||||
/* Call the backend to try to lock the mutex */
|
||||
status = __objc_mutex_trylock (mutex);
|
||||
|
||||
/* Failed? */
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Successfully locked the thread */
|
||||
mutex->owner = thread_id;
|
||||
return mutex->depth = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Unlocks the mutex by one level.
|
||||
Decrements the lock count on this mutex by one.
|
||||
If the lock count reaches zero, release the lock on the mutex.
|
||||
Returns the lock count on the mutex.
|
||||
It is an error to attempt to unlock a mutex which this thread
|
||||
doesn't hold in which case return -1 and the mutex is unaffected.
|
||||
*/
|
||||
int
|
||||
objc_mutex_unlock (objc_mutex_t mutex)
|
||||
{
|
||||
objc_thread_t thread_id;
|
||||
int status;
|
||||
|
||||
/* Valid mutex? */
|
||||
if (! mutex)
|
||||
return -1;
|
||||
|
||||
/* If another thread owns the lock then abort */
|
||||
thread_id = __objc_thread_id ();
|
||||
if (mutex->owner != thread_id)
|
||||
return -1;
|
||||
|
||||
/* Decrement depth and return */
|
||||
if (mutex->depth > 1)
|
||||
return --mutex->depth;
|
||||
|
||||
/* Depth down to zero so we are no longer the owner */
|
||||
mutex->depth = 0;
|
||||
mutex->owner = NULL;
|
||||
|
||||
/* Have the backend unlock the mutex */
|
||||
status = __objc_mutex_unlock (mutex);
|
||||
|
||||
/* Failed? */
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Frontend condition mutex functions */
|
||||
|
||||
/*
|
||||
Allocate a condition. Return the condition pointer if successful or NULL
|
||||
if the allocation failed for any reason.
|
||||
*/
|
||||
objc_condition_t
|
||||
objc_condition_allocate (void)
|
||||
{
|
||||
objc_condition_t condition;
|
||||
|
||||
/* Allocate the condition mutex structure */
|
||||
if (! (condition =
|
||||
(objc_condition_t) objc_malloc (sizeof (struct objc_condition))))
|
||||
return NULL;
|
||||
|
||||
/* Call the backend to create the condition mutex */
|
||||
if (__objc_condition_allocate (condition))
|
||||
{
|
||||
/* failed! */
|
||||
objc_free (condition);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Success! */
|
||||
return condition;
|
||||
}
|
||||
|
||||
/*
|
||||
Deallocate a condition. Note that this includes an implicit
|
||||
condition_broadcast to insure that waiting threads have the opportunity
|
||||
to wake. It is legal to dealloc a condition only if no other
|
||||
thread is/will be using it. Here we do NOT check for other threads
|
||||
waiting but just wake them up.
|
||||
*/
|
||||
int
|
||||
objc_condition_deallocate (objc_condition_t condition)
|
||||
{
|
||||
/* Broadcast the condition */
|
||||
if (objc_condition_broadcast (condition))
|
||||
return -1;
|
||||
|
||||
/* Call the backend to destroy */
|
||||
if (__objc_condition_deallocate (condition))
|
||||
return -1;
|
||||
|
||||
/* Free the condition mutex structure */
|
||||
objc_free (condition);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Wait on the condition unlocking the mutex until objc_condition_signal ()
|
||||
or objc_condition_broadcast () are called for the same condition. The
|
||||
given mutex *must* have the depth set to 1 so that it can be unlocked
|
||||
here, so that someone else can lock it and signal/broadcast the condition.
|
||||
The mutex is used to lock access to the shared data that make up the
|
||||
"condition" predicate.
|
||||
*/
|
||||
int
|
||||
objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
|
||||
{
|
||||
objc_thread_t thread_id;
|
||||
|
||||
/* Valid arguments? */
|
||||
if (! mutex || ! condition)
|
||||
return -1;
|
||||
|
||||
/* Make sure we are owner of mutex */
|
||||
thread_id = __objc_thread_id ();
|
||||
if (mutex->owner != thread_id)
|
||||
return -1;
|
||||
|
||||
/* Cannot be locked more than once */
|
||||
if (mutex->depth > 1)
|
||||
return -1;
|
||||
|
||||
/* Virtually unlock the mutex */
|
||||
mutex->depth = 0;
|
||||
mutex->owner = (objc_thread_t)NULL;
|
||||
|
||||
/* Call the backend to wait */
|
||||
__objc_condition_wait (condition, mutex);
|
||||
|
||||
/* Make ourselves owner of the mutex */
|
||||
mutex->owner = thread_id;
|
||||
mutex->depth = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Wake up all threads waiting on this condition. It is recommended that
|
||||
the called would lock the same mutex as the threads in objc_condition_wait
|
||||
before changing the "condition predicate" and make this call and unlock it
|
||||
right away after this call.
|
||||
*/
|
||||
int
|
||||
objc_condition_broadcast (objc_condition_t condition)
|
||||
{
|
||||
/* Valid condition mutex? */
|
||||
if (! condition)
|
||||
return -1;
|
||||
|
||||
return __objc_condition_broadcast (condition);
|
||||
}
|
||||
|
||||
/*
|
||||
Wake up one thread waiting on this condition. It is recommended that
|
||||
the called would lock the same mutex as the threads in objc_condition_wait
|
||||
before changing the "condition predicate" and make this call and unlock it
|
||||
right away after this call.
|
||||
*/
|
||||
int
|
||||
objc_condition_signal (objc_condition_t condition)
|
||||
{
|
||||
/* Valid condition mutex? */
|
||||
if (! condition)
|
||||
return -1;
|
||||
|
||||
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 */
|
@ -283,8 +283,6 @@
|
||||
..
|
||||
nfsserver
|
||||
..
|
||||
objc
|
||||
..
|
||||
openssl
|
||||
..
|
||||
pcap
|
||||
|
@ -11,8 +11,4 @@ SUBDIR= csu libgcc libgcov libdialog libgomp libodialog libregex libreadline \
|
||||
SUBDIR+= libstdc++ libsupc++
|
||||
.endif
|
||||
|
||||
.if ${MK_OBJC} != "no"
|
||||
SUBDIR+= libobjc
|
||||
.endif
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
@ -1,50 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
OBJCDIR=${.CURDIR}/../../../contrib/libobjc
|
||||
GCCDIR= ${.CURDIR}/../../../contrib/gcc
|
||||
GCCLIB= ${.CURDIR}/../../../contrib/gcclibs
|
||||
|
||||
.PATH: ${OBJCDIR}/objc ${OBJCDIR}
|
||||
|
||||
LIB= objc
|
||||
SHLIB_MAJOR= 4
|
||||
|
||||
SRCS= archive.c class.c encoding.c gc.c hash.c init.c linking.m misc.c \
|
||||
nil_method.c NXConstStr.m Object.m objects.c Protocol.m sarray.c \
|
||||
selector.c sendmsg.c thr.c thr-objc.c exception.c
|
||||
|
||||
# XXX: clang cannot compile libobjc yet
|
||||
CC:=${CC:C/^(.*\/)?clang$/gcc/1}
|
||||
|
||||
INCS= encoding.h hash.h objc-api.h objc-decls.h objc-list.h objc.h runtime.h \
|
||||
sarray.h thr.h typedstream.h NXConstStr.h Object.h Protocol.h
|
||||
INCSDIR=${INCLUDEDIR}/objc
|
||||
|
||||
CFLAGS+= -DHAVE_GTHR_DEFAULT -DIN_GCC -DIN_TARGET_LIBS
|
||||
CFLAGS+= -I. -I${.CURDIR}/../../usr.bin/cc/cc_tools
|
||||
CFLAGS+= -I${OBJCDIR}/objc -I${OBJCDIR}
|
||||
CFLAGS+= -I${GCCDIR}/config -I${GCCDIR}
|
||||
CFLAGS+= -I${GCCLIB}/include
|
||||
CFLAGS+= -fexceptions -frandom-seed=RepeatabilityConsideredGood
|
||||
OBJCFLAGS= -fgnu-runtime ${CFLAGS}
|
||||
|
||||
GENHDRS= runtime-info.h
|
||||
|
||||
runtime-info.h:
|
||||
`${CC} --print-prog-name=cc1obj` -print-objc-runtime-info \
|
||||
< /dev/null > ${.TARGET}
|
||||
|
||||
.for H in tconfig.h tm.h config.h options.h gthr-default.h unwind.h
|
||||
$H: ${.CURDIR}/../../usr.bin/cc/cc_tools/Makefile
|
||||
${MAKE} -f ${.ALLSRC} MFILE=${.ALLSRC} GCCDIR=${GCCDIR} ${.TARGET}
|
||||
GENHDRS+= $H
|
||||
.endfor
|
||||
|
||||
CLEANFILES+= ${GENHDRS} cs-* optionlist
|
||||
SRCS+= ${GENHDRS}
|
||||
|
||||
${OBJS}: ${GENHDRS}
|
||||
|
||||
.include <bsd.lib.mk>
|
@ -15,10 +15,6 @@ SUBDIR+= cpp
|
||||
SUBDIR+= cc1plus c++ c++filt
|
||||
.endif
|
||||
|
||||
.if ${MK_OBJC} != "no"
|
||||
SUBDIR+= cc1obj
|
||||
.endif
|
||||
|
||||
.if ${MK_GCOV} != "no"
|
||||
SUBDIR+= gcov
|
||||
.endif
|
||||
|
@ -1,28 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include "../Makefile.inc"
|
||||
|
||||
.PATH: ${GCCDIR}/objc ${GCCDIR}
|
||||
|
||||
PROG= cc1obj
|
||||
SRCS= main.c c-parser.c objc-act.c objc-lang.c c-decl.c
|
||||
BINDIR= /usr/libexec
|
||||
NO_MAN=
|
||||
NO_SHARED?=yes
|
||||
|
||||
CFLAGS+= -I${GCCDIR}/objc -I.
|
||||
|
||||
OBJS+= ${PROG}-checksum.o
|
||||
DPADD= ${LIBBACKEND} ${LIBCPP} ${LIBDECNUMBER} ${LIBIBERTY}
|
||||
LDADD= ${LIBBACKEND} ${LIBCPP} ${LIBDECNUMBER} ${LIBIBERTY}
|
||||
|
||||
DOBJS+= ${SRCS:N*.h:R:S/$/.o/g}
|
||||
${PROG}-dummy: ${DOBJS}
|
||||
${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${DOBJS} ${LDADD}
|
||||
CLEANFILES+= ${PROG}-dummy
|
||||
|
||||
${PROG}-checksum.c: ${PROG}-dummy
|
||||
../cc_tools/genchecksum ${PROG}-dummy > ${.TARGET}
|
||||
CLEANFILES+= ${PROG}-checksum.c
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -130,10 +130,6 @@ GTFILES_LANG_DIR_NAMES=
|
||||
GTFILES_LANG_DIR_NAMES+= cp
|
||||
.endif
|
||||
|
||||
.if ${MK_OBJC} != "no"
|
||||
GTFILES_LANG_DIR_NAMES+= objc
|
||||
.endif
|
||||
|
||||
# The list of language specific files for gengtype
|
||||
.for L in ${GTFILES_LANG_DIR_NAMES} c
|
||||
.if exists(${GCCDIR}/$L-config-lang.in)
|
||||
@ -158,10 +154,6 @@ TREE_DEF_FILES=
|
||||
TREE_DEF_FILES+= cp/cp-tree.def
|
||||
.endif
|
||||
|
||||
.if ${MK_OBJC} != "no"
|
||||
TREE_DEF_FILES+= objc/objc-tree.def
|
||||
.endif
|
||||
|
||||
#
|
||||
# Option files.
|
||||
#
|
||||
@ -342,7 +334,6 @@ GENSRCS+= configargs.h
|
||||
# Language spec files
|
||||
specs.h:
|
||||
echo '#include "cp/lang-specs.h"' > ${.TARGET}
|
||||
echo '#include "objc/lang-specs.h"' >> ${.TARGET}
|
||||
|
||||
GENSRCS+= specs.h
|
||||
|
||||
|
@ -14,7 +14,7 @@ INFOENTRY_gccint= "* gccint: (gccint). The GNU compiler family internal documen
|
||||
INFOENTRY_cppinternals= "* cppinternals: (cppinternals). The GNU compiler preprocessor internal documentation."
|
||||
|
||||
gcc.info: gcc.texi gcc-common.texi gcc-vers.texi frontends.texi \
|
||||
standards.texi invoke.texi extend.texi md.texi objc.texi \
|
||||
standards.texi invoke.texi extend.texi md.texi \
|
||||
gcov.texi trouble.texi bugreport.texi service.texi \
|
||||
contribute.texi compat.texi funding.texi gnu.texi gpl.texi \
|
||||
fdl.texi contrib.texi cppenv.texi cppopts.texi \
|
||||
|
@ -128,11 +128,9 @@ depend: beforedepend ${DEPENDFILE} afterdepend
|
||||
.if ${CC:T:Micc} == "icc"
|
||||
MKDEP_CFLAGS= ${CFLAGS:M-X*} ${CFLAGS:M-[BIDU]*}
|
||||
MKDEP_CXXFLAGS= ${CXXFLAGS:M-X*} ${CXXFLAGS:M-[BIDU]*}
|
||||
MKDEP_OBJCFLAGS=${OBJCFLAGS:M-X*} ${OBJCFLAGS:M-[BIDU]*}
|
||||
.else
|
||||
MKDEP_CFLAGS= ${CFLAGS:M-nostdinc*} ${CFLAGS:M-[BIDU]*}
|
||||
MKDEP_CXXFLAGS= ${CXXFLAGS:M-nostdinc*} ${CXXFLAGS:M-[BIDU]*}
|
||||
MKDEP_OBJCFLAGS=${OBJCFLAGS:M-nostdinc*} ${OBJCFLAGS:M-[BIDU]*} ${OBJCFLAGS:M-Wno-import*}
|
||||
.endif
|
||||
|
||||
DPSRCS+= ${SRCS}
|
||||
@ -148,10 +146,6 @@ ${DEPENDFILE}: ${DPSRCS}
|
||||
${MKDEP_CXXFLAGS} \
|
||||
${.ALLSRC:M*.cc} ${.ALLSRC:M*.C} ${.ALLSRC:M*.cpp} ${.ALLSRC:M*.cxx}
|
||||
.endif
|
||||
.if !empty(DPSRCS:M*.m)
|
||||
${MKDEPCMD} -f ${DEPENDFILE} -a ${MKDEP} \
|
||||
${MKDEP_OBJCFLAGS} ${.ALLSRC:M*.m}
|
||||
.endif
|
||||
.if target(_EXTRADEPEND)
|
||||
_EXTRADEPEND: .USE
|
||||
${DEPENDFILE}: _EXTRADEPEND
|
||||
|
@ -55,7 +55,7 @@ STRIP?= -s
|
||||
# prefer .s to a .c, add .po, remove stuff not used in the BSD libraries
|
||||
# .So used for PIC object files
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .out .o .po .So .S .asm .s .c .cc .cpp .cxx .m .C .f .y .l .ln
|
||||
.SUFFIXES: .out .o .po .So .S .asm .s .c .cc .cpp .cxx .C .f .y .l .ln
|
||||
|
||||
.if !defined(PICFLAG)
|
||||
.if ${MACHINE_CPUARCH} == "sparc64"
|
||||
@ -101,18 +101,6 @@ PO_FLAG=-pg
|
||||
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
|
||||
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
|
||||
|
||||
.m.po:
|
||||
${OBJC} ${OBJCFLAGS} -pg -c ${.IMPSRC} -o ${.TARGET}
|
||||
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
|
||||
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
|
||||
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
|
||||
|
||||
.m.So:
|
||||
${OBJC} ${PICFLAG} -DPIC ${OBJCFLAGS} -c ${.IMPSRC} -o ${.TARGET}
|
||||
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
|
||||
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
|
||||
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
|
||||
|
||||
.s.po .s.So:
|
||||
${AS} ${AFLAGS} -o ${.TARGET} ${.IMPSRC}
|
||||
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
|
||||
|
@ -100,7 +100,6 @@ LIBNCURSESW?= ${DESTDIR}${LIBDIR}/libncursesw.a
|
||||
LIBNETGRAPH?= ${DESTDIR}${LIBDIR}/libnetgraph.a
|
||||
LIBNGATM?= ${DESTDIR}${LIBDIR}/libngatm.a
|
||||
LIBNVPAIR?= ${DESTDIR}${LIBDIR}/libnvpair.a
|
||||
LIBOBJC?= ${DESTDIR}${LIBDIR}/libobjc.a
|
||||
LIBODIALOG?= ${DESTDIR}${LIBDIR}/libodialog.a
|
||||
LIBOPIE?= ${DESTDIR}${LIBDIR}/libopie.a
|
||||
|
||||
|
@ -248,7 +248,6 @@ WITHOUT_${var}=
|
||||
NLS \
|
||||
NLS_CATALOGS \
|
||||
NS_CACHING \
|
||||
OBJC \
|
||||
OPENSSH \
|
||||
OPENSSL \
|
||||
PAM \
|
||||
@ -356,7 +355,6 @@ __DEFAULT_YES_OPTIONS = \
|
||||
NLS_CATALOGS \
|
||||
NS_CACHING \
|
||||
NTP \
|
||||
OBJC \
|
||||
OPENSSH \
|
||||
OPENSSL \
|
||||
PAM \
|
||||
|
@ -48,16 +48,6 @@ PROG= ${PROG_CXX}
|
||||
.if defined(PROG)
|
||||
.if defined(SRCS)
|
||||
|
||||
# If there are Objective C sources, link with Objective C libraries.
|
||||
.if !empty(SRCS:M*.m)
|
||||
.if defined(OBJCLIBS)
|
||||
LDADD+= ${OBJCLIBS}
|
||||
.else
|
||||
DPADD+= ${LIBOBJC} ${LIBPTHREAD}
|
||||
LDADD+= -lobjc -lpthread
|
||||
.endif
|
||||
.endif
|
||||
|
||||
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
|
||||
|
||||
.if target(beforelinking)
|
||||
|
Loading…
Reference in New Issue
Block a user