1 /* Utility macros to read Java(TM) .class files and byte codes.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2006, 2007 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>.
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
32 #define JCF_u4 unsigned long
35 #define JCF_u2 unsigned short
39 #define REALLOC xrealloc
41 #define FREE(PTR) free(PTR)
45 #define JCF_word JCF_u4
48 /* If we have both "scandir" and "alphasort", we can cache directory
49 listings to reduce the time taken to search the classpath. */
50 #if defined(HAVE_SCANDIR) && defined(HAVE_ALPHASORT)
51 #define JCF_USE_SCANDIR 1
53 #define JCF_USE_SCANDIR 0
56 /* On case-insensitive file systems, we need to ensure that a request
57 to open a .java or .class file is honored only if the file to be
58 opened is of the exact case we are asking for. In other words, we
59 want to override the inherent case insensitivity of the underlying
60 file system. On other platforms, this macro becomes the vanilla
63 If you want to add another host, add your define to the list below
64 (i.e. defined(WIN32) || defined(YOUR_HOST)) and add a host-specific
65 .c file to Make-lang.in similar to win32-host.c. */
68 jcf_open_exact_case (const char* filename
, int oflag
);
69 #define JCF_OPEN_EXACT_CASE(X, Y) jcf_open_exact_case (X, Y)
71 #define JCF_OPEN_EXACT_CASE open
75 typedef int (*jcf_filbuf_t
) (struct JCF
*, int needed
);
77 union cpool_entry
GTY(()) {
78 jword
GTY ((tag ("0"))) w
;
79 tree
GTY ((tag ("1"))) t
;
82 #define cpool_entry_is_tree(tag) \
83 (tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8
85 typedef struct CPool
GTY(()) {
86 /* Available number of elements in the constants array, before it
87 must be re-allocated. */
90 /* The constant_pool_count. */
93 uint8
* GTY((length ("%h.count"))) tags
;
95 union cpool_entry
* GTY((length ("%h.count"),
96 desc ("cpool_entry_is_tree (%1.tags%a)"))) data
;
101 /* JCF encapsulates the state of reading a Java Class File. */
103 typedef struct JCF
GTY(()) {
104 unsigned char * GTY ((skip
)) buffer
;
105 unsigned char * GTY ((skip
)) buffer_end
;
106 unsigned char * GTY ((skip
)) read_ptr
;
107 unsigned char * GTY ((skip
)) read_end
;
108 unsigned int right_zip
: 1;
109 unsigned int finished
: 1;
111 PTR
GTY ((skip
)) read_state
;
112 const char *filename
;
113 const char *classname
;
114 /* Directory entry where it was found. */
115 struct ZipDirectory
* GTY ((skip
)) zipd
;
121 /*typedef JCF* JCF_FILE;*/
123 #define JCF_SEEN_IN_ZIP(JCF) ((JCF)->zipd != NULL)
125 /* The CPOOL macros take a (pointer to a) CPool.
126 The JPOOL macros take a (pointer to a) JCF.
127 Some of the latter should perhaps be deprecated or removed. */
129 #define CPOOL_COUNT(CPOOL) ((CPOOL)->count)
130 #define JPOOL_SIZE(JCF) CPOOL_COUNT(&(JCF)->cpool)
131 #define JPOOL_TAG(JCF, INDEX) ((JCF)->cpool.tags[INDEX])
132 /* The INDEX'th constant pool entry as a JCF_u4. */
133 #define CPOOL_UINT(CPOOL, INDEX) ((CPOOL)->data[INDEX].w)
134 #define JPOOL_UINT(JCF, INDEX) CPOOL_UINT(&(JCF)->cpool, INDEX) /*deprecated*/
135 /* The first uint16 of the INDEX'th constant pool entry. */
136 #define CPOOL_USHORT1(CPOOL, INDEX) ((CPOOL)->data[INDEX].w & 0xFFFF)
137 #define JPOOL_USHORT1(JCF, INDEX) CPOOL_USHORT1(&(JCF)->cpool, INDEX)
138 /* The second uint16 of the INDEX'th constant pool entry. */
139 #define CPOOL_USHORT2(CPOOL, INDEX) ((CPOOL)->data[INDEX].w >> 16)
140 #define JPOOL_USHORT2(JCF, INDEX) CPOOL_USHORT2(&(JCF)->cpool, INDEX)
141 #define JPOOL_LONG(JCF, INDEX) \
142 WORDS_TO_LONG (JPOOL_UINT(JCF, INDEX), JPOOL_UINT(JCF, (INDEX)+1))
143 #define JPOOL_DOUBLE(JCF, INDEX) \
144 WORDS_TO_DOUBLE (JPOOL_UINT(JCF, INDEX), JPOOL_UINT(JCF, (INDEX)+1))
145 #ifndef JPOOL_UTF_LENGTH
146 #define JPOOL_UTF_LENGTH(JCF, INDEX) \
147 GET_u2 ((JCF)->buffer+JPOOL_UINT(JCF, INDEX))
149 #ifndef JPOOL_UTF_DATA
150 #define JPOOL_UTF_DATA(JCF, INDEX) \
151 ((JCF)->buffer+JPOOL_UINT(JCF, INDEX)+2)
153 #define JPOOL_INT(JCF, INDEX) (WORD_TO_INT(JPOOL_UINT (JCF, INDEX)))
154 #define JPOOL_FLOAT(JCF, INDEX) WORD_TO_FLOAT (JPOOL_UINT (JCF, INDEX))
156 #define CPOOL_INDEX_IN_RANGE(CPOOL, INDEX) \
157 ((INDEX) > 0 && (INDEX) < CPOOL_COUNT(CPOOL))
159 #define CPOOL_FINISH(CPOOL) { \
164 #define JCF_FINISH(JCF) { \
165 CPOOL_FINISH(&(JCF)->cpool); \
166 if ((JCF)->buffer) free ((JCF)->buffer); \
167 if ((JCF)->filename) free (CONST_CAST (char *, (JCF)->filename)); \
168 if ((JCF)->classname) free (CONST_CAST (char *, (JCF)->classname)); \
169 (JCF)->finished = 1; }
171 #define CPOOL_INIT(CPOOL) \
172 ((CPOOL)->capacity = 0, (CPOOL)->count = 0, (CPOOL)->tags = 0, (CPOOL)->data = 0)
174 #define CPOOL_REINIT(CPOOL) ((CPOOL)->count = 0)
176 #define JCF_ZERO(JCF) \
177 ((JCF)->buffer = (JCF)->buffer_end = (JCF)->read_ptr = (JCF)->read_end = 0,\
178 (JCF)->read_state = 0, (JCF)->filename = (JCF)->classname = 0, \
179 CPOOL_INIT(&(JCF)->cpool), (JCF)->zipd = 0, \
182 /* Given that PTR points to a 2-byte unsigned integer in network
183 (big-endian) byte-order, return that integer. */
184 #define GET_u2(PTR) (((PTR)[0] << 8) | ((PTR)[1]))
185 /* Like GET_u2, but for little-endian format. */
186 #define GET_u2_le(PTR) (((PTR)[1] << 8) | ((PTR)[0]))
188 /* Given that PTR points to a 4-byte unsigned integer in network
189 (big-endian) byte-order, return that integer. */
190 #define GET_u4(PTR) (((JCF_u4)(PTR)[0] << 24) | ((JCF_u4)(PTR)[1] << 16) \
191 | ((JCF_u4)(PTR)[2] << 8) | ((JCF_u4)(PTR)[3]))
192 /* Like GET_u4, but for little-endian order. */
193 #define GET_u4_le(PTR) (((JCF_u4)(PTR)[3] << 24) | ((JCF_u4)(PTR)[2] << 16) \
194 | ((JCF_u4)(PTR)[1] << 8) | ((JCF_u4)(PTR)[0]))
196 /* Make sure there are COUNT bytes readable. */
197 #define JCF_FILL(JCF, COUNT) \
198 ((JCF)->read_end-(JCF)->read_ptr >= (COUNT) ? 0 : (*(JCF)->filbuf)(JCF, COUNT))
199 #define JCF_GETC(JCF) (JCF_FILL(JCF, 1) ? -1 : *(JCF)->read_ptr++)
200 #define JCF_READ(JCF, BUFFER, N) \
201 (memcpy (BUFFER, (JCF)->read_ptr, N), (JCF)->read_ptr += (N))
202 #define JCF_SKIP(JCF,N) ((JCF)->read_ptr += (N))
203 #define JCF_readu(JCF) (*(JCF)->read_ptr++)
205 /* Reads an unsigned 2-byte integer in network (big-endian) byte-order
206 from JCF. Returns that integer.
207 Does not check for EOF (make sure to call JCF_FILL before-hand). */
208 #define JCF_readu2(JCF) ((JCF)->read_ptr += 2, GET_u2 ((JCF)->read_ptr-2))
209 #define JCF_readu2_le(JCF) ((JCF)->read_ptr += 2, GET_u2_le((JCF)->read_ptr-2))
211 /* Like JCF_readu2, but read a 4-byte unsigned integer. */
212 #define JCF_readu4(JCF) ((JCF)->read_ptr += 4, GET_u4 ((JCF)->read_ptr-4))
213 #define JCF_readu4_le(JCF) ((JCF)->read_ptr += 4, GET_u4_le((JCF)->read_ptr-4))
215 #define JCF_TELL(JCF) ((JCF)->read_ptr - (JCF)->buffer)
216 #define JCF_SEEK(JCF, POS) ((JCF)->read_ptr = (JCF)->buffer + (POS))
218 #define ACC_PUBLIC 0x0001
219 #define ACC_PRIVATE 0x0002
220 #define ACC_PROTECTED 0x0004
221 #define ACC_STATIC 0x0008
222 #define ACC_FINAL 0x0010
223 #define ACC_SYNCHRONIZED 0x0020
224 #define ACC_SUPER 0x0020
225 #define ACC_BRIDGE 0x0040
226 #define ACC_VOLATILE 0x0040
227 #define ACC_TRANSIENT 0x0080
228 #define ACC_VARARGS 0x0080
229 #define ACC_NATIVE 0x0100
230 #define ACC_INTERFACE 0x0200
231 #define ACC_ABSTRACT 0x0400
232 #define ACC_STRICT 0x0800
233 #define ACC_SYNTHETIC 0x01000
234 #define ACC_ANNOTATION 0x02000
235 #define ACC_ENUM 0x04000
236 /* "Invisible" refers to Miranda methods inserted into an abstract
237 class. It is also used in the runtime. */
238 #define ACC_INVISIBLE 0x8000
240 #define ACC_VISIBILITY (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED)
245 CONSTANT_Fieldref
= 9,
246 CONSTANT_Methodref
= 10,
247 CONSTANT_InterfaceMethodref
= 11,
249 CONSTANT_Integer
= 3,
253 CONSTANT_NameAndType
= 12,
255 CONSTANT_Unicode
= 2,
259 #define DEFAULT_CLASS_PATH "."
261 extern const char *find_class (const char *, int, JCF
*);
262 extern const char *find_classfile (char *, JCF
*, const char *);
263 extern int jcf_filbuf_from_stdio (JCF
*jcf
, int count
);
264 extern int jcf_unexpected_eof (JCF
*, int) ATTRIBUTE_NORETURN
;
266 /* Extract a character from a Java-style Utf8 string.
267 * PTR points to the current character.
268 * LIMIT points to the end of the Utf8 string.
269 * PTR is incremented to point after the character that gets returned.
270 * On an error, -1 is returned. */
271 #define UTF8_GET(PTR, LIMIT) \
272 ((PTR) >= (LIMIT) ? -1 \
273 : *(PTR) < 128 ? *(PTR)++ \
274 : (*(PTR)&0xE0) == 0xC0 && ((PTR)+=2)<=(LIMIT) && ((PTR)[-1]&0xC0) == 0x80 \
275 ? (((PTR)[-2] & 0x1F) << 6) + ((PTR)[-1] & 0x3F) \
276 : (*(PTR) & 0xF0) == 0xE0 && ((PTR) += 3) <= (LIMIT) \
277 && ((PTR)[-2] & 0xC0) == 0x80 && ((PTR)[-1] & 0xC0) == 0x80 \
278 ? (((PTR)[-3]&0x0F) << 12) + (((PTR)[-2]&0x3F) << 6) + ((PTR)[-1]&0x3F) \
281 extern const char *jcf_write_base_directory
;
283 /* Debug macros, for the front end */
285 extern int quiet_flag
;
286 #ifdef VERBOSE_SKELETON
287 #undef SOURCE_FRONTEND_DEBUG
288 #define SOURCE_FRONTEND_DEBUG(X) \
289 {if (!quiet_flag) {printf ("* "); printf X; putchar ('\n');} }
291 #define SOURCE_FRONTEND_DEBUG(X)
294 /* Declarations for dependency code. */
295 extern void jcf_dependency_reset (void);
296 extern void jcf_dependency_set_target (const char *);
297 extern void jcf_dependency_add_target (const char *);
298 extern void jcf_dependency_set_dep_file (const char *);
299 extern void jcf_dependency_add_file (const char *, int);
300 extern void jcf_dependency_write (void);
301 extern void jcf_dependency_init (int);
302 extern void jcf_dependency_print_dummies (void);
304 /* Declarations for path handling code. */
305 extern void jcf_path_init (void);
306 extern void jcf_path_classpath_arg (const char *);
307 extern void jcf_path_bootclasspath_arg (const char *);
308 extern void jcf_path_extdirs_arg (const char *);
309 extern void jcf_path_include_arg (const char *);
310 extern void jcf_path_seal (int);
311 extern void *jcf_path_start (void);
312 extern void *jcf_path_next (void *);
313 extern char *jcf_path_name (void *);
314 extern char *jcf_path_compute (const char *);
315 extern int jcf_path_is_zipfile (void *);
316 extern int jcf_path_is_system (void *);
317 extern int jcf_path_max_len (void);
319 #endif /* ! GCC_JCF_H */