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