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
);
693 this->next
= *closures
;
698 // This implements the initialization process for a class. From Spec
701 java::lang::Class::initializeClass (void)
703 // Short-circuit to avoid needless locking (expression includes
704 // JV_STATE_PHANTOM and JV_STATE_DONE).
705 if (state
>= JV_STATE_PHANTOM
)
708 // Step 1. We introduce a new scope so we can synchronize more
711 JvSynchronize
sync (this);
713 if (state
< JV_STATE_LINKED
)
717 _Jv_Linker::wait_for_state(this, JV_STATE_LINKED
);
719 catch (java::lang::SecurityException
*x
)
723 catch (java::lang::Throwable
*x
)
725 // Turn into a NoClassDefFoundError.
726 java::lang::NoClassDefFoundError
*result
727 = new java::lang::NoClassDefFoundError(getName());
728 result
->initCause(x
);
734 java::lang::Thread
*self
= java::lang::Thread::currentThread();
735 self
= (java::lang::Thread
*) ((long) self
| 1);
736 while (state
== JV_STATE_IN_PROGRESS
&& thread
&& thread
!= self
)
740 if (state
== JV_STATE_DONE
|| state
== JV_STATE_IN_PROGRESS
)
744 if (state
== JV_STATE_ERROR
)
745 throw new java::lang::NoClassDefFoundError (getName());
749 _Jv_Linker::wait_for_state (this, JV_STATE_LINKED
);
750 state
= JV_STATE_IN_PROGRESS
;
754 if (! isInterface () && superclass
)
758 _Jv_InitClass (superclass
);
760 catch (java::lang::SecurityException
*x
)
764 catch (java::lang::Throwable
*except
)
766 // Caught an exception.
767 JvSynchronize
sync (this);
768 state
= JV_STATE_ERROR
;
774 // Steps 8, 9, 10, 11.
777 _Jv_Method
*meth
= _Jv_GetMethodLocal (this, clinit_name
,
780 ((void (*) (void)) meth
->ncode
) ();
782 catch (java::lang::SecurityException
*x
)
786 catch (java::lang::Throwable
*except
)
788 if (! java::lang::Error::class$
.isInstance(except
))
792 except
= new ExceptionInInitializerError (except
);
794 catch (java::lang::Throwable
*t
)
800 JvSynchronize
sync (this);
801 state
= JV_STATE_ERROR
;
806 JvSynchronize
sync (this);
807 state
= JV_STATE_DONE
;
811 // Only used by serialization
812 java::lang::reflect::Field
*
813 java::lang::Class::getPrivateField (jstring name
)
815 int hash
= name
->hashCode ();
817 java::lang::reflect::Field
* rfield
;
818 for (int i
= 0; i
< field_count
; i
++)
820 _Jv_Field
*field
= &fields
[i
];
821 if (! _Jv_equal (field
->name
, name
, hash
))
823 rfield
= new java::lang::reflect::Field ();
824 rfield
->offset
= (char*) field
- (char*) fields
;
825 rfield
->declaringClass
= this;
829 jclass superclass
= getSuperclass();
830 if (superclass
== NULL
)
832 rfield
= superclass
->getPrivateField(name
);
833 for (int i
= 0; i
< interface_count
&& rfield
== NULL
; ++i
)
834 rfield
= interfaces
[i
]->getPrivateField (name
);
838 // Only used by serialization
839 java::lang::reflect::Method
*
840 java::lang::Class::getPrivateMethod (jstring name
, JArray
<jclass
> *param_types
)
842 jstring partial_sig
= getSignature (param_types
, false);
843 jint p_len
= partial_sig
->length();
844 _Jv_Utf8Const
*utf_name
= _Jv_makeUtf8Const (name
);
845 for (Class
*klass
= this; klass
; klass
= klass
->getSuperclass())
847 int i
= klass
->isPrimitive () ? 0 : klass
->method_count
;
850 if (_Jv_equalUtf8Consts (klass
->methods
[i
].name
, utf_name
)
851 && _Jv_equaln (klass
->methods
[i
].signature
, partial_sig
, p_len
))
854 using namespace java::lang::reflect
;
856 Method
*rmethod
= new Method ();
857 rmethod
->offset
= ((char *) (&klass
->methods
[i
])
858 - (char *) klass
->methods
);
859 rmethod
->declaringClass
= klass
;
864 throw new java::lang::NoSuchMethodException (name
);
867 // Private accessor method for Java code to retrieve the protection domain.
868 java::security::ProtectionDomain
*
869 java::lang::Class::getProtectionDomain0 ()
871 return protectionDomain
;
875 java::lang::Class::getSigners()
881 java::lang::Class::setSigners(JArray
<jobject
> *s
)
889 read_u1 (unsigned char *&p
)
895 read_u1 (unsigned char *&p
, unsigned char *next
)
898 throw new java::lang::InternalError();
903 read_u2 (unsigned char *&p
)
905 unsigned int b1
= *p
++;
906 unsigned int b2
= *p
++;
907 return (b1
<< 8) | b2
;
911 read_u2 (unsigned char *&p
, unsigned char *next
)
914 throw new java::lang::InternalError();
919 read_4 (unsigned char *&p
)
925 return (b1
<< 24) | (b2
<< 16) | (b3
<< 8) | b4
;
929 java::lang::Class::getReflectionSignature (jint
/*jv_attr_type*/ type
,
932 // We just re-parse the bytecode for this data each time. If
933 // necessary we can cache results, but I suspect this is not
934 // performance sensitive.
935 unsigned char *bytes
= reflection_data
;
940 int kind
= read_u1 (bytes
);
941 if (kind
== JV_DONE_ATTR
)
943 int len
= read_4 (bytes
);
944 unsigned char *next
= bytes
+ len
;
950 if (type
!= JV_CLASS_ATTR
)
952 unsigned short index
= read_u2 (bytes
, next
);
953 if (index
!= obj_index
)
959 int nt
= read_u1 (bytes
, next
);
960 if (nt
!= JV_SIGNATURE_KIND
)
965 unsigned int cpool_idx
= read_u2 (bytes
, next
);
966 if (cpool_idx
>= (unsigned int) constants
.size
967 || constants
.tags
[cpool_idx
] != JV_CONSTANT_Utf8
)
969 // We just ignore errors for now. It isn't clear what is
970 // best to do here, as an encoding error here means a bug
971 // either in the compiler or in defineclass.cc.
974 return _Jv_NewStringUtf8Const (constants
.data
[cpool_idx
].utf8
);
979 java::lang::Class::getReflectionSignature (::java::lang::reflect::Constructor
*c
)
981 _Jv_Method
*meth
= _Jv_FromReflectedConstructor (c
);
982 unsigned short meth_index
= meth
- methods
;
983 return getReflectionSignature (JV_METHOD_ATTR
, meth_index
);
987 java::lang::Class::getReflectionSignature (::java::lang::reflect::Method
*m
)
989 _Jv_Method
*meth
= _Jv_FromReflectedMethod (m
);
990 unsigned short meth_index
= meth
- methods
;
991 return getReflectionSignature (JV_METHOD_ATTR
, meth_index
);
995 java::lang::Class::getReflectionSignature (::java::lang::reflect::Field
*f
)
997 _Jv_Field
*fld
= _Jv_FromReflectedField (f
);
998 unsigned short fld_index
= fld
- fields
;
999 return getReflectionSignature (JV_FIELD_ATTR
, fld_index
);
1003 java::lang::Class::getClassSignature()
1005 return getReflectionSignature (JV_CLASS_ATTR
, 0);
1009 java::lang::Class::getEnclosingMethodData()
1011 unsigned char *bytes
= reflection_data
;
1016 int kind
= read_u1 (bytes
);
1017 if (kind
== JV_DONE_ATTR
)
1019 int len
= read_4 (bytes
);
1020 unsigned char *next
= bytes
+ len
;
1021 if (kind
!= JV_CLASS_ATTR
)
1026 int type
= read_u1 (bytes
, next
);
1027 if (type
!= JV_ENCLOSING_METHOD_KIND
)
1032 int class_index
= read_u2 (bytes
, next
);
1033 int method_index
= read_u2 (bytes
, next
);
1035 _Jv_storeIndexes (&result
, class_index
, method_index
);
1041 java::lang::Class::getEnclosingClass()
1044 indexes
.i
= getEnclosingMethodData();
1046 // No enclosing method, but perhaps a member or anonymous class
1047 return getDeclaringClass();
1048 _Jv_ushort class_index
, method_index
;
1049 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1050 return _Jv_Linker::resolve_pool_entry (this, class_index
).clazz
;
1053 ::java::lang::reflect::Method
*
1054 java::lang::Class::getEnclosingMethod()
1057 indexes
.i
= getEnclosingMethodData();
1060 _Jv_ushort class_index
, method_index
;
1061 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1063 _Jv_Method
*method
= _Jv_Linker::resolve_method_entry (this, found_class
,
1067 using namespace java::lang::reflect
;
1068 Method
*rmethod
= new Method ();
1069 rmethod
->offset
= (char *) method
- (char *) found_class
->methods
;
1070 rmethod
->declaringClass
= found_class
;
1074 ::java::lang::reflect::Constructor
*
1075 java::lang::Class::getEnclosingConstructor()
1078 indexes
.i
= getEnclosingMethodData();
1081 _Jv_ushort class_index
, method_index
;
1082 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1084 _Jv_Method
*method
= _Jv_Linker::resolve_method_entry (this, found_class
,
1088 using namespace java::lang::reflect
;
1089 Constructor
*cons
= new Constructor ();
1090 cons
->offset
= (char *) method
- (char *) found_class
->methods
;
1091 cons
->declaringClass
= this;
1096 check_constant (_Jv_Constants
*pool
, jint cpool_index
, jint type
)
1098 if (cpool_index
<= 0 || cpool_index
>= pool
->size
)
1099 throw new InternalError(JvNewStringLatin1("invalid constant pool index"));
1100 if ((pool
->tags
[cpool_index
] &
1101 ~(JV_CONSTANT_ResolvedFlag
|JV_CONSTANT_LazyFlag
)) != type
)
1103 ::java::lang::StringBuffer
*sb
= new ::java::lang::StringBuffer();
1104 sb
->append(JvNewStringLatin1("expected pool constant "));
1106 sb
->append(JvNewStringLatin1(" but got "));
1107 sb
->append(jint (pool
->tags
[cpool_index
]));
1108 throw new InternalError(sb
->toString());
1112 // Forward declaration
1113 static ::java::lang::annotation::Annotation
*
1114 parseAnnotation(jclass klass
, _Jv_Constants
*pool
,
1115 unsigned char *&bytes
, unsigned char *last
);
1118 parseAnnotationElement(jclass klass
, _Jv_Constants
*pool
,
1119 unsigned char *&bytes
, unsigned char *last
)
1121 int tag
= read_u1 (bytes
, last
);
1127 int cindex
= read_u2 (bytes
, last
);
1128 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1129 result
= Byte::valueOf (pool
->data
[cindex
].i
);
1134 int cindex
= read_u2 (bytes
, last
);
1135 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1136 result
= Character::valueOf (pool
->data
[cindex
].i
);
1141 int cindex
= read_u2 (bytes
, last
);
1142 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1143 result
= Short::valueOf (pool
->data
[cindex
].i
);
1148 int cindex
= read_u2 (bytes
, last
);
1149 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1150 result
= Boolean::valueOf (jboolean (pool
->data
[cindex
].i
));
1155 int cindex
= read_u2 (bytes
, last
);
1156 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1157 result
= Integer::valueOf (pool
->data
[cindex
].i
);
1162 int cindex
= read_u2 (bytes
, last
);
1163 check_constant (pool
, cindex
, JV_CONSTANT_Double
);
1165 memcpy (&word
, &pool
->data
[cindex
], 2 * sizeof (_Jv_word
));
1166 result
= Double::valueOf (word
.d
);
1171 int cindex
= read_u2 (bytes
, last
);
1172 check_constant (pool
, cindex
, JV_CONSTANT_Float
);
1173 result
= Float::valueOf (pool
->data
[cindex
].f
);
1178 int cindex
= read_u2 (bytes
, last
);
1179 check_constant (pool
, cindex
, JV_CONSTANT_Long
);
1181 memcpy (&word
, &pool
->data
[cindex
], 2 * sizeof (_Jv_word
));
1182 result
= Long::valueOf (word
.l
);
1187 int cindex
= read_u2 (bytes
, last
);
1188 // Despite what the JVM spec says, compilers generate a Utf8
1189 // constant here, not a String.
1190 check_constant (pool
, cindex
, JV_CONSTANT_Utf8
);
1191 result
= pool
->data
[cindex
].utf8
->toString();
1196 int type_name_index
= read_u2 (bytes
, last
);
1197 check_constant (pool
, type_name_index
, JV_CONSTANT_Utf8
);
1198 int const_name_index
= read_u2 (bytes
, last
);
1199 check_constant (pool
, const_name_index
, JV_CONSTANT_Utf8
);
1201 _Jv_Utf8Const
*u_name
= pool
->data
[type_name_index
].utf8
;
1202 _Jv_Utf8Const
*e_name
= pool
->data
[const_name_index
].utf8
;
1204 // FIXME: throw correct exceptions at the correct times.
1205 jclass e_class
= _Jv_FindClassFromSignature(u_name
->chars(),
1206 klass
->getClassLoaderInternal());
1207 result
= ::java::lang::Enum::valueOf(e_class
, e_name
->toString());
1212 int cindex
= read_u2 (bytes
, last
);
1213 check_constant (pool
, cindex
, JV_CONSTANT_Utf8
);
1214 _Jv_Utf8Const
*u_name
= pool
->data
[cindex
].utf8
;
1216 = _Jv_FindClassFromSignatureNoException(u_name
->chars(),
1217 klass
->getClassLoaderInternal());
1218 // FIXME: not correct: we should lazily do this when trying to
1219 // read the element. This means that
1220 // AnnotationInvocationHandler needs to have a special case.
1222 // FIXME: original exception...
1223 throw new TypeNotPresentException(u_name
->toString(), NULL
);
1224 result
= anno_class
;
1228 result
= parseAnnotation (klass
, pool
, bytes
, last
);
1232 int n_array_elts
= read_u2 (bytes
, last
);
1233 jobjectArray aresult
= _Jv_NewObjectArray (n_array_elts
,
1234 &Object::class$
, NULL
);
1235 jobject
*elts
= elements (aresult
);
1236 for (int i
= 0; i
< n_array_elts
; ++i
)
1237 elts
[i
] = parseAnnotationElement(klass
, pool
, bytes
, last
);
1242 throw new java::lang::InternalError();
1247 static ::java::lang::annotation::Annotation
*
1248 parseAnnotation(jclass klass
, _Jv_Constants
*pool
,
1249 unsigned char *&bytes
, unsigned char *last
)
1251 int type_index
= read_u2 (bytes
, last
);
1252 check_constant (pool
, type_index
, JV_CONSTANT_Utf8
);
1254 _Jv_Utf8Const
*u_name
= pool
->data
[type_index
].utf8
;
1255 jclass anno_class
= _Jv_FindClassFromSignatureNoException(u_name
->chars(),
1256 klass
->getClassLoaderInternal());
1257 // FIXME: what to do if anno_class==NULL?
1259 ::java::util::HashMap
*hmap
= new ::java::util::HashMap();
1260 int npairs
= read_u2 (bytes
, last
);
1261 for (int i
= 0; i
< npairs
; ++i
)
1263 int name_index
= read_u2 (bytes
, last
);
1264 check_constant (pool
, name_index
, JV_CONSTANT_Utf8
);
1265 jstring name
= _Jv_NewStringUtf8Const (pool
->data
[name_index
].utf8
);
1266 jobject value
= parseAnnotationElement (klass
, pool
, bytes
, last
);
1267 // FIXME: any checks needed for name?
1268 hmap
->put(name
, value
);
1270 using namespace ::sun::reflect::annotation
;
1271 return AnnotationInvocationHandler::create (anno_class
,
1272 (::java::util::Map
*) hmap
);
1276 parseAnnotations(jclass klass
, _Jv_Constants
*pool
,
1277 unsigned char *&bytes
, unsigned char *last
)
1279 int num
= read_u2 (bytes
, last
);
1280 jobjectArray result
= _Jv_NewObjectArray (num
,
1281 &::java::lang::annotation::Annotation::class$
,
1283 jobject
*elts
= elements (result
);
1284 for (int i
= 0; i
< num
; ++i
)
1285 elts
[i
] = parseAnnotation(klass
, pool
, bytes
, last
);
1290 parseParameterAnnotations(jclass klass
, _Jv_Constants
*pool
,
1291 unsigned char *&bytes
, unsigned char *last
)
1293 jclass anno
= &::java::lang::annotation::Annotation::class$
;
1294 jclass annoary
= _Jv_GetArrayClass (anno
, anno
->getClassLoaderInternal());
1296 // FIXME: something should check the number of params versus the
1298 int n_params
= read_u1 (bytes
, last
);
1299 jobjectArray result
= _Jv_NewObjectArray (n_params
, annoary
, NULL
);
1300 jobject
*elts
= elements (result
);
1301 for (int i
= 0; i
< n_params
; ++i
)
1302 elts
[i
] = parseAnnotations(klass
, pool
, bytes
, last
);
1307 java::lang::Class::getMethodDefaultValue(::java::lang::reflect::Method
*meth
)
1309 // FIXME: could cache the value here...
1311 unsigned char *bytes
= reflection_data
;
1315 unsigned short meth_index
= _Jv_FromReflectedMethod (meth
) - methods
;
1319 int type
= read_u1 (bytes
);
1320 if (type
== JV_DONE_ATTR
)
1322 int len
= read_4 (bytes
);
1323 unsigned char *next
= bytes
+ len
;
1324 if (type
!= JV_METHOD_ATTR
)
1329 int kind
= read_u1 (bytes
, next
);
1330 if (kind
!= JV_ANNOTATION_DEFAULT_KIND
)
1335 int index
= read_u2 (bytes
, next
);
1336 if (meth_index
!= index
)
1342 // FIXME: could cache here. If we do then we have to clone any
1344 return parseAnnotationElement(this, &this->constants
, bytes
, next
);
1349 java::lang::Class::getDeclaredAnnotations(jint
/* jv_attr_type */ member_type
,
1351 jint
/* jv_attr_kind */ kind_req
)
1353 using namespace java::lang::annotation
;
1354 jobjectArray result
;
1356 unsigned char *bytes
= reflection_data
;
1361 loader
= (ClassLoader
*)VMClassLoader::bootLoader
;
1363 result
= (loader
->getDeclaredAnnotations
1364 (this, member_type
, member_index
, kind_req
));
1370 int type
= read_u1 (bytes
);
1371 if (type
== JV_DONE_ATTR
)
1373 int len
= read_4 (bytes
);
1374 unsigned char *next
= bytes
+ len
;
1375 if (type
!= member_type
)
1380 int kind
= read_u1 (bytes
, next
);
1381 if (kind
!= kind_req
)
1386 if (member_type
!= JV_CLASS_ATTR
)
1388 int index
= read_u2 (bytes
, next
);
1389 if (member_index
!= index
)
1396 if (kind_req
== JV_PARAMETER_ANNOTATIONS_KIND
)
1397 result
= ((parseParameterAnnotations
1398 (this, &this->constants
, bytes
, next
)));
1400 result
= ((parseAnnotations (this, &this->constants
, bytes
, next
)));
1404 return (loader
->putDeclaredAnnotations
1405 (this, member_type
, member_index
, kind_req
, result
));
1409 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Method
*meth
,
1412 unsigned short meth_index
= _Jv_FromReflectedMethod (meth
) - methods
;
1413 return getDeclaredAnnotations(JV_METHOD_ATTR
, meth_index
,
1415 ? JV_PARAMETER_ANNOTATIONS_KIND
1416 : JV_ANNOTATIONS_KIND
));
1420 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Constructor
*cons
,
1423 unsigned short meth_index
= _Jv_FromReflectedConstructor (cons
) - 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::Field
*fld
)
1433 unsigned short field_index
= _Jv_FromReflectedField (fld
) - fields
;
1434 return getDeclaredAnnotations(JV_FIELD_ATTR
, field_index
,
1435 JV_ANNOTATIONS_KIND
);
1438 JArray
< ::java::lang::annotation::Annotation
*> *
1439 java::lang::Class::getDeclaredAnnotationsInternal()
1441 return (JArray
< ::java::lang::annotation::Annotation
*> *) getDeclaredAnnotations(JV_CLASS_ATTR
, 0, JV_ANNOTATIONS_KIND
);
1445 resolve_class_constant (jclass klass
, _Jv_Constants
*pool
, int cpool_index
)
1447 check_constant (pool
, cpool_index
, JV_CONSTANT_Class
);
1448 // FIXME: what is the correct thing to do with an exception here?
1449 return _Jv_Linker::resolve_pool_entry (klass
, cpool_index
, false).clazz
;
1453 java::lang::Class::findInnerClassAttribute()
1455 unsigned char *bytes
= reflection_data
;
1460 int type
= read_u1 (bytes
);
1461 if (type
== JV_DONE_ATTR
)
1463 // After the type but before the length.
1464 unsigned char *save
= bytes
;
1465 int len
= read_4 (bytes
);
1466 unsigned char *next
= bytes
+ len
;
1467 if (type
!= JV_CLASS_ATTR
)
1472 int kind
= read_u1 (bytes
, next
);
1473 if (kind
!= JV_INNER_CLASSES_KIND
)
1478 return save
- reflection_data
;
1484 java::lang::Class::findDeclaredClasses(JArray
<jclass
> *result
,
1485 jboolean publicOnly
,
1488 unsigned char *bytes
= reflection_data
+ offset
;
1489 int len
= read_4 (bytes
);
1490 unsigned char *next
= bytes
+ len
;
1492 read_u1 (bytes
, next
);
1493 int n_classes
= read_u2 (bytes
, next
);
1495 for (int i
= 0; i
< n_classes
; ++i
)
1497 int inner_class_index
= read_u2 (bytes
, next
);
1498 int outer_class_index
= read_u2 (bytes
, next
);
1499 /*int inner_name_index = */ read_u2 (bytes
, next
);
1500 int inner_flags
= read_u2 (bytes
, next
);
1502 if (inner_class_index
== 0 || outer_class_index
== 0)
1504 if (resolve_class_constant (this, &constants
, outer_class_index
) == this)
1506 jclass inner
= resolve_class_constant (this, &constants
,
1510 & java::lang::reflect::Modifier::PUBLIC
) != 0))
1514 jclass
*elts
= elements (result
);
1515 elts
[count
] = inner
;
1526 java::lang::Class::getDeclaredClasses (jboolean publicOnly
)
1528 int offset
= findInnerClassAttribute();
1532 // No InnerClasses attribute, so no declared classes.
1536 count
= findDeclaredClasses(NULL
, publicOnly
, offset
);
1537 JArray
<jclass
> *result
1538 = (JArray
<jclass
> *) JvNewObjectArray (count
, &java::lang::Class::class$
,
1541 findDeclaredClasses(result
, publicOnly
, offset
);
1546 java::lang::Class::getDeclaringClass (void)
1548 int offset
= findInnerClassAttribute();
1552 unsigned char *bytes
= reflection_data
+ offset
;
1553 int len
= read_4 (bytes
);
1554 unsigned char *next
= bytes
+ len
;
1556 read_u1 (bytes
, next
);
1557 int n_classes
= read_u2 (bytes
, next
);
1558 for (int i
= 0; i
< n_classes
; ++i
)
1560 int inner_class_index
= read_u2 (bytes
, next
);
1561 int outer_class_index
= read_u2 (bytes
, next
);
1562 /*int inner_name_index = */read_u2 (bytes
, next
);
1563 /*int inner_flags = */read_u2 (bytes
, next
);
1565 if (inner_class_index
== 0 || outer_class_index
== 0)
1567 if (resolve_class_constant (this, &constants
, inner_class_index
) == this)
1568 return resolve_class_constant (this, &constants
, outer_class_index
);
1575 java::lang::Class::isAnonymousClass()
1577 int offset
= findInnerClassAttribute();
1581 unsigned char *bytes
= reflection_data
+ offset
;
1582 int len
= read_4 (bytes
);
1583 unsigned char *next
= bytes
+ len
;
1585 read_u1 (bytes
, next
);
1586 int n_classes
= read_u2 (bytes
, next
);
1587 for (int i
= 0; i
< n_classes
; ++i
)
1589 int inner_class_index
= read_u2 (bytes
, next
);
1590 /*int outer_class_index = */read_u2 (bytes
, next
);
1591 int inner_name_index
= read_u2 (bytes
, next
);
1592 /*int inner_flags = */read_u2 (bytes
, next
);
1594 if (inner_class_index
== 0)
1596 if (resolve_class_constant (this, &constants
, inner_class_index
) == this)
1597 return inner_name_index
== 0;
1604 java::lang::Class::isLocalClass()
1607 indexes
.i
= getEnclosingMethodData();
1608 return indexes
.i
!= 0;
1612 java::lang::Class::isMemberClass()
1614 // FIXME: is this correct?
1615 return !isLocalClass() && getDeclaringClass() != NULL
;
1621 // Some class-related convenience functions.
1624 // Find a method declared in the class. If it is not declared locally
1625 // (or if it is inherited), return NULL.
1627 _Jv_GetMethodLocal (jclass klass
, _Jv_Utf8Const
*name
,
1628 _Jv_Utf8Const
*signature
)
1630 for (int i
= 0; i
< klass
->method_count
; ++i
)
1632 if (_Jv_equalUtf8Consts (name
, klass
->methods
[i
].name
)
1633 && _Jv_equalUtf8Consts (signature
, klass
->methods
[i
].signature
))
1634 return &klass
->methods
[i
];
1640 _Jv_LookupDeclaredMethod (jclass klass
, _Jv_Utf8Const
*name
,
1641 _Jv_Utf8Const
*signature
,
1642 jclass
*declarer_result
)
1644 for (; klass
; klass
= klass
->getSuperclass())
1646 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
1650 if (declarer_result
)
1651 *declarer_result
= klass
;
1659 java::lang::reflect::Method
*
1660 _Jv_GetReflectedMethod (jclass klass
, _Jv_Utf8Const
*name
,
1661 _Jv_Utf8Const
*signature
)
1663 for (; klass
; klass
= klass
->getSuperclass())
1665 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
1668 using namespace java::lang::reflect
;
1669 Method
*rmethod
= new Method ();
1670 rmethod
->offset
= (char*) meth
- (char*) klass
->methods
;
1671 rmethod
->declaringClass
= klass
;
1681 // NOTE: MCACHE_SIZE should be a power of 2 minus one.
1682 #define MCACHE_SIZE 31
1690 static __thread _Jv_mcache
*method_cache
;
1694 _Jv_FindMethodInCache (jclass klass MAYBE_UNUSED
,
1695 _Jv_Utf8Const
*name MAYBE_UNUSED
,
1696 _Jv_Utf8Const
*signature MAYBE_UNUSED
)
1699 _Jv_mcache
*cache
= method_cache
;
1702 int index
= name
->hash16 () & MCACHE_SIZE
;
1703 _Jv_mcache
*mc
= &cache
[index
];
1704 _Jv_Method
*m
= mc
->method
;
1706 if (mc
->klass
== klass
1707 && _Jv_equalUtf8Consts (m
->name
, name
)
1708 && _Jv_equalUtf8Consts (m
->signature
, signature
))
1709 return mc
->method
->ncode
;
1716 _Jv_AddMethodToCache (jclass klass MAYBE_UNUSED
,
1717 _Jv_Method
*method MAYBE_UNUSED
)
1720 if (method_cache
== NULL
)
1721 method_cache
= (_Jv_mcache
*) _Jv_MallocUnchecked((MCACHE_SIZE
+ 1)
1722 * sizeof (_Jv_mcache
));
1723 // If the allocation failed, just keep going.
1724 if (method_cache
!= NULL
)
1726 int index
= method
->name
->hash16 () & MCACHE_SIZE
;
1727 method_cache
[index
].method
= method
;
1728 method_cache
[index
].klass
= klass
;
1733 // Free this thread's method cache. We explicitly manage this memory
1734 // as the GC does not yet know how to scan TLS on all platforms.
1736 _Jv_FreeMethodCache ()
1739 if (method_cache
!= NULL
)
1741 _Jv_Free(method_cache
);
1742 method_cache
= NULL
;
1748 _Jv_LookupInterfaceMethod (jclass klass
, _Jv_Utf8Const
*name
,
1749 _Jv_Utf8Const
*signature
)
1751 using namespace java::lang::reflect
;
1753 void *ncode
= _Jv_FindMethodInCache (klass
, name
, signature
);
1757 for (; klass
; klass
= klass
->getSuperclass())
1759 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
1763 if (Modifier::isStatic(meth
->accflags
))
1764 throw new java::lang::IncompatibleClassChangeError
1765 (_Jv_GetMethodString (klass
, meth
));
1766 if (Modifier::isAbstract(meth
->accflags
))
1767 throw new java::lang::AbstractMethodError
1768 (_Jv_GetMethodString (klass
, meth
));
1769 if (! Modifier::isPublic(meth
->accflags
))
1770 throw new java::lang::IllegalAccessError
1771 (_Jv_GetMethodString (klass
, meth
));
1773 _Jv_AddMethodToCache (klass
, meth
);
1777 throw new java::lang::IncompatibleClassChangeError
;
1780 // Fast interface method lookup by index.
1782 _Jv_LookupInterfaceMethodIdx (jclass klass
, jclass iface
, int method_idx
)
1784 _Jv_IDispatchTable
*cldt
= klass
->idt
;
1785 int idx
= iface
->ioffsets
[cldt
->iindex
] + method_idx
;
1786 return cldt
->itable
[idx
];
1790 _Jv_IsAssignableFrom (jclass source
, jclass target
)
1792 if (source
== target
)
1795 // If target is array, so must source be.
1796 while (target
->isArray ())
1798 if (! source
->isArray())
1800 target
= target
->getComponentType();
1801 source
= source
->getComponentType();
1804 if (target
->isInterface())
1806 // Abstract classes have no IDT, and IDTs provide no way to check
1807 // two interfaces for assignability.
1808 if (__builtin_expect
1809 (source
->idt
== NULL
|| source
->isInterface(), false))
1810 return _Jv_InterfaceAssignableFrom (source
, target
);
1812 _Jv_IDispatchTable
*cl_idt
= source
->idt
;
1814 if (__builtin_expect ((target
->ioffsets
== NULL
), false))
1815 return false; // No class implementing TARGET has been loaded.
1816 jshort cl_iindex
= cl_idt
->iindex
;
1817 if (cl_iindex
< target
->ioffsets
[0])
1819 jshort offset
= target
->ioffsets
[cl_iindex
];
1820 if (offset
!= -1 && offset
< cl_idt
->itable_length
1821 && cl_idt
->itable
[offset
] == target
)
1827 // Primitive TYPE classes are only assignable to themselves.
1828 if (__builtin_expect (target
->isPrimitive() || source
->isPrimitive(), false))
1831 if (target
== &java::lang::Object::class$
)
1833 else if (source
->ancestors
== NULL
|| target
->ancestors
== NULL
)
1835 // We need this case when either SOURCE or TARGET has not has
1836 // its constant-time tables prepared.
1838 // At this point we know that TARGET can't be Object, so it is
1839 // safe to use that as the termination point.
1840 while (source
&& source
!= &java::lang::Object::class$
)
1842 if (source
== target
)
1844 source
= source
->getSuperclass();
1847 else if (source
->depth
>= target
->depth
1848 && source
->ancestors
[source
->depth
- target
->depth
] == target
)
1854 // Interface type checking, the slow way. Returns TRUE if IFACE is a
1855 // superinterface of SOURCE. This is used when SOURCE is also an interface,
1856 // or a class with no interface dispatch table.
1858 _Jv_InterfaceAssignableFrom (jclass source
, jclass iface
)
1860 for (int i
= 0; i
< source
->interface_count
; i
++)
1862 jclass interface
= source
->interfaces
[i
];
1863 if (iface
== interface
1864 || _Jv_InterfaceAssignableFrom (interface
, iface
))
1868 if (!source
->isInterface()
1869 && source
->superclass
1870 && _Jv_InterfaceAssignableFrom (source
->superclass
, iface
))
1877 _Jv_IsInstanceOf(jobject obj
, jclass cl
)
1879 if (__builtin_expect (!obj
, false))
1881 return _Jv_IsAssignableFrom (JV_CLASS (obj
), cl
);
1885 _Jv_CheckCast (jclass c
, jobject obj
)
1887 if (__builtin_expect
1888 (obj
!= NULL
&& ! _Jv_IsAssignableFrom(JV_CLASS (obj
), c
), false))
1889 throw new java::lang::ClassCastException
1890 ((new java::lang::StringBuffer
1891 (obj
->getClass()->getName()))->append
1892 (JvNewStringUTF(" cannot be cast to "))->append
1893 (c
->getName())->toString());
1899 _Jv_CheckArrayStore (jobject arr
, jobject obj
)
1903 JvAssert (arr
!= NULL
);
1904 jclass elt_class
= (JV_CLASS (arr
))->getComponentType();
1905 if (elt_class
== &java::lang::Object::class$
)
1907 jclass obj_class
= JV_CLASS (obj
);
1908 if (__builtin_expect
1909 (! _Jv_IsAssignableFrom (obj_class
, elt_class
), false))
1910 throw new java::lang::ArrayStoreException
1911 ((new java::lang::StringBuffer
1912 (JvNewStringUTF("Cannot store ")))->append
1913 (obj_class
->getName())->append
1914 (JvNewStringUTF(" in array of type "))->append
1915 (elt_class
->getName())->toString());
1920 _Jv_IsAssignableFromSlow (jclass source
, jclass target
)
1922 // First, strip arrays.
1923 while (target
->isArray ())
1925 // If target is array, source must be as well.
1926 if (! source
->isArray ())
1928 target
= target
->getComponentType ();
1929 source
= source
->getComponentType ();
1933 if (target
== &java::lang::Object::class$
)
1936 // Ensure that the classes have their supers installed.
1937 _Jv_Linker::wait_for_state (source
, JV_STATE_LOADING
);
1938 _Jv_Linker::wait_for_state (target
, JV_STATE_LOADING
);
1942 if (source
== target
)
1945 if (target
->isPrimitive () || source
->isPrimitive ())
1948 if (target
->isInterface ())
1950 for (int i
= 0; i
< source
->interface_count
; ++i
)
1952 // We use a recursive call because we also need to
1953 // check superinterfaces.
1954 if (_Jv_IsAssignableFromSlow (source
->getInterface (i
), target
))
1958 source
= source
->getSuperclass ();
1960 while (source
!= NULL
);
1965 // Lookup an interface method by name. This is very similar to
1966 // purpose to _getMethod, but the interfaces are quite different. It
1967 // might be a good idea for _getMethod to call this function.
1969 // Return true of the method is found, with the class in FOUND_CLASS
1970 // and the index in INDEX.
1972 _Jv_getInterfaceMethod (jclass search_class
, jclass
&found_class
, int &index
,
1973 const _Jv_Utf8Const
*utf_name
,
1974 const _Jv_Utf8Const
*utf_sig
)
1976 for (jclass klass
= search_class
; klass
; klass
= klass
->getSuperclass())
1978 // FIXME: Throw an exception?
1979 if (!klass
->isInterface ())
1982 int max
= klass
->method_count
;
1984 for (int i
= 0; i
< max
; ++i
)
1986 // Skip <clinit> here, as it will not be in the IDT.
1987 if (klass
->methods
[i
].name
->first() == '<')
1990 if (_Jv_equalUtf8Consts (klass
->methods
[i
].name
, utf_name
)
1991 && _Jv_equalUtf8Consts (klass
->methods
[i
].signature
, utf_sig
))
1994 using namespace java::lang::reflect
;
1996 // FIXME: Method must be public. Throw an exception?
1997 if (! Modifier::isPublic (klass
->methods
[i
].accflags
))
2000 found_class
= klass
;
2001 // Interface method indexes count from 1.
2010 // If we haven't found a match, and this class is an interface, then
2011 // check all the superinterfaces.
2012 if (search_class
->isInterface())
2014 for (int i
= 0; i
< search_class
->interface_count
; ++i
)
2016 using namespace java::lang::reflect
;
2017 bool found
= _Jv_getInterfaceMethod (search_class
->interfaces
[i
],
2030 _Jv_FindInterpreterMethod (jclass klass
, jmethodID desired_method
)
2032 using namespace java::lang::reflect
;
2034 _Jv_InterpClass
*iclass
2035 = reinterpret_cast<_Jv_InterpClass
*> (klass
->aux_info
);
2036 _Jv_MethodBase
**imethods
= _Jv_GetFirstMethod (iclass
);
2038 for (int i
= 0; i
< JvNumMethods (klass
); ++i
)
2040 _Jv_MethodBase
*imeth
= imethods
[i
];
2041 if (imeth
->get_method () == desired_method
)
2049 // Return Utf8 name of a class. This function is here for code that
2050 // can't access klass->name directly.
2052 _Jv_GetClassNameUtf8 (jclass klass
)
2058 _Jv_GetMethodDeclaringClass (jmethodID method
)
2060 _Jv_StackTrace::UpdateNCodeMap ();
2061 jobject obj
= reinterpret_cast<jobject
> (method
->ncode
);
2062 return reinterpret_cast<jclass
> (_Jv_StackTrace::ncodeMap
->get (obj
));
2066 _Jv_GetClassState (jclass klass
)
2068 return klass
->state
;
2073 _Jv_GetInterpClassSourceFile (jclass klass
)
2075 if (_Jv_IsInterpretedClass (klass
))
2077 _Jv_InterpClass
*iclass
=
2078 reinterpret_cast<_Jv_InterpClass
*> (klass
->aux_info
);
2079 return iclass
->source_file_name
;