1 // natClass.cc - Implementation of java.lang.Class native methods.
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 Free Software Foundation
6 This file is part of libgcj.
8 This software is copyrighted work licensed under the terms of the
9 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
19 #pragma implementation "Class.h"
23 #include <java-threads.h>
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>
77 #include <java-cpool.h>
78 #include <java-interp.h>
79 #include <java-assert.h>
80 #include <java-stack.h>
81 #include <execution.h>
88 java::lang::Class::forName (jstring className
, jboolean initialize
,
89 java::lang::ClassLoader
*loader
)
92 throw new java::lang::NullPointerException
;
94 jsize length
= _Jv_GetStringUTFLength (className
);
96 _Jv_GetStringUTFRegion (className
, 0, className
->length(), buffer
);
98 _Jv_Utf8Const
*name
= _Jv_makeUtf8Const (buffer
, length
);
100 if (! _Jv_VerifyClassName (name
))
101 throw new java::lang::ClassNotFoundException (className
);
103 jclass klass
= (buffer
[0] == '['
104 ? _Jv_FindClassFromSignature (name
->chars(), loader
)
105 : _Jv_FindClass (name
, loader
));
108 throw new java::lang::ClassNotFoundException (className
);
111 _Jv_InitClass (klass
);
117 java::lang::Class::forName (jstring className
)
119 java::lang::ClassLoader
*loader
= NULL
;
121 jclass caller
= _Jv_StackTrace::GetCallingClass (&Class::class$
);
123 loader
= caller
->getClassLoaderInternal();
125 return forName (className
, true, loader
);
128 java::lang::ClassLoader
*
129 java::lang::Class::getClassLoader (void)
131 java::lang::SecurityManager
*s
= java::lang::System::getSecurityManager();
134 jclass caller
= _Jv_StackTrace::GetCallingClass (&Class::class$
);
135 return getClassLoader (caller
);
141 java::lang::ClassLoader
*
142 java::lang::Class::getClassLoader (jclass caller
)
144 java::lang::SecurityManager
*s
= java::lang::System::getSecurityManager();
147 ClassLoader
*caller_loader
= caller
->getClassLoaderInternal();
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
152 if (caller_loader
!= NULL
&& ! caller_loader
->isAncestorOf(loader
))
153 s
->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader")));
159 java::lang::reflect::Constructor
*
160 java::lang::Class::getConstructor (JArray
<jclass
> *param_types
)
162 memberAccessCheck(java::lang::reflect::Member::PUBLIC
);
164 jstring partial_sig
= getSignature (param_types
, true);
165 jint hash
= partial_sig
->hashCode ();
167 int i
= isPrimitive () ? 0 : method_count
;
170 if (_Jv_equalUtf8Consts (methods
[i
].name
, init_name
)
171 && _Jv_equal (methods
[i
].signature
, partial_sig
, hash
))
173 // Found it. For getConstructor, the constructor must be
175 using namespace java::lang::reflect
;
176 if (! Modifier::isPublic(methods
[i
].accflags
))
178 Constructor
*cons
= new Constructor ();
179 cons
->offset
= (char *) (&methods
[i
]) - (char *) methods
;
180 cons
->declaringClass
= this;
184 throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name
));
187 JArray
<java::lang::reflect::Constructor
*> *
188 java::lang::Class::getDeclaredConstructors (jboolean publicOnly
)
190 int numConstructors
= 0;
191 int max
= isPrimitive () ? 0 : method_count
;
193 for (i
= max
; --i
>= 0; )
195 _Jv_Method
*method
= &methods
[i
];
196 if (method
->name
== NULL
197 || ! _Jv_equalUtf8Consts (method
->name
, init_name
))
200 && ! java::lang::reflect::Modifier::isPublic(method
->accflags
))
204 JArray
<java::lang::reflect::Constructor
*> *result
205 = (JArray
<java::lang::reflect::Constructor
*> *)
206 JvNewObjectArray (numConstructors
,
207 &java::lang::reflect::Constructor::class$
,
209 java::lang::reflect::Constructor
** cptr
= elements (result
);
210 for (i
= 0; i
< max
; i
++)
212 _Jv_Method
*method
= &methods
[i
];
213 if (method
->name
== NULL
214 || ! _Jv_equalUtf8Consts (method
->name
, init_name
))
217 && ! java::lang::reflect::Modifier::isPublic(method
->accflags
))
219 java::lang::reflect::Constructor
*cons
220 = new java::lang::reflect::Constructor ();
221 cons
->offset
= (char *) method
- (char *) methods
;
222 cons
->declaringClass
= this;
228 java::lang::reflect::Constructor
*
229 java::lang::Class::getDeclaredConstructor (JArray
<jclass
> *param_types
)
231 memberAccessCheck(java::lang::reflect::Member::DECLARED
);
233 jstring partial_sig
= getSignature (param_types
, true);
234 jint hash
= partial_sig
->hashCode ();
236 int i
= isPrimitive () ? 0 : method_count
;
239 if (_Jv_equalUtf8Consts (methods
[i
].name
, init_name
)
240 && _Jv_equal (methods
[i
].signature
, partial_sig
, hash
))
243 using namespace java::lang::reflect
;
244 Constructor
*cons
= new Constructor ();
245 cons
->offset
= (char *) (&methods
[i
]) - (char *) methods
;
246 cons
->declaringClass
= this;
250 throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name
));
253 java::lang::reflect::Field
*
254 java::lang::Class::getField (jstring name
, jint hash
)
256 java::lang::reflect::Field
* rfield
;
257 for (int i
= 0; i
< field_count
; i
++)
259 _Jv_Field
*field
= &fields
[i
];
260 if (! _Jv_equal (field
->name
, name
, hash
))
262 if (! (field
->getModifiers() & java::lang::reflect::Modifier::PUBLIC
))
264 rfield
= new java::lang::reflect::Field ();
265 rfield
->offset
= (char*) field
- (char*) fields
;
266 rfield
->declaringClass
= this;
270 jclass superclass
= getSuperclass();
271 if (superclass
== 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
);
279 java::lang::reflect::Field
*
280 java::lang::Class::getDeclaredField (jstring name
)
282 memberAccessCheck(java::lang::reflect::Member::DECLARED
);
283 int hash
= name
->hashCode();
284 for (int i
= 0; i
< field_count
; i
++)
286 _Jv_Field
*field
= &fields
[i
];
287 if (! _Jv_equal (field
->name
, name
, hash
))
289 java::lang::reflect::Field
* rfield
= new java::lang::reflect::Field ();
290 rfield
->offset
= (char*) field
- (char*) fields
;
291 rfield
->declaringClass
= this;
295 throw new java::lang::NoSuchFieldException (name
);
298 JArray
<java::lang::reflect::Field
*> *
299 java::lang::Class::getDeclaredFields (jboolean public_only
)
305 for (int i
= 0; i
< field_count
; ++i
)
307 _Jv_Field
*field
= &fields
[i
];
308 if ((field
->flags
& java::lang::reflect::Modifier::PUBLIC
))
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
++)
321 _Jv_Field
*field
= &fields
[i
];
323 && ! (field
->flags
& java::lang::reflect::Modifier::PUBLIC
))
325 java::lang::reflect::Field
* rfield
= new java::lang::reflect::Field ();
326 rfield
->offset
= (char*) field
- (char*) fields
;
327 rfield
->declaringClass
= this;
334 java::lang::Class::getSignature (java::lang::StringBuffer
*buffer
)
337 buffer
->append((jchar
) method_count
);
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
) ';');
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.
352 java::lang::Class::getSignature (JArray
<jclass
> *param_types
,
353 jboolean is_constructor
)
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
)
360 jclass
*v
= elements (param_types
);
361 for (int i
= 0; i
< param_types
->length
; ++i
)
362 v
[i
]->getSignature(buf
);
364 buf
->append((jchar
) ')');
366 buf
->append((jchar
) 'V');
367 return buf
->toString();
370 java::lang::reflect::Method
*
371 java::lang::Class::_getDeclaredMethod (jstring name
,
372 JArray
<jclass
> *param_types
)
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
;
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)
386 using namespace java::lang::reflect
;
387 Method
*rmethod
= new Method ();
388 rmethod
->offset
= (char*) (&methods
[i
]) - (char*) methods
;
389 rmethod
->declaringClass
= this;
396 JArray
<java::lang::reflect::Method
*> *
397 java::lang::Class::getDeclaredMethods (void)
399 memberAccessCheck(java::lang::reflect::Member::DECLARED
);
402 int max
= isPrimitive () ? 0 : method_count
;
404 for (i
= max
; --i
>= 0; )
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)
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
++)
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)
430 java::lang::reflect::Method
* rmethod
431 = new java::lang::reflect::Method ();
432 rmethod
->offset
= (char*) method
- (char*) methods
;
433 rmethod
->declaringClass
= this;
440 java::lang::Class::getName (void)
442 return name
->toString();
446 java::lang::Class::getInterfaces (void)
448 jobjectArray r
= JvNewObjectArray (interface_count
, getClass (), NULL
);
449 jobject
*data
= elements (r
);
450 for (int i
= 0; i
< interface_count
; ++i
)
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");
457 return reinterpret_cast<JArray
<jclass
> *> (r
);
460 java::lang::reflect::Method
*
461 java::lang::Class::_getMethod (jstring name
, JArray
<jclass
> *param_types
)
463 jstring partial_sig
= getSignature (param_types
, false);
464 jint p_len
= partial_sig
->length();
465 _Jv_Utf8Const
*utf_name
= _Jv_makeUtf8Const (name
);
467 for (Class
*klass
= this; klass
; klass
= klass
->getSuperclass())
469 int i
= klass
->isPrimitive () ? 0 : klass
->method_count
;
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)
478 using namespace java::lang::reflect
;
480 // Method must be public.
481 if (! Modifier::isPublic (klass
->methods
[i
].accflags
))
484 Method
*rmethod
= new Method ();
485 rmethod
->offset
= ((char *) (&klass
->methods
[i
])
486 - (char *) klass
->methods
);
487 rmethod
->declaringClass
= klass
;
493 // If we haven't found a match, and this class is an interface, then
494 // check all the superinterfaces.
497 for (int i
= 0; i
< interface_count
; ++i
)
499 using namespace java::lang::reflect
;
500 Method
*rmethod
= interfaces
[i
]->_getMethod (name
, param_types
);
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.
514 java::lang::Class::_getMethods (JArray
<java::lang::reflect::Method
*> *result
,
519 // First examine all local methods
520 for (int i
= isPrimitive () ? 0 : method_count
; --i
>= 0; )
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
)
528 & java::lang::reflect::Modifier::INVISIBLE
) != 0)
530 // Only want public methods.
531 if (! java::lang::reflect::Modifier::isPublic (method
->accflags
))
534 // This is where we over-count the slots required if we aren't
535 // filling the result for real.
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
543 for (int j
= 0; j
< offset
; ++j
)
545 _Jv_Method
*meth_2
= _Jv_FromReflectedMethod (mp
[j
]);
546 if (_Jv_equalUtf8Consts (method
->name
, meth_2
->name
)
547 && _Jv_equalUtf8Consts (method
->signature
,
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
;
571 // Now examine superclasses.
572 if (getSuperclass () != NULL
)
574 jint s_count
= getSuperclass()->_getMethods (result
, offset
);
579 // Finally, examine interfaces.
580 for (int i
= 0; i
< interface_count
; ++i
)
582 int f_count
= interfaces
[i
]->_getMethods (result
, offset
);
590 JArray
<java::lang::reflect::Method
*> *
591 java::lang::Class::getMethods (void)
593 using namespace java::lang::reflect
;
595 memberAccessCheck(Member::PUBLIC
);
597 // This will overestimate the size we need.
598 jint count
= _getMethods (NULL
, 0);
600 JArray
<Method
*> *result
601 = ((JArray
<Method
*> *) JvNewObjectArray (count
,
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);
609 if (real_count
!= count
)
612 = ((JArray
<Method
*> *) JvNewObjectArray (real_count
,
616 Method
**destp
= elements (r2
);
617 Method
**srcp
= elements (result
);
619 for (int i
= 0; i
< real_count
; ++i
)
629 java::lang::Class::isAssignableFrom (jclass klass
)
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);
639 java::lang::Class::isInstance (jobject obj
)
643 return _Jv_IsAssignableFrom (JV_CLASS (obj
), this);
647 java::lang::Class::newInstance (void)
649 memberAccessCheck(java::lang::reflect::Member::PUBLIC
);
654 || java::lang::reflect::Modifier::isAbstract(accflags
))
655 throw new java::lang::InstantiationException (getName ());
657 _Jv_InitClass (this);
659 _Jv_Method
*meth
= _Jv_GetMethodLocal (this, init_name
, void_signature
);
661 throw new java::lang::InstantiationException (getName());
663 jobject r
= _Jv_AllocObject (this);
664 ((void (*) (jobject
)) meth
->ncode
) (r
);
669 java::lang::Class::finalize (void)
671 engine
->unregister(this);
676 _Jv_ClosureList::releaseClosures (_Jv_ClosureList
**closures
)
681 while (_Jv_ClosureList
*current
= *closures
)
683 *closures
= current
->next
;
684 ffi_closure_free (current
->ptr
);
689 _Jv_ClosureList::registerClosure (jclass klass
, void *ptr
)
691 _Jv_ClosureList
**closures
= klass
->engine
->get_closure_list (klass
);
695 this->next
= *closures
;
701 // This implements the initialization process for a class. From Spec
704 java::lang::Class::initializeClass (void)
706 // Short-circuit to avoid needless locking (expression includes
707 // JV_STATE_PHANTOM and JV_STATE_DONE).
708 if (state
>= JV_STATE_PHANTOM
)
711 // Step 1. We introduce a new scope so we can synchronize more
714 JvSynchronize
sync (this);
716 if (state
< JV_STATE_LINKED
)
720 _Jv_Linker::wait_for_state(this, JV_STATE_LINKED
);
722 catch (java::lang::SecurityException
*x
)
726 catch (java::lang::Throwable
*x
)
728 // Turn into a NoClassDefFoundError.
729 java::lang::NoClassDefFoundError
*result
730 = new java::lang::NoClassDefFoundError(getName());
731 result
->initCause(x
);
737 java::lang::Thread
*self
= java::lang::Thread::currentThread();
738 self
= (java::lang::Thread
*) ((long) self
| 1);
739 while (state
== JV_STATE_IN_PROGRESS
&& thread
&& thread
!= self
)
743 if (state
== JV_STATE_DONE
|| state
== JV_STATE_IN_PROGRESS
)
747 if (state
== JV_STATE_ERROR
)
748 throw new java::lang::NoClassDefFoundError (getName());
752 _Jv_Linker::wait_for_state (this, JV_STATE_LINKED
);
753 state
= JV_STATE_IN_PROGRESS
;
757 if (! isInterface () && superclass
)
761 _Jv_InitClass (superclass
);
763 catch (java::lang::SecurityException
*x
)
767 catch (java::lang::Throwable
*except
)
769 // Caught an exception.
770 JvSynchronize
sync (this);
771 state
= JV_STATE_ERROR
;
777 // Steps 8, 9, 10, 11.
780 _Jv_Method
*meth
= _Jv_GetMethodLocal (this, clinit_name
,
783 ((void (*) (void)) meth
->ncode
) ();
785 catch (java::lang::SecurityException
*x
)
789 catch (java::lang::Throwable
*except
)
791 if (! java::lang::Error::class$
.isInstance(except
))
795 except
= new ExceptionInInitializerError (except
);
797 catch (java::lang::Throwable
*t
)
803 JvSynchronize
sync (this);
804 state
= JV_STATE_ERROR
;
809 JvSynchronize
sync (this);
810 state
= JV_STATE_DONE
;
814 // Only used by serialization
815 java::lang::reflect::Field
*
816 java::lang::Class::getPrivateField (jstring name
)
818 int hash
= name
->hashCode ();
820 java::lang::reflect::Field
* rfield
;
821 for (int i
= 0; i
< field_count
; i
++)
823 _Jv_Field
*field
= &fields
[i
];
824 if (! _Jv_equal (field
->name
, name
, hash
))
826 rfield
= new java::lang::reflect::Field ();
827 rfield
->offset
= (char*) field
- (char*) fields
;
828 rfield
->declaringClass
= this;
832 jclass superclass
= getSuperclass();
833 if (superclass
== NULL
)
835 rfield
= superclass
->getPrivateField(name
);
836 for (int i
= 0; i
< interface_count
&& rfield
== NULL
; ++i
)
837 rfield
= interfaces
[i
]->getPrivateField (name
);
841 // Only used by serialization
842 java::lang::reflect::Method
*
843 java::lang::Class::getPrivateMethod (jstring name
, JArray
<jclass
> *param_types
)
845 jstring partial_sig
= getSignature (param_types
, false);
846 jint p_len
= partial_sig
->length();
847 _Jv_Utf8Const
*utf_name
= _Jv_makeUtf8Const (name
);
848 for (Class
*klass
= this; klass
; klass
= klass
->getSuperclass())
850 int i
= klass
->isPrimitive () ? 0 : klass
->method_count
;
853 if (_Jv_equalUtf8Consts (klass
->methods
[i
].name
, utf_name
)
854 && _Jv_equaln (klass
->methods
[i
].signature
, partial_sig
, p_len
))
857 using namespace java::lang::reflect
;
859 Method
*rmethod
= new Method ();
860 rmethod
->offset
= ((char *) (&klass
->methods
[i
])
861 - (char *) klass
->methods
);
862 rmethod
->declaringClass
= klass
;
867 throw new java::lang::NoSuchMethodException (name
);
870 // Private accessor method for Java code to retrieve the protection domain.
871 java::security::ProtectionDomain
*
872 java::lang::Class::getProtectionDomain0 ()
874 return protectionDomain
;
878 java::lang::Class::getSigners()
884 java::lang::Class::setSigners(JArray
<jobject
> *s
)
892 read_u1 (unsigned char *&p
)
898 read_u1 (unsigned char *&p
, unsigned char *next
)
901 throw new java::lang::InternalError();
906 read_u2 (unsigned char *&p
)
908 unsigned int b1
= *p
++;
909 unsigned int b2
= *p
++;
910 return (b1
<< 8) | b2
;
914 read_u2 (unsigned char *&p
, unsigned char *next
)
917 throw new java::lang::InternalError();
922 read_4 (unsigned char *&p
)
928 return (b1
<< 24) | (b2
<< 16) | (b3
<< 8) | b4
;
932 java::lang::Class::getReflectionSignature (jint
/*jv_attr_type*/ type
,
935 // We just re-parse the bytecode for this data each time. If
936 // necessary we can cache results, but I suspect this is not
937 // performance sensitive.
938 unsigned char *bytes
= reflection_data
;
943 int kind
= read_u1 (bytes
);
944 if (kind
== JV_DONE_ATTR
)
946 int len
= read_4 (bytes
);
947 unsigned char *next
= bytes
+ len
;
953 if (type
!= JV_CLASS_ATTR
)
955 unsigned short index
= read_u2 (bytes
, next
);
956 if (index
!= obj_index
)
962 int nt
= read_u1 (bytes
, next
);
963 if (nt
!= JV_SIGNATURE_KIND
)
968 unsigned int cpool_idx
= read_u2 (bytes
, next
);
969 if (cpool_idx
>= (unsigned int) constants
.size
970 || constants
.tags
[cpool_idx
] != JV_CONSTANT_Utf8
)
972 // We just ignore errors for now. It isn't clear what is
973 // best to do here, as an encoding error here means a bug
974 // either in the compiler or in defineclass.cc.
977 return _Jv_NewStringUtf8Const (constants
.data
[cpool_idx
].utf8
);
982 java::lang::Class::getReflectionSignature (::java::lang::reflect::Constructor
*c
)
984 _Jv_Method
*meth
= _Jv_FromReflectedConstructor (c
);
985 unsigned short meth_index
= meth
- methods
;
986 return getReflectionSignature (JV_METHOD_ATTR
, meth_index
);
990 java::lang::Class::getReflectionSignature (::java::lang::reflect::Method
*m
)
992 _Jv_Method
*meth
= _Jv_FromReflectedMethod (m
);
993 unsigned short meth_index
= meth
- methods
;
994 return getReflectionSignature (JV_METHOD_ATTR
, meth_index
);
998 java::lang::Class::getReflectionSignature (::java::lang::reflect::Field
*f
)
1000 _Jv_Field
*fld
= _Jv_FromReflectedField (f
);
1001 unsigned short fld_index
= fld
- fields
;
1002 return getReflectionSignature (JV_FIELD_ATTR
, fld_index
);
1006 java::lang::Class::getClassSignature()
1008 return getReflectionSignature (JV_CLASS_ATTR
, 0);
1012 java::lang::Class::getEnclosingMethodData()
1014 unsigned char *bytes
= reflection_data
;
1019 int kind
= read_u1 (bytes
);
1020 if (kind
== JV_DONE_ATTR
)
1022 int len
= read_4 (bytes
);
1023 unsigned char *next
= bytes
+ len
;
1024 if (kind
!= JV_CLASS_ATTR
)
1029 int type
= read_u1 (bytes
, next
);
1030 if (type
!= JV_ENCLOSING_METHOD_KIND
)
1035 int class_index
= read_u2 (bytes
, next
);
1036 int method_index
= read_u2 (bytes
, next
);
1038 _Jv_storeIndexes (&result
, class_index
, method_index
);
1044 java::lang::Class::getEnclosingClass()
1047 indexes
.i
= getEnclosingMethodData();
1049 // No enclosing method, but perhaps a member or anonymous class
1050 return getDeclaringClass();
1051 _Jv_ushort class_index
, method_index
;
1052 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1053 return _Jv_Linker::resolve_pool_entry (this, class_index
).clazz
;
1056 ::java::lang::reflect::Method
*
1057 java::lang::Class::getEnclosingMethod()
1060 indexes
.i
= getEnclosingMethodData();
1063 _Jv_ushort class_index
, method_index
;
1064 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1066 _Jv_Method
*method
= _Jv_Linker::resolve_method_entry (this, found_class
,
1070 using namespace java::lang::reflect
;
1071 Method
*rmethod
= new Method ();
1072 rmethod
->offset
= (char *) method
- (char *) found_class
->methods
;
1073 rmethod
->declaringClass
= found_class
;
1077 ::java::lang::reflect::Constructor
*
1078 java::lang::Class::getEnclosingConstructor()
1081 indexes
.i
= getEnclosingMethodData();
1084 _Jv_ushort class_index
, method_index
;
1085 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1087 _Jv_Method
*method
= _Jv_Linker::resolve_method_entry (this, found_class
,
1091 using namespace java::lang::reflect
;
1092 Constructor
*cons
= new Constructor ();
1093 cons
->offset
= (char *) method
- (char *) found_class
->methods
;
1094 cons
->declaringClass
= this;
1099 check_constant (_Jv_Constants
*pool
, jint cpool_index
, jint type
)
1101 if (cpool_index
<= 0 || cpool_index
>= pool
->size
)
1102 throw new InternalError(JvNewStringLatin1("invalid constant pool index"));
1103 if ((pool
->tags
[cpool_index
] &
1104 ~(JV_CONSTANT_ResolvedFlag
|JV_CONSTANT_LazyFlag
)) != type
)
1106 ::java::lang::StringBuffer
*sb
= new ::java::lang::StringBuffer();
1107 sb
->append(JvNewStringLatin1("expected pool constant "));
1109 sb
->append(JvNewStringLatin1(" but got "));
1110 sb
->append(jint (pool
->tags
[cpool_index
]));
1111 throw new InternalError(sb
->toString());
1115 // Forward declaration
1116 static ::java::lang::annotation::Annotation
*
1117 parseAnnotation(jclass klass
, _Jv_Constants
*pool
,
1118 unsigned char *&bytes
, unsigned char *last
);
1121 parseAnnotationElement(jclass klass
, _Jv_Constants
*pool
,
1122 unsigned char *&bytes
, unsigned char *last
)
1124 int tag
= read_u1 (bytes
, last
);
1130 int cindex
= read_u2 (bytes
, last
);
1131 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1132 result
= Byte::valueOf (pool
->data
[cindex
].i
);
1137 int cindex
= read_u2 (bytes
, last
);
1138 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1139 result
= Character::valueOf (pool
->data
[cindex
].i
);
1144 int cindex
= read_u2 (bytes
, last
);
1145 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1146 result
= Short::valueOf (pool
->data
[cindex
].i
);
1151 int cindex
= read_u2 (bytes
, last
);
1152 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1153 result
= Boolean::valueOf (jboolean (pool
->data
[cindex
].i
));
1158 int cindex
= read_u2 (bytes
, last
);
1159 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1160 result
= Integer::valueOf (pool
->data
[cindex
].i
);
1165 int cindex
= read_u2 (bytes
, last
);
1166 check_constant (pool
, cindex
, JV_CONSTANT_Double
);
1168 memcpy (&word
, &pool
->data
[cindex
], 2 * sizeof (_Jv_word
));
1169 result
= Double::valueOf (word
.d
);
1174 int cindex
= read_u2 (bytes
, last
);
1175 check_constant (pool
, cindex
, JV_CONSTANT_Float
);
1176 result
= Float::valueOf (pool
->data
[cindex
].f
);
1181 int cindex
= read_u2 (bytes
, last
);
1182 check_constant (pool
, cindex
, JV_CONSTANT_Long
);
1184 memcpy (&word
, &pool
->data
[cindex
], 2 * sizeof (_Jv_word
));
1185 result
= Long::valueOf (word
.l
);
1190 int cindex
= read_u2 (bytes
, last
);
1191 // Despite what the JVM spec says, compilers generate a Utf8
1192 // constant here, not a String.
1193 check_constant (pool
, cindex
, JV_CONSTANT_Utf8
);
1194 result
= pool
->data
[cindex
].utf8
->toString();
1199 int type_name_index
= read_u2 (bytes
, last
);
1200 check_constant (pool
, type_name_index
, JV_CONSTANT_Utf8
);
1201 int const_name_index
= read_u2 (bytes
, last
);
1202 check_constant (pool
, const_name_index
, JV_CONSTANT_Utf8
);
1204 _Jv_Utf8Const
*u_name
= pool
->data
[type_name_index
].utf8
;
1205 _Jv_Utf8Const
*e_name
= pool
->data
[const_name_index
].utf8
;
1207 // FIXME: throw correct exceptions at the correct times.
1208 jclass e_class
= _Jv_FindClassFromSignature(u_name
->chars(),
1209 klass
->getClassLoaderInternal());
1210 result
= ::java::lang::Enum::valueOf(e_class
, e_name
->toString());
1215 int cindex
= read_u2 (bytes
, last
);
1216 check_constant (pool
, cindex
, JV_CONSTANT_Utf8
);
1217 _Jv_Utf8Const
*u_name
= pool
->data
[cindex
].utf8
;
1219 = _Jv_FindClassFromSignatureNoException(u_name
->chars(),
1220 klass
->getClassLoaderInternal());
1221 // FIXME: not correct: we should lazily do this when trying to
1222 // read the element. This means that
1223 // AnnotationInvocationHandler needs to have a special case.
1225 // FIXME: original exception...
1226 throw new TypeNotPresentException(u_name
->toString(), NULL
);
1227 result
= anno_class
;
1231 result
= parseAnnotation (klass
, pool
, bytes
, last
);
1235 int n_array_elts
= read_u2 (bytes
, last
);
1236 jobjectArray aresult
= _Jv_NewObjectArray (n_array_elts
,
1237 &Object::class$
, NULL
);
1238 jobject
*elts
= elements (aresult
);
1239 for (int i
= 0; i
< n_array_elts
; ++i
)
1240 elts
[i
] = parseAnnotationElement(klass
, pool
, bytes
, last
);
1245 throw new java::lang::InternalError();
1250 static ::java::lang::annotation::Annotation
*
1251 parseAnnotation(jclass klass
, _Jv_Constants
*pool
,
1252 unsigned char *&bytes
, unsigned char *last
)
1254 int type_index
= read_u2 (bytes
, last
);
1255 check_constant (pool
, type_index
, JV_CONSTANT_Utf8
);
1257 _Jv_Utf8Const
*u_name
= pool
->data
[type_index
].utf8
;
1258 jclass anno_class
= _Jv_FindClassFromSignatureNoException(u_name
->chars(),
1259 klass
->getClassLoaderInternal());
1260 // FIXME: what to do if anno_class==NULL?
1262 ::java::util::HashMap
*hmap
= new ::java::util::HashMap();
1263 int npairs
= read_u2 (bytes
, last
);
1264 for (int i
= 0; i
< npairs
; ++i
)
1266 int name_index
= read_u2 (bytes
, last
);
1267 check_constant (pool
, name_index
, JV_CONSTANT_Utf8
);
1268 jstring name
= _Jv_NewStringUtf8Const (pool
->data
[name_index
].utf8
);
1269 jobject value
= parseAnnotationElement (klass
, pool
, bytes
, last
);
1270 // FIXME: any checks needed for name?
1271 hmap
->put(name
, value
);
1273 using namespace ::sun::reflect::annotation
;
1274 return AnnotationInvocationHandler::create (anno_class
,
1275 (::java::util::Map
*) hmap
);
1279 parseAnnotations(jclass klass
, _Jv_Constants
*pool
,
1280 unsigned char *&bytes
, unsigned char *last
)
1282 int num
= read_u2 (bytes
, last
);
1283 jobjectArray result
= _Jv_NewObjectArray (num
,
1284 &::java::lang::annotation::Annotation::class$
,
1286 jobject
*elts
= elements (result
);
1287 for (int i
= 0; i
< num
; ++i
)
1288 elts
[i
] = parseAnnotation(klass
, pool
, bytes
, last
);
1293 parseParameterAnnotations(jclass klass
, _Jv_Constants
*pool
,
1294 unsigned char *&bytes
, unsigned char *last
)
1296 jclass anno
= &::java::lang::annotation::Annotation::class$
;
1297 jclass annoary
= _Jv_GetArrayClass (anno
, anno
->getClassLoaderInternal());
1299 // FIXME: something should check the number of params versus the
1301 int n_params
= read_u1 (bytes
, last
);
1302 jobjectArray result
= _Jv_NewObjectArray (n_params
, annoary
, NULL
);
1303 jobject
*elts
= elements (result
);
1304 for (int i
= 0; i
< n_params
; ++i
)
1305 elts
[i
] = parseAnnotations(klass
, pool
, bytes
, last
);
1310 java::lang::Class::getMethodDefaultValue(::java::lang::reflect::Method
*meth
)
1312 // FIXME: could cache the value here...
1314 unsigned char *bytes
= reflection_data
;
1318 unsigned short meth_index
= _Jv_FromReflectedMethod (meth
) - methods
;
1322 int type
= read_u1 (bytes
);
1323 if (type
== JV_DONE_ATTR
)
1325 int len
= read_4 (bytes
);
1326 unsigned char *next
= bytes
+ len
;
1327 if (type
!= JV_METHOD_ATTR
)
1332 int kind
= read_u1 (bytes
, next
);
1333 if (kind
!= JV_ANNOTATION_DEFAULT_KIND
)
1338 int index
= read_u2 (bytes
, next
);
1339 if (meth_index
!= index
)
1345 // FIXME: could cache here. If we do then we have to clone any
1347 return parseAnnotationElement(this, &this->constants
, bytes
, next
);
1352 java::lang::Class::getDeclaredAnnotations(jint
/* jv_attr_type */ member_type
,
1354 jint
/* jv_attr_kind */ kind_req
)
1356 using namespace java::lang::annotation
;
1357 jobjectArray result
;
1359 unsigned char *bytes
= reflection_data
;
1364 loader
= (ClassLoader
*)VMClassLoader::bootLoader
;
1366 result
= (loader
->getDeclaredAnnotations
1367 (this, member_type
, member_index
, kind_req
));
1373 int type
= read_u1 (bytes
);
1374 if (type
== JV_DONE_ATTR
)
1376 int len
= read_4 (bytes
);
1377 unsigned char *next
= bytes
+ len
;
1378 if (type
!= member_type
)
1383 int kind
= read_u1 (bytes
, next
);
1384 if (kind
!= kind_req
)
1389 if (member_type
!= JV_CLASS_ATTR
)
1391 int index
= read_u2 (bytes
, next
);
1392 if (member_index
!= index
)
1399 if (kind_req
== JV_PARAMETER_ANNOTATIONS_KIND
)
1400 result
= ((parseParameterAnnotations
1401 (this, &this->constants
, bytes
, next
)));
1403 result
= ((parseAnnotations (this, &this->constants
, bytes
, next
)));
1407 return (loader
->putDeclaredAnnotations
1408 (this, member_type
, member_index
, kind_req
, result
));
1412 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Method
*meth
,
1415 unsigned short meth_index
= _Jv_FromReflectedMethod (meth
) - methods
;
1416 return getDeclaredAnnotations(JV_METHOD_ATTR
, meth_index
,
1418 ? JV_PARAMETER_ANNOTATIONS_KIND
1419 : JV_ANNOTATIONS_KIND
));
1423 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Constructor
*cons
,
1426 unsigned short meth_index
= _Jv_FromReflectedConstructor (cons
) - methods
;
1427 return getDeclaredAnnotations(JV_METHOD_ATTR
, meth_index
,
1429 ? JV_PARAMETER_ANNOTATIONS_KIND
1430 : JV_ANNOTATIONS_KIND
));
1434 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Field
*fld
)
1436 unsigned short field_index
= _Jv_FromReflectedField (fld
) - fields
;
1437 return getDeclaredAnnotations(JV_FIELD_ATTR
, field_index
,
1438 JV_ANNOTATIONS_KIND
);
1441 JArray
< ::java::lang::annotation::Annotation
*> *
1442 java::lang::Class::getDeclaredAnnotationsInternal()
1444 return (JArray
< ::java::lang::annotation::Annotation
*> *) getDeclaredAnnotations(JV_CLASS_ATTR
, 0, JV_ANNOTATIONS_KIND
);
1448 resolve_class_constant (jclass klass
, _Jv_Constants
*pool
, int cpool_index
)
1450 check_constant (pool
, cpool_index
, JV_CONSTANT_Class
);
1451 // FIXME: what is the correct thing to do with an exception here?
1452 return _Jv_Linker::resolve_pool_entry (klass
, cpool_index
, false).clazz
;
1456 java::lang::Class::findInnerClassAttribute()
1458 unsigned char *bytes
= reflection_data
;
1463 int type
= read_u1 (bytes
);
1464 if (type
== JV_DONE_ATTR
)
1466 // After the type but before the length.
1467 unsigned char *save
= bytes
;
1468 int len
= read_4 (bytes
);
1469 unsigned char *next
= bytes
+ len
;
1470 if (type
!= JV_CLASS_ATTR
)
1475 int kind
= read_u1 (bytes
, next
);
1476 if (kind
!= JV_INNER_CLASSES_KIND
)
1481 return save
- reflection_data
;
1487 java::lang::Class::findDeclaredClasses(JArray
<jclass
> *result
,
1488 jboolean publicOnly
,
1491 unsigned char *bytes
= reflection_data
+ offset
;
1492 int len
= read_4 (bytes
);
1493 unsigned char *next
= bytes
+ len
;
1495 read_u1 (bytes
, next
);
1496 int n_classes
= read_u2 (bytes
, next
);
1498 for (int i
= 0; i
< n_classes
; ++i
)
1500 int inner_class_index
= read_u2 (bytes
, next
);
1501 int outer_class_index
= read_u2 (bytes
, next
);
1502 /*int inner_name_index = */ read_u2 (bytes
, next
);
1503 int inner_flags
= read_u2 (bytes
, next
);
1505 if (inner_class_index
== 0 || outer_class_index
== 0)
1507 if (resolve_class_constant (this, &constants
, outer_class_index
) == this)
1509 jclass inner
= resolve_class_constant (this, &constants
,
1513 & java::lang::reflect::Modifier::PUBLIC
) != 0))
1517 jclass
*elts
= elements (result
);
1518 elts
[count
] = inner
;
1529 java::lang::Class::getDeclaredClasses (jboolean publicOnly
)
1531 int offset
= findInnerClassAttribute();
1535 // No InnerClasses attribute, so no declared classes.
1539 count
= findDeclaredClasses(NULL
, publicOnly
, offset
);
1540 JArray
<jclass
> *result
1541 = (JArray
<jclass
> *) JvNewObjectArray (count
, &java::lang::Class::class$
,
1544 findDeclaredClasses(result
, publicOnly
, offset
);
1549 java::lang::Class::getDeclaringClass (void)
1551 int offset
= findInnerClassAttribute();
1555 unsigned char *bytes
= reflection_data
+ offset
;
1556 int len
= read_4 (bytes
);
1557 unsigned char *next
= bytes
+ len
;
1559 read_u1 (bytes
, next
);
1560 int n_classes
= read_u2 (bytes
, next
);
1561 for (int i
= 0; i
< n_classes
; ++i
)
1563 int inner_class_index
= read_u2 (bytes
, next
);
1564 int outer_class_index
= read_u2 (bytes
, next
);
1565 /*int inner_name_index = */read_u2 (bytes
, next
);
1566 /*int inner_flags = */read_u2 (bytes
, next
);
1568 if (inner_class_index
== 0 || outer_class_index
== 0)
1570 if (resolve_class_constant (this, &constants
, inner_class_index
) == this)
1571 return resolve_class_constant (this, &constants
, outer_class_index
);
1578 java::lang::Class::isAnonymousClass()
1580 int offset
= findInnerClassAttribute();
1584 unsigned char *bytes
= reflection_data
+ offset
;
1585 int len
= read_4 (bytes
);
1586 unsigned char *next
= bytes
+ len
;
1588 read_u1 (bytes
, next
);
1589 int n_classes
= read_u2 (bytes
, next
);
1590 for (int i
= 0; i
< n_classes
; ++i
)
1592 int inner_class_index
= read_u2 (bytes
, next
);
1593 /*int outer_class_index = */read_u2 (bytes
, next
);
1594 int inner_name_index
= read_u2 (bytes
, next
);
1595 /*int inner_flags = */read_u2 (bytes
, next
);
1597 if (inner_class_index
== 0)
1599 if (resolve_class_constant (this, &constants
, inner_class_index
) == this)
1600 return inner_name_index
== 0;
1607 java::lang::Class::isLocalClass()
1610 indexes
.i
= getEnclosingMethodData();
1611 return indexes
.i
!= 0;
1615 java::lang::Class::isMemberClass()
1617 // FIXME: is this correct?
1618 return !isLocalClass() && getDeclaringClass() != NULL
;
1624 // Some class-related convenience functions.
1627 // Find a method declared in the class. If it is not declared locally
1628 // (or if it is inherited), return NULL.
1630 _Jv_GetMethodLocal (jclass klass
, _Jv_Utf8Const
*name
,
1631 _Jv_Utf8Const
*signature
)
1633 for (int i
= 0; i
< klass
->method_count
; ++i
)
1635 if (_Jv_equalUtf8Consts (name
, klass
->methods
[i
].name
)
1636 && _Jv_equalUtf8Consts (signature
, klass
->methods
[i
].signature
))
1637 return &klass
->methods
[i
];
1643 _Jv_LookupDeclaredMethod (jclass klass
, _Jv_Utf8Const
*name
,
1644 _Jv_Utf8Const
*signature
,
1645 jclass
*declarer_result
)
1647 for (; klass
; klass
= klass
->getSuperclass())
1649 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
1653 if (declarer_result
)
1654 *declarer_result
= klass
;
1662 java::lang::reflect::Method
*
1663 _Jv_GetReflectedMethod (jclass klass
, _Jv_Utf8Const
*name
,
1664 _Jv_Utf8Const
*signature
)
1666 for (; klass
; klass
= klass
->getSuperclass())
1668 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
1671 using namespace java::lang::reflect
;
1672 Method
*rmethod
= new Method ();
1673 rmethod
->offset
= (char*) meth
- (char*) klass
->methods
;
1674 rmethod
->declaringClass
= klass
;
1684 // NOTE: MCACHE_SIZE should be a power of 2 minus one.
1685 #define MCACHE_SIZE 31
1693 static __thread _Jv_mcache
*method_cache
;
1697 _Jv_FindMethodInCache (jclass klass MAYBE_UNUSED
,
1698 _Jv_Utf8Const
*name MAYBE_UNUSED
,
1699 _Jv_Utf8Const
*signature MAYBE_UNUSED
)
1702 _Jv_mcache
*cache
= method_cache
;
1705 int index
= name
->hash16 () & MCACHE_SIZE
;
1706 _Jv_mcache
*mc
= &cache
[index
];
1707 _Jv_Method
*m
= mc
->method
;
1709 if (mc
->klass
== klass
1710 && _Jv_equalUtf8Consts (m
->name
, name
)
1711 && _Jv_equalUtf8Consts (m
->signature
, signature
))
1712 return mc
->method
->ncode
;
1719 _Jv_AddMethodToCache (jclass klass MAYBE_UNUSED
,
1720 _Jv_Method
*method MAYBE_UNUSED
)
1723 if (method_cache
== NULL
)
1724 method_cache
= (_Jv_mcache
*) _Jv_MallocUnchecked((MCACHE_SIZE
+ 1)
1725 * sizeof (_Jv_mcache
));
1726 // If the allocation failed, just keep going.
1727 if (method_cache
!= NULL
)
1729 int index
= method
->name
->hash16 () & MCACHE_SIZE
;
1730 method_cache
[index
].method
= method
;
1731 method_cache
[index
].klass
= klass
;
1736 // Free this thread's method cache. We explicitly manage this memory
1737 // as the GC does not yet know how to scan TLS on all platforms.
1739 _Jv_FreeMethodCache ()
1742 if (method_cache
!= NULL
)
1744 _Jv_Free(method_cache
);
1745 method_cache
= NULL
;
1751 _Jv_LookupInterfaceMethod (jclass klass
, _Jv_Utf8Const
*name
,
1752 _Jv_Utf8Const
*signature
)
1754 using namespace java::lang::reflect
;
1756 void *ncode
= _Jv_FindMethodInCache (klass
, name
, signature
);
1760 for (; klass
; klass
= klass
->getSuperclass())
1762 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
1766 if (Modifier::isStatic(meth
->accflags
))
1767 throw new java::lang::IncompatibleClassChangeError
1768 (_Jv_GetMethodString (klass
, meth
));
1769 if (Modifier::isAbstract(meth
->accflags
))
1770 throw new java::lang::AbstractMethodError
1771 (_Jv_GetMethodString (klass
, meth
));
1772 if (! Modifier::isPublic(meth
->accflags
))
1773 throw new java::lang::IllegalAccessError
1774 (_Jv_GetMethodString (klass
, meth
));
1776 _Jv_AddMethodToCache (klass
, meth
);
1780 throw new java::lang::IncompatibleClassChangeError
;
1783 // Fast interface method lookup by index.
1785 _Jv_LookupInterfaceMethodIdx (jclass klass
, jclass iface
, int method_idx
)
1787 _Jv_IDispatchTable
*cldt
= klass
->idt
;
1788 int idx
= iface
->ioffsets
[cldt
->iindex
] + method_idx
;
1789 return cldt
->itable
[idx
];
1793 _Jv_IsAssignableFrom (jclass source
, jclass target
)
1795 if (source
== target
)
1798 // If target is array, so must source be.
1799 while (target
->isArray ())
1801 if (! source
->isArray())
1803 target
= target
->getComponentType();
1804 source
= source
->getComponentType();
1807 if (target
->isInterface())
1809 // Abstract classes have no IDT, and IDTs provide no way to check
1810 // two interfaces for assignability.
1811 if (__builtin_expect
1812 (source
->idt
== NULL
|| source
->isInterface(), false))
1813 return _Jv_InterfaceAssignableFrom (source
, target
);
1815 _Jv_IDispatchTable
*cl_idt
= source
->idt
;
1817 if (__builtin_expect ((target
->ioffsets
== NULL
), false))
1818 return false; // No class implementing TARGET has been loaded.
1819 jshort cl_iindex
= cl_idt
->iindex
;
1820 if (cl_iindex
< target
->ioffsets
[0])
1822 jshort offset
= target
->ioffsets
[cl_iindex
];
1823 if (offset
!= -1 && offset
< cl_idt
->itable_length
1824 && cl_idt
->itable
[offset
] == target
)
1830 // Primitive TYPE classes are only assignable to themselves.
1831 if (__builtin_expect (target
->isPrimitive() || source
->isPrimitive(), false))
1834 if (target
== &java::lang::Object::class$
)
1836 else if (source
->ancestors
== NULL
|| target
->ancestors
== NULL
)
1838 // We need this case when either SOURCE or TARGET has not has
1839 // its constant-time tables prepared.
1841 // At this point we know that TARGET can't be Object, so it is
1842 // safe to use that as the termination point.
1843 while (source
&& source
!= &java::lang::Object::class$
)
1845 if (source
== target
)
1847 source
= source
->getSuperclass();
1850 else if (source
->depth
>= target
->depth
1851 && source
->ancestors
[source
->depth
- target
->depth
] == target
)
1857 // Interface type checking, the slow way. Returns TRUE if IFACE is a
1858 // superinterface of SOURCE. This is used when SOURCE is also an interface,
1859 // or a class with no interface dispatch table.
1861 _Jv_InterfaceAssignableFrom (jclass source
, jclass iface
)
1863 for (int i
= 0; i
< source
->interface_count
; i
++)
1865 jclass interface
= source
->interfaces
[i
];
1866 if (iface
== interface
1867 || _Jv_InterfaceAssignableFrom (interface
, iface
))
1871 if (!source
->isInterface()
1872 && source
->superclass
1873 && _Jv_InterfaceAssignableFrom (source
->superclass
, iface
))
1880 _Jv_IsInstanceOf(jobject obj
, jclass cl
)
1882 if (__builtin_expect (!obj
, false))
1884 return _Jv_IsAssignableFrom (JV_CLASS (obj
), cl
);
1888 _Jv_CheckCast (jclass c
, jobject obj
)
1890 if (__builtin_expect
1891 (obj
!= NULL
&& ! _Jv_IsAssignableFrom(JV_CLASS (obj
), c
), false))
1892 throw new java::lang::ClassCastException
1893 ((new java::lang::StringBuffer
1894 (obj
->getClass()->getName()))->append
1895 (JvNewStringUTF(" cannot be cast to "))->append
1896 (c
->getName())->toString());
1902 _Jv_CheckArrayStore (jobject arr
, jobject obj
)
1906 JvAssert (arr
!= NULL
);
1907 jclass elt_class
= (JV_CLASS (arr
))->getComponentType();
1908 if (elt_class
== &java::lang::Object::class$
)
1910 jclass obj_class
= JV_CLASS (obj
);
1911 if (__builtin_expect
1912 (! _Jv_IsAssignableFrom (obj_class
, elt_class
), false))
1913 throw new java::lang::ArrayStoreException
1914 ((new java::lang::StringBuffer
1915 (JvNewStringUTF("Cannot store ")))->append
1916 (obj_class
->getName())->append
1917 (JvNewStringUTF(" in array of type "))->append
1918 (elt_class
->getName())->toString());
1923 _Jv_IsAssignableFromSlow (jclass source
, jclass target
)
1925 // First, strip arrays.
1926 while (target
->isArray ())
1928 // If target is array, source must be as well.
1929 if (! source
->isArray ())
1931 target
= target
->getComponentType ();
1932 source
= source
->getComponentType ();
1936 if (target
== &java::lang::Object::class$
)
1939 // Ensure that the classes have their supers installed.
1940 _Jv_Linker::wait_for_state (source
, JV_STATE_LOADING
);
1941 _Jv_Linker::wait_for_state (target
, JV_STATE_LOADING
);
1945 if (source
== target
)
1948 if (target
->isPrimitive () || source
->isPrimitive ())
1951 if (target
->isInterface ())
1953 for (int i
= 0; i
< source
->interface_count
; ++i
)
1955 // We use a recursive call because we also need to
1956 // check superinterfaces.
1957 if (_Jv_IsAssignableFromSlow (source
->getInterface (i
), target
))
1961 source
= source
->getSuperclass ();
1963 while (source
!= NULL
);
1968 // Lookup an interface method by name. This is very similar to
1969 // purpose to _getMethod, but the interfaces are quite different. It
1970 // might be a good idea for _getMethod to call this function.
1972 // Return true of the method is found, with the class in FOUND_CLASS
1973 // and the index in INDEX.
1975 _Jv_getInterfaceMethod (jclass search_class
, jclass
&found_class
, int &index
,
1976 const _Jv_Utf8Const
*utf_name
,
1977 const _Jv_Utf8Const
*utf_sig
)
1979 for (jclass klass
= search_class
; klass
; klass
= klass
->getSuperclass())
1981 // FIXME: Throw an exception?
1982 if (!klass
->isInterface ())
1985 int max
= klass
->method_count
;
1987 for (int i
= 0; i
< max
; ++i
)
1989 // Skip <clinit> here, as it will not be in the IDT.
1990 if (klass
->methods
[i
].name
->first() == '<')
1993 if (_Jv_equalUtf8Consts (klass
->methods
[i
].name
, utf_name
)
1994 && _Jv_equalUtf8Consts (klass
->methods
[i
].signature
, utf_sig
))
1997 using namespace java::lang::reflect
;
1999 // FIXME: Method must be public. Throw an exception?
2000 if (! Modifier::isPublic (klass
->methods
[i
].accflags
))
2003 found_class
= klass
;
2004 // Interface method indexes count from 1.
2013 // If we haven't found a match, and this class is an interface, then
2014 // check all the superinterfaces.
2015 if (search_class
->isInterface())
2017 for (int i
= 0; i
< search_class
->interface_count
; ++i
)
2019 using namespace java::lang::reflect
;
2020 bool found
= _Jv_getInterfaceMethod (search_class
->interfaces
[i
],
2033 _Jv_FindInterpreterMethod (jclass klass
, jmethodID desired_method
)
2035 using namespace java::lang::reflect
;
2037 _Jv_InterpClass
*iclass
2038 = reinterpret_cast<_Jv_InterpClass
*> (klass
->aux_info
);
2039 _Jv_MethodBase
**imethods
= _Jv_GetFirstMethod (iclass
);
2041 for (int i
= 0; i
< JvNumMethods (klass
); ++i
)
2043 _Jv_MethodBase
*imeth
= imethods
[i
];
2044 if (imeth
->get_method () == desired_method
)
2052 // Return Utf8 name of a class. This function is here for code that
2053 // can't access klass->name directly.
2055 _Jv_GetClassNameUtf8 (jclass klass
)
2061 _Jv_GetMethodDeclaringClass (jmethodID method
)
2063 _Jv_StackTrace::UpdateNCodeMap ();
2064 jobject obj
= reinterpret_cast<jobject
> (method
->ncode
);
2065 return reinterpret_cast<jclass
> (_Jv_StackTrace::ncodeMap
->get (obj
));
2069 _Jv_GetClassState (jclass klass
)
2071 return klass
->state
;
2076 _Jv_GetInterpClassSourceFile (jclass klass
)
2078 if (_Jv_IsInterpretedClass (klass
))
2080 _Jv_InterpClass
*iclass
=
2081 reinterpret_cast<_Jv_InterpClass
*> (klass
->aux_info
);
2082 return iclass
->source_file_name
;