OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [defineclass.cc] - Blame information for rev 848

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.