1 // natClass.cc - Implementation of java.lang.Class native methods.
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
4 2010 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 /* Class constructors/destructors have __thiscall calling
665 convention for 32-bit native Windows ABI. */
666 #if defined (__MINGW32__) && defined (__i386__)
667 ((void (__thiscall
*) (jobject
)) meth
->ncode
) (r
);
669 ((void (*) (jobject
)) meth
->ncode
) (r
);
675 java::lang::Class::finalize (void)
677 // Array classes don't have an engine, and don't need to be finalized.
679 engine
->unregister(this);
684 _Jv_ClosureList::releaseClosures (_Jv_ClosureList
**closures
)
689 while (_Jv_ClosureList
*current
= *closures
)
691 *closures
= current
->next
;
692 ffi_closure_free (current
->ptr
);
697 _Jv_ClosureList::registerClosure (jclass klass
, void *ptr
)
699 _Jv_ClosureList
**closures
= klass
->engine
->get_closure_list (klass
);
703 this->next
= *closures
;
709 // This implements the initialization process for a class. From Spec
712 java::lang::Class::initializeClass (void)
714 // Short-circuit to avoid needless locking (expression includes
715 // JV_STATE_PHANTOM and JV_STATE_DONE).
716 if (state
>= JV_STATE_PHANTOM
)
719 // Step 1. We introduce a new scope so we can synchronize more
722 JvSynchronize
sync (this);
724 if (state
< JV_STATE_LINKED
)
728 _Jv_Linker::wait_for_state(this, JV_STATE_LINKED
);
730 catch (java::lang::SecurityException
*x
)
734 catch (java::lang::Throwable
*x
)
736 // Turn into a NoClassDefFoundError.
737 java::lang::NoClassDefFoundError
*result
738 = new java::lang::NoClassDefFoundError(getName());
739 result
->initCause(x
);
745 java::lang::Thread
*self
= java::lang::Thread::currentThread();
746 self
= (java::lang::Thread
*) ((long) self
| 1);
747 while (state
== JV_STATE_IN_PROGRESS
&& thread
&& thread
!= self
)
751 if (state
== JV_STATE_DONE
|| state
== JV_STATE_IN_PROGRESS
)
755 if (state
== JV_STATE_ERROR
)
756 throw new java::lang::NoClassDefFoundError (getName());
760 _Jv_Linker::wait_for_state (this, JV_STATE_LINKED
);
761 state
= JV_STATE_IN_PROGRESS
;
765 if (! isInterface () && superclass
)
769 _Jv_InitClass (superclass
);
771 catch (java::lang::SecurityException
*x
)
775 catch (java::lang::Throwable
*except
)
777 // Caught an exception.
778 JvSynchronize
sync (this);
779 state
= JV_STATE_ERROR
;
785 // Steps 8, 9, 10, 11.
788 _Jv_Method
*meth
= _Jv_GetMethodLocal (this, clinit_name
,
791 ((void (*) (void)) meth
->ncode
) ();
793 catch (java::lang::SecurityException
*x
)
797 catch (java::lang::Throwable
*except
)
799 if (! java::lang::Error::class$
.isInstance(except
))
803 except
= new ExceptionInInitializerError (except
);
805 catch (java::lang::Throwable
*t
)
811 JvSynchronize
sync (this);
812 state
= JV_STATE_ERROR
;
817 JvSynchronize
sync (this);
818 state
= JV_STATE_DONE
;
822 // Only used by serialization
823 java::lang::reflect::Field
*
824 java::lang::Class::getPrivateField (jstring name
)
826 int hash
= name
->hashCode ();
828 java::lang::reflect::Field
* rfield
;
829 for (int i
= 0; i
< field_count
; i
++)
831 _Jv_Field
*field
= &fields
[i
];
832 if (! _Jv_equal (field
->name
, name
, hash
))
834 rfield
= new java::lang::reflect::Field ();
835 rfield
->offset
= (char*) field
- (char*) fields
;
836 rfield
->declaringClass
= this;
840 jclass superclass
= getSuperclass();
841 if (superclass
== NULL
)
843 rfield
= superclass
->getPrivateField(name
);
844 for (int i
= 0; i
< interface_count
&& rfield
== NULL
; ++i
)
845 rfield
= interfaces
[i
]->getPrivateField (name
);
849 // Only used by serialization
850 java::lang::reflect::Method
*
851 java::lang::Class::getPrivateMethod (jstring name
, JArray
<jclass
> *param_types
)
853 jstring partial_sig
= getSignature (param_types
, false);
854 jint p_len
= partial_sig
->length();
855 _Jv_Utf8Const
*utf_name
= _Jv_makeUtf8Const (name
);
856 for (Class
*klass
= this; klass
; klass
= klass
->getSuperclass())
858 int i
= klass
->isPrimitive () ? 0 : klass
->method_count
;
861 if (_Jv_equalUtf8Consts (klass
->methods
[i
].name
, utf_name
)
862 && _Jv_equaln (klass
->methods
[i
].signature
, partial_sig
, p_len
))
865 using namespace java::lang::reflect
;
867 Method
*rmethod
= new Method ();
868 rmethod
->offset
= ((char *) (&klass
->methods
[i
])
869 - (char *) klass
->methods
);
870 rmethod
->declaringClass
= klass
;
875 throw new java::lang::NoSuchMethodException (name
);
878 // Private accessor method for Java code to retrieve the protection domain.
879 java::security::ProtectionDomain
*
880 java::lang::Class::getProtectionDomain0 ()
882 return protectionDomain
;
886 java::lang::Class::getSigners()
892 java::lang::Class::setSigners(JArray
<jobject
> *s
)
900 read_u1 (unsigned char *&p
)
906 read_u1 (unsigned char *&p
, unsigned char *next
)
909 throw new java::lang::InternalError();
914 read_u2 (unsigned char *&p
)
916 unsigned int b1
= *p
++;
917 unsigned int b2
= *p
++;
918 return (b1
<< 8) | b2
;
922 read_u2 (unsigned char *&p
, unsigned char *next
)
925 throw new java::lang::InternalError();
930 read_4 (unsigned char *&p
)
936 return (b1
<< 24) | (b2
<< 16) | (b3
<< 8) | b4
;
940 java::lang::Class::getReflectionSignature (jint
/*jv_attr_type*/ type
,
943 // We just re-parse the bytecode for this data each time. If
944 // necessary we can cache results, but I suspect this is not
945 // performance sensitive.
946 unsigned char *bytes
= reflection_data
;
951 int kind
= read_u1 (bytes
);
952 if (kind
== JV_DONE_ATTR
)
954 int len
= read_4 (bytes
);
955 unsigned char *next
= bytes
+ len
;
961 if (type
!= JV_CLASS_ATTR
)
963 unsigned short index
= read_u2 (bytes
, next
);
964 if (index
!= obj_index
)
970 int nt
= read_u1 (bytes
, next
);
971 if (nt
!= JV_SIGNATURE_KIND
)
976 unsigned int cpool_idx
= read_u2 (bytes
, next
);
977 if (cpool_idx
>= (unsigned int) constants
.size
978 || constants
.tags
[cpool_idx
] != JV_CONSTANT_Utf8
)
980 // We just ignore errors for now. It isn't clear what is
981 // best to do here, as an encoding error here means a bug
982 // either in the compiler or in defineclass.cc.
985 return _Jv_NewStringUtf8Const (constants
.data
[cpool_idx
].utf8
);
990 java::lang::Class::getReflectionSignature (::java::lang::reflect::Constructor
*c
)
992 _Jv_Method
*meth
= _Jv_FromReflectedConstructor (c
);
993 unsigned short meth_index
= meth
- methods
;
994 return getReflectionSignature (JV_METHOD_ATTR
, meth_index
);
998 java::lang::Class::getReflectionSignature (::java::lang::reflect::Method
*m
)
1000 _Jv_Method
*meth
= _Jv_FromReflectedMethod (m
);
1001 unsigned short meth_index
= meth
- methods
;
1002 return getReflectionSignature (JV_METHOD_ATTR
, meth_index
);
1006 java::lang::Class::getReflectionSignature (::java::lang::reflect::Field
*f
)
1008 _Jv_Field
*fld
= _Jv_FromReflectedField (f
);
1009 unsigned short fld_index
= fld
- fields
;
1010 return getReflectionSignature (JV_FIELD_ATTR
, fld_index
);
1014 java::lang::Class::getClassSignature()
1016 return getReflectionSignature (JV_CLASS_ATTR
, 0);
1020 java::lang::Class::getEnclosingMethodData()
1022 unsigned char *bytes
= reflection_data
;
1027 int kind
= read_u1 (bytes
);
1028 if (kind
== JV_DONE_ATTR
)
1030 int len
= read_4 (bytes
);
1031 unsigned char *next
= bytes
+ len
;
1032 if (kind
!= JV_CLASS_ATTR
)
1037 int type
= read_u1 (bytes
, next
);
1038 if (type
!= JV_ENCLOSING_METHOD_KIND
)
1043 int class_index
= read_u2 (bytes
, next
);
1044 int method_index
= read_u2 (bytes
, next
);
1046 _Jv_storeIndexes (&result
, class_index
, method_index
);
1052 java::lang::Class::getEnclosingClass()
1055 indexes
.i
= getEnclosingMethodData();
1057 // No enclosing method, but perhaps a member or anonymous class
1058 return getDeclaringClass();
1059 _Jv_ushort class_index
, method_index
;
1060 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1061 return _Jv_Linker::resolve_pool_entry (this, class_index
).clazz
;
1064 ::java::lang::reflect::Method
*
1065 java::lang::Class::getEnclosingMethod()
1068 indexes
.i
= getEnclosingMethodData();
1071 _Jv_ushort class_index
, method_index
;
1072 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1074 _Jv_Method
*method
= _Jv_Linker::resolve_method_entry (this, found_class
,
1078 using namespace java::lang::reflect
;
1079 Method
*rmethod
= new Method ();
1080 rmethod
->offset
= (char *) method
- (char *) found_class
->methods
;
1081 rmethod
->declaringClass
= found_class
;
1085 ::java::lang::reflect::Constructor
*
1086 java::lang::Class::getEnclosingConstructor()
1089 indexes
.i
= getEnclosingMethodData();
1092 _Jv_ushort class_index
, method_index
;
1093 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1095 _Jv_Method
*method
= _Jv_Linker::resolve_method_entry (this, found_class
,
1099 using namespace java::lang::reflect
;
1100 Constructor
*cons
= new Constructor ();
1101 cons
->offset
= (char *) method
- (char *) found_class
->methods
;
1102 cons
->declaringClass
= this;
1107 check_constant (_Jv_Constants
*pool
, jint cpool_index
, jint type
)
1109 if (cpool_index
<= 0 || cpool_index
>= pool
->size
)
1110 throw new InternalError(JvNewStringLatin1("invalid constant pool index"));
1111 if ((pool
->tags
[cpool_index
] &
1112 ~(JV_CONSTANT_ResolvedFlag
|JV_CONSTANT_LazyFlag
)) != type
)
1114 ::java::lang::StringBuffer
*sb
= new ::java::lang::StringBuffer();
1115 sb
->append(JvNewStringLatin1("expected pool constant "));
1117 sb
->append(JvNewStringLatin1(" but got "));
1118 sb
->append(jint (pool
->tags
[cpool_index
]));
1119 throw new InternalError(sb
->toString());
1123 // Forward declaration
1124 static ::java::lang::annotation::Annotation
*
1125 parseAnnotation(jclass klass
, _Jv_Constants
*pool
,
1126 unsigned char *&bytes
, unsigned char *last
);
1129 parseAnnotationElement(jclass klass
, _Jv_Constants
*pool
,
1130 unsigned char *&bytes
, unsigned char *last
)
1132 int tag
= read_u1 (bytes
, last
);
1138 int cindex
= read_u2 (bytes
, last
);
1139 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1140 result
= Byte::valueOf (pool
->data
[cindex
].i
);
1145 int cindex
= read_u2 (bytes
, last
);
1146 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1147 result
= Character::valueOf (pool
->data
[cindex
].i
);
1152 int cindex
= read_u2 (bytes
, last
);
1153 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1154 result
= Short::valueOf (pool
->data
[cindex
].i
);
1159 int cindex
= read_u2 (bytes
, last
);
1160 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1161 result
= Boolean::valueOf (jboolean (pool
->data
[cindex
].i
));
1166 int cindex
= read_u2 (bytes
, last
);
1167 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1168 result
= Integer::valueOf (pool
->data
[cindex
].i
);
1173 int cindex
= read_u2 (bytes
, last
);
1174 check_constant (pool
, cindex
, JV_CONSTANT_Double
);
1176 memcpy (&word
, &pool
->data
[cindex
], 2 * sizeof (_Jv_word
));
1177 result
= Double::valueOf (word
.d
);
1182 int cindex
= read_u2 (bytes
, last
);
1183 check_constant (pool
, cindex
, JV_CONSTANT_Float
);
1184 result
= Float::valueOf (pool
->data
[cindex
].f
);
1189 int cindex
= read_u2 (bytes
, last
);
1190 check_constant (pool
, cindex
, JV_CONSTANT_Long
);
1192 memcpy (&word
, &pool
->data
[cindex
], 2 * sizeof (_Jv_word
));
1193 result
= Long::valueOf (word
.l
);
1198 int cindex
= read_u2 (bytes
, last
);
1199 // Despite what the JVM spec says, compilers generate a Utf8
1200 // constant here, not a String.
1201 check_constant (pool
, cindex
, JV_CONSTANT_Utf8
);
1202 result
= pool
->data
[cindex
].utf8
->toString();
1207 int type_name_index
= read_u2 (bytes
, last
);
1208 check_constant (pool
, type_name_index
, JV_CONSTANT_Utf8
);
1209 int const_name_index
= read_u2 (bytes
, last
);
1210 check_constant (pool
, const_name_index
, JV_CONSTANT_Utf8
);
1212 _Jv_Utf8Const
*u_name
= pool
->data
[type_name_index
].utf8
;
1213 _Jv_Utf8Const
*e_name
= pool
->data
[const_name_index
].utf8
;
1215 // FIXME: throw correct exceptions at the correct times.
1216 jclass e_class
= _Jv_FindClassFromSignature(u_name
->chars(),
1217 klass
->getClassLoaderInternal());
1218 result
= ::java::lang::Enum::valueOf(e_class
, e_name
->toString());
1223 int cindex
= read_u2 (bytes
, last
);
1224 check_constant (pool
, cindex
, JV_CONSTANT_Utf8
);
1225 _Jv_Utf8Const
*u_name
= pool
->data
[cindex
].utf8
;
1227 = _Jv_FindClassFromSignatureNoException(u_name
->chars(),
1228 klass
->getClassLoaderInternal());
1229 // FIXME: not correct: we should lazily do this when trying to
1230 // read the element. This means that
1231 // AnnotationInvocationHandler needs to have a special case.
1233 // FIXME: original exception...
1234 throw new TypeNotPresentException(u_name
->toString(), NULL
);
1235 result
= anno_class
;
1239 result
= parseAnnotation (klass
, pool
, bytes
, last
);
1243 int n_array_elts
= read_u2 (bytes
, last
);
1244 jobjectArray aresult
= _Jv_NewObjectArray (n_array_elts
,
1245 &Object::class$
, NULL
);
1246 jobject
*elts
= elements (aresult
);
1247 for (int i
= 0; i
< n_array_elts
; ++i
)
1248 elts
[i
] = parseAnnotationElement(klass
, pool
, bytes
, last
);
1253 throw new java::lang::InternalError();
1258 static ::java::lang::annotation::Annotation
*
1259 parseAnnotation(jclass klass
, _Jv_Constants
*pool
,
1260 unsigned char *&bytes
, unsigned char *last
)
1262 int type_index
= read_u2 (bytes
, last
);
1263 check_constant (pool
, type_index
, JV_CONSTANT_Utf8
);
1265 _Jv_Utf8Const
*u_name
= pool
->data
[type_index
].utf8
;
1266 jclass anno_class
= _Jv_FindClassFromSignatureNoException(u_name
->chars(),
1267 klass
->getClassLoaderInternal());
1268 // FIXME: what to do if anno_class==NULL?
1270 ::java::util::HashMap
*hmap
= new ::java::util::HashMap();
1271 int npairs
= read_u2 (bytes
, last
);
1272 for (int i
= 0; i
< npairs
; ++i
)
1274 int name_index
= read_u2 (bytes
, last
);
1275 check_constant (pool
, name_index
, JV_CONSTANT_Utf8
);
1276 jstring name
= _Jv_NewStringUtf8Const (pool
->data
[name_index
].utf8
);
1277 jobject value
= parseAnnotationElement (klass
, pool
, bytes
, last
);
1278 // FIXME: any checks needed for name?
1279 hmap
->put(name
, value
);
1281 using namespace ::sun::reflect::annotation
;
1282 return AnnotationInvocationHandler::create (anno_class
,
1283 (::java::util::Map
*) hmap
);
1287 parseAnnotations(jclass klass
, _Jv_Constants
*pool
,
1288 unsigned char *&bytes
, unsigned char *last
)
1290 int num
= read_u2 (bytes
, last
);
1291 jobjectArray result
= _Jv_NewObjectArray (num
,
1292 &::java::lang::annotation::Annotation::class$
,
1294 jobject
*elts
= elements (result
);
1295 for (int i
= 0; i
< num
; ++i
)
1296 elts
[i
] = parseAnnotation(klass
, pool
, bytes
, last
);
1301 parseParameterAnnotations(jclass klass
, _Jv_Constants
*pool
,
1302 unsigned char *&bytes
, unsigned char *last
)
1304 jclass anno
= &::java::lang::annotation::Annotation::class$
;
1305 jclass annoary
= _Jv_GetArrayClass (anno
, anno
->getClassLoaderInternal());
1307 // FIXME: something should check the number of params versus the
1309 int n_params
= read_u1 (bytes
, last
);
1310 jobjectArray result
= _Jv_NewObjectArray (n_params
, annoary
, NULL
);
1311 jobject
*elts
= elements (result
);
1312 for (int i
= 0; i
< n_params
; ++i
)
1313 elts
[i
] = parseAnnotations(klass
, pool
, bytes
, last
);
1318 java::lang::Class::getMethodDefaultValue(::java::lang::reflect::Method
*meth
)
1320 // FIXME: could cache the value here...
1322 unsigned char *bytes
= reflection_data
;
1326 unsigned short meth_index
= _Jv_FromReflectedMethod (meth
) - methods
;
1330 int type
= read_u1 (bytes
);
1331 if (type
== JV_DONE_ATTR
)
1333 int len
= read_4 (bytes
);
1334 unsigned char *next
= bytes
+ len
;
1335 if (type
!= JV_METHOD_ATTR
)
1340 int kind
= read_u1 (bytes
, next
);
1341 if (kind
!= JV_ANNOTATION_DEFAULT_KIND
)
1346 int index
= read_u2 (bytes
, next
);
1347 if (meth_index
!= index
)
1353 // FIXME: could cache here. If we do then we have to clone any
1355 return parseAnnotationElement(this, &this->constants
, bytes
, next
);
1360 java::lang::Class::getDeclaredAnnotations(jint
/* jv_attr_type */ member_type
,
1362 jint
/* jv_attr_kind */ kind_req
)
1364 using namespace java::lang::annotation
;
1365 jobjectArray result
;
1367 unsigned char *bytes
= reflection_data
;
1372 loader
= (ClassLoader
*)VMClassLoader::bootLoader
;
1374 result
= (loader
->getDeclaredAnnotations
1375 (this, member_type
, member_index
, kind_req
));
1381 int type
= read_u1 (bytes
);
1382 if (type
== JV_DONE_ATTR
)
1384 int len
= read_4 (bytes
);
1385 unsigned char *next
= bytes
+ len
;
1386 if (type
!= member_type
)
1391 int kind
= read_u1 (bytes
, next
);
1392 if (kind
!= kind_req
)
1397 if (member_type
!= JV_CLASS_ATTR
)
1399 int index
= read_u2 (bytes
, next
);
1400 if (member_index
!= index
)
1407 if (kind_req
== JV_PARAMETER_ANNOTATIONS_KIND
)
1408 result
= ((parseParameterAnnotations
1409 (this, &this->constants
, bytes
, next
)));
1411 result
= ((parseAnnotations (this, &this->constants
, bytes
, next
)));
1415 return (loader
->putDeclaredAnnotations
1416 (this, member_type
, member_index
, kind_req
, result
));
1420 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Method
*meth
,
1423 unsigned short meth_index
= _Jv_FromReflectedMethod (meth
) - methods
;
1424 return getDeclaredAnnotations(JV_METHOD_ATTR
, meth_index
,
1426 ? JV_PARAMETER_ANNOTATIONS_KIND
1427 : JV_ANNOTATIONS_KIND
));
1431 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Constructor
*cons
,
1434 unsigned short meth_index
= _Jv_FromReflectedConstructor (cons
) - methods
;
1435 return getDeclaredAnnotations(JV_METHOD_ATTR
, meth_index
,
1437 ? JV_PARAMETER_ANNOTATIONS_KIND
1438 : JV_ANNOTATIONS_KIND
));
1442 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Field
*fld
)
1444 unsigned short field_index
= _Jv_FromReflectedField (fld
) - fields
;
1445 return getDeclaredAnnotations(JV_FIELD_ATTR
, field_index
,
1446 JV_ANNOTATIONS_KIND
);
1449 JArray
< ::java::lang::annotation::Annotation
*> *
1450 java::lang::Class::getDeclaredAnnotationsInternal()
1452 return (JArray
< ::java::lang::annotation::Annotation
*> *) getDeclaredAnnotations(JV_CLASS_ATTR
, 0, JV_ANNOTATIONS_KIND
);
1456 resolve_class_constant (jclass klass
, _Jv_Constants
*pool
, int cpool_index
)
1458 check_constant (pool
, cpool_index
, JV_CONSTANT_Class
);
1459 // FIXME: what is the correct thing to do with an exception here?
1460 return _Jv_Linker::resolve_pool_entry (klass
, cpool_index
, false).clazz
;
1464 java::lang::Class::findInnerClassAttribute()
1466 unsigned char *bytes
= reflection_data
;
1471 int type
= read_u1 (bytes
);
1472 if (type
== JV_DONE_ATTR
)
1474 // After the type but before the length.
1475 unsigned char *save
= bytes
;
1476 int len
= read_4 (bytes
);
1477 unsigned char *next
= bytes
+ len
;
1478 if (type
!= JV_CLASS_ATTR
)
1483 int kind
= read_u1 (bytes
, next
);
1484 if (kind
!= JV_INNER_CLASSES_KIND
)
1489 return save
- reflection_data
;
1495 java::lang::Class::findDeclaredClasses(JArray
<jclass
> *result
,
1496 jboolean publicOnly
,
1499 unsigned char *bytes
= reflection_data
+ offset
;
1500 int len
= read_4 (bytes
);
1501 unsigned char *next
= bytes
+ len
;
1503 read_u1 (bytes
, next
);
1504 int n_classes
= read_u2 (bytes
, next
);
1506 for (int i
= 0; i
< n_classes
; ++i
)
1508 int inner_class_index
= read_u2 (bytes
, next
);
1509 int outer_class_index
= read_u2 (bytes
, next
);
1510 /*int inner_name_index = */ read_u2 (bytes
, next
);
1511 int inner_flags
= read_u2 (bytes
, next
);
1513 if (inner_class_index
== 0 || outer_class_index
== 0)
1515 if (resolve_class_constant (this, &constants
, outer_class_index
) == this)
1517 jclass inner
= resolve_class_constant (this, &constants
,
1521 & java::lang::reflect::Modifier::PUBLIC
) != 0))
1525 jclass
*elts
= elements (result
);
1526 elts
[count
] = inner
;
1537 java::lang::Class::getDeclaredClasses (jboolean publicOnly
)
1539 int offset
= findInnerClassAttribute();
1543 // No InnerClasses attribute, so no declared classes.
1547 count
= findDeclaredClasses(NULL
, publicOnly
, offset
);
1548 JArray
<jclass
> *result
1549 = (JArray
<jclass
> *) JvNewObjectArray (count
, &java::lang::Class::class$
,
1552 findDeclaredClasses(result
, publicOnly
, offset
);
1557 java::lang::Class::getDeclaringClass (void)
1559 int offset
= findInnerClassAttribute();
1563 unsigned char *bytes
= reflection_data
+ offset
;
1564 int len
= read_4 (bytes
);
1565 unsigned char *next
= bytes
+ len
;
1567 read_u1 (bytes
, next
);
1568 int n_classes
= read_u2 (bytes
, next
);
1569 for (int i
= 0; i
< n_classes
; ++i
)
1571 int inner_class_index
= read_u2 (bytes
, next
);
1572 int outer_class_index
= read_u2 (bytes
, next
);
1573 /*int inner_name_index = */read_u2 (bytes
, next
);
1574 /*int inner_flags = */read_u2 (bytes
, next
);
1576 if (inner_class_index
== 0 || outer_class_index
== 0)
1578 if (resolve_class_constant (this, &constants
, inner_class_index
) == this)
1579 return resolve_class_constant (this, &constants
, outer_class_index
);
1586 java::lang::Class::isAnonymousClass()
1588 int offset
= findInnerClassAttribute();
1592 unsigned char *bytes
= reflection_data
+ offset
;
1593 int len
= read_4 (bytes
);
1594 unsigned char *next
= bytes
+ len
;
1596 read_u1 (bytes
, next
);
1597 int n_classes
= read_u2 (bytes
, next
);
1598 for (int i
= 0; i
< n_classes
; ++i
)
1600 int inner_class_index
= read_u2 (bytes
, next
);
1601 /*int outer_class_index = */read_u2 (bytes
, next
);
1602 int inner_name_index
= read_u2 (bytes
, next
);
1603 /*int inner_flags = */read_u2 (bytes
, next
);
1605 if (inner_class_index
== 0)
1607 if (resolve_class_constant (this, &constants
, inner_class_index
) == this)
1608 return inner_name_index
== 0;
1615 java::lang::Class::isLocalClass()
1618 indexes
.i
= getEnclosingMethodData();
1619 return indexes
.i
!= 0;
1623 java::lang::Class::isMemberClass()
1625 // FIXME: is this correct?
1626 return !isLocalClass() && getDeclaringClass() != NULL
;
1632 // Some class-related convenience functions.
1635 // Find a method declared in the class. If it is not declared locally
1636 // (or if it is inherited), return NULL.
1638 _Jv_GetMethodLocal (jclass klass
, _Jv_Utf8Const
*name
,
1639 _Jv_Utf8Const
*signature
)
1641 for (int i
= 0; i
< klass
->method_count
; ++i
)
1643 if (_Jv_equalUtf8Consts (name
, klass
->methods
[i
].name
)
1644 && _Jv_equalUtf8Consts (signature
, klass
->methods
[i
].signature
))
1645 return &klass
->methods
[i
];
1651 _Jv_LookupDeclaredMethod (jclass klass
, _Jv_Utf8Const
*name
,
1652 _Jv_Utf8Const
*signature
,
1653 jclass
*declarer_result
)
1655 for (; klass
; klass
= klass
->getSuperclass())
1657 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
1661 if (declarer_result
)
1662 *declarer_result
= klass
;
1670 java::lang::reflect::Method
*
1671 _Jv_GetReflectedMethod (jclass klass
, _Jv_Utf8Const
*name
,
1672 _Jv_Utf8Const
*signature
)
1674 for (; klass
; klass
= klass
->getSuperclass())
1676 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
1679 using namespace java::lang::reflect
;
1680 Method
*rmethod
= new Method ();
1681 rmethod
->offset
= (char*) meth
- (char*) klass
->methods
;
1682 rmethod
->declaringClass
= klass
;
1692 // NOTE: MCACHE_SIZE should be a power of 2 minus one.
1693 #define MCACHE_SIZE 31
1701 static __thread _Jv_mcache
*method_cache
;
1705 _Jv_FindMethodInCache (jclass klass MAYBE_UNUSED
,
1706 _Jv_Utf8Const
*name MAYBE_UNUSED
,
1707 _Jv_Utf8Const
*signature MAYBE_UNUSED
)
1710 _Jv_mcache
*cache
= method_cache
;
1713 int index
= name
->hash16 () & MCACHE_SIZE
;
1714 _Jv_mcache
*mc
= &cache
[index
];
1715 _Jv_Method
*m
= mc
->method
;
1717 if (mc
->klass
== klass
1718 && _Jv_equalUtf8Consts (m
->name
, name
)
1719 && _Jv_equalUtf8Consts (m
->signature
, signature
))
1720 return mc
->method
->ncode
;
1727 _Jv_AddMethodToCache (jclass klass MAYBE_UNUSED
,
1728 _Jv_Method
*method MAYBE_UNUSED
)
1731 if (method_cache
== NULL
)
1732 method_cache
= (_Jv_mcache
*) _Jv_MallocUnchecked((MCACHE_SIZE
+ 1)
1733 * sizeof (_Jv_mcache
));
1734 // If the allocation failed, just keep going.
1735 if (method_cache
!= NULL
)
1737 int index
= method
->name
->hash16 () & MCACHE_SIZE
;
1738 method_cache
[index
].method
= method
;
1739 method_cache
[index
].klass
= klass
;
1744 // Free this thread's method cache. We explicitly manage this memory
1745 // as the GC does not yet know how to scan TLS on all platforms.
1747 _Jv_FreeMethodCache ()
1750 if (method_cache
!= NULL
)
1752 _Jv_Free(method_cache
);
1753 method_cache
= NULL
;
1759 _Jv_LookupInterfaceMethod (jclass klass
, _Jv_Utf8Const
*name
,
1760 _Jv_Utf8Const
*signature
)
1762 using namespace java::lang::reflect
;
1764 void *ncode
= _Jv_FindMethodInCache (klass
, name
, signature
);
1768 for (; klass
; klass
= klass
->getSuperclass())
1770 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
1774 if (Modifier::isStatic(meth
->accflags
))
1775 throw new java::lang::IncompatibleClassChangeError
1776 (_Jv_GetMethodString (klass
, meth
));
1777 if (Modifier::isAbstract(meth
->accflags
))
1778 throw new java::lang::AbstractMethodError
1779 (_Jv_GetMethodString (klass
, meth
));
1780 if (! Modifier::isPublic(meth
->accflags
))
1781 throw new java::lang::IllegalAccessError
1782 (_Jv_GetMethodString (klass
, meth
));
1784 _Jv_AddMethodToCache (klass
, meth
);
1788 throw new java::lang::IncompatibleClassChangeError
;
1791 // Fast interface method lookup by index.
1793 _Jv_LookupInterfaceMethodIdx (jclass klass
, jclass iface
, int method_idx
)
1795 _Jv_IDispatchTable
*cldt
= klass
->idt
;
1796 int idx
= iface
->ioffsets
[cldt
->iindex
] + method_idx
;
1797 return cldt
->itable
[idx
];
1801 _Jv_IsAssignableFrom (jclass source
, jclass target
)
1803 if (source
== target
)
1806 // If target is array, so must source be.
1807 while (target
->isArray ())
1809 if (! source
->isArray())
1811 target
= target
->getComponentType();
1812 source
= source
->getComponentType();
1815 if (target
->isInterface())
1817 // Abstract classes have no IDT, and IDTs provide no way to check
1818 // two interfaces for assignability.
1819 if (__builtin_expect
1820 (source
->idt
== NULL
|| source
->isInterface(), false))
1821 return _Jv_InterfaceAssignableFrom (source
, target
);
1823 _Jv_IDispatchTable
*cl_idt
= source
->idt
;
1825 if (__builtin_expect ((target
->ioffsets
== NULL
), false))
1826 return false; // No class implementing TARGET has been loaded.
1827 jshort cl_iindex
= cl_idt
->iindex
;
1828 if (cl_iindex
< target
->ioffsets
[0])
1830 jshort offset
= target
->ioffsets
[cl_iindex
];
1831 if (offset
!= -1 && offset
< cl_idt
->itable_length
1832 && cl_idt
->itable
[offset
] == target
)
1838 // Primitive TYPE classes are only assignable to themselves.
1839 if (__builtin_expect (target
->isPrimitive() || source
->isPrimitive(), false))
1842 if (target
== &java::lang::Object::class$
)
1844 else if (source
->ancestors
== NULL
|| target
->ancestors
== NULL
)
1846 // We need this case when either SOURCE or TARGET has not has
1847 // its constant-time tables prepared.
1849 // At this point we know that TARGET can't be Object, so it is
1850 // safe to use that as the termination point.
1851 while (source
&& source
!= &java::lang::Object::class$
)
1853 if (source
== target
)
1855 source
= source
->getSuperclass();
1858 else if (source
->depth
>= target
->depth
1859 && source
->ancestors
[source
->depth
- target
->depth
] == target
)
1865 // Interface type checking, the slow way. Returns TRUE if IFACE is a
1866 // superinterface of SOURCE. This is used when SOURCE is also an interface,
1867 // or a class with no interface dispatch table.
1869 _Jv_InterfaceAssignableFrom (jclass source
, jclass iface
)
1871 for (int i
= 0; i
< source
->interface_count
; i
++)
1873 jclass source_interface
= source
->interfaces
[i
];
1874 if (iface
== source_interface
1875 || _Jv_InterfaceAssignableFrom (source_interface
, iface
))
1879 if (!source
->isInterface()
1880 && source
->superclass
1881 && _Jv_InterfaceAssignableFrom (source
->superclass
, iface
))
1888 _Jv_IsInstanceOf(jobject obj
, jclass cl
)
1890 if (__builtin_expect (!obj
, false))
1892 return _Jv_IsAssignableFrom (JV_CLASS (obj
), cl
);
1896 _Jv_CheckCast (jclass c
, jobject obj
)
1898 if (__builtin_expect
1899 (obj
!= NULL
&& ! _Jv_IsAssignableFrom(JV_CLASS (obj
), c
), false))
1900 throw new java::lang::ClassCastException
1901 ((new java::lang::StringBuffer
1902 (obj
->getClass()->getName()))->append
1903 (JvNewStringUTF(" cannot be cast to "))->append
1904 (c
->getName())->toString());
1910 _Jv_CheckArrayStore (jobject arr
, jobject obj
)
1914 JvAssert (arr
!= NULL
);
1915 jclass elt_class
= (JV_CLASS (arr
))->getComponentType();
1916 if (elt_class
== &java::lang::Object::class$
)
1918 jclass obj_class
= JV_CLASS (obj
);
1919 if (__builtin_expect
1920 (! _Jv_IsAssignableFrom (obj_class
, elt_class
), false))
1921 throw new java::lang::ArrayStoreException
1922 ((new java::lang::StringBuffer
1923 (JvNewStringUTF("Cannot store ")))->append
1924 (obj_class
->getName())->append
1925 (JvNewStringUTF(" in array of type "))->append
1926 (elt_class
->getName())->toString());
1931 _Jv_IsAssignableFromSlow (jclass source
, jclass target
)
1933 // First, strip arrays.
1934 while (target
->isArray ())
1936 // If target is array, source must be as well.
1937 if (! source
->isArray ())
1939 target
= target
->getComponentType ();
1940 source
= source
->getComponentType ();
1944 if (target
== &java::lang::Object::class$
)
1947 // Ensure that the classes have their supers installed.
1948 _Jv_Linker::wait_for_state (source
, JV_STATE_LOADING
);
1949 _Jv_Linker::wait_for_state (target
, JV_STATE_LOADING
);
1953 if (source
== target
)
1956 if (target
->isPrimitive () || source
->isPrimitive ())
1959 if (target
->isInterface ())
1961 for (int i
= 0; i
< source
->interface_count
; ++i
)
1963 // We use a recursive call because we also need to
1964 // check superinterfaces.
1965 if (_Jv_IsAssignableFromSlow (source
->getInterface (i
), target
))
1969 source
= source
->getSuperclass ();
1971 while (source
!= NULL
);
1976 // Lookup an interface method by name. This is very similar to
1977 // purpose to _getMethod, but the interfaces are quite different. It
1978 // might be a good idea for _getMethod to call this function.
1980 // Return true of the method is found, with the class in FOUND_CLASS
1981 // and the index in INDEX.
1983 _Jv_getInterfaceMethod (jclass search_class
, jclass
&found_class
, int &index
,
1984 const _Jv_Utf8Const
*utf_name
,
1985 const _Jv_Utf8Const
*utf_sig
)
1987 for (jclass klass
= search_class
; klass
; klass
= klass
->getSuperclass())
1989 // FIXME: Throw an exception?
1990 if (!klass
->isInterface ())
1993 int max
= klass
->method_count
;
1995 for (int i
= 0; i
< max
; ++i
)
1997 // Skip <clinit> here, as it will not be in the IDT.
1998 if (klass
->methods
[i
].name
->first() == '<')
2001 if (_Jv_equalUtf8Consts (klass
->methods
[i
].name
, utf_name
)
2002 && _Jv_equalUtf8Consts (klass
->methods
[i
].signature
, utf_sig
))
2005 using namespace java::lang::reflect
;
2007 // FIXME: Method must be public. Throw an exception?
2008 if (! Modifier::isPublic (klass
->methods
[i
].accflags
))
2011 found_class
= klass
;
2012 // Interface method indexes count from 1.
2021 // If we haven't found a match, and this class is an interface, then
2022 // check all the superinterfaces.
2023 if (search_class
->isInterface())
2025 for (int i
= 0; i
< search_class
->interface_count
; ++i
)
2027 using namespace java::lang::reflect
;
2028 bool found
= _Jv_getInterfaceMethod (search_class
->interfaces
[i
],
2041 _Jv_FindInterpreterMethod (jclass klass
, jmethodID desired_method
)
2043 using namespace java::lang::reflect
;
2045 _Jv_InterpClass
*iclass
2046 = reinterpret_cast<_Jv_InterpClass
*> (klass
->aux_info
);
2047 _Jv_MethodBase
**imethods
= _Jv_GetFirstMethod (iclass
);
2049 for (int i
= 0; i
< JvNumMethods (klass
); ++i
)
2051 _Jv_MethodBase
*imeth
= imethods
[i
];
2052 if (imeth
->get_method () == desired_method
)
2060 // Return Utf8 name of a class. This function is here for code that
2061 // can't access klass->name directly.
2063 _Jv_GetClassNameUtf8 (jclass klass
)
2069 _Jv_GetMethodDeclaringClass (jmethodID method
)
2071 _Jv_StackTrace::UpdateNCodeMap ();
2072 jobject obj
= reinterpret_cast<jobject
> (method
->ncode
);
2073 return reinterpret_cast<jclass
> (_Jv_StackTrace::ncodeMap
->get (obj
));
2077 _Jv_GetClassState (jclass klass
)
2079 return klass
->state
;
2084 _Jv_GetInterpClassSourceFile (jclass klass
)
2086 if (_Jv_IsInterpretedClass (klass
))
2088 _Jv_InterpClass
*iclass
=
2089 reinterpret_cast<_Jv_InterpClass
*> (klass
->aux_info
);
2090 return iclass
->source_file_name
;