]> gcc.gnu.org Git - gcc.git/blame - libjava/defineclass.cc
2004-02-05 Michael Koch <konqueror@gmx.de>
[gcc.git] / libjava / defineclass.cc
CommitLineData
58eb6e7c
AG
1// defineclass.cc - defining a class from .class format.
2
4c98b1b0 3/* Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation
58eb6e7c
AG
4
5 This file is part of libgcj.
6
7This software is copyrighted work licensed under the terms of the
8Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9details. */
10
11/*
12 Author: Kresten Krab Thorup <krab@gnu.org>
13
14 Written using the online versions of Java Language Specification (1st
15 ed.) and The Java Virtual Machine Specification (2nd ed.).
16
17 Future work may include reading (and handling) attributes which are
18 currently being ignored ("InnerClasses", "LineNumber", etc...).
19*/
20
27e934d8
TT
21#include <config.h>
22
58eb6e7c
AG
23#include <java-interp.h>
24
a9770f9a 25#include <stdlib.h>
58eb6e7c 26#include <java-cpool.h>
27e934d8 27#include <gcj/cni.h>
58eb6e7c
AG
28
29#include <java/lang/Class.h>
30#include <java/lang/Float.h>
31#include <java/lang/Double.h>
32#include <java/lang/Character.h>
33#include <java/lang/LinkageError.h>
34#include <java/lang/InternalError.h>
35#include <java/lang/ClassFormatError.h>
36#include <java/lang/NoClassDefFoundError.h>
37#include <java/lang/ClassCircularityError.h>
58eb6e7c 38#include <java/lang/IncompatibleClassChangeError.h>
e409a2c8 39#include <java/lang/reflect/Modifier.h>
58eb6e7c 40
107abb2f 41using namespace gcj;
58eb6e7c 42
bea31ffb
TT
43#ifdef INTERPRETER
44
cc712abf 45// these go in some separate functions, to avoid having _Jv_InitClass
58eb6e7c
AG
46// inserted all over the place.
47static void throw_internal_error (char *msg)
48 __attribute__ ((__noreturn__));
49static void throw_no_class_def_found_error (jstring msg)
50 __attribute__ ((__noreturn__));
51static void throw_no_class_def_found_error (char *msg)
52 __attribute__ ((__noreturn__));
53static void throw_class_format_error (jstring msg)
54 __attribute__ ((__noreturn__));
58eb6e7c
AG
55static void throw_incompatible_class_change_error (jstring msg)
56 __attribute__ ((__noreturn__));
57static void throw_class_circularity_error (jstring msg)
58 __attribute__ ((__noreturn__));
59
58eb6e7c
AG
60/**
61 * We define class reading using a class. It is practical, since then
62 * the entire class-reader can be a friend of class Class (it needs to
63 * write all it's different structures); but also because this makes it
64 * easy to make class definition reentrant, and thus two threads can be
65 * defining classes at the same time. This class (_Jv_ClassReader) is
66 * never exposed outside this file, so we don't have to worry about
67 * public or private members here.
68 */
69
70struct _Jv_ClassReader {
71
72 // do verification? Currently, there is no option to disable this.
73 // This flag just controls the verificaiton done by the class loader;
74 // i.e., checking the integrity of the constant pool; and it is
75 // allways on. You always want this as far as I can see, but it also
76 // controls weither identifiers and type descriptors/signatures are
77 // verified as legal. This could be somewhat more expensive since it
a47c20a7 78 // will call Character.isJavaIdentifier{Start,Part} for each character
58eb6e7c
AG
79 // in any identifier (field name or method name) it comes by. Thus,
80 // it might be useful to turn off this verification for classes that
81 // come from a trusted source. However, for GCJ, trusted classes are
82 // most likely to be linked in.
83
84 bool verify;
85
86 // input data.
87 unsigned char *bytes;
88 int len;
89
90 // current input position
91 int pos;
92
93 // the constant pool data
94 int pool_count;
95 unsigned char *tags;
96 unsigned int *offsets;
97
98 // the class to define (see java-interp.h)
99 _Jv_InterpClass *def;
100
101 /* check that the given number of input bytes are available */
102 inline void check (int num)
103 {
104 if (pos + num > len)
105 throw_class_format_error ("Premature end of data");
106 }
107
108 /* skip a given number of bytes in input */
109 inline void skip (int num)
110 {
111 check (num);
112 pos += num;
113 }
114
115 /* read an unsignend 1-byte unit */
116 inline static jint get1u (unsigned char* bytes)
117 {
118 return bytes[0];
119 }
120
121 /* read an unsigned 1-byte unit */
122 inline jint read1u ()
123 {
124 skip (1);
125 return get1u (bytes+pos-1);
126 }
127
128 /* read an unsigned 2-byte unit */
129 inline static jint get2u (unsigned char *bytes)
130 {
131 return (((jint)bytes[0]) << 8) | ((jint)bytes[1]);
132 }
133
134 /* read an unsigned 2-byte unit */
135 inline jint read2u ()
136 {
137 skip (2);
138 return get2u (bytes+pos-2);
139 }
140
141 /* read a 4-byte unit */
142 static jint get4 (unsigned char *bytes)
143 {
144 return (((jint)bytes[0]) << 24)
145 | (((jint)bytes[1]) << 16)
146 | (((jint)bytes[2]) << 8)
147 | (((jint)bytes[3]) << 0);
148 }
149
150 /* read a 4-byte unit, (we don't do that quite so often) */
151 inline jint read4 ()
152 {
153 skip (4);
154 return get4 (bytes+pos-4);
155 }
156
157 /* read a 8-byte unit */
158 static jlong get8 (unsigned char* bytes)
159 {
160 return (((jlong)bytes[0]) << 56)
161 | (((jlong)bytes[1]) << 48)
162 | (((jlong)bytes[2]) << 40)
163 | (((jlong)bytes[3]) << 32)
164 | (((jlong)bytes[4]) << 24)
165 | (((jlong)bytes[5]) << 16)
166 | (((jlong)bytes[6]) << 8)
167 | (((jlong)bytes[7]) << 0);
168 }
169
170 /* read a 8-byte unit */
171 inline jlong read8 ()
172 {
173 skip (8);
174 return get8 (bytes+pos-8);
175 }
176
177 inline void check_tag (int index, char expected_tag)
178 {
179 if (index < 0
180 || index > pool_count
181 || tags[index] != expected_tag)
182 throw_class_format_error ("erroneous constant pool tag");
183 }
184
f9edddab
PB
185 inline void verify_identifier (_Jv_Utf8Const* name)
186 {
187 if (! _Jv_VerifyIdentifier (name))
188 throw_class_format_error ("erroneous identifier");
189 }
190
191 inline void verify_classname (unsigned char* ptr, _Jv_ushort length)
192 {
193 if (! _Jv_VerifyClassName (ptr, length))
194 throw_class_format_error ("erroneous class name");
195 }
196
197 inline void verify_classname (_Jv_Utf8Const *name)
198 {
199 if (! _Jv_VerifyClassName (name))
200 throw_class_format_error ("erroneous class name");
201 }
202
203 inline void verify_field_signature (_Jv_Utf8Const *sig)
204 {
205 if (! _Jv_VerifyFieldSignature (sig))
206 throw_class_format_error ("erroneous type descriptor");
207 }
208
209 inline void verify_method_signature (_Jv_Utf8Const *sig)
210 {
211 if (! _Jv_VerifyMethodSignature (sig))
212 throw_class_format_error ("erroneous type descriptor");
213 }
214
58eb6e7c
AG
215 _Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length)
216 {
217 if (klass == 0 || length < 0 || offset+length > data->length)
218 throw_internal_error ("arguments to _Jv_DefineClass");
219
220 verify = true;
221 bytes = (unsigned char*) (elements (data)+offset);
222 len = length;
223 pos = 0;
224 def = (_Jv_InterpClass*) klass;
225 }
226
227 /** and here goes the parser members defined out-of-line */
228 void parse ();
229 void read_constpool ();
230 void prepare_pool_entry (int index, unsigned char tag);
231 void read_fields ();
232 void read_methods ();
233 void read_one_class_attribute ();
234 void read_one_method_attribute (int method);
235 void read_one_code_attribute (int method);
236 void read_one_field_attribute (int field);
f9edddab 237 void throw_class_format_error (char *msg);
58eb6e7c
AG
238
239 /** check an utf8 entry, without creating a Utf8Const object */
240 bool is_attribute_name (int index, char *name);
241
242 /** here goes the class-loader members defined out-of-line */
243 void handleConstantPool ();
244 void handleClassBegin (int, int, int);
245 void handleInterfacesBegin (int);
246 void handleInterface (int, int);
247 void handleFieldsBegin (int);
248 void handleField (int, int, int, int);
249 void handleFieldsEnd ();
250 void handleConstantValueAttribute (int,int);
251 void handleMethodsBegin (int);
252 void handleMethod (int, int, int, int);
253 void handleMethodsEnd ();
254 void handleCodeAttribute (int, int, int, int, int, int);
255 void handleExceptionTableEntry (int, int, int, int, int, int);
256
257 void checkExtends (jclass sub, jclass super);
258 void checkImplements (jclass sub, jclass super);
259
260 /*
261 * FIXME: we should keep a hash table of utf8-strings, since many will
262 * be the same. It's a little tricky, however, because the hash table
263 * needs to interact gracefully with the garbage collector. Much
264 * memory is to be saved by this, however! perhaps the improvement
265 * could be implemented in prims.cc (_Jv_makeUtf8Const), since it
266 * computes the hash value anyway.
267 */
58eb6e7c
AG
268};
269
58eb6e7c
AG
270void
271_Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length)
272{
58eb6e7c
AG
273 _Jv_ClassReader reader (klass, data, offset, length);
274 reader.parse();
275
276 /* that's it! */
277}
278
58eb6e7c
AG
279\f
280/** This section defines the parsing/scanning of the class data */
281
282void
283_Jv_ClassReader::parse ()
284{
285 int magic = read4 ();
286
287 /* FIXME: Decide which range of version numbers to allow */
288
289 /* int minor_version = */ read2u ();
290 /* int major_verson = */ read2u ();
291
292 if (magic != (int) 0xCAFEBABE)
293 throw_class_format_error ("bad magic number");
294
295 pool_count = read2u ();
296
297 read_constpool ();
298
299 int access_flags = read2u ();
300 int this_class = read2u ();
301 int super_class = read2u ();
302
303 check_tag (this_class, JV_CONSTANT_Class);
304 if (super_class != 0)
305 check_tag (super_class, JV_CONSTANT_Class);
306
307 handleClassBegin (access_flags, this_class, super_class);
308
309 int interfaces_count = read2u ();
310
311 handleInterfacesBegin (interfaces_count);
312
313 for (int i = 0; i < interfaces_count; i++)
314 {
315 int iface = read2u ();
316 check_tag (iface, JV_CONSTANT_Class);
317 handleInterface (i, iface);
318 }
319
320 read_fields ();
321 read_methods ();
322
323 int attributes_count = read2u ();
324
325 for (int i = 0; i < attributes_count; i++)
326 {
327 read_one_class_attribute ();
328 }
329
330 if (pos != len)
331 throw_class_format_error ("unused data before end of file");
332
333 // tell everyone we're done.
334 def->state = JV_STATE_LOADED;
335 def->notifyAll ();
336
337}
338
339void _Jv_ClassReader::read_constpool ()
340{
3610e0d5
TT
341 tags = (unsigned char*) _Jv_AllocBytes (pool_count);
342 offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int)
58eb6e7c
AG
343 * pool_count) ;
344
345 /** first, we scan the constant pool, collecting tags and offsets */
346 tags[0] = JV_CONSTANT_Undefined;
347 offsets[0] = pos;
348 for (int c = 1; c < pool_count; c++)
349 {
350 tags[c] = read1u ();
351 offsets[c] = pos;
352
353 switch (tags[c])
354 {
355 case JV_CONSTANT_String:
356 case JV_CONSTANT_Class:
357 skip (2);
358 break;
359
360 case JV_CONSTANT_Fieldref:
361 case JV_CONSTANT_Methodref:
362 case JV_CONSTANT_InterfaceMethodref:
363 case JV_CONSTANT_NameAndType:
364 case JV_CONSTANT_Integer:
365 case JV_CONSTANT_Float:
366 skip (4);
367 break;
368
369 case JV_CONSTANT_Double:
370 case JV_CONSTANT_Long:
371 skip (8);
372 tags[++c] = JV_CONSTANT_Undefined;
373 break;
374
375 case JV_CONSTANT_Utf8:
376 {
377 int len = read2u ();
378 skip (len);
379 }
380 break;
381
382 case JV_CONSTANT_Unicode:
383 throw_class_format_error ("unicode not supported");
384 break;
385
386 default:
387 throw_class_format_error ("erroneous constant pool tag");
388 }
389 }
390
391 handleConstantPool ();
392}
393
394
395void _Jv_ClassReader::read_fields ()
396{
397 int fields_count = read2u ();
398 handleFieldsBegin (fields_count);
399
400 for (int i = 0; i < fields_count; i++)
401 {
402 int access_flags = read2u ();
403 int name_index = read2u ();
404 int descriptor_index = read2u ();
405 int attributes_count = read2u ();
a47c20a7 406
58eb6e7c
AG
407 check_tag (name_index, JV_CONSTANT_Utf8);
408 prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
409
410 check_tag (descriptor_index, JV_CONSTANT_Utf8);
411 prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
a47c20a7 412
58eb6e7c 413 handleField (i, access_flags, name_index, descriptor_index);
a47c20a7 414
58eb6e7c
AG
415 for (int j = 0; j < attributes_count; j++)
416 {
417 read_one_field_attribute (i);
418 }
419 }
420
421 handleFieldsEnd ();
422}
423
424bool
425_Jv_ClassReader::is_attribute_name (int index, char *name)
426{
427 check_tag (index, JV_CONSTANT_Utf8);
428 int len = get2u (bytes+offsets[index]);
429 if (len != (int) strlen (name))
430 return false;
431 else
432 return !memcmp (bytes+offsets[index]+2, name, len);
433}
434
435void _Jv_ClassReader::read_one_field_attribute (int field_index)
436{
437 int name = read2u ();
438 int length = read4 ();
439
440 if (is_attribute_name (name, "ConstantValue"))
441 {
442 int cv = read2u ();
443
444 if (cv < pool_count
445 && cv > 0
446 && (tags[cv] == JV_CONSTANT_Integer
447 || tags[cv] == JV_CONSTANT_Float
448 || tags[cv] == JV_CONSTANT_Long
449 || tags[cv] == JV_CONSTANT_Double
450 || tags[cv] == JV_CONSTANT_String))
451 {
452 handleConstantValueAttribute (field_index, cv);
453 }
454 else
455 {
456 throw_class_format_error ("erroneous ConstantValue attribute");
457 }
458
459 if (length != 2)
460 throw_class_format_error ("erroneous ConstantValue attribute");
461 }
462
463 else
464 {
465 skip (length);
466 }
467}
468
469void _Jv_ClassReader::read_methods ()
470{
471 int methods_count = read2u ();
472
473 handleMethodsBegin (methods_count);
474
475 for (int i = 0; i < methods_count; i++)
476 {
477 int access_flags = read2u ();
478 int name_index = read2u ();
479 int descriptor_index = read2u ();
480 int attributes_count = read2u ();
481
482 check_tag (name_index, JV_CONSTANT_Utf8);
483 prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
484
485 check_tag (name_index, JV_CONSTANT_Utf8);
486 prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
64d3a1b4 487
58eb6e7c
AG
488 handleMethod (i, access_flags, name_index,
489 descriptor_index);
64d3a1b4 490
58eb6e7c
AG
491 for (int j = 0; j < attributes_count; j++)
492 {
493 read_one_method_attribute (i);
494 }
495 }
496
497 handleMethodsEnd ();
498}
499
500void _Jv_ClassReader::read_one_method_attribute (int method_index)
501{
502 int name = read2u ();
503 int length = read4 ();
504
505 if (is_attribute_name (name, "Exceptions"))
506 {
224b7b7b
TT
507 _Jv_Method *method = reinterpret_cast<_Jv_Method *>
508 (&def->methods[method_index]);
509 if (method->throws != NULL)
510 throw_class_format_error ("only one Exceptions attribute allowed per method");
511
512 int num_exceptions = read2u ();
513 // We use malloc here because the GC won't scan the method
514 // objects. FIXME this means a memory leak if we GC a class.
515 // (Currently we never do.)
516 _Jv_Utf8Const **exceptions =
517 (_Jv_Utf8Const **) _Jv_Malloc ((num_exceptions + 1) * sizeof (_Jv_Utf8Const *));
518
519 int out = 0;
520 _Jv_word *pool_data = def->constants.data;
521 for (int i = 0; i < num_exceptions; ++i)
522 {
523 try
524 {
525 int ndx = read2u ();
526 // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
527 if (ndx != 0)
528 {
529 check_tag (ndx, JV_CONSTANT_Class);
530 exceptions[out++] = pool_data[ndx].utf8;
531 }
532 }
533 catch (java::lang::Throwable *exc)
534 {
535 _Jv_Free (exceptions);
536 throw exc;
537 }
538 }
539 exceptions[out] = NULL;
540 method->throws = exceptions;
58eb6e7c 541 }
224b7b7b 542
58eb6e7c
AG
543 else if (is_attribute_name (name, "Code"))
544 {
545 int start_off = pos;
546 int max_stack = read2u ();
547 int max_locals = read2u ();
548 int code_length = read4 ();
549
550 int code_start = pos;
551 skip (code_length);
552 int exception_table_length = read2u ();
553
554 handleCodeAttribute (method_index,
555 max_stack, max_locals,
556 code_start, code_length,
557 exception_table_length);
558
559
560 for (int i = 0; i < exception_table_length; i++)
561 {
562 int start_pc = read2u ();
563 int end_pc = read2u ();
564 int handler_pc = read2u ();
565 int catch_type = read2u ();
566
567 if (start_pc > end_pc
568 || start_pc < 0
ef9f3bc4
TT
569 // END_PC can be equal to CODE_LENGTH.
570 // See JVM Spec 4.7.4.
571 || end_pc > code_length
58eb6e7c
AG
572 || handler_pc >= code_length)
573 throw_class_format_error ("erroneous exception handler info");
574
575 if (! (tags[catch_type] == JV_CONSTANT_Class
576 || tags[catch_type] == 0))
577 {
578 throw_class_format_error ("erroneous exception handler info");
579 }
580
581 handleExceptionTableEntry (method_index,
582 i,
583 start_pc,
584 end_pc,
585 handler_pc,
586 catch_type);
587
588 }
589
590 int attributes_count = read2u ();
591
592 for (int i = 0; i < attributes_count; i++)
593 {
594 read_one_code_attribute (method_index);
595 }
596
597 if ((pos - start_off) != length)
598 throw_class_format_error ("code attribute too short");
599 }
600
601 else
602 {
603 /* ignore unknown attributes */
604 skip (length);
605 }
606}
607
608void _Jv_ClassReader::read_one_code_attribute (int /*method*/)
609{
610 /* ignore for now, ... later we may want to pick up
611 line number information, for debugging purposes;
612 in fact, the whole debugger issue is open! */
613
614 /* int name = */ read2u ();
615 int length = read4 ();
616 skip (length);
617
618}
619
620void _Jv_ClassReader::read_one_class_attribute ()
621{
622 /* we also ignore the class attributes, ...
623 some day we'll add inner-classes support. */
624
625 /* int name = */ read2u ();
626 int length = read4 ();
627 skip (length);
628}
629
630
631
632\f
633/* this section defines the semantic actions of the parser */
634
635void _Jv_ClassReader::handleConstantPool ()
636{
637 /** now, we actually define the class' constant pool */
638
639 // the pool is scanned explicitly by the collector
3610e0d5 640 jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
7941ceab 641 _Jv_word *pool_data
3610e0d5 642 = (_Jv_word*) _Jv_AllocBytes (pool_count * sizeof (_Jv_word));
58eb6e7c
AG
643
644 def->constants.tags = pool_tags;
645 def->constants.data = pool_data;
646 def->constants.size = pool_count;
647
648 // Here we make a pass to collect the strings! We do this, because
649 // internally in the GCJ runtime, classes are encoded with .'s not /'s.
650 // Therefore, we first collect the strings, and then translate the rest
651 // of the utf8-entries (thus not representing strings) from /-notation
652 // to .-notation.
653 for (int i = 1; i < pool_count; i++)
654 {
655 if (tags[i] == JV_CONSTANT_String)
656 {
657 unsigned char* str_data = bytes + offsets [i];
658 int utf_index = get2u (str_data);
659 check_tag (utf_index, JV_CONSTANT_Utf8);
660 unsigned char *utf_data = bytes + offsets[utf_index];
661 int len = get2u (utf_data);
7941ceab 662 pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
58eb6e7c
AG
663 pool_tags[i] = JV_CONSTANT_String;
664 }
665 else
666 {
667 pool_tags[i] = JV_CONSTANT_Undefined;
668 }
669 }
670
671 // and now, we scan everything else but strings & utf8-entries. This
672 // leaves out those utf8-entries which are not used; which will be left
673 // with a tag of JV_CONSTANT_Undefined in the class definition.
674 for (int index = 1; index < pool_count; index++)
675 {
676 switch (tags[index])
677 {
678 case JV_CONSTANT_Undefined:
679 case JV_CONSTANT_String:
680 case JV_CONSTANT_Utf8:
681 continue;
682
683 default:
684 prepare_pool_entry (index, tags[index]);
685 }
686 }
687
688}
689
690/* this is a recursive procedure, which will prepare pool entries as needed.
691 Which is how we avoid initializing those entries which go unused. */
692void
693_Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
694{
695 /* these two, pool_data and pool_tags, point into the class
696 structure we are currently defining */
697
698 unsigned char *pool_tags = (unsigned char*) def->constants.tags;
7941ceab 699 _Jv_word *pool_data = def->constants.data;
58eb6e7c
AG
700
701 /* this entry was already prepared */
702 if (pool_tags[index] == this_tag)
703 return;
704
705 /* this_data points to the constant-pool information for the current
706 constant-pool entry */
707
708 unsigned char *this_data = bytes + offsets[index];
709
710 switch (this_tag)
711 {
712 case JV_CONSTANT_Utf8:
713 {
714 // If we came here, it is because some other tag needs this
715 // utf8-entry for type information! Thus, we translate /'s to .'s in
716 // order to accomondate gcj's internal representation.
717
718 int len = get2u (this_data);
c2200099 719 char *buffer = (char*) __builtin_alloca (len);
58eb6e7c
AG
720 char *s = ((char*) this_data)+2;
721
722 /* FIXME: avoid using a buffer here */
723 for (int i = 0; i < len; i++)
724 {
725 if (s[i] == '/')
726 buffer[i] = '.';
727 else
728 buffer[i] = (char) s[i];
729 }
730
7941ceab 731 pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
58eb6e7c
AG
732 pool_tags[index] = JV_CONSTANT_Utf8;
733 }
734 break;
735
736 case JV_CONSTANT_Class:
737 {
738 int utf_index = get2u (this_data);
739 check_tag (utf_index, JV_CONSTANT_Utf8);
740 prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
741
742 if (verify)
f9edddab 743 verify_classname (pool_data[utf_index].utf8);
58eb6e7c 744
7941ceab 745 pool_data[index].utf8 = pool_data[utf_index].utf8;
58eb6e7c
AG
746 pool_tags[index] = JV_CONSTANT_Class;
747 }
748 break;
749
750 case JV_CONSTANT_String:
751 // already handled before...
752 break;
753
754 case JV_CONSTANT_Fieldref:
755 case JV_CONSTANT_Methodref:
756 case JV_CONSTANT_InterfaceMethodref:
757 {
758 int class_index = get2u (this_data);
759 int nat_index = get2u (this_data+2);
760
761 check_tag (class_index, JV_CONSTANT_Class);
762 prepare_pool_entry (class_index, JV_CONSTANT_Class);
763
764 check_tag (nat_index, JV_CONSTANT_NameAndType);
765 prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
766
767 // here, verify the signature and identifier name
768 if (verify)
769 {
770 _Jv_ushort name_index, type_index;
7941ceab 771 _Jv_loadIndexes (&pool_data[nat_index],
58eb6e7c
AG
772 name_index, type_index);
773
774 if (this_tag == JV_CONSTANT_Fieldref)
7941ceab 775 _Jv_VerifyFieldSignature (pool_data[type_index].utf8);
58eb6e7c 776 else
7941ceab 777 _Jv_VerifyMethodSignature (pool_data[type_index].utf8);
58eb6e7c 778
7941ceab 779 _Jv_Utf8Const* name = pool_data[name_index].utf8;
58eb6e7c
AG
780
781 if (this_tag != JV_CONSTANT_Fieldref
782 && ( _Jv_equalUtf8Consts (name, clinit_name)
783 || _Jv_equalUtf8Consts (name, init_name)))
784 /* ignore */;
785 else
f9edddab 786 verify_identifier (pool_data[name_index].utf8);
58eb6e7c
AG
787 }
788
789 _Jv_storeIndexes (&pool_data[index], class_index, nat_index);
790 pool_tags[index] = this_tag;
791 }
792 break;
793
794 case JV_CONSTANT_NameAndType:
795 {
796 _Jv_ushort name_index = get2u (this_data);
797 _Jv_ushort type_index = get2u (this_data+2);
798
799 check_tag (name_index, JV_CONSTANT_Utf8);
800 prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
801
802 check_tag (type_index, JV_CONSTANT_Utf8);
803 prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
804
805 _Jv_storeIndexes (&pool_data[index], name_index, type_index);
806 pool_tags[index] = JV_CONSTANT_NameAndType;
807 }
808 break;
809
810 case JV_CONSTANT_Float:
811 {
a12fe13d 812 jfloat f = java::lang::Float::intBitsToFloat ((jint) get4 (this_data));
58eb6e7c
AG
813 _Jv_storeFloat (&pool_data[index], f);
814 pool_tags[index] = JV_CONSTANT_Float;
815 }
816 break;
817
818 case JV_CONSTANT_Integer:
819 {
820 int i = get4 (this_data);
821 _Jv_storeInt (&pool_data[index], i);
822 pool_tags[index] = JV_CONSTANT_Integer;
823 }
824 break;
825
826 case JV_CONSTANT_Double:
827 {
a12fe13d
TT
828 jdouble d
829 = java::lang::Double::longBitsToDouble ((jlong) get8 (this_data));
58eb6e7c
AG
830 _Jv_storeDouble (&pool_data[index], d);
831 pool_tags[index] = JV_CONSTANT_Double;
832 }
833 break;
834
835 case JV_CONSTANT_Long:
836 {
837 jlong i = get8 (this_data);
838 _Jv_storeLong (&pool_data[index], i);
839 pool_tags[index] = JV_CONSTANT_Long;
840 }
841 break;
842
843 default:
844 throw_class_format_error ("erroneous constant pool tag");
845 }
846}
847
848
849void
850_Jv_ClassReader::handleClassBegin
851 (int access_flags, int this_class, int super_class)
852{
e409a2c8
TT
853 using namespace java::lang::reflect;
854
58eb6e7c 855 unsigned char *pool_tags = (unsigned char*) def->constants.tags;
7941ceab 856 _Jv_word *pool_data = def->constants.data;
58eb6e7c
AG
857
858 check_tag (this_class, JV_CONSTANT_Class);
7941ceab 859 _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
58eb6e7c
AG
860
861 // was ClassLoader.defineClass called with an expected class name?
862 if (def->name == 0)
863 {
864 jclass orig = _Jv_FindClassInCache (loadedName, def->loader);
865
866 if (orig == 0)
867 {
868 def->name = loadedName;
869 }
870 else
871 {
872 jstring msg = JvNewStringUTF ("anonymous "
873 "class data denotes "
874 "existing class ");
875 msg = msg->concat (orig->getName ());
876
877 throw_no_class_def_found_error (msg);
878 }
879 }
880
881 // assert that the loaded class has the expected name, 5.3.5
882 else if (! _Jv_equalUtf8Consts (loadedName, def->name))
883 {
884 jstring msg = JvNewStringUTF ("loaded class ");
885 msg = msg->concat (def->getName ());
886 msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
887 jstring klass_name = _Jv_NewStringUTF (loadedName->data);
888 msg = msg->concat (klass_name);
889
890 throw_no_class_def_found_error (msg);
891 }
892
a1aba4f9 893 def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
7941ceab 894 pool_data[this_class].clazz = def;
58eb6e7c
AG
895 pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
896
04a704a4 897 if (super_class == 0 && ! (access_flags & Modifier::INTERFACE))
58eb6e7c 898 {
58eb6e7c 899 // FIXME: Consider this carefully!
04a704a4
TT
900 if (! _Jv_equalUtf8Consts (def->name, java::lang::Object::class$.name))
901 throw_no_class_def_found_error ("loading java.lang.Object");
58eb6e7c
AG
902 }
903
904 // In the pre-loading state, it can be looked up in the
905 // cache only by this thread! This allows the super-class
906 // to include references to this class.
907
908 def->state = JV_STATE_PRELOADING;
107abb2f
BM
909
910 {
911 JvSynchronize sync (&java::lang::Class::class$);
912 _Jv_RegisterClass (def);
913 }
58eb6e7c
AG
914
915 if (super_class != 0)
916 {
04a704a4 917 // Load the superclass.
58eb6e7c 918 check_tag (super_class, JV_CONSTANT_Class);
7941ceab 919 _Jv_Utf8Const* super_name = pool_data[super_class].utf8;
58eb6e7c 920
04a704a4 921 // Load the superclass using our defining loader.
58eb6e7c
AG
922 jclass the_super = _Jv_FindClass (super_name,
923 def->loader);
924
925 // This will establish that we are allowed to be a subclass,
04a704a4 926 // and check for class circularity error.
58eb6e7c
AG
927 checkExtends (def, the_super);
928
04a704a4
TT
929 // Note: for an interface we will find Object as the
930 // superclass. We still check it above to ensure class file
931 // validity, but we simply assign `null' to the actual field in
932 // this case.
933 def->superclass = (((access_flags & Modifier::INTERFACE))
934 ? NULL : the_super);
7941ceab 935 pool_data[super_class].clazz = the_super;
58eb6e7c
AG
936 pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
937 }
6d8b1244 938
04a704a4
TT
939 // Now we've come past the circularity problem, we can
940 // now say that we're loading.
58eb6e7c
AG
941
942 def->state = JV_STATE_LOADING;
943 def->notifyAll ();
944}
945
946///// implements the checks described in sect. 5.3.5.3
947void
948_Jv_ClassReader::checkExtends (jclass sub, jclass super)
949{
e409a2c8
TT
950 using namespace java::lang::reflect;
951
58eb6e7c 952 // having an interface or a final class as a superclass is no good
e409a2c8 953 if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
58eb6e7c
AG
954 {
955 throw_incompatible_class_change_error (sub->getName ());
956 }
957
958 // if the super class is not public, we need to check some more
e409a2c8 959 if ((super->accflags & Modifier::PUBLIC) == 0)
58eb6e7c
AG
960 {
961 // With package scope, the classes must have the same
962 // class loader.
963 if ( sub->loader != super->loader
964 || !_Jv_ClassNameSamePackage (sub->name, super->name))
965 {
966 throw_incompatible_class_change_error (sub->getName ());
967 }
968 }
969
970 for (; super != 0; super = super->superclass)
971 {
972 if (super == sub)
973 throw_class_circularity_error (sub->getName ());
974 }
975}
976
977
978
979void _Jv_ClassReader::handleInterfacesBegin (int count)
980{
3610e0d5 981 def->interfaces = (jclass*) _Jv_AllocBytes (count*sizeof (jclass));
58eb6e7c
AG
982 def->interface_count = count;
983}
984
985void _Jv_ClassReader::handleInterface (int if_number, int offset)
986{
7941ceab 987 _Jv_word * pool_data = def->constants.data;
58eb6e7c
AG
988 unsigned char * pool_tags = (unsigned char*) def->constants.tags;
989
990 jclass the_interface;
991
992 if (pool_tags[offset] == JV_CONSTANT_Class)
993 {
7941ceab 994 _Jv_Utf8Const* name = pool_data[offset].utf8;
58eb6e7c
AG
995 the_interface = _Jv_FindClass (name, def->loader);
996 }
997 else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
998 {
7941ceab 999 the_interface = pool_data[offset].clazz;
58eb6e7c
AG
1000 }
1001 else
1002 {
1003 throw_no_class_def_found_error ("erroneous constant pool tag");
1004 }
1005
1006 // checks the validity of the_interface, and that we are in fact
1007 // allowed to implement that interface.
1008 checkImplements (def, the_interface);
1009
7941ceab 1010 pool_data[offset].clazz = the_interface;
58eb6e7c
AG
1011 pool_tags[offset] = JV_CONSTANT_ResolvedClass;
1012
1013 def->interfaces[if_number] = the_interface;
1014}
1015
1016void
1017_Jv_ClassReader::checkImplements (jclass sub, jclass super)
1018{
e409a2c8
TT
1019 using namespace java::lang::reflect;
1020
58eb6e7c 1021 // well, it *must* be an interface
e409a2c8 1022 if ((super->accflags & Modifier::INTERFACE) == 0)
58eb6e7c
AG
1023 {
1024 throw_incompatible_class_change_error (sub->getName ());
1025 }
1026
1027 // if it has package scope, it must also be defined by the
1028 // same loader.
e409a2c8 1029 if ((super->accflags & Modifier::PUBLIC) == 0)
58eb6e7c
AG
1030 {
1031 if ( sub->loader != super->loader
1032 || !_Jv_ClassNameSamePackage (sub->name, super->name))
1033 {
1034 throw_incompatible_class_change_error (sub->getName ());
1035 }
1036 }
1037
1038 // FIXME: add interface circularity check here
1039 if (sub == super)
1040 {
1041 throw_class_circularity_error (sub->getName ());
1042 }
1043}
1044
1045void _Jv_ClassReader::handleFieldsBegin (int count)
1046{
1047 def->fields = (_Jv_Field*)
3610e0d5 1048 _Jv_AllocBytes (count * sizeof (_Jv_Field));
58eb6e7c
AG
1049 def->field_count = count;
1050 def->field_initializers = (_Jv_ushort*)
3610e0d5 1051 _Jv_AllocBytes (count * sizeof (_Jv_ushort));
58eb6e7c
AG
1052 for (int i = 0; i < count; i++)
1053 def->field_initializers[i] = (_Jv_ushort) 0;
1054}
1055
1056void _Jv_ClassReader::handleField (int field_no,
1057 int flags,
1058 int name,
1059 int desc)
1060{
e409a2c8
TT
1061 using namespace java::lang::reflect;
1062
7941ceab 1063 _Jv_word *pool_data = def->constants.data;
58eb6e7c
AG
1064
1065 _Jv_Field *field = &def->fields[field_no];
7941ceab 1066 _Jv_Utf8Const *field_name = pool_data[name].utf8;
58eb6e7c
AG
1067
1068#ifndef COMPACT_FIELDS
1069 field->name = field_name;
1070#else
1071 field->nameIndex = name;
1072#endif
1073
a47c20a7 1074 // Ignore flags we don't know about.
e409a2c8 1075 field->flags = flags & Modifier::ALL_FLAGS;
58eb6e7c 1076
a47c20a7
TT
1077 _Jv_Utf8Const* sig = pool_data[desc].utf8;
1078
58eb6e7c
AG
1079 if (verify)
1080 {
a47c20a7
TT
1081 verify_identifier (field_name);
1082
1083 for (int i = 0; i < field_no; ++i)
1084 {
1085 if (_Jv_equalUtf8Consts (field_name, def->fields[i].name)
1086 && _Jv_equalUtf8Consts (sig,
1087 // We know the other fields are
1088 // unresolved.
1089 (_Jv_Utf8Const *) def->fields[i].type))
1090 throw_class_format_error ("duplicate field name");
1091 }
1092
e409a2c8
TT
1093 if (field->flags & (Modifier::SYNCHRONIZED
1094 | Modifier::NATIVE
1095 | Modifier::INTERFACE
1096 | Modifier::ABSTRACT))
58eb6e7c
AG
1097 throw_class_format_error ("erroneous field access flags");
1098
e409a2c8
TT
1099 if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
1100 +((field->flags & Modifier::PRIVATE) ? 1 : 0)
1101 +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
58eb6e7c
AG
1102 throw_class_format_error ("erroneous field access flags");
1103 }
1104
58eb6e7c
AG
1105 if (verify)
1106 _Jv_VerifyFieldSignature (sig);
1107
1108 // field->type is really a jclass, but while it is still
1109 // unresolved we keep an _Jv_Utf8Const* instead.
1110 field->type = (jclass) sig;
1111 field->flags |= _Jv_FIELD_UNRESOLVED_FLAG;
1112 field->u.boffset = 0;
1113}
1114
1115
1116void _Jv_ClassReader::handleConstantValueAttribute (int field_index,
1117 int value)
1118{
e409a2c8
TT
1119 using namespace java::lang::reflect;
1120
58eb6e7c
AG
1121 _Jv_Field *field = &def->fields[field_index];
1122
e409a2c8
TT
1123 if ((field->flags & (Modifier::STATIC
1124 | Modifier::FINAL
1125 | Modifier::PRIVATE)) == 0)
58eb6e7c
AG
1126 {
1127 // Ignore, as per vmspec #4.7.2
1128 return;
1129 }
1130
1131 // do not allow multiple constant fields!
1132 if (field->flags & _Jv_FIELD_CONSTANT_VALUE)
1133 throw_class_format_error ("field has multiple ConstantValue attributes");
1134
1135 field->flags |= _Jv_FIELD_CONSTANT_VALUE;
1136 def->field_initializers[field_index] = value;
1137
1138 /* type check the initializer */
1139
1140 if (value <= 0 || value >= pool_count)
1141 throw_class_format_error ("erroneous ConstantValue attribute");
1142
1143 /* FIXME: do the rest */
1144}
1145
1146void _Jv_ClassReader::handleFieldsEnd ()
1147{
e409a2c8
TT
1148 using namespace java::lang::reflect;
1149
58eb6e7c
AG
1150 // We need to reorganize the fields so that the static ones are first,
1151 // to conform to GCJ class layout.
1152
1153 int low = 0;
1154 int high = def->field_count-1;
1155 _Jv_Field *fields = def->fields;
1156 _Jv_ushort *inits = def->field_initializers;
1157
1158 // this is kind of a raw version of quicksort.
1159 while (low < high)
1160 {
1161 // go forward on low, while it's a static
e409a2c8 1162 while (low < high && (fields[low].flags & Modifier::STATIC) != 0)
58eb6e7c
AG
1163 low++;
1164
1165 // go backwards on high, while it's a non-static
e409a2c8 1166 while (low < high && (fields[high].flags & Modifier::STATIC) == 0)
58eb6e7c
AG
1167 high--;
1168
1169 if (low==high)
1170 break;
1171
1172 _Jv_Field tmp = fields[low];
1173 _Jv_ushort itmp = inits[low];
1174
1175 fields[low] = fields[high];
1176 inits[low] = inits[high];
1177
1178 fields[high] = tmp;
1179 inits[high] = itmp;
1180
1181 high -= 1;
1182 low += 1;
1183 }
1184
e409a2c8 1185 if ((fields[low].flags & Modifier::STATIC) != 0)
58eb6e7c
AG
1186 low += 1;
1187
1188 def->static_field_count = low;
1189}
1190
1191
1192
facc279f
TT
1193void
1194_Jv_ClassReader::handleMethodsBegin (int count)
58eb6e7c 1195{
eaa2834f 1196 def->methods = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method) * count);
58eb6e7c 1197
facc279f 1198 def->interpreted_methods
3610e0d5
TT
1199 = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
1200 * count);
58eb6e7c
AG
1201
1202 for (int i = 0; i < count; i++)
eaa2834f
TT
1203 {
1204 def->interpreted_methods[i] = 0;
1205 def->methods[i].index = (_Jv_ushort) -1;
1206 }
58eb6e7c
AG
1207
1208 def->method_count = count;
1209}
1210
1211
1212void _Jv_ClassReader::handleMethod
1213 (int mth_index, int accflags, int name, int desc)
1214{
e409a2c8
TT
1215 using namespace java::lang::reflect;
1216
7941ceab 1217 _Jv_word *pool_data = def->constants.data;
58eb6e7c
AG
1218 _Jv_Method *method = &def->methods[mth_index];
1219
1220 check_tag (name, JV_CONSTANT_Utf8);
1221 prepare_pool_entry (name, JV_CONSTANT_Utf8);
7941ceab 1222 method->name = pool_data[name].utf8;
58eb6e7c
AG
1223
1224 check_tag (desc, JV_CONSTANT_Utf8);
1225 prepare_pool_entry (desc, JV_CONSTANT_Utf8);
7941ceab 1226 method->signature = pool_data[desc].utf8;
58eb6e7c
AG
1227
1228 // ignore unknown flags
e409a2c8 1229 method->accflags = accflags & Modifier::ALL_FLAGS;
58eb6e7c
AG
1230
1231 // intialize...
1232 method->ncode = 0;
224b7b7b 1233 method->throws = NULL;
58eb6e7c
AG
1234
1235 if (verify)
1236 {
1237 if (_Jv_equalUtf8Consts (method->name, clinit_name)
1238 || _Jv_equalUtf8Consts (method->name, init_name))
1239 /* ignore */;
1240 else
f9edddab 1241 verify_identifier (method->name);
58eb6e7c
AG
1242
1243 _Jv_VerifyMethodSignature (method->signature);
1244
a47c20a7
TT
1245 for (int i = 0; i < mth_index; ++i)
1246 {
1247 if (_Jv_equalUtf8Consts (method->name, def->methods[i].name)
1248 && _Jv_equalUtf8Consts (method->signature,
1249 def->methods[i].signature))
1250 throw_class_format_error ("duplicate method");
1251 }
1252
e409a2c8
TT
1253 if (method->accflags & (Modifier::VOLATILE
1254 | Modifier::TRANSIENT
1255 | Modifier::INTERFACE))
58eb6e7c
AG
1256 throw_class_format_error ("erroneous method access flags");
1257
e409a2c8
TT
1258 if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
1259 +((method->accflags & Modifier::PRIVATE) ? 1 : 0)
1260 +((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
58eb6e7c
AG
1261 throw_class_format_error ("erroneous method access flags");
1262 }
1263}
1264
1265void _Jv_ClassReader::handleCodeAttribute
1266 (int method_index, int max_stack, int max_locals,
1267 int code_start, int code_length, int exc_table_length)
1268{
1269 int size = _Jv_InterpMethod::size (exc_table_length, code_length);
1270 _Jv_InterpMethod *method =
3610e0d5 1271 (_Jv_InterpMethod*) (_Jv_AllocBytes (size));
58eb6e7c 1272
90471585 1273 method->deferred = NULL;
58eb6e7c
AG
1274 method->max_stack = max_stack;
1275 method->max_locals = max_locals;
1276 method->code_length = code_length;
1277 method->exc_count = exc_table_length;
1278 method->defining_class = def;
1279 method->self = &def->methods[method_index];
fdae83ab 1280 method->prepared = NULL;
58eb6e7c
AG
1281
1282 // grab the byte code!
1283 memcpy ((void*) method->bytecode (),
1284 (void*) (bytes+code_start),
1285 code_length);
a12fe13d 1286
58eb6e7c 1287 def->interpreted_methods[method_index] = method;
4c98b1b0
TT
1288
1289 if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
1290 {
1291 // Precompute the ncode field for a static method. This lets us
1292 // call a static method of an interpreted class from precompiled
1293 // code without first resolving the class (that will happen
1294 // during class initialization instead).
1295 method->self->ncode = method->ncode ();
1296 }
58eb6e7c
AG
1297}
1298
fdae83ab 1299void _Jv_ClassReader::handleExceptionTableEntry
58eb6e7c
AG
1300 (int method_index, int exc_index,
1301 int start_pc, int end_pc, int handler_pc, int catch_type)
1302{
facc279f
TT
1303 _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1304 (def->interpreted_methods[method_index]);
58eb6e7c
AG
1305 _Jv_InterpException *exc = method->exceptions ();
1306
fdae83ab
TT
1307 exc[exc_index].start_pc.i = start_pc;
1308 exc[exc_index].end_pc.i = end_pc;
1309 exc[exc_index].handler_pc.i = handler_pc;
1310 exc[exc_index].handler_type.i = catch_type;
58eb6e7c
AG
1311}
1312
1313void _Jv_ClassReader::handleMethodsEnd ()
1314{
e409a2c8
TT
1315 using namespace java::lang::reflect;
1316
58eb6e7c
AG
1317 for (int i = 0; i < def->method_count; i++)
1318 {
1319 _Jv_Method *method = &def->methods[i];
facc279f
TT
1320 if ((method->accflags & Modifier::NATIVE) != 0)
1321 {
1322 if (def->interpreted_methods[i] != 0)
1323 throw_class_format_error ("code provided for native method");
1324 else
1325 {
1326 _Jv_JNIMethod *m = (_Jv_JNIMethod *)
3610e0d5 1327 _Jv_AllocBytes (sizeof (_Jv_JNIMethod));
facc279f
TT
1328 m->defining_class = def;
1329 m->self = method;
1330 m->function = NULL;
1331 def->interpreted_methods[i] = m;
90471585 1332 m->deferred = NULL;
4c98b1b0
TT
1333
1334 if ((method->accflags & Modifier::STATIC))
1335 {
1336 // Precompute the ncode field for a static method.
1337 // This lets us call a static method of an
1338 // interpreted class from precompiled code without
1339 // first resolving the class (that will happen
1340 // during class initialization instead).
1341 method->ncode = m->ncode ();
1342 }
facc279f
TT
1343 }
1344 }
1345 else if ((method->accflags & Modifier::ABSTRACT) != 0)
58eb6e7c
AG
1346 {
1347 if (def->interpreted_methods[i] != 0)
facc279f 1348 throw_class_format_error ("code provided for abstract method");
58eb6e7c
AG
1349 }
1350 else
1351 {
1352 if (def->interpreted_methods[i] == 0)
facc279f 1353 throw_class_format_error ("method with no code");
58eb6e7c
AG
1354 }
1355 }
58eb6e7c
AG
1356}
1357
f9edddab
PB
1358void _Jv_ClassReader::throw_class_format_error (char *msg)
1359{
1360 jstring str;
1361 if (def->name != NULL)
1362 {
1363 jsize mlen = strlen (msg);
1364 unsigned char* data = (unsigned char*) def->name->data;
1365 int ulen = def->name->length;
1366 unsigned char* limit = data + ulen;
1367 jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
1368 jsize len = nlen + mlen + 3;
1369 str = JvAllocString(len);
1370 jchar *chrs = JvGetStringChars(str);
1371 while (data < limit)
1372 *chrs++ = UTF8_GET(data, limit);
1373 *chrs++ = ' ';
1374 *chrs++ = '(';
1375 for (;;)
1376 {
1377 char c = *msg++;
1378 if (c == 0)
1379 break;
1380 *chrs++ = c & 0xFFFF;
1381 }
1382 *chrs++ = ')';
1383 }
1384 else
1385 str = JvNewStringLatin1 (msg);
1386 ::throw_class_format_error (str);
1387}
58eb6e7c 1388\f
bea31ffb
TT
1389/** Here we define the exceptions that can be thrown */
1390
1391static void
1392throw_no_class_def_found_error (jstring msg)
1393{
1394 throw (msg
1395 ? new java::lang::NoClassDefFoundError (msg)
1396 : new java::lang::NoClassDefFoundError);
1397}
1398
1399static void
1400throw_no_class_def_found_error (char *msg)
1401{
1402 throw_no_class_def_found_error (JvNewStringLatin1 (msg));
1403}
1404
1405static void
1406throw_class_format_error (jstring msg)
1407{
1408 throw (msg
1409 ? new java::lang::ClassFormatError (msg)
1410 : new java::lang::ClassFormatError);
1411}
1412
1413static void
1414throw_internal_error (char *msg)
1415{
1416 throw new java::lang::InternalError (JvNewStringLatin1 (msg));
1417}
1418
eaa2834f
TT
1419static void
1420throw_incompatible_class_change_error (jstring msg)
bea31ffb
TT
1421{
1422 throw new java::lang::IncompatibleClassChangeError (msg);
1423}
1424
eaa2834f
TT
1425static void
1426throw_class_circularity_error (jstring msg)
bea31ffb
TT
1427{
1428 throw new java::lang::ClassCircularityError (msg);
1429}
1430
1431#endif /* INTERPRETER */
1432
1433\f
1434
58eb6e7c
AG
1435/** This section takes care of verifying integrity of identifiers,
1436 signatures, field ddescriptors, and class names */
1437
1438#define UTF8_PEEK(PTR, LIMIT) \
1439 ({ unsigned char* xxkeep = (PTR); \
1440 int xxch = UTF8_GET(PTR,LIMIT); \
1441 PTR = xxkeep; xxch; })
1442
bea31ffb 1443/* Verify one element of a type descriptor or signature. */
58eb6e7c
AG
1444static unsigned char*
1445_Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
1446{
1447 if (ptr >= limit)
1448 return 0;
1449
1450 int ch = UTF8_GET (ptr, limit);
1451
1452 switch (ch)
1453 {
1454 case 'V':
bea31ffb
TT
1455 if (! void_ok)
1456 return 0;
58eb6e7c
AG
1457
1458 case 'S': case 'B': case 'I': case 'J':
1459 case 'Z': case 'C': case 'F': case 'D':
1460 break;
1461
1462 case 'L':
1463 {
1464 unsigned char *start = ptr, *end;
bea31ffb
TT
1465 do
1466 {
1467 if (ptr > limit)
1468 return 0;
1469
1470 end = ptr;
1471
1472 if ((ch = UTF8_GET (ptr, limit)) == -1)
1473 return 0;
1474
1475 }
1476 while (ch != ';');
f9edddab
PB
1477 if (! _Jv_VerifyClassName (start, (unsigned short) (end-start)))
1478 return 0;
58eb6e7c
AG
1479 }
1480 break;
1481
1482 case '[':
1483 return _Jv_VerifyOne (ptr, limit, false);
1484 break;
bea31ffb 1485
58eb6e7c
AG
1486 default:
1487 return 0;
1488 }
1489
1490 return ptr;
58eb6e7c
AG
1491}
1492
bea31ffb 1493/* Verification and loading procedures. */
f9edddab 1494bool
58eb6e7c
AG
1495_Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
1496{
1497 unsigned char* ptr = (unsigned char*) sig->data;
1498 unsigned char* limit = ptr + sig->length;
1499
1500 ptr = _Jv_VerifyOne (ptr, limit, false);
1501
f9edddab 1502 return ptr == limit;
58eb6e7c
AG
1503}
1504
f9edddab 1505bool
58eb6e7c
AG
1506_Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
1507{
1508 unsigned char* ptr = (unsigned char*) sig->data;
1509 unsigned char* limit = ptr + sig->length;
1510
f9edddab
PB
1511 if (ptr == limit || UTF8_GET(ptr,limit) != '(')
1512 return false;
58eb6e7c
AG
1513
1514 while (ptr && UTF8_PEEK (ptr, limit) != ')')
1515 ptr = _Jv_VerifyOne (ptr, limit, false);
bea31ffb 1516
58eb6e7c 1517 if (UTF8_GET (ptr, limit) != ')')
f9edddab 1518 return false;
58eb6e7c
AG
1519
1520 // get the return type
1521 ptr = _Jv_VerifyOne (ptr, limit, true);
1522
f9edddab 1523 return ptr == limit;
58eb6e7c
AG
1524}
1525
bea31ffb
TT
1526/* We try to avoid calling the Character methods all the time, in
1527 fact, they will only be called for non-standard things. */
58eb6e7c
AG
1528static __inline__ int
1529is_identifier_start (int c)
1530{
1531 unsigned int ch = (unsigned)c;
1532
1533 if ((ch - 0x41U) < 29U) /* A ... Z */
1534 return 1;
1535 if ((ch - 0x61U) < 29U) /* a ... z */
1536 return 1;
1537 if (ch == 0x5FU) /* _ */
1538 return 1;
1539
82ae7822 1540 return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
58eb6e7c
AG
1541}
1542
1543static __inline__ int
1544is_identifier_part (int c)
1545{
1546 unsigned int ch = (unsigned)c;
1547
1548 if ((ch - 0x41U) < 29U) /* A ... Z */
1549 return 1;
1550 if ((ch - 0x61U) < 29U) /* a ... z */
1551 return 1;
1552 if ((ch - 0x30) < 10U) /* 0 .. 9 */
1553 return 1;
1554 if (ch == 0x5FU || ch == 0x24U) /* _ $ */
1555 return 1;
1556
82ae7822 1557 return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
58eb6e7c
AG
1558}
1559
f9edddab 1560bool
58eb6e7c
AG
1561_Jv_VerifyIdentifier (_Jv_Utf8Const* name)
1562{
1563 unsigned char *ptr = (unsigned char*) name->data;
1564 unsigned char *limit = ptr + name->length;
1565 int ch;
1566
1567 if ((ch = UTF8_GET (ptr, limit))==-1
1568 || ! is_identifier_start (ch))
f9edddab 1569 return false;
58eb6e7c
AG
1570
1571 while (ptr != limit)
1572 {
1573 if ((ch = UTF8_GET (ptr, limit))==-1
1574 || ! is_identifier_part (ch))
f9edddab 1575 return false;
58eb6e7c 1576 }
f9edddab 1577 return true;
58eb6e7c
AG
1578}
1579
f9edddab 1580bool
58eb6e7c
AG
1581_Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
1582{
1583 unsigned char *limit = ptr+length;
1584 int ch;
1585
e3253af5
AG
1586 if ('[' == UTF8_PEEK (ptr, limit))
1587 {
bea31ffb
TT
1588 unsigned char *end = _Jv_VerifyOne (++ptr, limit, false);
1589 // _Jv_VerifyOne must leave us looking at the terminating nul
1590 // byte.
1591 if (! end || *end)
f9edddab 1592 return false;
e3253af5 1593 else
f9edddab 1594 return true;
e3253af5
AG
1595 }
1596
58eb6e7c 1597 next_level:
f9edddab 1598 for (;;) {
58eb6e7c 1599 if ((ch = UTF8_GET (ptr, limit))==-1)
f9edddab 1600 return false;
58eb6e7c 1601 if (! is_identifier_start (ch))
f9edddab
PB
1602 return false;
1603 for (;;) {
58eb6e7c 1604 if (ptr == limit)
f9edddab 1605 return true;
58eb6e7c 1606 else if ((ch = UTF8_GET (ptr, limit))==-1)
f9edddab 1607 return false;
58eb6e7c
AG
1608 else if (ch == '.')
1609 goto next_level;
1610 else if (! is_identifier_part (ch))
f9edddab
PB
1611 return false;
1612 }
1613 }
58eb6e7c
AG
1614}
1615
f9edddab 1616bool
58eb6e7c
AG
1617_Jv_VerifyClassName (_Jv_Utf8Const *name)
1618{
f9edddab
PB
1619 return _Jv_VerifyClassName ((unsigned char*)&name->data[0],
1620 (_Jv_ushort) name->length);
58eb6e7c
AG
1621}
1622
bea31ffb
TT
1623/* Returns true, if NAME1 and NAME2 represent classes in the same
1624 package. */
58eb6e7c
AG
1625bool
1626_Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
1627{
1628 unsigned char* ptr1 = (unsigned char*) name1->data;
1629 unsigned char* limit1 = ptr1 + name1->length;
1630
1631 unsigned char* last1 = ptr1;
1632
1633 // scan name1, and find the last occurrence of '.'
1634 while (ptr1 < limit1) {
1635 int ch1 = UTF8_GET (ptr1, limit1);
1636
1637 if (ch1 == '.')
1638 last1 = ptr1;
bea31ffb 1639
58eb6e7c
AG
1640 else if (ch1 == -1)
1641 return false;
1642 }
1643
bea31ffb 1644 // Now the length of NAME1's package name is LEN.
58eb6e7c
AG
1645 int len = last1 - (unsigned char*) name1->data;
1646
bea31ffb 1647 // If this is longer than NAME2, then we're off.
58eb6e7c
AG
1648 if (len > name2->length)
1649 return false;
1650
bea31ffb 1651 // Then compare the first len bytes for equality.
58eb6e7c
AG
1652 if (memcmp ((void*) name1->data, (void*) name2->data, len) == 0)
1653 {
bea31ffb 1654 // Check that there are no .'s after position LEN in NAME2.
58eb6e7c
AG
1655
1656 unsigned char* ptr2 = (unsigned char*) name2->data + len;
1657 unsigned char* limit2 =
1658 (unsigned char*) name2->data + name2->length;
1659
1660 while (ptr2 < limit2)
1661 {
1662 int ch2 = UTF8_GET (ptr2, limit2);
1663 if (ch2 == -1 || ch2 == '.')
1664 return false;
1665 }
1666 return true;
1667 }
1668 return false;
1669}
This page took 0.521736 seconds and 5 git commands to generate.