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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 758 jeremybenn
// natClass.cc - Implementation of java.lang.Class native methods.
2
 
3
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
4
   2010 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
#include <config.h>
13
 
14
#include <limits.h>
15
#include <string.h>
16
#include <stddef.h>
17
#include <stdio.h>
18
 
19
#pragma implementation "Class.h"
20
 
21
#include <gcj/cni.h>
22
#include <jvm.h>
23
#include <java-threads.h>
24
 
25
#include <java/lang/Class.h>
26
#include <java/lang/ClassLoader.h>
27
#include <java/lang/String.h>
28
#include <java/lang/reflect/Modifier.h>
29
#include <java/lang/reflect/Member.h>
30
#include <java/lang/reflect/Method.h>
31
#include <java/lang/reflect/Field.h>
32
#include <java/lang/reflect/Proxy.h>
33
#include <java/lang/reflect/Constructor.h>
34
#include <java/lang/AbstractMethodError.h>
35
#include <java/lang/ArrayStoreException.h>
36
#include <java/lang/ClassCastException.h>
37
#include <java/lang/ClassNotFoundException.h>
38
#include <java/lang/ExceptionInInitializerError.h>
39
#include <java/lang/IllegalAccessException.h>
40
#include <java/lang/IllegalAccessError.h>
41
#include <java/lang/IllegalArgumentException.h>
42
#include <java/lang/IncompatibleClassChangeError.h>
43
#include <java/lang/NoSuchFieldError.h>
44
#include <java/lang/ArrayIndexOutOfBoundsException.h>
45
#include <java/lang/InstantiationException.h>
46
#include <java/lang/NoClassDefFoundError.h>
47
#include <java/lang/NoSuchFieldException.h>
48
#include <java/lang/NoSuchMethodError.h>
49
#include <java/lang/NoSuchMethodException.h>
50
#include <java/lang/Thread.h>
51
#include <java/lang/NullPointerException.h>
52
#include <java/lang/RuntimePermission.h>
53
#include <java/lang/System.h>
54
#include <java/lang/SecurityException.h>
55
#include <java/lang/SecurityManager.h>
56
#include <java/lang/StringBuffer.h>
57
#include <java/lang/VMClassLoader.h>
58
#include <gcj/method.h>
59
#include <gnu/gcj/RawData.h>
60
#include <java/lang/VerifyError.h>
61
#include <java/lang/InternalError.h>
62
#include <java/lang/TypeNotPresentException.h>
63
#include <java/lang/Byte.h>
64
#include <java/lang/Short.h>
65
#include <java/lang/Integer.h>
66
#include <java/lang/Float.h>
67
#include <java/lang/Double.h>
68
#include <java/lang/Long.h>
69
#include <java/lang/Character.h>
70
#include <java/lang/Boolean.h>
71
#include <java/lang/annotation/Annotation.h>
72
#include <java/util/HashMap.h>
73
#include <java/util/Map.h>
74
#include <sun/reflect/annotation/AnnotationInvocationHandler.h>
75
#include <java/lang/Enum.h>
76
 
77
#include <java-cpool.h>
78
#include <java-interp.h>
79
#include <java-assert.h>
80
#include <java-stack.h>
81
#include <execution.h>
82
 
83
 
84
 
85
using namespace gcj;
86
 
87
jclass
88
java::lang::Class::forName (jstring className, jboolean initialize,
89
                            java::lang::ClassLoader *loader)
90
{
91
  if (! className)
92
    throw new java::lang::NullPointerException;
93
 
94
  jsize length = _Jv_GetStringUTFLength (className);
95
  char buffer[length];
96
  _Jv_GetStringUTFRegion (className, 0, className->length(), buffer);
97
 
98
  _Jv_Utf8Const *name = _Jv_makeUtf8Const (buffer, length);
99
 
100
  if (! _Jv_VerifyClassName (name))
101
    throw new java::lang::ClassNotFoundException (className);
102
 
103
  jclass klass = (buffer[0] == '['
104
                  ? _Jv_FindClassFromSignature (name->chars(), loader)
105
                  : _Jv_FindClass (name, loader));
106
 
107
  if (klass == NULL)
108
    throw new java::lang::ClassNotFoundException (className);
109
 
110
  if (initialize)
111
    _Jv_InitClass (klass);
112
 
113
  return klass;
114
}
115
 
116
jclass
117
java::lang::Class::forName (jstring className)
118
{
119
  java::lang::ClassLoader *loader = NULL;
120
 
121
  jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$);
122
  if (caller)
123
    loader = caller->getClassLoaderInternal();
124
 
125
  return forName (className, true, loader);
126
}
127
 
128
java::lang::ClassLoader *
129
java::lang::Class::getClassLoader (void)
130
{
131
  java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
132
  if (s != NULL)
133
    {
134
      jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$);
135
      return getClassLoader (caller);
136
   }
137
 
138
  return loader;
139
}
140
 
141
java::lang::ClassLoader *
142
java::lang::Class::getClassLoader (jclass caller)
143
{
144
  java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
145
  if (s != NULL)
146
    {
147
      ClassLoader *caller_loader = caller->getClassLoaderInternal();
148
 
149
      // If the caller has a non-null class loader, and that loader
150
      // is not this class' loader or an ancestor thereof, then do a
151
      // security check.
152
      if (caller_loader != NULL && ! caller_loader->isAncestorOf(loader))
153
        s->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader")));
154
    }
155
 
156
  return loader;
157
}
158
 
159
java::lang::reflect::Constructor *
160
java::lang::Class::getConstructor (JArray<jclass> *param_types)
161
{
162
  memberAccessCheck(java::lang::reflect::Member::PUBLIC);
163
 
164
  jstring partial_sig = getSignature (param_types, true);
165
  jint hash = partial_sig->hashCode ();
166
 
167
  int i = isPrimitive () ? 0 : method_count;
168
  while (--i >= 0)
169
    {
170
      if (_Jv_equalUtf8Consts (methods[i].name, init_name)
171
          && _Jv_equal (methods[i].signature, partial_sig, hash))
172
        {
173
          // Found it.  For getConstructor, the constructor must be
174
          // public.
175
          using namespace java::lang::reflect;
176
          if (! Modifier::isPublic(methods[i].accflags))
177
            break;
178
          Constructor *cons = new Constructor ();
179
          cons->offset = (char *) (&methods[i]) - (char *) methods;
180
          cons->declaringClass = this;
181
          return cons;
182
        }
183
    }
184
  throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name));
185
}
186
 
187
JArray<java::lang::reflect::Constructor *> *
188
java::lang::Class::getDeclaredConstructors (jboolean publicOnly)
189
{
190
  int numConstructors = 0;
191
  int max = isPrimitive () ? 0 : method_count;
192
  int i;
193
  for (i = max; --i >= 0; )
194
    {
195
      _Jv_Method *method = &methods[i];
196
      if (method->name == NULL
197
          || ! _Jv_equalUtf8Consts (method->name, init_name))
198
        continue;
199
      if (publicOnly
200
          && ! java::lang::reflect::Modifier::isPublic(method->accflags))
201
        continue;
202
      numConstructors++;
203
    }
204
  JArray<java::lang::reflect::Constructor *> *result
205
    = (JArray<java::lang::reflect::Constructor *> *)
206
    JvNewObjectArray (numConstructors,
207
                      &java::lang::reflect::Constructor::class$,
208
                      NULL);
209
  java::lang::reflect::Constructor** cptr = elements (result);
210
  for (i = 0;  i < max;  i++)
211
    {
212
      _Jv_Method *method = &methods[i];
213
      if (method->name == NULL
214
          || ! _Jv_equalUtf8Consts (method->name, init_name))
215
        continue;
216
      if (publicOnly
217
          && ! java::lang::reflect::Modifier::isPublic(method->accflags))
218
        continue;
219
      java::lang::reflect::Constructor *cons
220
        = new java::lang::reflect::Constructor ();
221
      cons->offset = (char *) method - (char *) methods;
222
      cons->declaringClass = this;
223
      *cptr++ = cons;
224
    }
225
  return result;
226
}
227
 
228
java::lang::reflect::Constructor *
229
java::lang::Class::getDeclaredConstructor (JArray<jclass> *param_types)
230
{
231
  memberAccessCheck(java::lang::reflect::Member::DECLARED);
232
 
233
  jstring partial_sig = getSignature (param_types, true);
234
  jint hash = partial_sig->hashCode ();
235
 
236
  int i = isPrimitive () ? 0 : method_count;
237
  while (--i >= 0)
238
    {
239
      if (_Jv_equalUtf8Consts (methods[i].name, init_name)
240
          && _Jv_equal (methods[i].signature, partial_sig, hash))
241
        {
242
          // Found it.
243
          using namespace java::lang::reflect;
244
          Constructor *cons = new Constructor ();
245
          cons->offset = (char *) (&methods[i]) - (char *) methods;
246
          cons->declaringClass = this;
247
          return cons;
248
        }
249
    }
250
  throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name));
251
}
252
 
253
java::lang::reflect::Field *
254
java::lang::Class::getField (jstring name, jint hash)
255
{
256
  java::lang::reflect::Field* rfield;
257
  for (int i = 0;  i < field_count;  i++)
258
    {
259
      _Jv_Field *field = &fields[i];
260
      if (! _Jv_equal (field->name, name, hash))
261
        continue;
262
      if (! (field->getModifiers() & java::lang::reflect::Modifier::PUBLIC))
263
        continue;
264
      rfield = new java::lang::reflect::Field ();
265
      rfield->offset = (char*) field - (char*) fields;
266
      rfield->declaringClass = this;
267
      rfield->name = name;
268
      return rfield;
269
    }
270
  jclass superclass = getSuperclass();
271
  if (superclass == NULL)
272
    return NULL;
273
  rfield = superclass->getField(name, hash);
274
  for (int i = 0; i < interface_count && rfield == NULL; ++i)
275
    rfield = interfaces[i]->getField (name, hash);
276
  return rfield;
277
}
278
 
279
java::lang::reflect::Field *
280
java::lang::Class::getDeclaredField (jstring name)
281
{
282
  memberAccessCheck(java::lang::reflect::Member::DECLARED);
283
  int hash = name->hashCode();
284
  for (int i = 0;  i < field_count;  i++)
285
    {
286
      _Jv_Field *field = &fields[i];
287
      if (! _Jv_equal (field->name, name, hash))
288
        continue;
289
      java::lang::reflect::Field* rfield = new java::lang::reflect::Field ();
290
      rfield->offset = (char*) field - (char*) fields;
291
      rfield->declaringClass = this;
292
      rfield->name = name;
293
      return rfield;
294
    }
295
  throw new java::lang::NoSuchFieldException (name);
296
}
297
 
298
JArray<java::lang::reflect::Field *> *
299
java::lang::Class::getDeclaredFields (jboolean public_only)
300
{
301
  int size;
302
  if (public_only)
303
    {
304
      size = 0;
305
      for (int i = 0; i < field_count; ++i)
306
        {
307
          _Jv_Field *field = &fields[i];
308
          if ((field->flags & java::lang::reflect::Modifier::PUBLIC))
309
            ++size;
310
        }
311
    }
312
  else
313
    size = field_count;
314
 
315
  JArray<java::lang::reflect::Field *> *result
316
    = (JArray<java::lang::reflect::Field *> *)
317
    JvNewObjectArray (size, &java::lang::reflect::Field::class$, NULL);
318
  java::lang::reflect::Field** fptr = elements (result);
319
  for (int i = 0;  i < field_count;  i++)
320
    {
321
      _Jv_Field *field = &fields[i];
322
      if (public_only
323
          && ! (field->flags & java::lang::reflect::Modifier::PUBLIC))
324
        continue;
325
      java::lang::reflect::Field* rfield = new java::lang::reflect::Field ();
326
      rfield->offset = (char*) field - (char*) fields;
327
      rfield->declaringClass = this;
328
      *fptr++ = rfield;
329
    }
330
  return result;
331
}
332
 
333
void
334
java::lang::Class::getSignature (java::lang::StringBuffer *buffer)
335
{
336
  if (isPrimitive())
337
    buffer->append((jchar) method_count);
338
  else
339
    {
340
      jstring name = getName();
341
      if (name->charAt(0) != '[')
342
        buffer->append((jchar) 'L');
343
      buffer->append(name);
344
      if (name->charAt(0) != '[')
345
        buffer->append((jchar) ';');
346
    }
347
}
348
 
349
// This doesn't have to be native.  It is an implementation detail
350
// only called from the C++ code, though, so maybe this is clearer.
351
jstring
352
java::lang::Class::getSignature (JArray<jclass> *param_types,
353
                                 jboolean is_constructor)
354
{
355
  java::lang::StringBuffer *buf = new java::lang::StringBuffer ();
356
  buf->append((jchar) '(');
357
  // A NULL param_types means "no parameters".
358
  if (param_types != NULL)
359
    {
360
      jclass *v = elements (param_types);
361
      for (int i = 0; i < param_types->length; ++i)
362
        v[i]->getSignature(buf);
363
    }
364
  buf->append((jchar) ')');
365
  if (is_constructor)
366
    buf->append((jchar) 'V');
367
  return buf->toString();
368
}
369
 
370
java::lang::reflect::Method *
371
java::lang::Class::_getDeclaredMethod (jstring name,
372
                                       JArray<jclass> *param_types)
373
{
374
  jstring partial_sig = getSignature (param_types, false);
375
  jint p_len = partial_sig->length();
376
  _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
377
  int i = isPrimitive () ? 0 : method_count;
378
  while (--i >= 0)
379
    {
380
      if (_Jv_equalUtf8Consts (methods[i].name, utf_name)
381
          && _Jv_equaln (methods[i].signature, partial_sig, p_len)
382
          && (methods[i].accflags
383
              & java::lang::reflect::Modifier::INVISIBLE) == 0)
384
        {
385
          // Found it.
386
          using namespace java::lang::reflect;
387
          Method *rmethod = new Method ();
388
          rmethod->offset = (char*) (&methods[i]) - (char*) methods;
389
          rmethod->declaringClass = this;
390
          return rmethod;
391
        }
392
    }
393
  return NULL;
394
}
395
 
396
JArray<java::lang::reflect::Method *> *
397
java::lang::Class::getDeclaredMethods (void)
398
{
399
  memberAccessCheck(java::lang::reflect::Member::DECLARED);
400
 
401
  int numMethods = 0;
402
  int max = isPrimitive () ? 0 : method_count;
403
  int i;
404
  for (i = max; --i >= 0; )
405
    {
406
      _Jv_Method *method = &methods[i];
407
      if (method->name == NULL
408
          || _Jv_equalUtf8Consts (method->name, clinit_name)
409
          || _Jv_equalUtf8Consts (method->name, init_name)
410
          || _Jv_equalUtf8Consts (method->name, finit_name)
411
          || (methods[i].accflags
412
              & java::lang::reflect::Modifier::INVISIBLE) != 0)
413
        continue;
414
      numMethods++;
415
    }
416
  JArray<java::lang::reflect::Method *> *result
417
    = (JArray<java::lang::reflect::Method *> *)
418
    JvNewObjectArray (numMethods, &java::lang::reflect::Method::class$, NULL);
419
  java::lang::reflect::Method** mptr = elements (result);
420
  for (i = 0;  i < max;  i++)
421
    {
422
      _Jv_Method *method = &methods[i];
423
      if (method->name == NULL
424
          || _Jv_equalUtf8Consts (method->name, clinit_name)
425
          || _Jv_equalUtf8Consts (method->name, init_name)
426
          || _Jv_equalUtf8Consts (method->name, finit_name)
427
          || (methods[i].accflags
428
              & java::lang::reflect::Modifier::INVISIBLE) != 0)
429
        continue;
430
      java::lang::reflect::Method* rmethod
431
        = new java::lang::reflect::Method ();
432
      rmethod->offset = (char*) method - (char*) methods;
433
      rmethod->declaringClass = this;
434
      *mptr++ = rmethod;
435
    }
436
  return result;
437
}
438
 
439
jstring
440
java::lang::Class::getName (void)
441
{
442
  return name->toString();
443
}
444
 
445
JArray<jclass> *
446
java::lang::Class::getInterfaces (void)
447
{
448
  jobjectArray r = JvNewObjectArray (interface_count, getClass (), NULL);
449
  jobject *data = elements (r);
450
  for (int i = 0; i < interface_count; ++i)
451
    {
452
      typedef unsigned int uaddr __attribute__ ((mode (pointer)));
453
      data[i] = interfaces[i];
454
      if ((uaddr)data[i] < (uaddr)constants.size)
455
        fprintf (stderr, "ERROR !!!\n");
456
    }
457
  return reinterpret_cast<JArray<jclass> *> (r);
458
}
459
 
460
java::lang::reflect::Method *
461
java::lang::Class::_getMethod (jstring name, JArray<jclass> *param_types)
462
{
463
  jstring partial_sig = getSignature (param_types, false);
464
  jint p_len = partial_sig->length();
465
  _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
466
 
467
   for (Class *klass = this; klass; klass = klass->getSuperclass())
468
    {
469
      int i = klass->isPrimitive () ? 0 : klass->method_count;
470
      while (--i >= 0)
471
        {
472
          if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
473
              && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len)
474
              && (klass->methods[i].accflags
475
                  & java::lang::reflect::Modifier::INVISIBLE) == 0)
476
            {
477
              // Found it.
478
              using namespace java::lang::reflect;
479
 
480
              // Method must be public.
481
              if (! Modifier::isPublic (klass->methods[i].accflags))
482
                break;
483
 
484
              Method *rmethod = new Method ();
485
              rmethod->offset = ((char *) (&klass->methods[i])
486
                                 - (char *) klass->methods);
487
              rmethod->declaringClass = klass;
488
              return rmethod;
489
            }
490
        }
491
    }
492
 
493
  // If we haven't found a match, and this class is an interface, then
494
  // check all the superinterfaces.
495
  if (isInterface())
496
    {
497
      for (int i = 0; i < interface_count; ++i)
498
        {
499
          using namespace java::lang::reflect;
500
          Method *rmethod = interfaces[i]->_getMethod (name, param_types);
501
          if (rmethod != NULL)
502
            return rmethod;
503
        }
504
    }
505
 
506
  return NULL;
507
}
508
 
509
// This is a very slow implementation, since it re-scans all the
510
// methods we've already listed to make sure we haven't duplicated a
511
// method.  It also over-estimates the required size, so we have to
512
// shrink the result array later.
513
jint
514
java::lang::Class::_getMethods (JArray<java::lang::reflect::Method *> *result,
515
                                jint offset)
516
{
517
  jint count = 0;
518
 
519
  // First examine all local methods
520
  for (int i = isPrimitive () ? 0 : method_count; --i >= 0; )
521
    {
522
      _Jv_Method *method = &methods[i];
523
      if (method->name == NULL
524
          || _Jv_equalUtf8Consts (method->name, clinit_name)
525
          || _Jv_equalUtf8Consts (method->name, init_name)
526
          || _Jv_equalUtf8Consts (method->name, finit_name)
527
          || (method->accflags
528
              & java::lang::reflect::Modifier::INVISIBLE) != 0)
529
        continue;
530
      // Only want public methods.
531
      if (! java::lang::reflect::Modifier::isPublic (method->accflags))
532
        continue;
533
 
534
      // This is where we over-count the slots required if we aren't
535
      // filling the result for real.
536
      if (result != NULL)
537
        {
538
          jboolean add = true;
539
          java::lang::reflect::Method **mp = elements (result);
540
          // If we already have a method with this name and signature,
541
          // then ignore this one.  This can happen with virtual
542
          // methods.
543
          for (int j = 0; j < offset; ++j)
544
            {
545
              _Jv_Method *meth_2 = _Jv_FromReflectedMethod (mp[j]);
546
              if (_Jv_equalUtf8Consts (method->name, meth_2->name)
547
                  && _Jv_equalUtf8Consts (method->signature,
548
                                          meth_2->signature))
549
                {
550
                  add = false;
551
                  break;
552
                }
553
            }
554
          if (! add)
555
            continue;
556
        }
557
 
558
      if (result != NULL)
559
        {
560
          using namespace java::lang::reflect;
561
          Method *rmethod = new Method ();
562
          rmethod->offset = (char *) method - (char *) methods;
563
          rmethod->declaringClass = this;
564
          Method **mp = elements (result);
565
          mp[offset + count] = rmethod;
566
        }
567
      ++count;
568
    }
569
  offset += count;
570
 
571
  // Now examine superclasses.
572
  if (getSuperclass () != NULL)
573
    {
574
      jint s_count = getSuperclass()->_getMethods (result, offset);
575
      offset += s_count;
576
      count += s_count;
577
    }
578
 
579
  // Finally, examine interfaces.
580
  for (int i = 0; i < interface_count; ++i)
581
    {
582
      int f_count = interfaces[i]->_getMethods (result, offset);
583
      count += f_count;
584
      offset += f_count;
585
    }
586
 
587
  return count;
588
}
589
 
590
JArray<java::lang::reflect::Method *> *
591
java::lang::Class::getMethods (void)
592
{
593
  using namespace java::lang::reflect;
594
 
595
  memberAccessCheck(Member::PUBLIC);
596
 
597
  // This will overestimate the size we need.
598
  jint count = _getMethods (NULL, 0);
599
 
600
  JArray<Method *> *result
601
    = ((JArray<Method *> *) JvNewObjectArray (count,
602
                                              &Method::class$,
603
                                              NULL));
604
 
605
  // When filling the array for real, we get the actual count.  Then
606
  // we resize the array.
607
  jint real_count = _getMethods (result, 0);
608
 
609
  if (real_count != count)
610
    {
611
      JArray<Method *> *r2
612
        = ((JArray<Method *> *) JvNewObjectArray (real_count,
613
                                                  &Method::class$,
614
                                                  NULL));
615
 
616
      Method **destp = elements (r2);
617
      Method **srcp = elements (result);
618
 
619
      for (int i = 0; i < real_count; ++i)
620
        *destp++ = *srcp++;
621
 
622
      result = r2;
623
    }
624
 
625
  return result;
626
}
627
 
628
jboolean
629
java::lang::Class::isAssignableFrom (jclass klass)
630
{
631
  // Arguments may not have been initialized, given ".class" syntax.
632
  // This ensures we can at least look at their superclasses.
633
  _Jv_Linker::wait_for_state (this, JV_STATE_LOADING);
634
  _Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
635
  return _Jv_IsAssignableFrom (klass, this);
636
}
637
 
638
jboolean
639
java::lang::Class::isInstance (jobject obj)
640
{
641
  if (! obj)
642
    return false;
643
  return _Jv_IsAssignableFrom (JV_CLASS (obj), this);
644
}
645
 
646
jobject
647
java::lang::Class::newInstance (void)
648
{
649
  memberAccessCheck(java::lang::reflect::Member::PUBLIC);
650
 
651
  if (isPrimitive ()
652
      || isInterface ()
653
      || isArray ()
654
      || java::lang::reflect::Modifier::isAbstract(accflags))
655
    throw new java::lang::InstantiationException (getName ());
656
 
657
  _Jv_InitClass (this);
658
 
659
  _Jv_Method *meth = _Jv_GetMethodLocal (this, init_name, void_signature);
660
  if (! meth)
661
    throw new java::lang::InstantiationException (getName());
662
 
663
  jobject r = _Jv_AllocObject (this);
664
  /* Class constructors/destructors have __thiscall calling
665
     convention for 32-bit native Windows ABI.  */
666
#if defined (__MINGW32__) && defined (__i386__)
667
  ((void (__thiscall *) (jobject)) meth->ncode) (r);
668
#else
669
  ((void (*) (jobject)) meth->ncode) (r);
670
#endif
671
  return r;
672
}
673
 
674
void
675
java::lang::Class::finalize (void)
676
{
677
  // Array classes don't have an engine, and don't need to be finalized.
678
   if (engine)
679
     engine->unregister(this);
680
}
681
 
682
#ifdef INTERPRETER
683
void
684
_Jv_ClosureList::releaseClosures (_Jv_ClosureList **closures)
685
{
686
  if (!closures)
687
    return;
688
 
689
  while (_Jv_ClosureList *current = *closures)
690
    {
691
      *closures = current->next;
692
      ffi_closure_free (current->ptr);
693
    }
694
}
695
 
696
void
697
_Jv_ClosureList::registerClosure (jclass klass, void *ptr)
698
{
699
  _Jv_ClosureList **closures = klass->engine->get_closure_list (klass);
700
  if (closures)
701
    {
702
      this->ptr = ptr;
703
      this->next = *closures;
704
      *closures = this;
705
    }
706
}
707
#endif
708
 
709
// This implements the initialization process for a class.  From Spec
710
// section 12.4.2.
711
void
712
java::lang::Class::initializeClass (void)
713
{
714
  // Short-circuit to avoid needless locking (expression includes
715
  // JV_STATE_PHANTOM and JV_STATE_DONE).
716
  if (state >= JV_STATE_PHANTOM)
717
    return;
718
 
719
  // Step 1.  We introduce a new scope so we can synchronize more
720
  // easily.
721
  {
722
    JvSynchronize sync (this);
723
 
724
    if (state < JV_STATE_LINKED)
725
      {
726
        try
727
          {
728
            _Jv_Linker::wait_for_state(this, JV_STATE_LINKED);
729
          }
730
        catch (java::lang::SecurityException *x)
731
          {
732
            throw x;
733
          }
734
        catch (java::lang::Throwable *x)
735
          {
736
            // Turn into a NoClassDefFoundError.
737
            java::lang::NoClassDefFoundError *result
738
              = new java::lang::NoClassDefFoundError(getName());
739
            result->initCause(x);
740
            throw result;
741
          }
742
      }
743
 
744
    // Step 2.
745
    java::lang::Thread *self = java::lang::Thread::currentThread();
746
    self = (java::lang::Thread *) ((long) self | 1);
747
    while (state == JV_STATE_IN_PROGRESS && thread && thread != self)
748
      wait ();
749
 
750
    // Steps 3 &  4.
751
    if (state == JV_STATE_DONE || state == JV_STATE_IN_PROGRESS)
752
      return;
753
 
754
    // Step 5.
755
    if (state == JV_STATE_ERROR)
756
      throw new java::lang::NoClassDefFoundError (getName());
757
 
758
    // Step 6.
759
    thread = self;
760
    _Jv_Linker::wait_for_state (this, JV_STATE_LINKED);
761
    state = JV_STATE_IN_PROGRESS;
762
  }
763
 
764
  // Step 7.
765
  if (! isInterface () && superclass)
766
    {
767
      try
768
        {
769
          _Jv_InitClass (superclass);
770
        }
771
      catch (java::lang::SecurityException *x)
772
        {
773
          throw x;
774
        }
775
      catch (java::lang::Throwable *except)
776
        {
777
          // Caught an exception.
778
          JvSynchronize sync (this);
779
          state = JV_STATE_ERROR;
780
          notifyAll ();
781
          throw except;
782
        }
783
    }
784
 
785
  // Steps 8, 9, 10, 11.
786
  try
787
    {
788
      _Jv_Method *meth = _Jv_GetMethodLocal (this, clinit_name,
789
                                             void_signature);
790
      if (meth)
791
        ((void (*) (void)) meth->ncode) ();
792
    }
793
  catch (java::lang::SecurityException *x)
794
    {
795
      throw x;
796
    }
797
  catch (java::lang::Throwable *except)
798
    {
799
      if (! java::lang::Error::class$.isInstance(except))
800
        {
801
          try
802
            {
803
              except = new ExceptionInInitializerError (except);
804
            }
805
          catch (java::lang::Throwable *t)
806
            {
807
              except = t;
808
            }
809
        }
810
 
811
      JvSynchronize sync (this);
812
      state = JV_STATE_ERROR;
813
      notifyAll ();
814
      throw except;
815
    }
816
 
817
  JvSynchronize sync (this);
818
  state = JV_STATE_DONE;
819
  notifyAll ();
820
}
821
 
822
// Only used by serialization
823
java::lang::reflect::Field *
824
java::lang::Class::getPrivateField (jstring name)
825
{
826
  int hash = name->hashCode ();
827
 
828
  java::lang::reflect::Field* rfield;
829
  for (int i = 0;  i < field_count;  i++)
830
    {
831
      _Jv_Field *field = &fields[i];
832
      if (! _Jv_equal (field->name, name, hash))
833
        continue;
834
      rfield = new java::lang::reflect::Field ();
835
      rfield->offset = (char*) field - (char*) fields;
836
      rfield->declaringClass = this;
837
      rfield->name = name;
838
      return rfield;
839
    }
840
  jclass superclass = getSuperclass();
841
  if (superclass == NULL)
842
    return NULL;
843
  rfield = superclass->getPrivateField(name);
844
  for (int i = 0; i < interface_count && rfield == NULL; ++i)
845
    rfield = interfaces[i]->getPrivateField (name);
846
  return rfield;
847
}
848
 
849
// Only used by serialization
850
java::lang::reflect::Method *
851
java::lang::Class::getPrivateMethod (jstring name, JArray<jclass> *param_types)
852
{
853
  jstring partial_sig = getSignature (param_types, false);
854
  jint p_len = partial_sig->length();
855
  _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
856
  for (Class *klass = this; klass; klass = klass->getSuperclass())
857
    {
858
      int i = klass->isPrimitive () ? 0 : klass->method_count;
859
      while (--i >= 0)
860
        {
861
          if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
862
              && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len))
863
            {
864
              // Found it.
865
              using namespace java::lang::reflect;
866
 
867
              Method *rmethod = new Method ();
868
              rmethod->offset = ((char *) (&klass->methods[i])
869
                                 - (char *) klass->methods);
870
              rmethod->declaringClass = klass;
871
              return rmethod;
872
            }
873
        }
874
    }
875
  throw new java::lang::NoSuchMethodException (name);
876
}
877
 
878
// Private accessor method for Java code to retrieve the protection domain.
879
java::security::ProtectionDomain *
880
java::lang::Class::getProtectionDomain0 ()
881
{
882
  return protectionDomain;
883
}
884
 
885
JArray<jobject> *
886
java::lang::Class::getSigners()
887
{
888
  return hack_signers;
889
}
890
 
891
void
892
java::lang::Class::setSigners(JArray<jobject> *s)
893
{
894
  hack_signers = s;
895
}
896
 
897
 
898
 
899
static unsigned char
900
read_u1 (unsigned char *&p)
901
{
902
  return *p++;
903
}
904
 
905
static unsigned char
906
read_u1 (unsigned char *&p, unsigned char *next)
907
{
908
  if (next - p < 1)
909
    throw new java::lang::InternalError();
910
  return *p++;
911
}
912
 
913
static unsigned int
914
read_u2 (unsigned char *&p)
915
{
916
  unsigned int b1 = *p++;
917
  unsigned int b2 = *p++;
918
  return (b1 << 8) | b2;
919
}
920
 
921
static unsigned int
922
read_u2 (unsigned char *&p, unsigned char *next)
923
{
924
  if (next - p < 2)
925
    throw new java::lang::InternalError();
926
  return read_u2 (p);
927
}
928
 
929
static int
930
read_4 (unsigned char *&p)
931
{
932
  int b1 = *p++;
933
  int b2 = *p++;
934
  int b3 = *p++;
935
  int b4 = *p++;
936
  return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
937
}
938
 
939
jstring
940
java::lang::Class::getReflectionSignature (jint /*jv_attr_type*/ type,
941
                                           jint obj_index)
942
{
943
  // We just re-parse the bytecode for this data each time.  If
944
  // necessary we can cache results, but I suspect this is not
945
  // performance sensitive.
946
  unsigned char *bytes = reflection_data;
947
  if (bytes == NULL)
948
    return NULL;
949
  while (true)
950
    {
951
      int kind = read_u1 (bytes);
952
      if (kind == JV_DONE_ATTR)
953
        return NULL;
954
      int len = read_4 (bytes);
955
      unsigned char *next = bytes + len;
956
      if (kind != type)
957
        {
958
          bytes = next;
959
          continue;
960
        }
961
      if (type != JV_CLASS_ATTR)
962
        {
963
          unsigned short index = read_u2 (bytes, next);
964
          if (index != obj_index)
965
            {
966
              bytes = next;
967
              continue;
968
            }
969
        }
970
      int nt = read_u1 (bytes, next);
971
      if (nt != JV_SIGNATURE_KIND)
972
        {
973
          bytes = next;
974
          continue;
975
        }
976
      unsigned int cpool_idx = read_u2 (bytes, next);
977
      if (cpool_idx >= (unsigned int) constants.size
978
          || constants.tags[cpool_idx] != JV_CONSTANT_Utf8)
979
        {
980
          // We just ignore errors for now.  It isn't clear what is
981
          // best to do here, as an encoding error here means a bug
982
          // either in the compiler or in defineclass.cc.
983
          return NULL;
984
        }
985
      return _Jv_NewStringUtf8Const (constants.data[cpool_idx].utf8);
986
    }
987
}
988
 
989
jstring
990
java::lang::Class::getReflectionSignature (::java::lang::reflect::Constructor *c)
991
{
992
  _Jv_Method *meth = _Jv_FromReflectedConstructor (c);
993
  unsigned short meth_index = meth - methods;
994
  return getReflectionSignature (JV_METHOD_ATTR, meth_index);
995
}
996
 
997
jstring
998
java::lang::Class::getReflectionSignature (::java::lang::reflect::Method *m)
999
{
1000
  _Jv_Method *meth = _Jv_FromReflectedMethod (m);
1001
  unsigned short meth_index = meth - methods;
1002
  return getReflectionSignature (JV_METHOD_ATTR, meth_index);
1003
}
1004
 
1005
jstring
1006
java::lang::Class::getReflectionSignature (::java::lang::reflect::Field *f)
1007
{
1008
  _Jv_Field *fld = _Jv_FromReflectedField (f);
1009
  unsigned short fld_index = fld - fields;
1010
  return getReflectionSignature (JV_FIELD_ATTR, fld_index);
1011
}
1012
 
1013
jstring
1014
java::lang::Class::getClassSignature()
1015
{
1016
  return getReflectionSignature (JV_CLASS_ATTR, 0);
1017
}
1018
 
1019
jint
1020
java::lang::Class::getEnclosingMethodData()
1021
{
1022
  unsigned char *bytes = reflection_data;
1023
  if (bytes == NULL)
1024
    return 0;
1025
  while (true)
1026
    {
1027
      int kind = read_u1 (bytes);
1028
      if (kind == JV_DONE_ATTR)
1029
        return 0;
1030
      int len = read_4 (bytes);
1031
      unsigned char *next = bytes + len;
1032
      if (kind != JV_CLASS_ATTR)
1033
        {
1034
          bytes = next;
1035
          continue;
1036
        }
1037
      int type = read_u1 (bytes, next);
1038
      if (type != JV_ENCLOSING_METHOD_KIND)
1039
        {
1040
          bytes = next;
1041
          continue;
1042
        }
1043
      int class_index = read_u2 (bytes, next);
1044
      int method_index = read_u2 (bytes, next);
1045
      _Jv_word result;
1046
      _Jv_storeIndexes (&result, class_index, method_index);
1047
      return result.i;
1048
    }
1049
}
1050
 
1051
jclass
1052
java::lang::Class::getEnclosingClass()
1053
{
1054
  _Jv_word indexes;
1055
  indexes.i = getEnclosingMethodData();
1056
  if (indexes.i == 0)
1057
    // No enclosing method, but perhaps a member or anonymous class
1058
    return getDeclaringClass();
1059
  _Jv_ushort class_index, method_index;
1060
  _Jv_loadIndexes (&indexes, class_index, method_index);
1061
  return _Jv_Linker::resolve_pool_entry (this, class_index).clazz;
1062
}
1063
 
1064
::java::lang::reflect::Method *
1065
java::lang::Class::getEnclosingMethod()
1066
{
1067
  _Jv_word indexes;
1068
  indexes.i = getEnclosingMethodData();
1069
  if (indexes.i == 0)
1070
    return NULL;
1071
  _Jv_ushort class_index, method_index;
1072
  _Jv_loadIndexes (&indexes, class_index, method_index);
1073
  jclass found_class;
1074
  _Jv_Method *method = _Jv_Linker::resolve_method_entry (this, found_class,
1075
                                                         class_index,
1076
                                                         method_index,
1077
                                                         false, false);
1078
  using namespace java::lang::reflect;
1079
  Method *rmethod = new Method ();
1080
  rmethod->offset = (char *) method - (char *) found_class->methods;
1081
  rmethod->declaringClass = found_class;
1082
  return rmethod;
1083
}
1084
 
1085
::java::lang::reflect::Constructor *
1086
java::lang::Class::getEnclosingConstructor()
1087
{
1088
  _Jv_word indexes;
1089
  indexes.i = getEnclosingMethodData();
1090
  if (indexes.i == 0)
1091
    return NULL;
1092
  _Jv_ushort class_index, method_index;
1093
  _Jv_loadIndexes (&indexes, class_index, method_index);
1094
  jclass found_class;
1095
  _Jv_Method *method = _Jv_Linker::resolve_method_entry (this, found_class,
1096
                                                         class_index,
1097
                                                         method_index,
1098
                                                         false, false);
1099
  using namespace java::lang::reflect;
1100
  Constructor *cons = new Constructor ();
1101
  cons->offset = (char *) method - (char *) found_class->methods;
1102
  cons->declaringClass = this;
1103
  return cons;
1104
}
1105
 
1106
static void
1107
check_constant (_Jv_Constants *pool, jint cpool_index, jint type)
1108
{
1109
  if (cpool_index <= 0 || cpool_index >= pool->size)
1110
    throw new InternalError(JvNewStringLatin1("invalid constant pool index"));
1111
  if ((pool->tags[cpool_index] &
1112
        ~(JV_CONSTANT_ResolvedFlag|JV_CONSTANT_LazyFlag)) != type)
1113
    {
1114
      ::java::lang::StringBuffer *sb = new ::java::lang::StringBuffer();
1115
      sb->append(JvNewStringLatin1("expected pool constant "));
1116
      sb->append(type);
1117
      sb->append(JvNewStringLatin1(" but got "));
1118
      sb->append(jint (pool->tags[cpool_index]));
1119
      throw new InternalError(sb->toString());
1120
    }
1121
}
1122
 
1123
// Forward declaration
1124
static ::java::lang::annotation::Annotation *
1125
parseAnnotation(jclass klass, _Jv_Constants *pool,
1126
                unsigned char *&bytes, unsigned char *last);
1127
 
1128
static jobject
1129
parseAnnotationElement(jclass klass, _Jv_Constants *pool,
1130
                       unsigned char *&bytes, unsigned char *last)
1131
{
1132
  int tag = read_u1 (bytes, last);
1133
  jobject result;
1134
  switch (tag)
1135
    {
1136
    case 'B':
1137
      {
1138
        int cindex = read_u2 (bytes, last);
1139
        check_constant (pool, cindex, JV_CONSTANT_Integer);
1140
        result = Byte::valueOf (pool->data[cindex].i);
1141
      }
1142
      break;
1143
    case 'C':
1144
      {
1145
        int cindex = read_u2 (bytes, last);
1146
        check_constant (pool, cindex, JV_CONSTANT_Integer);
1147
        result = Character::valueOf (pool->data[cindex].i);
1148
      }
1149
      break;
1150
    case 'S':
1151
      {
1152
        int cindex = read_u2 (bytes, last);
1153
        check_constant (pool, cindex, JV_CONSTANT_Integer);
1154
        result = Short::valueOf (pool->data[cindex].i);
1155
      }
1156
      break;
1157
    case 'Z':
1158
      {
1159
        int cindex = read_u2 (bytes, last);
1160
        check_constant (pool, cindex, JV_CONSTANT_Integer);
1161
        result = Boolean::valueOf (jboolean (pool->data[cindex].i));
1162
      }
1163
      break;
1164
    case 'I':
1165
      {
1166
        int cindex = read_u2 (bytes, last);
1167
        check_constant (pool, cindex, JV_CONSTANT_Integer);
1168
        result = Integer::valueOf (pool->data[cindex].i);
1169
      }
1170
      break;
1171
    case 'D':
1172
      {
1173
        int cindex = read_u2 (bytes, last);
1174
        check_constant (pool, cindex, JV_CONSTANT_Double);
1175
        _Jv_word2 word;
1176
        memcpy (&word, &pool->data[cindex], 2 * sizeof (_Jv_word));
1177
        result = Double::valueOf (word.d);
1178
      }
1179
      break;
1180
    case 'F':
1181
      {
1182
        int cindex = read_u2 (bytes, last);
1183
        check_constant (pool, cindex, JV_CONSTANT_Float);
1184
        result = Float::valueOf (pool->data[cindex].f);
1185
      }
1186
      break;
1187
    case 'J':
1188
      {
1189
        int cindex = read_u2 (bytes, last);
1190
        check_constant (pool, cindex, JV_CONSTANT_Long);
1191
        _Jv_word2 word;
1192
        memcpy (&word, &pool->data[cindex], 2 * sizeof (_Jv_word));
1193
        result = Long::valueOf (word.l);
1194
      }
1195
      break;
1196
    case 's':
1197
      {
1198
        int cindex = read_u2 (bytes, last);
1199
        // Despite what the JVM spec says, compilers generate a Utf8
1200
        // constant here, not a String.
1201
        check_constant (pool, cindex, JV_CONSTANT_Utf8);
1202
        result = pool->data[cindex].utf8->toString();
1203
      }
1204
      break;
1205
    case 'e':
1206
      {
1207
        int type_name_index = read_u2 (bytes, last);
1208
        check_constant (pool, type_name_index, JV_CONSTANT_Utf8);
1209
        int const_name_index = read_u2 (bytes, last);
1210
        check_constant (pool, const_name_index, JV_CONSTANT_Utf8);
1211
 
1212
        _Jv_Utf8Const *u_name = pool->data[type_name_index].utf8;
1213
        _Jv_Utf8Const *e_name = pool->data[const_name_index].utf8;
1214
 
1215
        // FIXME: throw correct exceptions at the correct times.
1216
        jclass e_class = _Jv_FindClassFromSignature(u_name->chars(),
1217
                                                    klass->getClassLoaderInternal());
1218
        result = ::java::lang::Enum::valueOf(e_class, e_name->toString());
1219
      }
1220
      break;
1221
    case 'c':
1222
      {
1223
        int cindex = read_u2 (bytes, last);
1224
        check_constant (pool, cindex, JV_CONSTANT_Utf8);
1225
        _Jv_Utf8Const *u_name = pool->data[cindex].utf8;
1226
        jclass anno_class
1227
          = _Jv_FindClassFromSignatureNoException(u_name->chars(),
1228
                                                  klass->getClassLoaderInternal());
1229
        // FIXME: not correct: we should lazily do this when trying to
1230
        // read the element.  This means that
1231
        // AnnotationInvocationHandler needs to have a special case.
1232
        if (! anno_class)
1233
          // FIXME: original exception...
1234
          throw new TypeNotPresentException(u_name->toString(), NULL);
1235
        result = anno_class;
1236
      }
1237
      break;
1238
    case '@':
1239
      result = parseAnnotation (klass, pool, bytes, last);
1240
      break;
1241
    case '[':
1242
      {
1243
        int n_array_elts = read_u2 (bytes, last);
1244
        jobjectArray aresult = _Jv_NewObjectArray (n_array_elts,
1245
                                                   &Object::class$, NULL);
1246
        jobject *elts = elements (aresult);
1247
        for (int i = 0; i < n_array_elts; ++i)
1248
          elts[i] = parseAnnotationElement(klass, pool, bytes, last);
1249
        result = aresult;
1250
      }
1251
      break;
1252
    default:
1253
      throw new java::lang::InternalError();
1254
    }
1255
  return result;
1256
}
1257
 
1258
static ::java::lang::annotation::Annotation *
1259
parseAnnotation(jclass klass, _Jv_Constants *pool,
1260
                unsigned char *&bytes, unsigned char *last)
1261
{
1262
  int type_index = read_u2 (bytes, last);
1263
  check_constant (pool, type_index, JV_CONSTANT_Utf8);
1264
 
1265
  _Jv_Utf8Const *u_name = pool->data[type_index].utf8;
1266
  jclass anno_class = _Jv_FindClassFromSignatureNoException(u_name->chars(),
1267
                                                            klass->getClassLoaderInternal());
1268
  // FIXME: what to do if anno_class==NULL?
1269
 
1270
  ::java::util::HashMap *hmap = new ::java::util::HashMap();
1271
  int npairs = read_u2 (bytes, last);
1272
  for (int i = 0; i < npairs; ++i)
1273
    {
1274
      int name_index = read_u2 (bytes, last);
1275
      check_constant (pool, name_index, JV_CONSTANT_Utf8);
1276
      jstring name = _Jv_NewStringUtf8Const (pool->data[name_index].utf8);
1277
      jobject value = parseAnnotationElement (klass, pool, bytes, last);
1278
      // FIXME: any checks needed for name?
1279
      hmap->put(name, value);
1280
    }
1281
  using namespace ::sun::reflect::annotation;
1282
  return AnnotationInvocationHandler::create (anno_class,
1283
                                              (::java::util::Map *) hmap);
1284
}
1285
 
1286
static jobjectArray
1287
parseAnnotations(jclass klass, _Jv_Constants *pool,
1288
                 unsigned char *&bytes, unsigned char *last)
1289
{
1290
  int num = read_u2 (bytes, last);
1291
  jobjectArray result = _Jv_NewObjectArray (num,
1292
                                            &::java::lang::annotation::Annotation::class$,
1293
                                            NULL);
1294
  jobject *elts = elements (result);
1295
  for (int i = 0; i < num; ++i)
1296
    elts[i] = parseAnnotation(klass, pool, bytes, last);
1297
  return result;
1298
}
1299
 
1300
static jobjectArray
1301
parseParameterAnnotations(jclass klass, _Jv_Constants *pool,
1302
                          unsigned char *&bytes, unsigned char *last)
1303
{
1304
  jclass anno = &::java::lang::annotation::Annotation::class$;
1305
  jclass annoary = _Jv_GetArrayClass (anno, anno->getClassLoaderInternal());
1306
 
1307
  // FIXME: something should check the number of params versus the
1308
  // method
1309
  int n_params = read_u1 (bytes, last);
1310
  jobjectArray result = _Jv_NewObjectArray (n_params, annoary, NULL);
1311
  jobject *elts = elements (result);
1312
  for (int i = 0; i < n_params; ++i)
1313
    elts[i] = parseAnnotations(klass, pool, bytes, last);
1314
  return result;
1315
}
1316
 
1317
jobject
1318
java::lang::Class::getMethodDefaultValue(::java::lang::reflect::Method *meth)
1319
{
1320
  // FIXME: could cache the value here...
1321
 
1322
  unsigned char *bytes = reflection_data;
1323
  if (bytes == NULL)
1324
    return 0;
1325
 
1326
  unsigned short meth_index = _Jv_FromReflectedMethod (meth) - methods;
1327
 
1328
  while (true)
1329
    {
1330
      int type = read_u1 (bytes);
1331
      if (type == JV_DONE_ATTR)
1332
        return NULL;
1333
      int len = read_4 (bytes);
1334
      unsigned char *next = bytes + len;
1335
      if (type != JV_METHOD_ATTR)
1336
        {
1337
          bytes = next;
1338
          continue;
1339
        }
1340
      int kind = read_u1 (bytes, next);
1341
      if (kind != JV_ANNOTATION_DEFAULT_KIND)
1342
        {
1343
          bytes = next;
1344
          continue;
1345
        }
1346
      int index = read_u2 (bytes, next);
1347
      if (meth_index != index)
1348
        {
1349
          bytes = next;
1350
          continue;
1351
        }
1352
 
1353
      // FIXME: could cache here.  If we do then we have to clone any
1354
      // array result.
1355
      return parseAnnotationElement(this, &this->constants, bytes, next);
1356
    }
1357
}
1358
 
1359
jobjectArray
1360
java::lang::Class::getDeclaredAnnotations(jint /* jv_attr_type */ member_type,
1361
                                          jint member_index,
1362
                                          jint /* jv_attr_kind */ kind_req)
1363
{
1364
  using namespace java::lang::annotation;
1365
  jobjectArray result;
1366
 
1367
  unsigned char *bytes = reflection_data;
1368
  if (bytes == NULL)
1369
    return 0;
1370
 
1371
  if (loader == NULL)
1372
    loader = (ClassLoader *)VMClassLoader::bootLoader;
1373
 
1374
  result = (loader->getDeclaredAnnotations
1375
            (this, member_type, member_index, kind_req));
1376
  if (result)
1377
    return result;
1378
 
1379
  for (;;)
1380
    {
1381
      int type = read_u1 (bytes);
1382
      if (type == JV_DONE_ATTR)
1383
        return NULL;
1384
      int len = read_4 (bytes);
1385
      unsigned char *next = bytes + len;
1386
      if (type != member_type)
1387
        {
1388
          bytes = next;
1389
          continue;
1390
        }
1391
      int kind = read_u1 (bytes, next);
1392
      if (kind != kind_req)
1393
        {
1394
          bytes = next;
1395
          continue;
1396
        }
1397
      if (member_type != JV_CLASS_ATTR)
1398
        {
1399
          int index = read_u2 (bytes, next);
1400
          if (member_index != index)
1401
            {
1402
              bytes = next;
1403
              continue;
1404
            }
1405
        }
1406
 
1407
      if (kind_req == JV_PARAMETER_ANNOTATIONS_KIND)
1408
        result = ((parseParameterAnnotations
1409
                   (this, &this->constants, bytes, next)));
1410
      else
1411
        result = ((parseAnnotations (this, &this->constants, bytes, next)));
1412
      break;
1413
    }
1414
 
1415
  return (loader->putDeclaredAnnotations
1416
          (this, member_type, member_index, kind_req, result));
1417
}
1418
 
1419
jobjectArray
1420
java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Method *meth,
1421
                                          jboolean is_param)
1422
{
1423
  unsigned short meth_index = _Jv_FromReflectedMethod (meth) - methods;
1424
  return getDeclaredAnnotations(JV_METHOD_ATTR, meth_index,
1425
                                (is_param
1426
                                 ? JV_PARAMETER_ANNOTATIONS_KIND
1427
                                 : JV_ANNOTATIONS_KIND));
1428
}
1429
 
1430
jobjectArray
1431
java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Constructor *cons,
1432
                                          jboolean is_param)
1433
{
1434
  unsigned short meth_index = _Jv_FromReflectedConstructor (cons) - methods;
1435
  return getDeclaredAnnotations(JV_METHOD_ATTR, meth_index,
1436
                                (is_param
1437
                                 ? JV_PARAMETER_ANNOTATIONS_KIND
1438
                                 : JV_ANNOTATIONS_KIND));
1439
}
1440
 
1441
jobjectArray
1442
java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Field *fld)
1443
{
1444
  unsigned short field_index = _Jv_FromReflectedField (fld) - fields;
1445
  return getDeclaredAnnotations(JV_FIELD_ATTR, field_index,
1446
                                JV_ANNOTATIONS_KIND);
1447
}
1448
 
1449
JArray< ::java::lang::annotation::Annotation *> *
1450
java::lang::Class::getDeclaredAnnotationsInternal()
1451
{
1452
  return (JArray< ::java::lang::annotation::Annotation *> *) getDeclaredAnnotations(JV_CLASS_ATTR, 0, JV_ANNOTATIONS_KIND);
1453
}
1454
 
1455
static jclass
1456
resolve_class_constant (jclass klass, _Jv_Constants *pool, int cpool_index)
1457
{
1458
  check_constant (pool, cpool_index, JV_CONSTANT_Class);
1459
  // FIXME: what is the correct thing to do with an exception here?
1460
  return _Jv_Linker::resolve_pool_entry (klass, cpool_index, false).clazz;
1461
}
1462
 
1463
jint
1464
java::lang::Class::findInnerClassAttribute()
1465
{
1466
  unsigned char *bytes = reflection_data;
1467
  if (bytes == NULL)
1468
    return -1;
1469
  while (true)
1470
    {
1471
      int type = read_u1 (bytes);
1472
      if (type == JV_DONE_ATTR)
1473
        break;
1474
      // After the type but before the length.
1475
      unsigned char *save = bytes;
1476
      int len = read_4 (bytes);
1477
      unsigned char *next = bytes + len;
1478
      if (type != JV_CLASS_ATTR)
1479
        {
1480
          bytes = next;
1481
          continue;
1482
        }
1483
      int kind = read_u1 (bytes, next);
1484
      if (kind != JV_INNER_CLASSES_KIND)
1485
        {
1486
          bytes = next;
1487
          continue;
1488
        }
1489
      return save - reflection_data;
1490
    }
1491
  return -1;
1492
}
1493
 
1494
jint
1495
java::lang::Class::findDeclaredClasses(JArray<jclass> *result,
1496
                                       jboolean publicOnly,
1497
                                       jint offset)
1498
{
1499
  unsigned char *bytes = reflection_data + offset;
1500
  int len = read_4 (bytes);
1501
  unsigned char *next = bytes + len;
1502
  // Skip a byte.
1503
  read_u1 (bytes, next);
1504
  int n_classes = read_u2 (bytes, next);
1505
  int count = 0;
1506
  for (int i = 0; i < n_classes; ++i)
1507
    {
1508
      int inner_class_index = read_u2 (bytes, next);
1509
      int outer_class_index = read_u2 (bytes, next);
1510
      /*int inner_name_index = */ read_u2 (bytes, next);
1511
      int inner_flags = read_u2 (bytes, next);
1512
 
1513
      if (inner_class_index == 0 || outer_class_index == 0)
1514
        continue;
1515
      if (resolve_class_constant (this, &constants, outer_class_index) == this)
1516
        {
1517
          jclass inner = resolve_class_constant (this, &constants,
1518
                                                 inner_class_index);
1519
          if (! publicOnly
1520
              || ((inner_flags
1521
                   & java::lang::reflect::Modifier::PUBLIC) != 0))
1522
            {
1523
              if (result)
1524
                {
1525
                  jclass *elts = elements (result);
1526
                  elts[count] = inner;
1527
                }
1528
              ++count;
1529
            }
1530
        }
1531
    }
1532
 
1533
  return count;
1534
}
1535
 
1536
JArray<jclass> *
1537
java::lang::Class::getDeclaredClasses (jboolean publicOnly)
1538
{
1539
  int offset = findInnerClassAttribute();
1540
  int count;
1541
  if (offset == -1)
1542
    {
1543
      // No InnerClasses attribute, so no declared classes.
1544
      count = 0;
1545
    }
1546
  else
1547
    count = findDeclaredClasses(NULL, publicOnly, offset);
1548
  JArray<jclass> *result
1549
    = (JArray<jclass> *) JvNewObjectArray (count, &java::lang::Class::class$,
1550
                                           NULL);
1551
  if (count > 0)
1552
    findDeclaredClasses(result, publicOnly, offset);
1553
  return result;
1554
}
1555
 
1556
jclass
1557
java::lang::Class::getDeclaringClass (void)
1558
{
1559
  int offset = findInnerClassAttribute();
1560
  if (offset == -1)
1561
    return NULL;
1562
 
1563
  unsigned char *bytes = reflection_data + offset;
1564
  int len = read_4 (bytes);
1565
  unsigned char *next = bytes + len;
1566
  // Skip a byte.
1567
  read_u1 (bytes, next);
1568
  int n_classes = read_u2 (bytes, next);
1569
  for (int i = 0; i < n_classes; ++i)
1570
    {
1571
      int inner_class_index = read_u2 (bytes, next);
1572
      int outer_class_index = read_u2 (bytes, next);
1573
      /*int inner_name_index = */read_u2 (bytes, next);
1574
      /*int inner_flags = */read_u2 (bytes, next);
1575
 
1576
      if (inner_class_index == 0 || outer_class_index == 0)
1577
        continue;
1578
      if (resolve_class_constant (this, &constants, inner_class_index) == this)
1579
        return resolve_class_constant (this, &constants, outer_class_index);
1580
    }
1581
 
1582
  return NULL;
1583
}
1584
 
1585
jboolean
1586
java::lang::Class::isAnonymousClass()
1587
{
1588
  int offset = findInnerClassAttribute();
1589
  if (offset == -1)
1590
    return false;
1591
 
1592
  unsigned char *bytes = reflection_data + offset;
1593
  int len = read_4 (bytes);
1594
  unsigned char *next = bytes + len;
1595
  // Skip a byte.
1596
  read_u1 (bytes, next);
1597
  int n_classes = read_u2 (bytes, next);
1598
  for (int i = 0; i < n_classes; ++i)
1599
    {
1600
      int inner_class_index = read_u2 (bytes, next);
1601
      /*int outer_class_index = */read_u2 (bytes, next);
1602
      int inner_name_index = read_u2 (bytes, next);
1603
      /*int inner_flags = */read_u2 (bytes, next);
1604
 
1605
      if (inner_class_index == 0)
1606
        continue;
1607
      if (resolve_class_constant (this, &constants, inner_class_index) == this)
1608
        return inner_name_index == 0;
1609
    }
1610
 
1611
  return false;
1612
}
1613
 
1614
jboolean
1615
java::lang::Class::isLocalClass()
1616
{
1617
  _Jv_word indexes;
1618
  indexes.i = getEnclosingMethodData();
1619
  return indexes.i != 0;
1620
}
1621
 
1622
jboolean
1623
java::lang::Class::isMemberClass()
1624
{
1625
  // FIXME: is this correct?
1626
  return !isLocalClass() && getDeclaringClass() != NULL;
1627
}
1628
 
1629
 
1630
 
1631
//
1632
// Some class-related convenience functions.
1633
//
1634
 
1635
// Find a method declared in the class.  If it is not declared locally
1636
// (or if it is inherited), return NULL.
1637
_Jv_Method *
1638
_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
1639
                    _Jv_Utf8Const *signature)
1640
{
1641
  for (int i = 0; i < klass->method_count; ++i)
1642
    {
1643
      if (_Jv_equalUtf8Consts (name, klass->methods[i].name)
1644
          && _Jv_equalUtf8Consts (signature, klass->methods[i].signature))
1645
        return &klass->methods[i];
1646
    }
1647
  return NULL;
1648
}
1649
 
1650
_Jv_Method *
1651
_Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
1652
                          _Jv_Utf8Const *signature,
1653
                          jclass *declarer_result)
1654
{
1655
  for (; klass; klass = klass->getSuperclass())
1656
    {
1657
      _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
1658
 
1659
      if (meth)
1660
        {
1661
          if (declarer_result)
1662
            *declarer_result = klass;
1663
          return meth;
1664
        }
1665
    }
1666
 
1667
  return NULL;
1668
}
1669
 
1670
java::lang::reflect::Method *
1671
_Jv_GetReflectedMethod (jclass klass, _Jv_Utf8Const *name,
1672
                       _Jv_Utf8Const *signature)
1673
{
1674
  for (; klass; klass = klass->getSuperclass())
1675
    {
1676
      _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
1677
      if (meth)
1678
        {
1679
          using namespace java::lang::reflect;
1680
          Method *rmethod = new Method ();
1681
          rmethod->offset = (char*) meth - (char*) klass->methods;
1682
          rmethod->declaringClass = klass;
1683
          return rmethod;
1684
        }
1685
    }
1686
 
1687
  return NULL;
1688
}
1689
 
1690
#ifdef HAVE_TLS
1691
 
1692
// NOTE: MCACHE_SIZE should be a power of 2 minus one.
1693
#define MCACHE_SIZE 31
1694
 
1695
struct _Jv_mcache
1696
{
1697
  jclass klass;
1698
  _Jv_Method *method;
1699
};
1700
 
1701
static __thread _Jv_mcache *method_cache;
1702
#endif // HAVE_TLS
1703
 
1704
static void *
1705
_Jv_FindMethodInCache (jclass klass MAYBE_UNUSED,
1706
                       _Jv_Utf8Const *name MAYBE_UNUSED,
1707
                       _Jv_Utf8Const *signature MAYBE_UNUSED)
1708
{
1709
#ifdef HAVE_TLS
1710
  _Jv_mcache *cache = method_cache;
1711
  if (cache)
1712
    {
1713
      int index = name->hash16 () & MCACHE_SIZE;
1714
      _Jv_mcache *mc = &cache[index];
1715
      _Jv_Method *m = mc->method;
1716
 
1717
      if (mc->klass == klass
1718
          && _Jv_equalUtf8Consts (m->name, name)
1719
          && _Jv_equalUtf8Consts (m->signature, signature))
1720
        return mc->method->ncode;
1721
    }
1722
#endif // HAVE_TLS
1723
  return NULL;
1724
}
1725
 
1726
static void
1727
_Jv_AddMethodToCache (jclass klass MAYBE_UNUSED,
1728
                      _Jv_Method *method MAYBE_UNUSED)
1729
{
1730
#ifdef HAVE_TLS
1731
  if (method_cache == NULL)
1732
    method_cache = (_Jv_mcache *) _Jv_MallocUnchecked((MCACHE_SIZE + 1)
1733
                                                      * sizeof (_Jv_mcache));
1734
  // If the allocation failed, just keep going.
1735
  if (method_cache != NULL)
1736
    {
1737
      int index = method->name->hash16 () & MCACHE_SIZE;
1738
      method_cache[index].method = method;
1739
      method_cache[index].klass = klass;
1740
    }
1741
#endif // HAVE_TLS
1742
}
1743
 
1744
// Free this thread's method cache.  We explicitly manage this memory
1745
// as the GC does not yet know how to scan TLS on all platforms.
1746
void
1747
_Jv_FreeMethodCache ()
1748
{
1749
#ifdef HAVE_TLS
1750
  if (method_cache != NULL)
1751
    {
1752
      _Jv_Free(method_cache);
1753
      method_cache = NULL;
1754
    }
1755
#endif // HAVE_TLS
1756
}
1757
 
1758
void *
1759
_Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
1760
                           _Jv_Utf8Const *signature)
1761
{
1762
  using namespace java::lang::reflect;
1763
 
1764
  void *ncode = _Jv_FindMethodInCache (klass, name, signature);
1765
  if (ncode != 0)
1766
    return ncode;
1767
 
1768
  for (; klass; klass = klass->getSuperclass())
1769
    {
1770
      _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
1771
      if (! meth)
1772
        continue;
1773
 
1774
      if (Modifier::isStatic(meth->accflags))
1775
        throw new java::lang::IncompatibleClassChangeError
1776
          (_Jv_GetMethodString (klass, meth));
1777
      if (Modifier::isAbstract(meth->accflags))
1778
        throw new java::lang::AbstractMethodError
1779
          (_Jv_GetMethodString (klass, meth));
1780
      if (! Modifier::isPublic(meth->accflags))
1781
        throw new java::lang::IllegalAccessError
1782
          (_Jv_GetMethodString (klass, meth));
1783
 
1784
      _Jv_AddMethodToCache (klass, meth);
1785
 
1786
      return meth->ncode;
1787
    }
1788
  throw new java::lang::IncompatibleClassChangeError;
1789
}
1790
 
1791
// Fast interface method lookup by index.
1792
void *
1793
_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface, int method_idx)
1794
{
1795
  _Jv_IDispatchTable *cldt = klass->idt;
1796
  int idx = iface->ioffsets[cldt->iindex] + method_idx;
1797
  return cldt->itable[idx];
1798
}
1799
 
1800
jboolean
1801
_Jv_IsAssignableFrom (jclass source, jclass target)
1802
{
1803
  if (source == target)
1804
    return true;
1805
 
1806
  // If target is array, so must source be.  
1807
  while (target->isArray ())
1808
    {
1809
      if (! source->isArray())
1810
        return false;
1811
      target = target->getComponentType();
1812
      source = source->getComponentType();
1813
    }
1814
 
1815
  if (target->isInterface())
1816
    {
1817
      // Abstract classes have no IDT, and IDTs provide no way to check
1818
      // two interfaces for assignability.
1819
      if (__builtin_expect
1820
          (source->idt == NULL || source->isInterface(), false))
1821
        return _Jv_InterfaceAssignableFrom (source, target);
1822
 
1823
      _Jv_IDispatchTable *cl_idt = source->idt;
1824
 
1825
      if (__builtin_expect ((target->ioffsets == NULL), false))
1826
        return false; // No class implementing TARGET has been loaded.    
1827
      jshort cl_iindex = cl_idt->iindex;
1828
      if (cl_iindex < target->ioffsets[0])
1829
        {
1830
          jshort offset = target->ioffsets[cl_iindex];
1831
          if (offset != -1 && offset < cl_idt->itable_length
1832
              && cl_idt->itable[offset] == target)
1833
            return true;
1834
        }
1835
      return false;
1836
    }
1837
 
1838
  // Primitive TYPE classes are only assignable to themselves.
1839
  if (__builtin_expect (target->isPrimitive() || source->isPrimitive(), false))
1840
    return false;
1841
 
1842
  if (target == &java::lang::Object::class$)
1843
    return true;
1844
  else if (source->ancestors == NULL || target->ancestors == NULL)
1845
    {
1846
      // We need this case when either SOURCE or TARGET has not has
1847
      // its constant-time tables prepared.
1848
 
1849
      // At this point we know that TARGET can't be Object, so it is
1850
      // safe to use that as the termination point.
1851
      while (source && source != &java::lang::Object::class$)
1852
        {
1853
          if (source == target)
1854
            return true;
1855
          source = source->getSuperclass();
1856
        }
1857
    }
1858
  else if (source->depth >= target->depth
1859
           && source->ancestors[source->depth - target->depth] == target)
1860
    return true;
1861
 
1862
  return false;
1863
}
1864
 
1865
// Interface type checking, the slow way. Returns TRUE if IFACE is a 
1866
// superinterface of SOURCE. This is used when SOURCE is also an interface,
1867
// or a class with no interface dispatch table.
1868
jboolean
1869
_Jv_InterfaceAssignableFrom (jclass source, jclass iface)
1870
{
1871
  for (int i = 0; i < source->interface_count; i++)
1872
    {
1873
      jclass interface = source->interfaces[i];
1874
      if (iface == interface
1875
          || _Jv_InterfaceAssignableFrom (interface, iface))
1876
        return true;
1877
    }
1878
 
1879
  if (!source->isInterface()
1880
      && source->superclass
1881
      && _Jv_InterfaceAssignableFrom (source->superclass, iface))
1882
    return true;
1883
 
1884
  return false;
1885
}
1886
 
1887
jboolean
1888
_Jv_IsInstanceOf(jobject obj, jclass cl)
1889
{
1890
  if (__builtin_expect (!obj, false))
1891
    return false;
1892
  return _Jv_IsAssignableFrom (JV_CLASS (obj), cl);
1893
}
1894
 
1895
void *
1896
_Jv_CheckCast (jclass c, jobject obj)
1897
{
1898
  if (__builtin_expect
1899
      (obj != NULL && ! _Jv_IsAssignableFrom(JV_CLASS (obj), c), false))
1900
    throw new java::lang::ClassCastException
1901
      ((new java::lang::StringBuffer
1902
        (obj->getClass()->getName()))->append
1903
       (JvNewStringUTF(" cannot be cast to "))->append
1904
       (c->getName())->toString());
1905
 
1906
  return obj;
1907
}
1908
 
1909
void
1910
_Jv_CheckArrayStore (jobject arr, jobject obj)
1911
{
1912
  if (obj)
1913
    {
1914
      JvAssert (arr != NULL);
1915
      jclass elt_class = (JV_CLASS (arr))->getComponentType();
1916
      if (elt_class == &java::lang::Object::class$)
1917
        return;
1918
      jclass obj_class = JV_CLASS (obj);
1919
      if (__builtin_expect
1920
          (! _Jv_IsAssignableFrom (obj_class, elt_class), false))
1921
        throw new java::lang::ArrayStoreException
1922
                ((new java::lang::StringBuffer
1923
                 (JvNewStringUTF("Cannot store ")))->append
1924
                 (obj_class->getName())->append
1925
                 (JvNewStringUTF(" in array of type "))->append
1926
                 (elt_class->getName())->toString());
1927
    }
1928
}
1929
 
1930
jboolean
1931
_Jv_IsAssignableFromSlow (jclass source, jclass target)
1932
{
1933
  // First, strip arrays.
1934
  while (target->isArray ())
1935
    {
1936
      // If target is array, source must be as well.
1937
      if (! source->isArray ())
1938
       return false;
1939
      target = target->getComponentType ();
1940
      source = source->getComponentType ();
1941
    }
1942
 
1943
  // Quick success.
1944
  if (target == &java::lang::Object::class$)
1945
    return true;
1946
 
1947
  // Ensure that the classes have their supers installed.
1948
  _Jv_Linker::wait_for_state (source, JV_STATE_LOADING);
1949
  _Jv_Linker::wait_for_state (target, JV_STATE_LOADING);
1950
 
1951
  do
1952
    {
1953
      if (source == target)
1954
       return true;
1955
 
1956
      if (target->isPrimitive () || source->isPrimitive ())
1957
       return false;
1958
 
1959
      if (target->isInterface ())
1960
       {
1961
         for (int i = 0; i < source->interface_count; ++i)
1962
           {
1963
             // We use a recursive call because we also need to
1964
             // check superinterfaces.
1965
             if (_Jv_IsAssignableFromSlow (source->getInterface (i), target))
1966
               return true;
1967
           }
1968
       }
1969
      source = source->getSuperclass ();
1970
    }
1971
  while (source != NULL);
1972
 
1973
  return false;
1974
}
1975
 
1976
// Lookup an interface method by name.  This is very similar to
1977
// purpose to _getMethod, but the interfaces are quite different.  It
1978
// might be a good idea for _getMethod to call this function.
1979
//
1980
// Return true of the method is found, with the class in FOUND_CLASS
1981
// and the index in INDEX.
1982
bool
1983
_Jv_getInterfaceMethod (jclass search_class, jclass &found_class, int &index,
1984
                        const _Jv_Utf8Const *utf_name,
1985
                        const _Jv_Utf8Const *utf_sig)
1986
{
1987
   for (jclass klass = search_class; klass; klass = klass->getSuperclass())
1988
    {
1989
      // FIXME: Throw an exception?
1990
      if (!klass->isInterface ())
1991
        return false;
1992
 
1993
      int max = klass->method_count;
1994
      int offset = 0;
1995
      for (int i = 0; i < max; ++i)
1996
        {
1997
          // Skip <clinit> here, as it will not be in the IDT.
1998
          if (klass->methods[i].name->first() == '<')
1999
            continue;
2000
 
2001
          if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
2002
              && _Jv_equalUtf8Consts (klass->methods[i].signature, utf_sig))
2003
            {
2004
              // Found it.
2005
              using namespace java::lang::reflect;
2006
 
2007
              // FIXME: Method must be public.  Throw an exception?
2008
              if (! Modifier::isPublic (klass->methods[i].accflags))
2009
                break;
2010
 
2011
              found_class = klass;
2012
              // Interface method indexes count from 1.
2013
              index = offset + 1;
2014
              return true;
2015
            }
2016
 
2017
          ++offset;
2018
        }
2019
    }
2020
 
2021
  // If we haven't found a match, and this class is an interface, then
2022
  // check all the superinterfaces.
2023
  if (search_class->isInterface())
2024
    {
2025
      for (int i = 0; i < search_class->interface_count; ++i)
2026
        {
2027
          using namespace java::lang::reflect;
2028
          bool found = _Jv_getInterfaceMethod (search_class->interfaces[i],
2029
                                               found_class, index,
2030
                                               utf_name, utf_sig);
2031
          if (found)
2032
            return true;
2033
        }
2034
    }
2035
 
2036
  return false;
2037
}
2038
 
2039
#ifdef INTERPRETER
2040
_Jv_MethodBase *
2041
_Jv_FindInterpreterMethod (jclass klass, jmethodID desired_method)
2042
{
2043
  using namespace java::lang::reflect;
2044
 
2045
  _Jv_InterpClass *iclass
2046
    = reinterpret_cast<_Jv_InterpClass *> (klass->aux_info);
2047
  _Jv_MethodBase **imethods = _Jv_GetFirstMethod (iclass);
2048
 
2049
  for (int i = 0; i < JvNumMethods (klass); ++i)
2050
    {
2051
      _Jv_MethodBase *imeth = imethods[i];
2052
      if (imeth->get_method () == desired_method)
2053
        return imeth;
2054
    }
2055
 
2056
  return NULL;
2057
}
2058
#endif
2059
 
2060
// Return Utf8 name of a class. This function is here for code that
2061
// can't access klass->name directly.
2062
_Jv_Utf8Const*
2063
_Jv_GetClassNameUtf8 (jclass klass)
2064
{
2065
  return klass->name;
2066
}
2067
 
2068
jclass
2069
_Jv_GetMethodDeclaringClass (jmethodID method)
2070
{
2071
  _Jv_StackTrace::UpdateNCodeMap ();
2072
  jobject obj = reinterpret_cast<jobject> (method->ncode);
2073
  return reinterpret_cast<jclass> (_Jv_StackTrace::ncodeMap->get (obj));
2074
}
2075
 
2076
jbyte
2077
_Jv_GetClassState (jclass klass)
2078
{
2079
  return klass->state;
2080
}
2081
 
2082
#ifdef INTERPRETER
2083
jstring
2084
_Jv_GetInterpClassSourceFile (jclass klass)
2085
{
2086
  if (_Jv_IsInterpretedClass (klass))
2087
    {
2088
      _Jv_InterpClass *iclass =
2089
        reinterpret_cast<_Jv_InterpClass *> (klass->aux_info);
2090
      return iclass->source_file_name;
2091
    }
2092
 
2093
  return NULL;
2094
}
2095
#endif

powered by: WebSVN 2.1.0

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