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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [java/] [lang/] [natClassLoader.cc] - Blame information for rev 758

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 758 jeremybenn
// natClassLoader.cc - Implementation of java.lang.ClassLoader native methods.
2
 
3
/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008  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
/* Author: Kresten Krab Thorup <krab@gnu.org>  */
12
 
13
#include <config.h>
14
 
15
#include <stdlib.h>
16
#include <stdio.h>
17
#include <string.h>
18
 
19
#include <gcj/cni.h>
20
#include <jvm.h>
21
#include <execution.h>
22
 
23
#include <java-threads.h>
24
#include <java-interp.h>
25
 
26
#include <java/lang/Character.h>
27
#include <java/lang/Thread.h>
28
#include <java/lang/ClassLoader.h>
29
#include <java/lang/InternalError.h>
30
#include <java/lang/IllegalAccessError.h>
31
#include <java/lang/LinkageError.h>
32
#include <java/lang/NoClassDefFoundError.h>
33
#include <java/lang/ClassNotFoundException.h>
34
#include <java/lang/ClassCircularityError.h>
35
#include <java/lang/IncompatibleClassChangeError.h>
36
#include <java/lang/ClassFormatError.h>
37
#include <java/lang/VirtualMachineError.h>
38
#include <java/lang/VMClassLoader.h>
39
#include <java/lang/reflect/Modifier.h>
40
#include <java/lang/Runtime.h>
41
#include <java/lang/StringBuffer.h>
42
#include <java/io/Serializable.h>
43
#include <java/lang/Cloneable.h>
44
#include <java/lang/ref/WeakReference.h>
45
#include <java/util/HashMap.h>
46
#include <gnu/gcj/runtime/BootClassLoader.h>
47
#include <gnu/gcj/runtime/SystemClassLoader.h>
48
 
49
// Size of local hash table.
50
#define HASH_LEN 1013
51
 
52
// Hash function for Utf8Consts.
53
#define HASH_UTF(Utf) ((Utf)->hash16() % HASH_LEN)
54
 
55
// This records classes which will be registered with the system class
56
// loader when it is initialized.
57
static jclass system_class_list;
58
 
59
// This is used as the value of system_class_list after we have
60
// initialized the system class loader; it lets us know that we should
61
// no longer pay attention to the system abi flag.
62
#define SYSTEM_LOADER_INITIALIZED ((jclass) -1)
63
 
64
static jclass loaded_classes[HASH_LEN];
65
 
66
// This is the root of a linked list of classes
67
static jclass stack_head;
68
 
69
// While bootstrapping we keep a list of classes we found, so that we
70
// can register their packages.  There aren't many of these so we
71
// just keep a small buffer here and abort if we overflow.
72
#define BOOTSTRAP_CLASS_LIST_SIZE 20
73
static jclass bootstrap_class_list[BOOTSTRAP_CLASS_LIST_SIZE];
74
static int bootstrap_index;
75
 
76
 
77
 
78
 
79
jclass
80
java::lang::ClassLoader::loadClassFromSig(jstring name)
81
{
82
  int len = _Jv_GetStringUTFLength (name);
83
  char sig[len + 1];
84
  _Jv_GetStringUTFRegion (name, 0, name->length(), sig);
85
  jclass result = _Jv_FindClassFromSignature(sig, this);
86
  if (result == NULL)
87
    throw new ClassNotFoundException(name);
88
  return result;
89
}
90
 
91
 
92
 
93
// This tries to find a class in our built-in cache.  This cache is
94
// used only for classes which are linked in to the executable or
95
// loaded via dlopen().
96
jclass
97
_Jv_FindClassInCache (_Jv_Utf8Const *name)
98
{
99
  JvSynchronize sync (&java::lang::Class::class$);
100
  jint hash = HASH_UTF (name);
101
 
102
  jclass klass;
103
  for (klass = loaded_classes[hash]; klass; klass = klass->next_or_version)
104
    {
105
      if (_Jv_equalUtf8Consts (name, klass->name))
106
        break;
107
    }
108
 
109
  return klass;
110
}
111
 
112
void
113
_Jv_UnregisterClass (jclass the_class)
114
{
115
  // This can happen if the class could not be defined properly.
116
  if (! the_class->name)
117
    return;
118
 
119
  JvSynchronize sync (&java::lang::Class::class$);
120
  jint hash = HASH_UTF(the_class->name);
121
 
122
  jclass *klass = &(loaded_classes[hash]);
123
  for ( ; *klass; klass = &((*klass)->next_or_version))
124
    {
125
      if (*klass == the_class)
126
        {
127
          *klass = (*klass)->next_or_version;
128
          break;
129
        }
130
    }
131
}
132
 
133
// Register an initiating class loader for a given class.
134
void
135
_Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
136
{
137
  if (! loader)
138
    loader = java::lang::VMClassLoader::bootLoader;
139
  if (! loader)
140
    {
141
      // Very early in the bootstrap process, the Bootstrap classloader may 
142
      // not exist yet.
143
      // FIXME: We could maintain a list of these and come back and register
144
      // them later.
145
      return;
146
    }
147
 
148
  JvSynchronize sync (loader->loadingConstraints);
149
 
150
  using namespace java::lang::ref;
151
 
152
  jstring name = klass->getName();
153
  WeakReference *ref = (WeakReference *) loader->loadingConstraints->get (name);
154
  if (ref)
155
    {
156
      jclass constraint = (jclass) ref->get();
157
      if (constraint && constraint != klass)
158
        throw new java::lang::LinkageError(JvNewStringLatin1("loading constraint violated"));
159
    }
160
  loader->loadingConstraints->put(name, new WeakReference(klass));
161
  loader->loadedClasses->put(name, klass);
162
}
163
 
164
// If we found an error while defining an interpreted class, we must
165
// go back and unregister it.
166
void
167
_Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
168
{
169
  if (! loader)
170
    loader = java::lang::VMClassLoader::bootLoader;
171
  loader->loadedClasses->remove(klass->name->toString());
172
}
173
 
174
// Check a loading constraint.  In particular check that, if there is
175
// a constraint for the name of KLASS in LOADER, that it maps to
176
// KLASS.  If there is no such constraint, make a new one.  If the
177
// constraint is violated, throw an exception.  Do nothing for
178
// primitive types.
179
void
180
_Jv_CheckOrCreateLoadingConstraint (jclass klass,
181
                                    java::lang::ClassLoader *loader)
182
{
183
  // Strip arrays.
184
  while (klass->isArray())
185
    klass = klass->getComponentType();
186
  // Ignore primitive types.
187
  if (klass->isPrimitive())
188
    return;
189
 
190
  if (! loader)
191
    loader = java::lang::VMClassLoader::bootLoader;
192
  jstring name = klass->getName();
193
 
194
  JvSynchronize sync (loader->loadingConstraints);
195
 
196
  using namespace java::lang::ref;
197
 
198
  WeakReference *ref = (WeakReference *) loader->loadingConstraints->get (name);
199
  if (ref)
200
    {
201
      jclass constraint = (jclass) ref->get();
202
      if (constraint)
203
        {
204
          if (klass != constraint)
205
            throw new java::lang::LinkageError(JvNewStringLatin1("loading constraint violated"));
206
          // Otherwise, all is ok.
207
          return;
208
        }
209
    }
210
  // No constraint (or old constraint GC'd).  Make a new one.
211
  loader->loadingConstraints->put(name, new WeakReference(klass));
212
}
213
 
214
 
215
// Class registration.
216
//
217
// There are two kinds of functions that register classes.  
218
//
219
// Type 1:
220
//
221
// These take the address of a class that is in an object file.
222
// Because these classes are not allocated on the heap, It is also
223
// necessary to register the address of the object for garbage
224
// collection.  This is used with the "old" C++ ABI and with
225
// -findirect-dispatch -fno-indirect-classes.
226
//
227
// Type 2:
228
//
229
// These take an initializer struct, create the class, and return the
230
// address of the newly created class to their caller.  These are used
231
// with -findirect-dispatch.
232
//
233
// _Jv_RegisterClasses() and _Jv_RegisterClasses_Counted() are
234
// functions of Type 1, and _Jv_NewClassFromInitializer() and
235
// _Jv_RegisterNewClasses() are of Type 2.
236
 
237
 
238
// Check that the file we're trying to load has been compiled with a
239
// compatible version of gcj.  In previous versions of libgcj we
240
// silently failed to register classes of an incompatible ABI version,
241
// but this was totally bogus.
242
void
243
_Jv_CheckABIVersion (unsigned long value)
244
{
245
  // We are compatible with GCJ 4.0.0 BC-ABI classes. This release used a
246
  // different format for the version ID string.
247
   if (value == OLD_GCJ_40_BC_ABI_VERSION)
248
     return;
249
 
250
  // The 20 low-end bits are used for the version number.
251
  unsigned long version = value & 0xfffff;
252
 
253
  if (value & FLAG_BINARYCOMPAT_ABI)
254
    {
255
      int abi_rev = version % 100;
256
      int abi_ver = version - abi_rev;
257
      // We are compatible with abi_rev 0 and 1.
258
      if (abi_ver == GCJ_40_BC_ABI_VERSION && abi_rev <= 1)
259
        return;
260
    }
261
  else
262
    {
263
      // C++ ABI
264
      if (version == GCJ_CXX_ABI_VERSION)
265
        return;
266
 
267
      // If we've loaded a library that uses the C++ ABI, and this
268
      // library is an incompatible version, then we're dead.  There's
269
      // no point throwing an exception: that will crash.
270
      JvFail ("gcj linkage error.\n"
271
              "Incorrect library ABI version detected.  Aborting.\n");
272
    }
273
 
274
  throw new ::java::lang::ClassFormatError
275
    (JvNewStringLatin1 ("Library compiled with later ABI version than"
276
                        " this version of libgcj supports"));
277
}
278
 
279
// This function is called many times during startup, before main() is
280
// run.  At that point in time we know for certain we are running 
281
// single-threaded, so we don't need to lock when adding classes to the 
282
// class chain.  At all other times, the caller should synchronize on
283
// Class::class$.
284
void
285
_Jv_RegisterClasses (const jclass *classes)
286
{
287
  _Jv_RegisterLibForGc (classes);
288
 
289
  for (; *classes; ++classes)
290
    {
291
      jclass klass = *classes;
292
 
293
      _Jv_CheckABIVersion ((unsigned long) klass->next_or_version);
294
      (*_Jv_RegisterClassHook) (klass);
295
    }
296
}
297
 
298
// This is a version of _Jv_RegisterClasses that takes a count.
299
void
300
_Jv_RegisterClasses_Counted (const jclass * classes, size_t count)
301
{
302
  size_t i;
303
 
304
  _Jv_RegisterLibForGc (classes);
305
 
306
  for (i = 0; i < count; i++)
307
    {
308
      jclass klass = classes[i];
309
 
310
      _Jv_CheckABIVersion ((unsigned long) klass->next_or_version);
311
      (*_Jv_RegisterClassHook) (klass);
312
    }
313
}
314
 
315
// Create a class on the heap from an initializer struct.
316
inline jclass
317
_Jv_NewClassFromInitializer (const char *class_initializer)
318
{
319
  const unsigned long version
320
    = ((unsigned long)
321
       ((::java::lang::Class *)class_initializer)->next_or_version);
322
  _Jv_CheckABIVersion (version);
323
 
324
  /* We create an instance of java::lang::Class and copy all of its
325
     fields except the first word (the vtable pointer) from
326
     CLASS_INITIALIZER.  This first word is pre-initialized by
327
     _Jv_AllocObj, and we don't want to overwrite it.  */
328
 
329
  jclass new_class
330
    = (jclass)_Jv_AllocObj (sizeof (::java::lang::Class),
331
                            &::java::lang::Class::class$);
332
  const char *src = class_initializer + sizeof (void*);
333
  char *dst = (char*)new_class + sizeof (void*);
334
  size_t len = (::java::lang::Class::initializerSize (version)
335
                - sizeof (void*));
336
  memcpy (dst, src, len);
337
 
338
  new_class->engine = &_Jv_soleIndirectCompiledEngine;
339
 
340
  /* FIXME:  Way back before the dawn of time, we overloaded the
341
     SYNTHETIC class access modifier to mean INTERPRETED.  This was a
342
     Bad Thing, but it didn't matter then because classes were never
343
     marked synthetic.  However, it is possible to redeem the
344
     situation: _Jv_NewClassFromInitializer is only called from
345
     compiled classes, so we clear the INTERPRETED flag.  This is a
346
     kludge!  */
347
  new_class->accflags &= ~java::lang::reflect::Modifier::INTERPRETED;
348
 
349
  (*_Jv_RegisterClassHook) (new_class);
350
 
351
  return new_class;
352
}
353
 
354
// Called by compiler-generated code at DSO initialization.  CLASSES
355
// is an array of pairs: the first item of each pair is a pointer to
356
// the initialized data that is a class initializer in a DSO, and the
357
// second is a pointer to a class reference.
358
// _Jv_NewClassFromInitializer() creates the new class (on the Java
359
// heap) and we write the address of the new class into the address
360
// pointed to by the second word.
361
void
362
_Jv_RegisterNewClasses (char **classes)
363
{
364
  _Jv_InitGC ();
365
 
366
  const char *initializer;
367
 
368
  while ((initializer = *classes++))
369
    {
370
      jclass *class_ptr = (jclass *)*classes++;
371
      *class_ptr = _Jv_NewClassFromInitializer (initializer);
372
    }
373
}
374
 
375
void
376
_Jv_RegisterClassHookDefault (jclass klass)
377
{
378
  // This is bogus, but there doesn't seem to be a better place to do
379
  // it.
380
  if (! klass->engine)
381
    klass->engine = &_Jv_soleCompiledEngine;
382
 
383
  /* FIXME:  Way back before the dawn of time, we overloaded the
384
     SYNTHETIC class access modifier to mean INTERPRETED.  This was a
385
     Bad Thing, but it didn't matter then because classes were never
386
     marked synthetic.  However, it is possible to redeem the
387
     situation: _Jv_RegisterClassHookDefault is only called from
388
     compiled classes, so we clear the INTERPRETED flag.  This is a
389
     kludge!  */
390
  klass->accflags &= ~java::lang::reflect::Modifier::INTERPRETED;
391
 
392
  if (system_class_list != SYSTEM_LOADER_INITIALIZED)
393
    {
394
      unsigned long abi = (unsigned long) klass->next_or_version;
395
      if (! _Jv_ClassForBootstrapLoader (abi))
396
        {
397
          klass->next_or_version = system_class_list;
398
          system_class_list = klass;
399
          return;
400
        }
401
    }
402
 
403
  jint hash = HASH_UTF (klass->name);
404
 
405
  // If the class is already registered, don't re-register it.
406
  for (jclass check_class = loaded_classes[hash];
407
       check_class != NULL;
408
       check_class = check_class->next_or_version)
409
    {
410
      if (check_class == klass)
411
        {
412
          // If you get this, it means you have the same class in two
413
          // different libraries.
414
#define TEXT "Duplicate class registration: "
415
          // We size-limit MESSAGE so that you can't trash the stack.
416
          char message[200];
417
          strcpy (message, TEXT);
418
          strncpy (message + sizeof (TEXT) - 1, klass->name->chars(),
419
                   sizeof (message) - sizeof (TEXT));
420
          message[sizeof (message) - 1] = '\0';
421
          if (! gcj::runtimeInitialized)
422
            JvFail (message);
423
          else
424
            {
425
              java::lang::String *str = JvNewStringLatin1 (message);
426
              throw new java::lang::VirtualMachineError (str);
427
            }
428
        }
429
    }
430
 
431
  klass->next_or_version = loaded_classes[hash];
432
  loaded_classes[hash] = klass;
433
}
434
 
435
// A pointer to a function that actually registers a class.
436
// Normally _Jv_RegisterClassHookDefault, but could be some other function
437
// that registers the class in e.g. a ClassLoader-local table.
438
// Should synchronize on Class:class$ while setting/restore this variable.
439
 
440
void (*_Jv_RegisterClassHook) (jclass cl) = _Jv_RegisterClassHookDefault;
441
 
442
void
443
_Jv_RegisterClass (jclass klass)
444
{
445
  jclass classes[2];
446
  classes[0] = klass;
447
  classes[1] = NULL;
448
  _Jv_RegisterClasses (classes);
449
}
450
 
451
// This is used during initialization to register all compiled-in
452
// classes that are not part of the core with the system class loader.
453
void
454
_Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::SystemClassLoader *loader)
455
{
456
  for (jclass klass = system_class_list;
457
       klass;
458
       klass = klass->next_or_version)
459
    {
460
      klass->loader = loader;
461
      loader->addClass(klass);
462
    }
463
  system_class_list = SYSTEM_LOADER_INITIALIZED;
464
}
465
 
466
// An internal variant of _Jv_FindClass which simply swallows a
467
// NoClassDefFoundError or a ClassNotFoundException. This gives the
468
// caller a chance to evaluate the situation and behave accordingly.
469
jclass
470
_Jv_FindClassNoException (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
471
{
472
  jclass klass;
473
 
474
  try
475
    {
476
      klass = _Jv_FindClass(name, loader);
477
    }
478
  catch ( java::lang::NoClassDefFoundError *ncdfe )
479
    {
480
      return NULL;
481
    }
482
  catch ( java::lang::ClassNotFoundException *cnfe )
483
    {
484
      return NULL;
485
    }
486
 
487
  return klass;
488
}
489
 
490
jclass
491
_Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
492
{
493
  // See if the class was already loaded by this loader.  This handles
494
  // initiating loader checks, as we register classes with their
495
  // initiating loaders.
496
 
497
  java::lang::ClassLoader *boot = java::lang::VMClassLoader::bootLoader;
498
  java::lang::ClassLoader *real = loader;
499
  if (! real)
500
    real = boot;
501
  jstring sname = name->toString();
502
  // We might still be bootstrapping the VM, in which case there
503
  // won't be a bootstrap class loader yet.
504
  jclass klass = real ? real->findLoadedClass (sname) : NULL;
505
 
506
  if (! klass)
507
    {
508
      if (loader)
509
        {
510
          // Load using a user-defined loader, jvmspec 5.3.2.
511
          // Note that we explicitly must call the single-argument form.
512
          klass = loader->loadClass(sname);
513
 
514
          // If "loader" delegated the loadClass operation to another
515
          // loader, explicitly register that it is also an initiating
516
          // loader of the given class.
517
          java::lang::ClassLoader *delegate = (loader == boot
518
                                               ? NULL
519
                                               : loader);
520
          if (klass && klass->getClassLoaderInternal () != delegate)
521
            _Jv_RegisterInitiatingLoader (klass, loader);
522
        }
523
      else if (boot)
524
        {
525
          // Load using the bootstrap loader jvmspec 5.3.1.
526
          klass = java::lang::VMClassLoader::loadClass (sname, false);
527
 
528
          // Register that we're an initiating loader.
529
          if (klass)
530
            _Jv_RegisterInitiatingLoader (klass, 0);
531
        }
532
      else
533
        {
534
          // Not even a bootstrap loader, try the built-in cache.
535
          klass = _Jv_FindClassInCache (name);
536
 
537
          if (klass)
538
            {
539
              bool found = false;
540
              for (int i = 0; i < bootstrap_index; ++i)
541
                {
542
                  if (bootstrap_class_list[i] == klass)
543
                    {
544
                      found = true;
545
                      break;
546
                    }
547
                }
548
              if (! found)
549
                {
550
                  if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE)
551
                    abort ();
552
                  bootstrap_class_list[bootstrap_index++] = klass;
553
                }
554
            }
555
        }
556
    }
557
 
558
  return klass;
559
}
560
 
561
void
562
_Jv_RegisterBootstrapPackages ()
563
{
564
  for (int i = 0; i < bootstrap_index; ++i)
565
    java::lang::VMClassLoader::definePackageForNative(bootstrap_class_list[i]->getName());
566
}
567
 
568
jclass
569
_Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
570
              java::lang::ClassLoader *loader)
571
{
572
  jclass ret = (jclass) _Jv_AllocObject (&java::lang::Class::class$);
573
  ret->name = name;
574
  ret->superclass = superclass;
575
  ret->loader = loader;
576
 
577
  _Jv_RegisterInitiatingLoader (ret, loader);
578
 
579
  return ret;
580
}
581
 
582
static _Jv_IDispatchTable *array_idt = NULL;
583
static jshort array_depth = 0;
584
static jclass *array_ancestors = NULL;
585
 
586
static jclass interfaces[] =
587
{
588
  &java::lang::Cloneable::class$,
589
  &java::io::Serializable::class$
590
};
591
 
592
// Create a class representing an array of ELEMENT and store a pointer to it
593
// in element->arrayclass. LOADER is the ClassLoader which _initiated_ the 
594
// instantiation of this array. ARRAY_VTABLE is the vtable to use for the new 
595
// array class. This parameter is optional.
596
void
597
_Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
598
                   _Jv_VTable *array_vtable)
599
{
600
  JvSynchronize sync (element);
601
 
602
  _Jv_Utf8Const *array_name;
603
  int len;
604
 
605
  if (element->arrayclass)
606
    return;
607
 
608
  if (element->isPrimitive())
609
    {
610
      if (element == JvPrimClass (void))
611
        throw new java::lang::ClassNotFoundException ();
612
      len = 3;
613
    }
614
  else
615
    len = element->name->len() + 5;
616
 
617
  {
618
    char signature[len];
619
    int index = 0;
620
    signature[index++] = '[';
621
    // Compute name of array class.
622
    if (element->isPrimitive())
623
      {
624
        signature[index++] = (char) element->method_count;
625
      }
626
    else
627
      {
628
        size_t length = element->name->len();
629
        const char *const name = element->name->chars();
630
        if (name[0] != '[')
631
          signature[index++] = 'L';
632
        memcpy (&signature[index], name, length);
633
        index += length;
634
        if (name[0] != '[')
635
          signature[index++] = ';';
636
      }
637
    array_name = _Jv_makeUtf8Const (signature, index);
638
  }
639
 
640
  // Create new array class.
641
  jclass array_class = _Jv_NewClass (array_name, &java::lang::Object::class$,
642
                                     element->loader);
643
 
644
  // Note that `vtable_method_count' doesn't include the initial
645
  // gc_descr slot.
646
  int dm_count = java::lang::Object::class$.vtable_method_count;
647
 
648
  // Create a new vtable by copying Object's vtable.
649
  _Jv_VTable *vtable;
650
  if (array_vtable)
651
    vtable = array_vtable;
652
  else
653
    vtable = _Jv_VTable::new_vtable (dm_count);
654
  vtable->clas = array_class;
655
  vtable->gc_descr = java::lang::Object::class$.vtable->gc_descr;
656
  for (int i = 0; i < dm_count; ++i)
657
    vtable->set_method (i, java::lang::Object::class$.vtable->get_method (i));
658
 
659
  array_class->vtable = vtable;
660
  array_class->vtable_method_count
661
    = java::lang::Object::class$.vtable_method_count;
662
 
663
  // Stash the pointer to the element type.
664
  array_class->element_type = element;
665
 
666
  // Register our interfaces.
667
  array_class->interfaces = interfaces;
668
  array_class->interface_count = sizeof interfaces / sizeof interfaces[0];
669
 
670
  // Since all array classes have the same interface dispatch table, we can 
671
  // cache one and reuse it. It is not necessary to synchronize this.
672
  if (!array_idt)
673
    {
674
      _Jv_Linker::wait_for_state(array_class, JV_STATE_PREPARED);
675
      array_idt = array_class->idt;
676
      array_depth = array_class->depth;
677
      array_ancestors = array_class->ancestors;
678
    }
679
  else
680
    {
681
      array_class->idt = array_idt;
682
      array_class->depth = array_depth;
683
      array_class->ancestors = array_ancestors;
684
    }
685
 
686
  using namespace java::lang::reflect;
687
  {
688
    // Array classes are "abstract final" and inherit accessibility
689
    // from element type, per vmspec 5.3.3.2
690
    _Jv_ushort accflags = (Modifier::FINAL | Modifier::ABSTRACT
691
                           | (element->accflags
692
                              & (Modifier::PUBLIC | Modifier::PROTECTED
693
                                 | Modifier::PRIVATE)));
694
    array_class->accflags = accflags;
695
  }
696
 
697
  // An array class has no visible instance fields. "length" is invisible to 
698
  // reflection.
699
 
700
  // Say this class is initialized and ready to go!
701
  array_class->state = JV_STATE_DONE;
702
 
703
  // vmspec, section 5.3.3 describes this
704
  if (element->loader != loader)
705
    _Jv_RegisterInitiatingLoader (array_class, loader);
706
 
707
  element->arrayclass = array_class;
708
}
709
 
710
// These two functions form a stack of classes.   When a class is loaded
711
// it is pushed onto the stack by the class loader; this is so that
712
// StackTrace can quickly determine which classes have been loaded.
713
 
714
jclass
715
_Jv_PopClass (void)
716
{
717
  JvSynchronize sync (&java::lang::Class::class$);
718
  if (stack_head)
719
    {
720
      jclass tmp = stack_head;
721
      stack_head = tmp->chain;
722
      return tmp;
723
    }
724
  return NULL;
725
}
726
 
727
void
728
_Jv_PushClass (jclass k)
729
{
730
  JvSynchronize sync (&java::lang::Class::class$);
731
  jclass tmp = stack_head;
732
  stack_head = k;
733
  k->chain = tmp;
734
}

powered by: WebSVN 2.1.0

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