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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [defineclass.cc] - Blame information for rev 22

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

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

powered by: WebSVN 2.1.0

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