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