jcf.h (bootstrap_method): New.
[gcc.git] / gcc / java / jcf.h
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, 2008, 2009, 2010 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
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)
10 any later version.
11
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.
16
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/>.
20
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. */
24
25 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
26
27 #ifndef GCC_JCF_H
28 #define GCC_JCF_H
29 #include "javaop.h"
30
31 #ifndef JCF_u4
32 #define JCF_u4 unsigned long
33 #endif
34 #ifndef JCF_u2
35 #define JCF_u2 unsigned short
36 #endif
37
38 #define ALLOC xmalloc
39 #define REALLOC xrealloc
40 #ifndef FREE
41 #define FREE(PTR) free(PTR)
42 #endif
43
44 #ifdef JCF_word
45 #define JCF_word JCF_u4
46 #endif
47
48 /* On case-insensitive file systems, we need to ensure that a request
49 to open a .java or .class file is honored only if the file to be
50 opened is of the exact case we are asking for. In other words, we
51 want to override the inherent case insensitivity of the underlying
52 file system. On other platforms, this macro becomes the vanilla
53 open() call.
54
55 If you want to add another host, add your define to the list below
56 (i.e. defined(WIN32) || defined(YOUR_HOST)) and add a host-specific
57 .c file to Make-lang.in similar to win32-host.c. */
58 #if defined(WIN32)
59 extern int
60 jcf_open_exact_case (const char* filename, int oflag);
61 #define JCF_OPEN_EXACT_CASE(X, Y) jcf_open_exact_case (X, Y)
62 #else
63 #define JCF_OPEN_EXACT_CASE open
64 #endif /* WIN32 */
65
66 struct JCF;
67 typedef int (*jcf_filbuf_t) (struct JCF*, int needed);
68
69 union GTY((variable_size)) cpool_entry {
70 jword GTY ((tag ("0"))) w;
71 tree GTY ((tag ("1"))) t;
72 };
73
74 #define cpool_entry_is_tree(tag) \
75 (tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8
76
77 typedef struct GTY(()) CPool {
78 /* Available number of elements in the constants array, before it
79 must be re-allocated. */
80 int capacity;
81
82 /* The constant_pool_count. */
83 int count;
84
85 uint8* GTY((length ("%h.count"))) tags;
86
87 union cpool_entry * GTY((length ("%h.count"),
88 desc ("cpool_entry_is_tree (%1.tags%a)"))) data;
89 } CPool;
90
91 typedef struct GTY(()) bootstrap_method {
92 unsigned method_ref;
93 unsigned num_arguments;
94 unsigned* GTY((length ("%h.num_arguments"))) bootstrap_arguments;
95 } bootstrap_method;
96
97 typedef struct GTY(()) BootstrapMethods {
98 unsigned count;
99 bootstrap_method* GTY((length ("%h.count"))) methods;
100 } BootstrapMethods;
101
102 struct ZipDirectory;
103
104 /* JCF encapsulates the state of reading a Java Class File. */
105
106 typedef struct GTY(()) JCF {
107 unsigned char * GTY ((skip)) buffer;
108 unsigned char * GTY ((skip)) buffer_end;
109 unsigned char * GTY ((skip)) read_ptr;
110 unsigned char * GTY ((skip)) read_end;
111 unsigned int right_zip : 1;
112 unsigned int finished : 1;
113 jcf_filbuf_t filbuf;
114 PTR GTY ((skip)) read_state;
115 const char *filename;
116 const char *classname;
117 /* Directory entry where it was found. */
118 struct ZipDirectory * GTY ((skip)) zipd;
119 JCF_u2 access_flags;
120 JCF_u2 this_class;
121 JCF_u2 super_class;
122 CPool cpool;
123 BootstrapMethods bootstrap_methods;
124 } JCF;
125 /*typedef JCF* JCF_FILE;*/
126
127 #define JCF_SEEN_IN_ZIP(JCF) ((JCF)->zipd != NULL)
128
129 /* The CPOOL macros take a (pointer to a) CPool.
130 The JPOOL macros take a (pointer to a) JCF.
131 Some of the latter should perhaps be deprecated or removed. */
132
133 #define CPOOL_COUNT(CPOOL) ((CPOOL)->count)
134 #define JPOOL_SIZE(JCF) CPOOL_COUNT(&(JCF)->cpool)
135 #define JPOOL_TAG(JCF, INDEX) ((JCF)->cpool.tags[INDEX])
136 /* The INDEX'th constant pool entry as a JCF_u4. */
137 #define CPOOL_UINT(CPOOL, INDEX) ((CPOOL)->data[INDEX].w)
138 #define JPOOL_UINT(JCF, INDEX) CPOOL_UINT(&(JCF)->cpool, INDEX) /*deprecated*/
139 /* The first uint16 of the INDEX'th constant pool entry. */
140 #define CPOOL_USHORT1(CPOOL, INDEX) ((CPOOL)->data[INDEX].w & 0xFFFF)
141 #define JPOOL_USHORT1(JCF, INDEX) CPOOL_USHORT1(&(JCF)->cpool, INDEX)
142 /* The second uint16 of the INDEX'th constant pool entry. */
143 #define CPOOL_USHORT2(CPOOL, INDEX) ((CPOOL)->data[INDEX].w >> 16)
144 #define JPOOL_USHORT2(JCF, INDEX) CPOOL_USHORT2(&(JCF)->cpool, INDEX)
145 #define JPOOL_LONG(JCF, INDEX) \
146 WORDS_TO_LONG (JPOOL_UINT(JCF, INDEX), JPOOL_UINT(JCF, (INDEX)+1))
147 #define JPOOL_DOUBLE(JCF, INDEX) \
148 WORDS_TO_DOUBLE (JPOOL_UINT(JCF, INDEX), JPOOL_UINT(JCF, (INDEX)+1))
149 #ifndef JPOOL_UTF_LENGTH
150 #define JPOOL_UTF_LENGTH(JCF, INDEX) \
151 GET_u2 ((JCF)->buffer+JPOOL_UINT(JCF, INDEX))
152 #endif
153 #ifndef JPOOL_UTF_DATA
154 #define JPOOL_UTF_DATA(JCF, INDEX) \
155 ((JCF)->buffer+JPOOL_UINT(JCF, INDEX)+2)
156 #endif
157 #define JPOOL_INT(JCF, INDEX) (WORD_TO_INT(JPOOL_UINT (JCF, INDEX)))
158 #define JPOOL_FLOAT(JCF, INDEX) WORD_TO_FLOAT (JPOOL_UINT (JCF, INDEX))
159
160 #define CPOOL_INDEX_IN_RANGE(CPOOL, INDEX) \
161 ((INDEX) > 0 && (INDEX) < CPOOL_COUNT(CPOOL))
162
163 #define CPOOL_FINISH(CPOOL) { \
164 (CPOOL)->tags = 0; \
165 (CPOOL)->data = 0; \
166 }
167
168 #define JCF_FINISH(JCF) { \
169 CPOOL_FINISH(&(JCF)->cpool); \
170 if ((JCF)->buffer) free ((JCF)->buffer); \
171 if ((JCF)->filename) free (CONST_CAST (char *, (JCF)->filename)); \
172 if ((JCF)->classname) free (CONST_CAST (char *, (JCF)->classname)); \
173 (JCF)->finished = 1; }
174
175 #define CPOOL_INIT(CPOOL) \
176 ((CPOOL)->capacity = 0, (CPOOL)->count = 0, (CPOOL)->tags = 0, (CPOOL)->data = 0)
177
178 #define CPOOL_REINIT(CPOOL) ((CPOOL)->count = 0)
179
180 #define JCF_ZERO(JCF) \
181 ((JCF)->buffer = (JCF)->buffer_end = (JCF)->read_ptr = (JCF)->read_end = 0,\
182 (JCF)->read_state = 0, (JCF)->filename = (JCF)->classname = 0, \
183 CPOOL_INIT(&(JCF)->cpool), (JCF)->zipd = 0, \
184 (JCF)->finished = 0)
185
186 /* Given that PTR points to a 2-byte unsigned integer in network
187 (big-endian) byte-order, return that integer. */
188 #define GET_u2(PTR) (((PTR)[0] << 8) | ((PTR)[1]))
189 /* Like GET_u2, but for little-endian format. */
190 #define GET_u2_le(PTR) (((PTR)[1] << 8) | ((PTR)[0]))
191
192 /* Given that PTR points to a 4-byte unsigned integer in network
193 (big-endian) byte-order, return that integer. */
194 #define GET_u4(PTR) (((JCF_u4)(PTR)[0] << 24) | ((JCF_u4)(PTR)[1] << 16) \
195 | ((JCF_u4)(PTR)[2] << 8) | ((JCF_u4)(PTR)[3]))
196 /* Like GET_u4, but for little-endian order. */
197 #define GET_u4_le(PTR) (((JCF_u4)(PTR)[3] << 24) | ((JCF_u4)(PTR)[2] << 16) \
198 | ((JCF_u4)(PTR)[1] << 8) | ((JCF_u4)(PTR)[0]))
199
200 /* Make sure there are COUNT bytes readable. */
201 #define JCF_FILL(JCF, COUNT) \
202 ((JCF)->read_end-(JCF)->read_ptr >= (COUNT) ? 0 : (*(JCF)->filbuf)(JCF, COUNT))
203 #define JCF_GETC(JCF) (JCF_FILL(JCF, 1) ? -1 : *(JCF)->read_ptr++)
204 #define JCF_READ(JCF, BUFFER, N) \
205 (memcpy (BUFFER, (JCF)->read_ptr, N), (JCF)->read_ptr += (N))
206 #define JCF_SKIP(JCF,N) ((JCF)->read_ptr += (N))
207 #define JCF_readu(JCF) (*(JCF)->read_ptr++)
208
209 /* Reads an unsigned 2-byte integer in network (big-endian) byte-order
210 from JCF. Returns that integer.
211 Does not check for EOF (make sure to call JCF_FILL before-hand). */
212 #define JCF_readu2(JCF) ((JCF)->read_ptr += 2, GET_u2 ((JCF)->read_ptr-2))
213 #define JCF_readu2_le(JCF) ((JCF)->read_ptr += 2, GET_u2_le((JCF)->read_ptr-2))
214
215 /* Like JCF_readu2, but read a 4-byte unsigned integer. */
216 #define JCF_readu4(JCF) ((JCF)->read_ptr += 4, GET_u4 ((JCF)->read_ptr-4))
217 #define JCF_readu4_le(JCF) ((JCF)->read_ptr += 4, GET_u4_le((JCF)->read_ptr-4))
218
219 #define JCF_TELL(JCF) ((JCF)->read_ptr - (JCF)->buffer)
220 #define JCF_SEEK(JCF, POS) ((JCF)->read_ptr = (JCF)->buffer + (POS))
221
222 #define ACC_PUBLIC 0x0001
223 #define ACC_PRIVATE 0x0002
224 #define ACC_PROTECTED 0x0004
225 #define ACC_STATIC 0x0008
226 #define ACC_FINAL 0x0010
227 #define ACC_SYNCHRONIZED 0x0020
228 #define ACC_SUPER 0x0020
229 #define ACC_BRIDGE 0x0040
230 #define ACC_VOLATILE 0x0040
231 #define ACC_TRANSIENT 0x0080
232 #define ACC_VARARGS 0x0080
233 #define ACC_NATIVE 0x0100
234 #define ACC_INTERFACE 0x0200
235 #define ACC_ABSTRACT 0x0400
236 #define ACC_STRICT 0x0800
237 #define ACC_SYNTHETIC 0x01000
238 #define ACC_ANNOTATION 0x02000
239 #define ACC_ENUM 0x04000
240 /* "Invisible" refers to Miranda methods inserted into an abstract
241 class. It is also used in the runtime. */
242 #define ACC_INVISIBLE 0x8000
243
244 #define ACC_VISIBILITY (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED)
245
246 enum cpool_tag
247 {
248 CONSTANT_Class = 7,
249 CONSTANT_Fieldref = 9,
250 CONSTANT_Methodref = 10,
251 CONSTANT_InterfaceMethodref = 11,
252 CONSTANT_String = 8,
253 CONSTANT_Integer = 3,
254 CONSTANT_Float = 4,
255 CONSTANT_Long = 5,
256 CONSTANT_Double = 6,
257 CONSTANT_NameAndType = 12,
258 CONSTANT_Utf8 = 1,
259 CONSTANT_Unicode = 2,
260 CONSTANT_MethodHandle = 15,
261 CONSTANT_MethodType = 16,
262 CONSTANT_InvokeDynamic = 18,
263
264 CONSTANT_None = 0
265 };
266
267 #define DEFAULT_CLASS_PATH "."
268
269 extern const char *find_class (const char *, int, JCF *);
270 extern const char *find_classfile (char *, JCF*, const char *);
271 extern int jcf_filbuf_from_stdio (JCF *jcf, int count);
272 extern int jcf_unexpected_eof (JCF*, int) ATTRIBUTE_NORETURN;
273
274 /* Extract a character from a Java-style Utf8 string.
275 * PTR points to the current character.
276 * LIMIT points to the end of the Utf8 string.
277 * PTR is incremented to point after the character that gets returned.
278 * On an error, -1 is returned. */
279 #define UTF8_GET(PTR, LIMIT) \
280 ((PTR) >= (LIMIT) ? -1 \
281 : *(PTR) < 128 ? *(PTR)++ \
282 : (*(PTR)&0xE0) == 0xC0 && ((PTR)+=2)<=(LIMIT) && ((PTR)[-1]&0xC0) == 0x80 \
283 ? (((PTR)[-2] & 0x1F) << 6) + ((PTR)[-1] & 0x3F) \
284 : (*(PTR) & 0xF0) == 0xE0 && ((PTR) += 3) <= (LIMIT) \
285 && ((PTR)[-2] & 0xC0) == 0x80 && ((PTR)[-1] & 0xC0) == 0x80 \
286 ? (((PTR)[-3]&0x0F) << 12) + (((PTR)[-2]&0x3F) << 6) + ((PTR)[-1]&0x3F) \
287 : ((PTR)++, -1))
288
289 extern const char *jcf_write_base_directory;
290
291 /* Debug macros, for the front end */
292
293 #ifdef VERBOSE_SKELETON
294 #undef SOURCE_FRONTEND_DEBUG
295 #define SOURCE_FRONTEND_DEBUG(X) \
296 {if (!quiet_flag) {printf ("* "); printf X; putchar ('\n');} }
297 #else
298 #define SOURCE_FRONTEND_DEBUG(X)
299 #endif
300
301 /* Declarations for dependency code. */
302 extern void jcf_dependency_reset (void);
303 extern void jcf_dependency_set_target (const char *);
304 extern void jcf_dependency_add_target (const char *);
305 extern void jcf_dependency_set_dep_file (const char *);
306 extern void jcf_dependency_add_file (const char *, int);
307 extern void jcf_dependency_write (void);
308 extern void jcf_dependency_init (int);
309 extern void jcf_dependency_print_dummies (void);
310
311 /* Declarations for path handling code. */
312 extern void jcf_path_init (void);
313 extern void jcf_path_classpath_arg (const char *);
314 extern void jcf_path_bootclasspath_arg (const char *);
315 extern void jcf_path_extdirs_arg (const char *);
316 extern void jcf_path_include_arg (const char *);
317 extern void jcf_path_seal (int);
318 extern void *jcf_path_start (void);
319 extern void *jcf_path_next (void *);
320 extern char *jcf_path_name (void *);
321 extern char *jcf_path_compute (const char *);
322 extern int jcf_path_is_zipfile (void *);
323 extern int jcf_path_is_system (void *);
324 extern int jcf_path_max_len (void);
325
326 #endif /* ! GCC_JCF_H */