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