OSDN Git Service

2007-05-31 Andrew Haley <aph@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / natClass.cc
1 // natClass.cc - Implementation of java.lang.Class native methods.
2
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4    Free Software Foundation
5
6    This file is part of libgcj.
7
8 This software is copyrighted work licensed under the terms of the
9 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
10 details.  */
11
12 #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 \f
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   ((void (*) (jobject)) meth->ncode) (r);
665   return r;
666 }
667
668 void
669 java::lang::Class::finalize (void)
670 {
671   engine->unregister(this);
672 }
673
674 void
675 _Jv_ClosureList::releaseClosures (_Jv_ClosureList **closures)
676 {
677   if (!closures)
678     return;
679
680   while (_Jv_ClosureList *current = *closures)
681     {
682       *closures = current->next;
683       ffi_closure_free (current->ptr);
684     }
685 }
686
687 void
688 _Jv_ClosureList::registerClosure (jclass klass, void *ptr)
689 {
690   _Jv_ClosureList **closures = klass->engine->get_closure_list (klass);
691   this->ptr = ptr;
692   this->next = *closures;
693   *closures = this;
694 }
695
696 // This implements the initialization process for a class.  From Spec
697 // section 12.4.2.
698 void
699 java::lang::Class::initializeClass (void)
700 {
701   // Short-circuit to avoid needless locking (expression includes
702   // JV_STATE_PHANTOM and JV_STATE_DONE).
703   if (state >= JV_STATE_PHANTOM)
704     return;
705
706   // Step 1.  We introduce a new scope so we can synchronize more
707   // easily.
708   {
709     JvSynchronize sync (this);
710
711     if (state < JV_STATE_LINKED)
712       {
713         try
714           {
715             _Jv_Linker::wait_for_state(this, JV_STATE_LINKED);
716           }
717         catch (java::lang::SecurityException *x)
718           {
719             throw x;
720           }
721         catch (java::lang::Throwable *x)
722           {
723             // Turn into a NoClassDefFoundError.
724             java::lang::NoClassDefFoundError *result
725               = new java::lang::NoClassDefFoundError(getName());
726             result->initCause(x);
727             throw result;
728           }
729       }
730
731     // Step 2.
732     java::lang::Thread *self = java::lang::Thread::currentThread();
733     self = (java::lang::Thread *) ((long) self | 1);
734     while (state == JV_STATE_IN_PROGRESS && thread && thread != self)
735       wait ();
736
737     // Steps 3 &  4.
738     if (state == JV_STATE_DONE || state == JV_STATE_IN_PROGRESS)
739       return;
740
741     // Step 5.
742     if (state == JV_STATE_ERROR)
743       throw new java::lang::NoClassDefFoundError (getName());
744
745     // Step 6.
746     thread = self;
747     _Jv_Linker::wait_for_state (this, JV_STATE_LINKED);
748     state = JV_STATE_IN_PROGRESS;
749   }
750
751   // Step 7.
752   if (! isInterface () && superclass)
753     {
754       try
755         {
756           _Jv_InitClass (superclass);
757         }
758       catch (java::lang::SecurityException *x)
759         {
760           throw x;
761         }
762       catch (java::lang::Throwable *except)
763         {
764           // Caught an exception.
765           JvSynchronize sync (this);
766           state = JV_STATE_ERROR;
767           notifyAll ();
768           throw except;
769         }
770     }
771
772   // Steps 8, 9, 10, 11.
773   try
774     {
775       _Jv_Method *meth = _Jv_GetMethodLocal (this, clinit_name,
776                                              void_signature);
777       if (meth)
778         ((void (*) (void)) meth->ncode) ();
779     }
780   catch (java::lang::SecurityException *x)
781     {
782       throw x;
783     }
784   catch (java::lang::Throwable *except)
785     {
786       if (! java::lang::Error::class$.isInstance(except))
787         {
788           try
789             {
790               except = new ExceptionInInitializerError (except);
791             }
792           catch (java::lang::Throwable *t)
793             {
794               except = t;
795             }
796         }
797
798       JvSynchronize sync (this);
799       state = JV_STATE_ERROR;
800       notifyAll ();
801       throw except;
802     }
803
804   JvSynchronize sync (this);
805   state = JV_STATE_DONE;
806   notifyAll ();
807 }
808
809 // Only used by serialization
810 java::lang::reflect::Field *
811 java::lang::Class::getPrivateField (jstring name)
812 {
813   int hash = name->hashCode ();
814
815   java::lang::reflect::Field* rfield;
816   for (int i = 0;  i < field_count;  i++)
817     {
818       _Jv_Field *field = &fields[i];
819       if (! _Jv_equal (field->name, name, hash))
820         continue;
821       rfield = new java::lang::reflect::Field ();
822       rfield->offset = (char*) field - (char*) fields;
823       rfield->declaringClass = this;
824       rfield->name = name;
825       return rfield;
826     }
827   jclass superclass = getSuperclass();
828   if (superclass == NULL)
829     return NULL;
830   rfield = superclass->getPrivateField(name);
831   for (int i = 0; i < interface_count && rfield == NULL; ++i)
832     rfield = interfaces[i]->getPrivateField (name);
833   return rfield;
834 }
835
836 // Only used by serialization
837 java::lang::reflect::Method *
838 java::lang::Class::getPrivateMethod (jstring name, JArray<jclass> *param_types)
839 {
840   jstring partial_sig = getSignature (param_types, false);
841   jint p_len = partial_sig->length();
842   _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
843   for (Class *klass = this; klass; klass = klass->getSuperclass())
844     {
845       int i = klass->isPrimitive () ? 0 : klass->method_count;
846       while (--i >= 0)
847         {
848           if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
849               && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len))
850             {
851               // Found it.
852               using namespace java::lang::reflect;
853
854               Method *rmethod = new Method ();
855               rmethod->offset = ((char *) (&klass->methods[i])
856                                  - (char *) klass->methods);
857               rmethod->declaringClass = klass;
858               return rmethod;
859             }
860         }
861     }
862   throw new java::lang::NoSuchMethodException (name);
863 }
864
865 // Private accessor method for Java code to retrieve the protection domain.
866 java::security::ProtectionDomain *
867 java::lang::Class::getProtectionDomain0 ()
868 {
869   return protectionDomain;
870 }
871
872 JArray<jobject> *
873 java::lang::Class::getSigners()
874 {
875   return hack_signers;
876 }
877
878 void
879 java::lang::Class::setSigners(JArray<jobject> *s)
880 {
881   hack_signers = s;
882 }
883
884 \f
885
886 static unsigned char
887 read_u1 (unsigned char *&p)
888 {
889   return *p++;
890 }
891
892 static unsigned char
893 read_u1 (unsigned char *&p, unsigned char *next)
894 {
895   if (next - p < 1)
896     throw new java::lang::InternalError();
897   return *p++;
898 }
899
900 static unsigned int
901 read_u2 (unsigned char *&p)
902 {
903   unsigned int b1 = *p++;
904   unsigned int b2 = *p++;
905   return (b1 << 8) | b2;
906 }
907
908 static unsigned int
909 read_u2 (unsigned char *&p, unsigned char *next)
910 {
911   if (next - p < 2)
912     throw new java::lang::InternalError();
913   return read_u2 (p);
914 }
915
916 static int
917 read_4 (unsigned char *&p)
918 {
919   int b1 = *p++;
920   int b2 = *p++;
921   int b3 = *p++;
922   int b4 = *p++;
923   return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
924 }
925
926 jstring
927 java::lang::Class::getReflectionSignature (jint /*jv_attr_type*/ type,
928                                            jint obj_index)
929 {
930   // We just re-parse the bytecode for this data each time.  If
931   // necessary we can cache results, but I suspect this is not
932   // performance sensitive.
933   unsigned char *bytes = reflection_data;
934   if (bytes == NULL)
935     return NULL;
936   while (true)
937     {
938       int kind = read_u1 (bytes);
939       if (kind == JV_DONE_ATTR)
940         return NULL;
941       int len = read_4 (bytes);
942       unsigned char *next = bytes + len;
943       if (kind != type)
944         {
945           bytes = next;
946           continue;
947         }
948       if (type != JV_CLASS_ATTR)
949         {
950           unsigned short index = read_u2 (bytes, next);
951           if (index != obj_index)
952             {
953               bytes = next;
954               continue;
955             }
956         }
957       int nt = read_u1 (bytes, next);
958       if (nt != JV_SIGNATURE_KIND)
959         {
960           bytes = next;
961           continue;
962         }
963       unsigned int cpool_idx = read_u2 (bytes, next);
964       if (cpool_idx >= (unsigned int) constants.size
965           || constants.tags[cpool_idx] != JV_CONSTANT_Utf8)
966         {
967           // We just ignore errors for now.  It isn't clear what is
968           // best to do here, as an encoding error here means a bug
969           // either in the compiler or in defineclass.cc.
970           return NULL;
971         }
972       return _Jv_NewStringUtf8Const (constants.data[cpool_idx].utf8);
973     }
974 }
975
976 jstring
977 java::lang::Class::getReflectionSignature (::java::lang::reflect::Constructor *c)
978 {
979   _Jv_Method *meth = _Jv_FromReflectedConstructor (c);
980   unsigned short meth_index = meth - methods;
981   return getReflectionSignature (JV_METHOD_ATTR, meth_index);
982 }
983
984 jstring
985 java::lang::Class::getReflectionSignature (::java::lang::reflect::Method *m)
986 {
987   _Jv_Method *meth = _Jv_FromReflectedMethod (m);
988   unsigned short meth_index = meth - methods;
989   return getReflectionSignature (JV_METHOD_ATTR, meth_index);
990 }
991
992 jstring
993 java::lang::Class::getReflectionSignature (::java::lang::reflect::Field *f)
994 {
995   _Jv_Field *fld = _Jv_FromReflectedField (f);
996   unsigned short fld_index = fld - fields;
997   return getReflectionSignature (JV_FIELD_ATTR, fld_index);
998 }
999
1000 jstring
1001 java::lang::Class::getClassSignature()
1002 {
1003   return getReflectionSignature (JV_CLASS_ATTR, 0);
1004 }
1005
1006 jint
1007 java::lang::Class::getEnclosingMethodData()
1008 {
1009   unsigned char *bytes = reflection_data;
1010   if (bytes == NULL)
1011     return 0;
1012   while (true)
1013     {
1014       int kind = read_u1 (bytes);
1015       if (kind == JV_DONE_ATTR)
1016         return 0;
1017       int len = read_4 (bytes);
1018       unsigned char *next = bytes + len;
1019       if (kind != JV_CLASS_ATTR)
1020         {
1021           bytes = next;
1022           continue;
1023         }
1024       int type = read_u1 (bytes, next);
1025       if (type != JV_ENCLOSING_METHOD_KIND)
1026         {
1027           bytes = next;
1028           continue;
1029         }
1030       int class_index = read_u2 (bytes, next);
1031       int method_index = read_u2 (bytes, next);
1032       _Jv_word result;
1033       _Jv_storeIndexes (&result, class_index, method_index);
1034       return result.i;
1035     }
1036 }
1037
1038 jclass
1039 java::lang::Class::getEnclosingClass()
1040 {
1041   _Jv_word indexes;
1042   indexes.i = getEnclosingMethodData();
1043   if (indexes.i == 0)
1044     return NULL;
1045   _Jv_ushort class_index, method_index;
1046   _Jv_loadIndexes (&indexes, class_index, method_index);
1047   return _Jv_Linker::resolve_pool_entry (this, class_index).clazz;
1048 }
1049
1050 ::java::lang::reflect::Method *
1051 java::lang::Class::getEnclosingMethod()
1052 {
1053   _Jv_word indexes;
1054   indexes.i = getEnclosingMethodData();
1055   if (indexes.i == 0)
1056     return NULL;
1057   _Jv_ushort class_index, method_index;
1058   _Jv_loadIndexes (&indexes, class_index, method_index);
1059   jclass found_class;
1060   _Jv_Method *method = _Jv_Linker::resolve_method_entry (this, found_class,
1061                                                          class_index,
1062                                                          method_index,
1063                                                          false, false);
1064   using namespace java::lang::reflect;
1065   Method *rmethod = new Method ();
1066   rmethod->offset = (char *) method - (char *) found_class->methods;
1067   rmethod->declaringClass = found_class;
1068   return rmethod;
1069 }
1070
1071 ::java::lang::reflect::Constructor *
1072 java::lang::Class::getEnclosingConstructor()
1073 {
1074   _Jv_word indexes;
1075   indexes.i = getEnclosingMethodData();
1076   if (indexes.i == 0)
1077     return NULL;
1078   _Jv_ushort class_index, method_index;
1079   _Jv_loadIndexes (&indexes, class_index, method_index);
1080   jclass found_class;
1081   _Jv_Method *method = _Jv_Linker::resolve_method_entry (this, found_class,
1082                                                          class_index,
1083                                                          method_index,
1084                                                          false, false);
1085   using namespace java::lang::reflect;
1086   Constructor *cons = new Constructor ();
1087   cons->offset = (char *) method - (char *) found_class->methods;
1088   cons->declaringClass = this;
1089   return cons;
1090 }
1091
1092 static void
1093 check_constant (_Jv_Constants *pool, jint cpool_index, jint type)
1094 {
1095   if (cpool_index <= 0 || cpool_index >= pool->size)
1096     throw new InternalError(JvNewStringLatin1("invalid constant pool index"));
1097   if ((pool->tags[cpool_index] & 
1098         ~(JV_CONSTANT_ResolvedFlag|JV_CONSTANT_LazyFlag)) != type)
1099     {
1100       ::java::lang::StringBuffer *sb = new ::java::lang::StringBuffer();
1101       sb->append(JvNewStringLatin1("expected pool constant "));
1102       sb->append(type);
1103       sb->append(JvNewStringLatin1(" but got "));
1104       sb->append(jint (pool->tags[cpool_index]));
1105       throw new InternalError(sb->toString());
1106     }
1107 }
1108
1109 // Forward declaration
1110 static ::java::lang::annotation::Annotation *
1111 parseAnnotation(jclass klass, _Jv_Constants *pool,
1112                 unsigned char *&bytes, unsigned char *last);
1113
1114 static jobject
1115 parseAnnotationElement(jclass klass, _Jv_Constants *pool,
1116                        unsigned char *&bytes, unsigned char *last)
1117 {
1118   int tag = read_u1 (bytes, last);
1119   jobject result;
1120   switch (tag)
1121     {
1122     case 'B':
1123       {
1124         int cindex = read_u2 (bytes, last);
1125         check_constant (pool, cindex, JV_CONSTANT_Integer);
1126         result = Byte::valueOf (pool->data[cindex].i);
1127       }
1128       break;
1129     case 'C':
1130       {
1131         int cindex = read_u2 (bytes, last);
1132         check_constant (pool, cindex, JV_CONSTANT_Integer);
1133         result = Character::valueOf (pool->data[cindex].i);
1134       }
1135       break;
1136     case 'S':
1137       {
1138         int cindex = read_u2 (bytes, last);
1139         check_constant (pool, cindex, JV_CONSTANT_Integer);
1140         result = Short::valueOf (pool->data[cindex].i);
1141       }
1142       break;
1143     case 'Z':
1144       {
1145         int cindex = read_u2 (bytes, last);
1146         check_constant (pool, cindex, JV_CONSTANT_Integer);
1147         result = Boolean::valueOf (jboolean (pool->data[cindex].i));
1148       }
1149       break;
1150     case 'I':
1151       {
1152         int cindex = read_u2 (bytes, last);
1153         check_constant (pool, cindex, JV_CONSTANT_Integer);
1154         result = Integer::valueOf (pool->data[cindex].i);
1155       }
1156       break;
1157     case 'D':
1158       {
1159         int cindex = read_u2 (bytes, last);
1160         check_constant (pool, cindex, JV_CONSTANT_Double);
1161         _Jv_word2 word;
1162         memcpy (&word, &pool->data[cindex], 2 * sizeof (_Jv_word));
1163         result = Double::valueOf (word.d);
1164       }
1165       break;
1166     case 'F':
1167       {
1168         int cindex = read_u2 (bytes, last);
1169         check_constant (pool, cindex, JV_CONSTANT_Float);
1170         result = Float::valueOf (pool->data[cindex].f);
1171       }
1172       break;
1173     case 'J':
1174       {
1175         int cindex = read_u2 (bytes, last);
1176         check_constant (pool, cindex, JV_CONSTANT_Long);
1177         _Jv_word2 word;
1178         memcpy (&word, &pool->data[cindex], 2 * sizeof (_Jv_word));
1179         result = Long::valueOf (word.l);
1180       }
1181       break;
1182     case 's':
1183       {
1184         int cindex = read_u2 (bytes, last);
1185         // Despite what the JVM spec says, compilers generate a Utf8
1186         // constant here, not a String.
1187         check_constant (pool, cindex, JV_CONSTANT_Utf8);
1188         result = pool->data[cindex].utf8->toString();
1189       }
1190       break;
1191     case 'e':
1192       {
1193         int type_name_index = read_u2 (bytes, last);
1194         check_constant (pool, type_name_index, JV_CONSTANT_Utf8);
1195         int const_name_index = read_u2 (bytes, last);
1196         check_constant (pool, const_name_index, JV_CONSTANT_Utf8);
1197
1198         _Jv_Utf8Const *u_name = pool->data[type_name_index].utf8;
1199         _Jv_Utf8Const *e_name = pool->data[const_name_index].utf8;
1200
1201         // FIXME: throw correct exceptions at the correct times.
1202         jclass e_class = _Jv_FindClassFromSignature(u_name->chars(),
1203                                                     klass->getClassLoaderInternal());
1204         result = ::java::lang::Enum::valueOf(e_class, e_name->toString());
1205       }
1206       break;
1207     case 'c':
1208       {
1209         int cindex = read_u2 (bytes, last);
1210         check_constant (pool, cindex, JV_CONSTANT_Utf8);
1211         _Jv_Utf8Const *u_name = pool->data[cindex].utf8;
1212         jclass anno_class
1213           = _Jv_FindClassFromSignatureNoException(u_name->chars(),
1214                                                   klass->getClassLoaderInternal());
1215         // FIXME: not correct: we should lazily do this when trying to
1216         // read the element.  This means that
1217         // AnnotationInvocationHandler needs to have a special case.
1218         if (! anno_class)
1219           // FIXME: original exception...
1220           throw new TypeNotPresentException(u_name->toString(), NULL);
1221         result = anno_class;
1222       }
1223       break;
1224     case '@':
1225       result = parseAnnotation (klass, pool, bytes, last);
1226       break;
1227     case '[':
1228       {
1229         int n_array_elts = read_u2 (bytes, last);
1230         jobjectArray aresult = _Jv_NewObjectArray (n_array_elts,
1231                                                    &Object::class$, NULL);
1232         jobject *elts = elements (aresult);
1233         for (int i = 0; i < n_array_elts; ++i)
1234           elts[i] = parseAnnotationElement(klass, pool, bytes, last);
1235         result = aresult;
1236       }
1237       break;
1238     default:
1239       throw new java::lang::InternalError();
1240     }
1241   return result;
1242 }
1243
1244 static ::java::lang::annotation::Annotation *
1245 parseAnnotation(jclass klass, _Jv_Constants *pool,
1246                 unsigned char *&bytes, unsigned char *last)
1247 {
1248   int type_index = read_u2 (bytes, last);
1249   check_constant (pool, type_index, JV_CONSTANT_Utf8);
1250
1251   _Jv_Utf8Const *u_name = pool->data[type_index].utf8;
1252   jclass anno_class = _Jv_FindClassFromSignatureNoException(u_name->chars(),
1253                                                             klass->getClassLoaderInternal());
1254   // FIXME: what to do if anno_class==NULL?
1255
1256   ::java::util::HashMap *hmap = new ::java::util::HashMap();
1257   int npairs = read_u2 (bytes, last);
1258   for (int i = 0; i < npairs; ++i)
1259     {
1260       int name_index = read_u2 (bytes, last);
1261       check_constant (pool, name_index, JV_CONSTANT_Utf8);
1262       jstring name = _Jv_NewStringUtf8Const (pool->data[name_index].utf8);
1263       jobject value = parseAnnotationElement (klass, pool, bytes, last);
1264       // FIXME: any checks needed for name?
1265       hmap->put(name, value);
1266     }
1267   using namespace ::sun::reflect::annotation;
1268   return AnnotationInvocationHandler::create (anno_class,
1269                                               (::java::util::Map *) hmap);
1270 }
1271
1272 static jobjectArray
1273 parseAnnotations(jclass klass, _Jv_Constants *pool,
1274                  unsigned char *&bytes, unsigned char *last)
1275 {
1276   int num = read_u2 (bytes, last);
1277   jobjectArray result = _Jv_NewObjectArray (num,
1278                                             &::java::lang::annotation::Annotation::class$,
1279                                             NULL);
1280   jobject *elts = elements (result);
1281   for (int i = 0; i < num; ++i)
1282     elts[i] = parseAnnotation(klass, pool, bytes, last);
1283   return result;
1284 }
1285
1286 static jobjectArray
1287 parseParameterAnnotations(jclass klass, _Jv_Constants *pool,
1288                           unsigned char *&bytes, unsigned char *last)
1289 {
1290   jclass anno = &::java::lang::annotation::Annotation::class$;
1291   jclass annoary = _Jv_GetArrayClass (anno, anno->getClassLoaderInternal());
1292
1293   // FIXME: something should check the number of params versus the
1294   // method
1295   int n_params = read_u1 (bytes, last);
1296   jobjectArray result = _Jv_NewObjectArray (n_params, annoary, NULL);
1297   jobject *elts = elements (result);
1298   for (int i = 0; i < n_params; ++i)
1299     elts[i] = parseAnnotations(klass, pool, bytes, last);
1300   return result;
1301 }
1302
1303 jobject
1304 java::lang::Class::getMethodDefaultValue(::java::lang::reflect::Method *meth)
1305 {
1306   // FIXME: could cache the value here...
1307
1308   unsigned char *bytes = reflection_data;
1309   if (bytes == NULL)
1310     return 0;
1311
1312   unsigned short meth_index = _Jv_FromReflectedMethod (meth) - methods;
1313
1314   while (true)
1315     {
1316       int type = read_u1 (bytes);
1317       if (type == JV_DONE_ATTR)
1318         return NULL;
1319       int len = read_4 (bytes);
1320       unsigned char *next = bytes + len;
1321       if (type != JV_METHOD_ATTR)
1322         {
1323           bytes = next;
1324           continue;
1325         }
1326       int kind = read_u1 (bytes, next);
1327       if (kind != JV_ANNOTATION_DEFAULT_KIND)
1328         {
1329           bytes = next;
1330           continue;
1331         }
1332       int index = read_u2 (bytes, next);
1333       if (meth_index != index)
1334         {
1335           bytes = next;
1336           continue;
1337         }
1338
1339       // FIXME: could cache here.  If we do then we have to clone any
1340       // array result.
1341       return parseAnnotationElement(this, &this->constants, bytes, next);
1342     }
1343 }
1344
1345 jobjectArray
1346 java::lang::Class::getDeclaredAnnotations(jint /* jv_attr_type */ member_type,
1347                                           jint member_index,
1348                                           jint /* jv_attr_kind */ kind_req)
1349 {
1350   using namespace java::lang::annotation;
1351   jobjectArray result;
1352
1353   unsigned char *bytes = reflection_data;
1354   if (bytes == NULL)
1355     return 0;
1356
1357   if (loader == NULL)
1358     loader = (ClassLoader *)VMClassLoader::bootLoader;
1359
1360   result = (loader->getDeclaredAnnotations
1361             (this, member_type, member_index, kind_req));
1362   if (result)
1363     return result;
1364
1365   for (;;)
1366     {
1367       int type = read_u1 (bytes);
1368       if (type == JV_DONE_ATTR)
1369         return NULL;
1370       int len = read_4 (bytes);
1371       unsigned char *next = bytes + len;
1372       if (type != member_type)
1373         {
1374           bytes = next;
1375           continue;
1376         }
1377       int kind = read_u1 (bytes, next);
1378       if (kind != kind_req)
1379         {
1380           bytes = next;
1381           continue;
1382         }
1383       if (member_type != JV_CLASS_ATTR)
1384         {
1385           int index = read_u2 (bytes, next);
1386           if (member_index != index)
1387             {
1388               bytes = next;
1389               continue;
1390             }
1391         }
1392
1393       if (kind_req == JV_PARAMETER_ANNOTATIONS_KIND)
1394         result = ((parseParameterAnnotations 
1395                    (this, &this->constants, bytes, next)));
1396       else
1397         result = ((parseAnnotations (this, &this->constants, bytes, next)));
1398       break;
1399     }
1400
1401   return (loader->putDeclaredAnnotations
1402           (this, member_type, member_index, kind_req, result));
1403 }
1404
1405 jobjectArray
1406 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Method *meth,
1407                                           jboolean is_param)
1408 {
1409   unsigned short meth_index = _Jv_FromReflectedMethod (meth) - methods;
1410   return getDeclaredAnnotations(JV_METHOD_ATTR, meth_index,
1411                                 (is_param
1412                                  ? JV_PARAMETER_ANNOTATIONS_KIND
1413                                  : JV_ANNOTATIONS_KIND));
1414 }
1415
1416 jobjectArray
1417 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Constructor *cons,
1418                                           jboolean is_param)
1419 {
1420   unsigned short meth_index = _Jv_FromReflectedConstructor (cons) - methods;
1421   return getDeclaredAnnotations(JV_METHOD_ATTR, meth_index,
1422                                 (is_param
1423                                  ? JV_PARAMETER_ANNOTATIONS_KIND
1424                                  : JV_ANNOTATIONS_KIND));
1425 }
1426
1427 jobjectArray
1428 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Field *fld)
1429 {
1430   unsigned short field_index = _Jv_FromReflectedField (fld) - fields;
1431   return getDeclaredAnnotations(JV_FIELD_ATTR, field_index,
1432                                 JV_ANNOTATIONS_KIND);
1433 }
1434
1435 JArray< ::java::lang::annotation::Annotation *> *
1436 java::lang::Class::getDeclaredAnnotationsInternal()
1437 {
1438   return (JArray< ::java::lang::annotation::Annotation *> *) getDeclaredAnnotations(JV_CLASS_ATTR, 0, JV_ANNOTATIONS_KIND);
1439 }
1440
1441 static jclass
1442 resolve_class_constant (jclass klass, _Jv_Constants *pool, int cpool_index)
1443 {
1444   check_constant (pool, cpool_index, JV_CONSTANT_Class);
1445   // FIXME: what is the correct thing to do with an exception here?
1446   return _Jv_Linker::resolve_pool_entry (klass, cpool_index, false).clazz;
1447 }
1448
1449 jint
1450 java::lang::Class::findInnerClassAttribute()
1451 {
1452   unsigned char *bytes = reflection_data;
1453   if (bytes == NULL)
1454     return -1;
1455   while (true)
1456     {
1457       int type = read_u1 (bytes);
1458       if (type == JV_DONE_ATTR)
1459         break;
1460       // After the type but before the length.
1461       unsigned char *save = bytes;
1462       int len = read_4 (bytes);
1463       unsigned char *next = bytes + len;
1464       if (type != JV_CLASS_ATTR)
1465         {
1466           bytes = next;
1467           continue;
1468         }
1469       int kind = read_u1 (bytes, next);
1470       if (kind != JV_INNER_CLASSES_KIND)
1471         {
1472           bytes = next;
1473           continue;
1474         }
1475       return save - reflection_data;
1476     }
1477   return -1;
1478 }
1479
1480 jint
1481 java::lang::Class::findDeclaredClasses(JArray<jclass> *result,
1482                                        jboolean publicOnly,
1483                                        jint offset)
1484 {
1485   unsigned char *bytes = reflection_data + offset;
1486   int len = read_4 (bytes);
1487   unsigned char *next = bytes + len;
1488   // Skip a byte.
1489   read_u1 (bytes, next);
1490   int n_classes = read_u2 (bytes, next);
1491   int count = 0;
1492   for (int i = 0; i < n_classes; ++i)
1493     {
1494       int inner_class_index = read_u2 (bytes, next);
1495       int outer_class_index = read_u2 (bytes, next);
1496       /*int inner_name_index = */ read_u2 (bytes, next);
1497       int inner_flags = read_u2 (bytes, next);
1498
1499       if (inner_class_index == 0 || outer_class_index == 0)
1500         continue;
1501       if (resolve_class_constant (this, &constants, outer_class_index) == this)
1502         {
1503           jclass inner = resolve_class_constant (this, &constants,
1504                                                  inner_class_index);
1505           if (! publicOnly
1506               || ((inner_flags
1507                    & java::lang::reflect::Modifier::PUBLIC) != 0))
1508             {
1509               if (result)
1510                 {
1511                   jclass *elts = elements (result);
1512                   elts[count] = inner;
1513                 }
1514               ++count;
1515             }
1516         }
1517     }
1518
1519   return count;
1520 }
1521
1522 JArray<jclass> *
1523 java::lang::Class::getDeclaredClasses (jboolean publicOnly)
1524 {
1525   int offset = findInnerClassAttribute();
1526   int count;
1527   if (offset == -1)
1528     {
1529       // No InnerClasses attribute, so no declared classes.
1530       count = 0;
1531     }
1532   else
1533     count = findDeclaredClasses(NULL, publicOnly, offset);
1534   JArray<jclass> *result
1535     = (JArray<jclass> *) JvNewObjectArray (count, &java::lang::Class::class$,
1536                                            NULL);
1537   if (count > 0)
1538     findDeclaredClasses(result, publicOnly, offset);
1539   return result;
1540 }
1541
1542 jclass
1543 java::lang::Class::getDeclaringClass (void)
1544 {
1545   int offset = findInnerClassAttribute();
1546   if (offset == -1)
1547     return NULL;
1548
1549   unsigned char *bytes = reflection_data + offset;
1550   int len = read_4 (bytes);
1551   unsigned char *next = bytes + len;
1552   // Skip a byte.
1553   read_u1 (bytes, next);
1554   int n_classes = read_u2 (bytes, next);
1555   for (int i = 0; i < n_classes; ++i)
1556     {
1557       int inner_class_index = read_u2 (bytes, next);
1558       int outer_class_index = read_u2 (bytes, next);
1559       /*int inner_name_index = */read_u2 (bytes, next);
1560       /*int inner_flags = */read_u2 (bytes, next);
1561
1562       if (inner_class_index == 0 || outer_class_index == 0)
1563         continue;
1564       if (resolve_class_constant (this, &constants, inner_class_index) == this)
1565         return resolve_class_constant (this, &constants, outer_class_index);
1566     }
1567
1568   return NULL;
1569 }
1570
1571 jboolean
1572 java::lang::Class::isAnonymousClass()
1573 {
1574   int offset = findInnerClassAttribute();
1575   if (offset == -1)
1576     return false;
1577
1578   unsigned char *bytes = reflection_data + offset;
1579   int len = read_4 (bytes);
1580   unsigned char *next = bytes + len;
1581   // Skip a byte.
1582   read_u1 (bytes, next);
1583   int n_classes = read_u2 (bytes, next);
1584   for (int i = 0; i < n_classes; ++i)
1585     {
1586       int inner_class_index = read_u2 (bytes, next);
1587       /*int outer_class_index = */read_u2 (bytes, next);
1588       int inner_name_index = read_u2 (bytes, next);
1589       /*int inner_flags = */read_u2 (bytes, next);
1590
1591       if (inner_class_index == 0)
1592         continue;
1593       if (resolve_class_constant (this, &constants, inner_class_index) == this)
1594         return inner_name_index == 0;
1595     }
1596
1597   return false;
1598 }
1599
1600 jboolean
1601 java::lang::Class::isLocalClass()
1602 {
1603   _Jv_word indexes;
1604   indexes.i = getEnclosingMethodData();
1605   return indexes.i != 0;
1606 }
1607
1608 jboolean
1609 java::lang::Class::isMemberClass()
1610 {
1611   // FIXME: is this correct?
1612   return !isLocalClass() && getDeclaringClass() != NULL;
1613 }
1614
1615 \f
1616
1617 //
1618 // Some class-related convenience functions.
1619 //
1620
1621 // Find a method declared in the class.  If it is not declared locally
1622 // (or if it is inherited), return NULL.
1623 _Jv_Method *
1624 _Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
1625                     _Jv_Utf8Const *signature)
1626 {
1627   for (int i = 0; i < klass->method_count; ++i)
1628     {
1629       if (_Jv_equalUtf8Consts (name, klass->methods[i].name)
1630           && _Jv_equalUtf8Consts (signature, klass->methods[i].signature))
1631         return &klass->methods[i];
1632     }
1633   return NULL;
1634 }
1635
1636 _Jv_Method *
1637 _Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
1638                           _Jv_Utf8Const *signature,
1639                           jclass *declarer_result)
1640 {
1641   for (; klass; klass = klass->getSuperclass())
1642     {
1643       _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
1644
1645       if (meth)
1646         {
1647           if (declarer_result)
1648             *declarer_result = klass;
1649           return meth;
1650         }
1651     }
1652
1653   return NULL;
1654 }
1655
1656 java::lang::reflect::Method *
1657 _Jv_GetReflectedMethod (jclass klass, _Jv_Utf8Const *name,
1658                        _Jv_Utf8Const *signature)
1659 {
1660   for (; klass; klass = klass->getSuperclass())
1661     {
1662       _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
1663       if (meth)
1664         {
1665           using namespace java::lang::reflect;
1666           Method *rmethod = new Method ();
1667           rmethod->offset = (char*) meth - (char*) klass->methods;
1668           rmethod->declaringClass = klass;
1669           return rmethod;
1670         }
1671     }
1672   
1673   return NULL;
1674 }
1675
1676 #ifdef HAVE_TLS
1677
1678 // NOTE: MCACHE_SIZE should be a power of 2 minus one.
1679 #define MCACHE_SIZE 31
1680
1681 struct _Jv_mcache
1682 {
1683   jclass klass;
1684   _Jv_Method *method;
1685 };
1686
1687 static __thread _Jv_mcache *method_cache;
1688 #endif // HAVE_TLS
1689
1690 static void *
1691 _Jv_FindMethodInCache (jclass klass MAYBE_UNUSED,
1692                        _Jv_Utf8Const *name MAYBE_UNUSED,
1693                        _Jv_Utf8Const *signature MAYBE_UNUSED)
1694 {
1695 #ifdef HAVE_TLS
1696   _Jv_mcache *cache = method_cache;
1697   if (cache)
1698     {
1699       int index = name->hash16 () & MCACHE_SIZE;
1700       _Jv_mcache *mc = &cache[index];
1701       _Jv_Method *m = mc->method;
1702
1703       if (mc->klass == klass
1704           && _Jv_equalUtf8Consts (m->name, name)
1705           && _Jv_equalUtf8Consts (m->signature, signature))
1706         return mc->method->ncode;
1707     }
1708 #endif // HAVE_TLS
1709   return NULL;
1710 }
1711
1712 static void
1713 _Jv_AddMethodToCache (jclass klass MAYBE_UNUSED,
1714                       _Jv_Method *method MAYBE_UNUSED)
1715 {
1716 #ifdef HAVE_TLS
1717   if (method_cache == NULL)
1718     method_cache = (_Jv_mcache *) _Jv_MallocUnchecked((MCACHE_SIZE + 1)
1719                                                       * sizeof (_Jv_mcache));
1720   // If the allocation failed, just keep going.
1721   if (method_cache != NULL)
1722     {
1723       int index = method->name->hash16 () & MCACHE_SIZE;
1724       method_cache[index].method = method;
1725       method_cache[index].klass = klass;
1726     }
1727 #endif // HAVE_TLS
1728 }
1729
1730 // Free this thread's method cache.  We explicitly manage this memory
1731 // as the GC does not yet know how to scan TLS on all platforms.
1732 void
1733 _Jv_FreeMethodCache ()
1734 {
1735 #ifdef HAVE_TLS
1736   if (method_cache != NULL)
1737     {
1738       _Jv_Free(method_cache);
1739       method_cache = NULL;
1740     }
1741 #endif // HAVE_TLS
1742 }
1743
1744 void *
1745 _Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
1746                            _Jv_Utf8Const *signature)
1747 {
1748   using namespace java::lang::reflect;
1749
1750   void *ncode = _Jv_FindMethodInCache (klass, name, signature);
1751   if (ncode != 0)
1752     return ncode;
1753
1754   for (; klass; klass = klass->getSuperclass())
1755     {
1756       _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
1757       if (! meth)
1758         continue;
1759
1760       if (Modifier::isStatic(meth->accflags))
1761         throw new java::lang::IncompatibleClassChangeError
1762           (_Jv_GetMethodString (klass, meth));
1763       if (Modifier::isAbstract(meth->accflags))
1764         throw new java::lang::AbstractMethodError
1765           (_Jv_GetMethodString (klass, meth));
1766       if (! Modifier::isPublic(meth->accflags))
1767         throw new java::lang::IllegalAccessError
1768           (_Jv_GetMethodString (klass, meth));
1769
1770       _Jv_AddMethodToCache (klass, meth);
1771
1772       return meth->ncode;
1773     }
1774   throw new java::lang::IncompatibleClassChangeError;
1775 }
1776
1777 // Fast interface method lookup by index.
1778 void *
1779 _Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface, int method_idx)
1780 {
1781   _Jv_IDispatchTable *cldt = klass->idt;
1782   int idx = iface->ioffsets[cldt->iindex] + method_idx;
1783   return cldt->itable[idx];
1784 }
1785
1786 jboolean
1787 _Jv_IsAssignableFrom (jclass source, jclass target)
1788 {
1789   if (source == target)
1790     return true;
1791
1792   // If target is array, so must source be.  
1793   while (target->isArray ())
1794     {
1795       if (! source->isArray())
1796         return false;
1797       target = target->getComponentType();
1798       source = source->getComponentType();
1799     }
1800
1801   if (target->isInterface())
1802     {
1803       // Abstract classes have no IDT, and IDTs provide no way to check
1804       // two interfaces for assignability.
1805       if (__builtin_expect 
1806           (source->idt == NULL || source->isInterface(), false))
1807         return _Jv_InterfaceAssignableFrom (source, target);
1808
1809       _Jv_IDispatchTable *cl_idt = source->idt;
1810
1811       if (__builtin_expect ((target->ioffsets == NULL), false))
1812         return false; // No class implementing TARGET has been loaded.    
1813       jshort cl_iindex = cl_idt->iindex;
1814       if (cl_iindex < target->ioffsets[0])
1815         {
1816           jshort offset = target->ioffsets[cl_iindex];
1817           if (offset != -1 && offset < cl_idt->itable_length
1818               && cl_idt->itable[offset] == target)
1819             return true;
1820         }
1821       return false;
1822     }
1823
1824   // Primitive TYPE classes are only assignable to themselves.
1825   if (__builtin_expect (target->isPrimitive() || source->isPrimitive(), false))
1826     return false;
1827
1828   if (target == &java::lang::Object::class$)
1829     return true;
1830   else if (source->ancestors == NULL || target->ancestors == NULL)
1831     {
1832       // We need this case when either SOURCE or TARGET has not has
1833       // its constant-time tables prepared.
1834
1835       // At this point we know that TARGET can't be Object, so it is
1836       // safe to use that as the termination point.
1837       while (source && source != &java::lang::Object::class$)
1838         {
1839           if (source == target)
1840             return true;
1841           source = source->getSuperclass();
1842         }
1843     }
1844   else if (source->depth >= target->depth
1845            && source->ancestors[source->depth - target->depth] == target)
1846     return true;
1847
1848   return false;
1849 }
1850
1851 // Interface type checking, the slow way. Returns TRUE if IFACE is a 
1852 // superinterface of SOURCE. This is used when SOURCE is also an interface,
1853 // or a class with no interface dispatch table.
1854 jboolean
1855 _Jv_InterfaceAssignableFrom (jclass source, jclass iface)
1856 {
1857   for (int i = 0; i < source->interface_count; i++)
1858     {
1859       jclass interface = source->interfaces[i];
1860       if (iface == interface
1861           || _Jv_InterfaceAssignableFrom (interface, iface))
1862         return true;      
1863     }
1864     
1865   if (!source->isInterface()
1866       && source->superclass 
1867       && _Jv_InterfaceAssignableFrom (source->superclass, iface))
1868     return true;
1869         
1870   return false;
1871 }
1872
1873 jboolean
1874 _Jv_IsInstanceOf(jobject obj, jclass cl)
1875 {
1876   if (__builtin_expect (!obj, false))
1877     return false;
1878   return _Jv_IsAssignableFrom (JV_CLASS (obj), cl);
1879 }
1880
1881 void *
1882 _Jv_CheckCast (jclass c, jobject obj)
1883 {
1884   if (__builtin_expect 
1885       (obj != NULL && ! _Jv_IsAssignableFrom(JV_CLASS (obj), c), false))
1886     throw new java::lang::ClassCastException
1887       ((new java::lang::StringBuffer
1888         (obj->getClass()->getName()))->append
1889        (JvNewStringUTF(" cannot be cast to "))->append
1890        (c->getName())->toString());
1891
1892   return obj;
1893 }
1894
1895 void
1896 _Jv_CheckArrayStore (jobject arr, jobject obj)
1897 {
1898   if (obj)
1899     {
1900       JvAssert (arr != NULL);
1901       jclass elt_class = (JV_CLASS (arr))->getComponentType();
1902       if (elt_class == &java::lang::Object::class$)
1903         return;
1904       jclass obj_class = JV_CLASS (obj);
1905       if (__builtin_expect 
1906           (! _Jv_IsAssignableFrom (obj_class, elt_class), false))
1907         throw new java::lang::ArrayStoreException
1908                 ((new java::lang::StringBuffer
1909                  (JvNewStringUTF("Cannot store ")))->append
1910                  (obj_class->getName())->append
1911                  (JvNewStringUTF(" in array of type "))->append
1912                  (elt_class->getName())->toString());
1913     }
1914 }
1915
1916 jboolean
1917 _Jv_IsAssignableFromSlow (jclass source, jclass target)
1918 {
1919   // First, strip arrays.
1920   while (target->isArray ())
1921     {
1922       // If target is array, source must be as well.
1923       if (! source->isArray ())
1924        return false;
1925       target = target->getComponentType ();
1926       source = source->getComponentType ();
1927     }
1928
1929   // Quick success.
1930   if (target == &java::lang::Object::class$)
1931     return true;
1932
1933   // Ensure that the classes have their supers installed.
1934   _Jv_Linker::wait_for_state (source, JV_STATE_LOADING);
1935   _Jv_Linker::wait_for_state (target, JV_STATE_LOADING);
1936
1937   do
1938     {
1939       if (source == target)
1940        return true;
1941
1942       if (target->isPrimitive () || source->isPrimitive ())
1943        return false;
1944
1945       if (target->isInterface ())
1946        {
1947          for (int i = 0; i < source->interface_count; ++i)
1948            {
1949              // We use a recursive call because we also need to
1950              // check superinterfaces.
1951              if (_Jv_IsAssignableFromSlow (source->getInterface (i), target))
1952                return true;
1953            }
1954        }
1955       source = source->getSuperclass ();
1956     }
1957   while (source != NULL);
1958
1959   return false;
1960 }
1961
1962 // Lookup an interface method by name.  This is very similar to
1963 // purpose to _getMethod, but the interfaces are quite different.  It
1964 // might be a good idea for _getMethod to call this function.
1965 //
1966 // Return true of the method is found, with the class in FOUND_CLASS
1967 // and the index in INDEX.
1968 bool
1969 _Jv_getInterfaceMethod (jclass search_class, jclass &found_class, int &index,
1970                         const _Jv_Utf8Const *utf_name,  
1971                         const _Jv_Utf8Const *utf_sig)
1972 {
1973    for (jclass klass = search_class; klass; klass = klass->getSuperclass())
1974     {
1975       // FIXME: Throw an exception?
1976       if (!klass->isInterface ())
1977         return false;
1978       
1979       int max = klass->method_count;
1980       int offset = 0;
1981       for (int i = 0; i < max; ++i)
1982         {
1983           // Skip <clinit> here, as it will not be in the IDT.
1984           if (klass->methods[i].name->first() == '<')
1985             continue;
1986
1987           if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
1988               && _Jv_equalUtf8Consts (klass->methods[i].signature, utf_sig))
1989             {
1990               // Found it.
1991               using namespace java::lang::reflect;
1992
1993               // FIXME: Method must be public.  Throw an exception?
1994               if (! Modifier::isPublic (klass->methods[i].accflags))
1995                 break;
1996
1997               found_class = klass;
1998               // Interface method indexes count from 1.
1999               index = offset + 1;
2000               return true;
2001             }
2002
2003           ++offset;
2004         }
2005     }
2006
2007   // If we haven't found a match, and this class is an interface, then
2008   // check all the superinterfaces.
2009   if (search_class->isInterface())
2010     {
2011       for (int i = 0; i < search_class->interface_count; ++i)
2012         {
2013           using namespace java::lang::reflect;
2014           bool found = _Jv_getInterfaceMethod (search_class->interfaces[i], 
2015                                                found_class, index,
2016                                                utf_name, utf_sig);
2017           if (found)
2018             return true;
2019         }
2020     }
2021
2022   return false;
2023 }
2024
2025 #ifdef INTERPRETER
2026 _Jv_MethodBase *
2027 _Jv_FindInterpreterMethod (jclass klass, jmethodID desired_method)
2028 {
2029   using namespace java::lang::reflect;
2030
2031   _Jv_InterpClass *iclass
2032     = reinterpret_cast<_Jv_InterpClass *> (klass->aux_info);
2033   _Jv_MethodBase **imethods = _Jv_GetFirstMethod (iclass);
2034
2035   for (int i = 0; i < JvNumMethods (klass); ++i)
2036     {
2037       _Jv_MethodBase *imeth = imethods[i];
2038       if (imeth->get_method () == desired_method)
2039         return imeth;
2040     }
2041
2042   return NULL;
2043 }
2044 #endif
2045
2046 // Return Utf8 name of a class. This function is here for code that
2047 // can't access klass->name directly.
2048 _Jv_Utf8Const*
2049 _Jv_GetClassNameUtf8 (jclass klass)
2050 {
2051   return klass->name;
2052 }
2053
2054 jclass
2055 _Jv_GetMethodDeclaringClass (jmethodID method)
2056 {
2057   _Jv_StackTrace::UpdateNCodeMap ();
2058   jobject obj = reinterpret_cast<jobject> (method->ncode);
2059   return reinterpret_cast<jclass> (_Jv_StackTrace::ncodeMap->get (obj));
2060 }
2061
2062 jbyte
2063 _Jv_GetClassState (jclass klass)
2064 {
2065   return klass->state;
2066 }
2067
2068 jstring
2069 _Jv_GetInterpClassSourceFile (jclass klass)
2070 {
2071   if (_Jv_IsInterpretedClass (klass))
2072     {
2073       _Jv_InterpClass *iclass =
2074         reinterpret_cast<_Jv_InterpClass *> (klass->aux_info);
2075       return iclass->source_file_name;
2076     }
2077
2078   return NULL;
2079 }