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/Constructor.h>
33 #include <java/lang/AbstractMethodError.h>
34 #include <java/lang/ArrayStoreException.h>
35 #include <java/lang/ClassCastException.h>
36 #include <java/lang/ClassNotFoundException.h>
37 #include <java/lang/ExceptionInInitializerError.h>
38 #include <java/lang/IllegalAccessException.h>
39 #include <java/lang/IllegalAccessError.h>
40 #include <java/lang/IllegalArgumentException.h>
41 #include <java/lang/IncompatibleClassChangeError.h>
42 #include <java/lang/NoSuchFieldError.h>
43 #include <java/lang/ArrayIndexOutOfBoundsException.h>
44 #include <java/lang/InstantiationException.h>
45 #include <java/lang/NoClassDefFoundError.h>
46 #include <java/lang/NoSuchFieldException.h>
47 #include <java/lang/NoSuchMethodError.h>
48 #include <java/lang/NoSuchMethodException.h>
49 #include <java/lang/Thread.h>
50 #include <java/lang/NullPointerException.h>
51 #include <java/lang/RuntimePermission.h>
52 #include <java/lang/System.h>
53 #include <java/lang/SecurityException.h>
54 #include <java/lang/SecurityManager.h>
55 #include <java/lang/StringBuffer.h>
56 #include <java/lang/VMClassLoader.h>
57 #include <gcj/method.h>
58 #include <gnu/gcj/RawData.h>
59 #include <java/lang/VerifyError.h>
60 #include <java/lang/InternalError.h>
61 #include <java/lang/TypeNotPresentException.h>
62 #include <java/lang/Byte.h>
63 #include <java/lang/Short.h>
64 #include <java/lang/Integer.h>
65 #include <java/lang/Float.h>
66 #include <java/lang/Double.h>
67 #include <java/lang/Long.h>
68 #include <java/lang/Character.h>
69 #include <java/lang/Boolean.h>
70 #include <java/lang/annotation/Annotation.h>
71 #include <java/util/HashMap.h>
72 #include <java/util/Map.h>
73 #include <sun/reflect/annotation/AnnotationInvocationHandler.h>
74 #include <java/lang/Enum.h>
76 #include <java-cpool.h>
77 #include <java-interp.h>
78 #include <java-assert.h>
79 #include <java-stack.h>
80 #include <execution.h>
87 java::lang::Class::forName (jstring className
, jboolean initialize
,
88 java::lang::ClassLoader
*loader
)
91 throw new java::lang::NullPointerException
;
93 jsize length
= _Jv_GetStringUTFLength (className
);
95 _Jv_GetStringUTFRegion (className
, 0, className
->length(), buffer
);
97 _Jv_Utf8Const
*name
= _Jv_makeUtf8Const (buffer
, length
);
99 if (! _Jv_VerifyClassName (name
))
100 throw new java::lang::ClassNotFoundException (className
);
102 jclass klass
= (buffer
[0] == '['
103 ? _Jv_FindClassFromSignature (name
->chars(), loader
)
104 : _Jv_FindClass (name
, loader
));
107 throw new java::lang::ClassNotFoundException (className
);
110 _Jv_InitClass (klass
);
116 java::lang::Class::forName (jstring className
)
118 java::lang::ClassLoader
*loader
= NULL
;
120 jclass caller
= _Jv_StackTrace::GetCallingClass (&Class::class$
);
122 loader
= caller
->getClassLoaderInternal();
124 return forName (className
, true, loader
);
127 java::lang::ClassLoader
*
128 java::lang::Class::getClassLoader (void)
130 java::lang::SecurityManager
*s
= java::lang::System::getSecurityManager();
133 jclass caller
= _Jv_StackTrace::GetCallingClass (&Class::class$
);
134 return getClassLoader (caller
);
140 java::lang::ClassLoader
*
141 java::lang::Class::getClassLoader (jclass caller
)
143 java::lang::SecurityManager
*s
= java::lang::System::getSecurityManager();
146 ClassLoader
*caller_loader
= caller
->getClassLoaderInternal();
148 // If the caller has a non-null class loader, and that loader
149 // is not this class' loader or an ancestor thereof, then do a
151 if (caller_loader
!= NULL
&& ! caller_loader
->isAncestorOf(loader
))
152 s
->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader")));
158 java::lang::reflect::Constructor
*
159 java::lang::Class::getConstructor (JArray
<jclass
> *param_types
)
161 memberAccessCheck(java::lang::reflect::Member::PUBLIC
);
163 jstring partial_sig
= getSignature (param_types
, true);
164 jint hash
= partial_sig
->hashCode ();
166 int i
= isPrimitive () ? 0 : method_count
;
169 if (_Jv_equalUtf8Consts (methods
[i
].name
, init_name
)
170 && _Jv_equal (methods
[i
].signature
, partial_sig
, hash
))
172 // Found it. For getConstructor, the constructor must be
174 using namespace java::lang::reflect
;
175 if (! Modifier::isPublic(methods
[i
].accflags
))
177 Constructor
*cons
= new Constructor ();
178 cons
->offset
= (char *) (&methods
[i
]) - (char *) methods
;
179 cons
->declaringClass
= this;
183 throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name
));
186 JArray
<java::lang::reflect::Constructor
*> *
187 java::lang::Class::getDeclaredConstructors (jboolean publicOnly
)
189 int numConstructors
= 0;
190 int max
= isPrimitive () ? 0 : method_count
;
192 for (i
= max
; --i
>= 0; )
194 _Jv_Method
*method
= &methods
[i
];
195 if (method
->name
== NULL
196 || ! _Jv_equalUtf8Consts (method
->name
, init_name
))
199 && ! java::lang::reflect::Modifier::isPublic(method
->accflags
))
203 JArray
<java::lang::reflect::Constructor
*> *result
204 = (JArray
<java::lang::reflect::Constructor
*> *)
205 JvNewObjectArray (numConstructors
,
206 &java::lang::reflect::Constructor::class$
,
208 java::lang::reflect::Constructor
** cptr
= elements (result
);
209 for (i
= 0; i
< max
; i
++)
211 _Jv_Method
*method
= &methods
[i
];
212 if (method
->name
== NULL
213 || ! _Jv_equalUtf8Consts (method
->name
, init_name
))
216 && ! java::lang::reflect::Modifier::isPublic(method
->accflags
))
218 java::lang::reflect::Constructor
*cons
219 = new java::lang::reflect::Constructor ();
220 cons
->offset
= (char *) method
- (char *) methods
;
221 cons
->declaringClass
= this;
227 java::lang::reflect::Constructor
*
228 java::lang::Class::getDeclaredConstructor (JArray
<jclass
> *param_types
)
230 memberAccessCheck(java::lang::reflect::Member::DECLARED
);
232 jstring partial_sig
= getSignature (param_types
, true);
233 jint hash
= partial_sig
->hashCode ();
235 int i
= isPrimitive () ? 0 : method_count
;
238 if (_Jv_equalUtf8Consts (methods
[i
].name
, init_name
)
239 && _Jv_equal (methods
[i
].signature
, partial_sig
, hash
))
242 using namespace java::lang::reflect
;
243 Constructor
*cons
= new Constructor ();
244 cons
->offset
= (char *) (&methods
[i
]) - (char *) methods
;
245 cons
->declaringClass
= this;
249 throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name
));
252 java::lang::reflect::Field
*
253 java::lang::Class::getField (jstring name
, jint hash
)
255 java::lang::reflect::Field
* rfield
;
256 for (int i
= 0; i
< field_count
; i
++)
258 _Jv_Field
*field
= &fields
[i
];
259 if (! _Jv_equal (field
->name
, name
, hash
))
261 if (! (field
->getModifiers() & java::lang::reflect::Modifier::PUBLIC
))
263 rfield
= new java::lang::reflect::Field ();
264 rfield
->offset
= (char*) field
- (char*) fields
;
265 rfield
->declaringClass
= this;
269 jclass superclass
= getSuperclass();
270 if (superclass
== NULL
)
272 rfield
= superclass
->getField(name
, hash
);
273 for (int i
= 0; i
< interface_count
&& rfield
== NULL
; ++i
)
274 rfield
= interfaces
[i
]->getField (name
, hash
);
278 java::lang::reflect::Field
*
279 java::lang::Class::getDeclaredField (jstring name
)
281 memberAccessCheck(java::lang::reflect::Member::DECLARED
);
282 int hash
= name
->hashCode();
283 for (int i
= 0; i
< field_count
; i
++)
285 _Jv_Field
*field
= &fields
[i
];
286 if (! _Jv_equal (field
->name
, name
, hash
))
288 java::lang::reflect::Field
* rfield
= new java::lang::reflect::Field ();
289 rfield
->offset
= (char*) field
- (char*) fields
;
290 rfield
->declaringClass
= this;
294 throw new java::lang::NoSuchFieldException (name
);
297 JArray
<java::lang::reflect::Field
*> *
298 java::lang::Class::getDeclaredFields (jboolean public_only
)
304 for (int i
= 0; i
< field_count
; ++i
)
306 _Jv_Field
*field
= &fields
[i
];
307 if ((field
->flags
& java::lang::reflect::Modifier::PUBLIC
))
314 JArray
<java::lang::reflect::Field
*> *result
315 = (JArray
<java::lang::reflect::Field
*> *)
316 JvNewObjectArray (size
, &java::lang::reflect::Field::class$
, NULL
);
317 java::lang::reflect::Field
** fptr
= elements (result
);
318 for (int i
= 0; i
< field_count
; i
++)
320 _Jv_Field
*field
= &fields
[i
];
322 && ! (field
->flags
& java::lang::reflect::Modifier::PUBLIC
))
324 java::lang::reflect::Field
* rfield
= new java::lang::reflect::Field ();
325 rfield
->offset
= (char*) field
- (char*) fields
;
326 rfield
->declaringClass
= this;
333 java::lang::Class::getSignature (java::lang::StringBuffer
*buffer
)
336 buffer
->append((jchar
) method_count
);
339 jstring name
= getName();
340 if (name
->charAt(0) != '[')
341 buffer
->append((jchar
) 'L');
342 buffer
->append(name
);
343 if (name
->charAt(0) != '[')
344 buffer
->append((jchar
) ';');
348 // This doesn't have to be native. It is an implementation detail
349 // only called from the C++ code, though, so maybe this is clearer.
351 java::lang::Class::getSignature (JArray
<jclass
> *param_types
,
352 jboolean is_constructor
)
354 java::lang::StringBuffer
*buf
= new java::lang::StringBuffer ();
355 buf
->append((jchar
) '(');
356 // A NULL param_types means "no parameters".
357 if (param_types
!= NULL
)
359 jclass
*v
= elements (param_types
);
360 for (int i
= 0; i
< param_types
->length
; ++i
)
361 v
[i
]->getSignature(buf
);
363 buf
->append((jchar
) ')');
365 buf
->append((jchar
) 'V');
366 return buf
->toString();
369 java::lang::reflect::Method
*
370 java::lang::Class::_getDeclaredMethod (jstring name
,
371 JArray
<jclass
> *param_types
)
373 jstring partial_sig
= getSignature (param_types
, false);
374 jint p_len
= partial_sig
->length();
375 _Jv_Utf8Const
*utf_name
= _Jv_makeUtf8Const (name
);
376 int i
= isPrimitive () ? 0 : method_count
;
379 if (_Jv_equalUtf8Consts (methods
[i
].name
, utf_name
)
380 && _Jv_equaln (methods
[i
].signature
, partial_sig
, p_len
)
381 && (methods
[i
].accflags
382 & java::lang::reflect::Modifier::INVISIBLE
) == 0)
385 using namespace java::lang::reflect
;
386 Method
*rmethod
= new Method ();
387 rmethod
->offset
= (char*) (&methods
[i
]) - (char*) methods
;
388 rmethod
->declaringClass
= this;
395 JArray
<java::lang::reflect::Method
*> *
396 java::lang::Class::getDeclaredMethods (void)
398 memberAccessCheck(java::lang::reflect::Member::DECLARED
);
401 int max
= isPrimitive () ? 0 : method_count
;
403 for (i
= max
; --i
>= 0; )
405 _Jv_Method
*method
= &methods
[i
];
406 if (method
->name
== NULL
407 || _Jv_equalUtf8Consts (method
->name
, clinit_name
)
408 || _Jv_equalUtf8Consts (method
->name
, init_name
)
409 || _Jv_equalUtf8Consts (method
->name
, finit_name
)
410 || (methods
[i
].accflags
411 & java::lang::reflect::Modifier::INVISIBLE
) != 0)
415 JArray
<java::lang::reflect::Method
*> *result
416 = (JArray
<java::lang::reflect::Method
*> *)
417 JvNewObjectArray (numMethods
, &java::lang::reflect::Method::class$
, NULL
);
418 java::lang::reflect::Method
** mptr
= elements (result
);
419 for (i
= 0; i
< max
; i
++)
421 _Jv_Method
*method
= &methods
[i
];
422 if (method
->name
== NULL
423 || _Jv_equalUtf8Consts (method
->name
, clinit_name
)
424 || _Jv_equalUtf8Consts (method
->name
, init_name
)
425 || _Jv_equalUtf8Consts (method
->name
, finit_name
)
426 || (methods
[i
].accflags
427 & java::lang::reflect::Modifier::INVISIBLE
) != 0)
429 java::lang::reflect::Method
* rmethod
430 = new java::lang::reflect::Method ();
431 rmethod
->offset
= (char*) method
- (char*) methods
;
432 rmethod
->declaringClass
= this;
439 java::lang::Class::getName (void)
441 return name
->toString();
445 java::lang::Class::getInterfaces (void)
447 jobjectArray r
= JvNewObjectArray (interface_count
, getClass (), NULL
);
448 jobject
*data
= elements (r
);
449 for (int i
= 0; i
< interface_count
; ++i
)
451 typedef unsigned int uaddr
__attribute__ ((mode (pointer
)));
452 data
[i
] = interfaces
[i
];
453 if ((uaddr
)data
[i
] < (uaddr
)constants
.size
)
454 fprintf (stderr
, "ERROR !!!\n");
456 return reinterpret_cast<JArray
<jclass
> *> (r
);
459 java::lang::reflect::Method
*
460 java::lang::Class::_getMethod (jstring name
, JArray
<jclass
> *param_types
)
462 jstring partial_sig
= getSignature (param_types
, false);
463 jint p_len
= partial_sig
->length();
464 _Jv_Utf8Const
*utf_name
= _Jv_makeUtf8Const (name
);
466 for (Class
*klass
= this; klass
; klass
= klass
->getSuperclass())
468 int i
= klass
->isPrimitive () ? 0 : klass
->method_count
;
471 if (_Jv_equalUtf8Consts (klass
->methods
[i
].name
, utf_name
)
472 && _Jv_equaln (klass
->methods
[i
].signature
, partial_sig
, p_len
)
473 && (klass
->methods
[i
].accflags
474 & java::lang::reflect::Modifier::INVISIBLE
) == 0)
477 using namespace java::lang::reflect
;
479 // Method must be public.
480 if (! Modifier::isPublic (klass
->methods
[i
].accflags
))
483 Method
*rmethod
= new Method ();
484 rmethod
->offset
= ((char *) (&klass
->methods
[i
])
485 - (char *) klass
->methods
);
486 rmethod
->declaringClass
= klass
;
492 // If we haven't found a match, and this class is an interface, then
493 // check all the superinterfaces.
496 for (int i
= 0; i
< interface_count
; ++i
)
498 using namespace java::lang::reflect
;
499 Method
*rmethod
= interfaces
[i
]->_getMethod (name
, param_types
);
508 // This is a very slow implementation, since it re-scans all the
509 // methods we've already listed to make sure we haven't duplicated a
510 // method. It also over-estimates the required size, so we have to
511 // shrink the result array later.
513 java::lang::Class::_getMethods (JArray
<java::lang::reflect::Method
*> *result
,
518 // First examine all local methods
519 for (int i
= isPrimitive () ? 0 : method_count
; --i
>= 0; )
521 _Jv_Method
*method
= &methods
[i
];
522 if (method
->name
== NULL
523 || _Jv_equalUtf8Consts (method
->name
, clinit_name
)
524 || _Jv_equalUtf8Consts (method
->name
, init_name
)
525 || _Jv_equalUtf8Consts (method
->name
, finit_name
)
527 & java::lang::reflect::Modifier::INVISIBLE
) != 0)
529 // Only want public methods.
530 if (! java::lang::reflect::Modifier::isPublic (method
->accflags
))
533 // This is where we over-count the slots required if we aren't
534 // filling the result for real.
538 java::lang::reflect::Method
**mp
= elements (result
);
539 // If we already have a method with this name and signature,
540 // then ignore this one. This can happen with virtual
542 for (int j
= 0; j
< offset
; ++j
)
544 _Jv_Method
*meth_2
= _Jv_FromReflectedMethod (mp
[j
]);
545 if (_Jv_equalUtf8Consts (method
->name
, meth_2
->name
)
546 && _Jv_equalUtf8Consts (method
->signature
,
559 using namespace java::lang::reflect
;
560 Method
*rmethod
= new Method ();
561 rmethod
->offset
= (char *) method
- (char *) methods
;
562 rmethod
->declaringClass
= this;
563 Method
**mp
= elements (result
);
564 mp
[offset
+ count
] = rmethod
;
570 // Now examine superclasses.
571 if (getSuperclass () != NULL
)
573 jint s_count
= getSuperclass()->_getMethods (result
, offset
);
578 // Finally, examine interfaces.
579 for (int i
= 0; i
< interface_count
; ++i
)
581 int f_count
= interfaces
[i
]->_getMethods (result
, offset
);
589 JArray
<java::lang::reflect::Method
*> *
590 java::lang::Class::getMethods (void)
592 using namespace java::lang::reflect
;
594 memberAccessCheck(Member::PUBLIC
);
596 // This will overestimate the size we need.
597 jint count
= _getMethods (NULL
, 0);
599 JArray
<Method
*> *result
600 = ((JArray
<Method
*> *) JvNewObjectArray (count
,
604 // When filling the array for real, we get the actual count. Then
605 // we resize the array.
606 jint real_count
= _getMethods (result
, 0);
608 if (real_count
!= count
)
611 = ((JArray
<Method
*> *) JvNewObjectArray (real_count
,
615 Method
**destp
= elements (r2
);
616 Method
**srcp
= elements (result
);
618 for (int i
= 0; i
< real_count
; ++i
)
628 java::lang::Class::isAssignableFrom (jclass klass
)
630 // Arguments may not have been initialized, given ".class" syntax.
631 // This ensures we can at least look at their superclasses.
632 _Jv_Linker::wait_for_state (this, JV_STATE_LOADING
);
633 _Jv_Linker::wait_for_state (klass
, JV_STATE_LOADING
);
634 return _Jv_IsAssignableFrom (klass
, this);
638 java::lang::Class::isInstance (jobject obj
)
642 return _Jv_IsAssignableFrom (JV_CLASS (obj
), this);
646 java::lang::Class::newInstance (void)
648 memberAccessCheck(java::lang::reflect::Member::PUBLIC
);
653 || java::lang::reflect::Modifier::isAbstract(accflags
))
654 throw new java::lang::InstantiationException (getName ());
656 _Jv_InitClass (this);
658 _Jv_Method
*meth
= _Jv_GetMethodLocal (this, init_name
, void_signature
);
660 throw new java::lang::InstantiationException (getName());
662 jobject r
= _Jv_AllocObject (this);
663 ((void (*) (jobject
)) meth
->ncode
) (r
);
668 java::lang::Class::finalize (void)
670 engine
->unregister(this);
673 // This implements the initialization process for a class. From Spec
676 java::lang::Class::initializeClass (void)
678 // Short-circuit to avoid needless locking (expression includes
679 // JV_STATE_PHANTOM and JV_STATE_DONE).
680 if (state
>= JV_STATE_PHANTOM
)
683 // Step 1. We introduce a new scope so we can synchronize more
686 JvSynchronize
sync (this);
688 if (state
< JV_STATE_LINKED
)
692 _Jv_Linker::wait_for_state(this, JV_STATE_LINKED
);
694 catch (java::lang::SecurityException
*x
)
698 catch (java::lang::Throwable
*x
)
700 // Turn into a NoClassDefFoundError.
701 java::lang::NoClassDefFoundError
*result
702 = new java::lang::NoClassDefFoundError(getName());
703 result
->initCause(x
);
709 java::lang::Thread
*self
= java::lang::Thread::currentThread();
710 self
= (java::lang::Thread
*) ((long) self
| 1);
711 while (state
== JV_STATE_IN_PROGRESS
&& thread
&& thread
!= self
)
715 if (state
== JV_STATE_DONE
|| state
== JV_STATE_IN_PROGRESS
)
719 if (state
== JV_STATE_ERROR
)
720 throw new java::lang::NoClassDefFoundError (getName());
724 _Jv_Linker::wait_for_state (this, JV_STATE_LINKED
);
725 state
= JV_STATE_IN_PROGRESS
;
729 if (! isInterface () && superclass
)
733 _Jv_InitClass (superclass
);
735 catch (java::lang::SecurityException
*x
)
739 catch (java::lang::Throwable
*except
)
741 // Caught an exception.
742 JvSynchronize
sync (this);
743 state
= JV_STATE_ERROR
;
749 // Steps 8, 9, 10, 11.
752 _Jv_Method
*meth
= _Jv_GetMethodLocal (this, clinit_name
,
755 ((void (*) (void)) meth
->ncode
) ();
757 catch (java::lang::SecurityException
*x
)
761 catch (java::lang::Throwable
*except
)
763 if (! java::lang::Error::class$
.isInstance(except
))
767 except
= new ExceptionInInitializerError (except
);
769 catch (java::lang::Throwable
*t
)
775 JvSynchronize
sync (this);
776 state
= JV_STATE_ERROR
;
781 JvSynchronize
sync (this);
782 state
= JV_STATE_DONE
;
786 // Only used by serialization
787 java::lang::reflect::Field
*
788 java::lang::Class::getPrivateField (jstring name
)
790 int hash
= name
->hashCode ();
792 java::lang::reflect::Field
* rfield
;
793 for (int i
= 0; i
< field_count
; i
++)
795 _Jv_Field
*field
= &fields
[i
];
796 if (! _Jv_equal (field
->name
, name
, hash
))
798 rfield
= new java::lang::reflect::Field ();
799 rfield
->offset
= (char*) field
- (char*) fields
;
800 rfield
->declaringClass
= this;
804 jclass superclass
= getSuperclass();
805 if (superclass
== NULL
)
807 rfield
= superclass
->getPrivateField(name
);
808 for (int i
= 0; i
< interface_count
&& rfield
== NULL
; ++i
)
809 rfield
= interfaces
[i
]->getPrivateField (name
);
813 // Only used by serialization
814 java::lang::reflect::Method
*
815 java::lang::Class::getPrivateMethod (jstring name
, JArray
<jclass
> *param_types
)
817 jstring partial_sig
= getSignature (param_types
, false);
818 jint p_len
= partial_sig
->length();
819 _Jv_Utf8Const
*utf_name
= _Jv_makeUtf8Const (name
);
820 for (Class
*klass
= this; klass
; klass
= klass
->getSuperclass())
822 int i
= klass
->isPrimitive () ? 0 : klass
->method_count
;
825 if (_Jv_equalUtf8Consts (klass
->methods
[i
].name
, utf_name
)
826 && _Jv_equaln (klass
->methods
[i
].signature
, partial_sig
, p_len
))
829 using namespace java::lang::reflect
;
831 Method
*rmethod
= new Method ();
832 rmethod
->offset
= ((char *) (&klass
->methods
[i
])
833 - (char *) klass
->methods
);
834 rmethod
->declaringClass
= klass
;
839 throw new java::lang::NoSuchMethodException (name
);
842 // Private accessor method for Java code to retrieve the protection domain.
843 java::security::ProtectionDomain
*
844 java::lang::Class::getProtectionDomain0 ()
846 return protectionDomain
;
850 java::lang::Class::getSigners()
856 java::lang::Class::setSigners(JArray
<jobject
> *s
)
864 read_u1 (unsigned char *&p
)
870 read_u1 (unsigned char *&p
, unsigned char *next
)
873 throw new java::lang::InternalError();
878 read_u2 (unsigned char *&p
)
880 unsigned int b1
= *p
++;
881 unsigned int b2
= *p
++;
882 return (b1
<< 8) | b2
;
886 read_u2 (unsigned char *&p
, unsigned char *next
)
889 throw new java::lang::InternalError();
894 read_4 (unsigned char *&p
)
900 return (b1
<< 24) | (b2
<< 16) | (b3
<< 8) | b4
;
904 java::lang::Class::getReflectionSignature (jint
/*jv_attr_type*/ type
,
907 // We just re-parse the bytecode for this data each time. If
908 // necessary we can cache results, but I suspect this is not
909 // performance sensitive.
910 unsigned char *bytes
= reflection_data
;
915 int kind
= read_u1 (bytes
);
916 if (kind
== JV_DONE_ATTR
)
918 int len
= read_4 (bytes
);
919 unsigned char *next
= bytes
+ len
;
925 if (type
!= JV_CLASS_ATTR
)
927 unsigned short index
= read_u2 (bytes
, next
);
928 if (index
!= obj_index
)
934 int nt
= read_u1 (bytes
, next
);
935 if (nt
!= JV_SIGNATURE_KIND
)
940 unsigned int cpool_idx
= read_u2 (bytes
, next
);
941 if (cpool_idx
>= (unsigned int) constants
.size
942 || constants
.tags
[cpool_idx
] != JV_CONSTANT_Utf8
)
944 // We just ignore errors for now. It isn't clear what is
945 // best to do here, as an encoding error here means a bug
946 // either in the compiler or in defineclass.cc.
949 return _Jv_NewStringUtf8Const (constants
.data
[cpool_idx
].utf8
);
954 java::lang::Class::getReflectionSignature (::java::lang::reflect::Constructor
*c
)
956 _Jv_Method
*meth
= _Jv_FromReflectedConstructor (c
);
957 unsigned short meth_index
= meth
- methods
;
958 return getReflectionSignature (JV_METHOD_ATTR
, meth_index
);
962 java::lang::Class::getReflectionSignature (::java::lang::reflect::Method
*m
)
964 _Jv_Method
*meth
= _Jv_FromReflectedMethod (m
);
965 unsigned short meth_index
= meth
- methods
;
966 return getReflectionSignature (JV_METHOD_ATTR
, meth_index
);
970 java::lang::Class::getReflectionSignature (::java::lang::reflect::Field
*f
)
972 _Jv_Field
*fld
= _Jv_FromReflectedField (f
);
973 unsigned short fld_index
= fld
- fields
;
974 return getReflectionSignature (JV_FIELD_ATTR
, fld_index
);
978 java::lang::Class::getClassSignature()
980 return getReflectionSignature (JV_CLASS_ATTR
, 0);
984 java::lang::Class::getEnclosingMethodData()
986 unsigned char *bytes
= reflection_data
;
991 int kind
= read_u1 (bytes
);
992 if (kind
== JV_DONE_ATTR
)
994 int len
= read_4 (bytes
);
995 unsigned char *next
= bytes
+ len
;
996 if (kind
!= JV_CLASS_ATTR
)
1001 int type
= read_u1 (bytes
, next
);
1002 if (type
!= JV_ENCLOSING_METHOD_KIND
)
1007 int class_index
= read_u2 (bytes
, next
);
1008 int method_index
= read_u2 (bytes
, next
);
1010 _Jv_storeIndexes (&result
, class_index
, method_index
);
1016 java::lang::Class::getEnclosingClass()
1019 indexes
.i
= getEnclosingMethodData();
1022 _Jv_ushort class_index
, method_index
;
1023 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1024 return _Jv_Linker::resolve_pool_entry (this, class_index
).clazz
;
1027 ::java::lang::reflect::Method
*
1028 java::lang::Class::getEnclosingMethod()
1031 indexes
.i
= getEnclosingMethodData();
1034 _Jv_ushort class_index
, method_index
;
1035 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1037 _Jv_Method
*method
= _Jv_Linker::resolve_method_entry (this, found_class
,
1041 using namespace java::lang::reflect
;
1042 Method
*rmethod
= new Method ();
1043 rmethod
->offset
= (char *) method
- (char *) found_class
->methods
;
1044 rmethod
->declaringClass
= found_class
;
1048 ::java::lang::reflect::Constructor
*
1049 java::lang::Class::getEnclosingConstructor()
1052 indexes
.i
= getEnclosingMethodData();
1055 _Jv_ushort class_index
, method_index
;
1056 _Jv_loadIndexes (&indexes
, class_index
, method_index
);
1058 _Jv_Method
*method
= _Jv_Linker::resolve_method_entry (this, found_class
,
1062 using namespace java::lang::reflect
;
1063 Constructor
*cons
= new Constructor ();
1064 cons
->offset
= (char *) method
- (char *) found_class
->methods
;
1065 cons
->declaringClass
= this;
1070 check_constant (_Jv_Constants
*pool
, jint cpool_index
, jint type
)
1072 if (cpool_index
<= 0 || cpool_index
>= pool
->size
)
1073 throw new InternalError(JvNewStringLatin1("invalid constant pool index"));
1074 if ((pool
->tags
[cpool_index
] &
1075 ~(JV_CONSTANT_ResolvedFlag
|JV_CONSTANT_LazyFlag
)) != type
)
1077 ::java::lang::StringBuffer
*sb
= new ::java::lang::StringBuffer();
1078 sb
->append(JvNewStringLatin1("expected pool constant "));
1080 sb
->append(JvNewStringLatin1(" but got "));
1081 sb
->append(jint (pool
->tags
[cpool_index
]));
1082 throw new InternalError(sb
->toString());
1086 // Forward declaration
1087 static ::java::lang::annotation::Annotation
*
1088 parseAnnotation(jclass klass
, _Jv_Constants
*pool
,
1089 unsigned char *&bytes
, unsigned char *last
);
1092 parseAnnotationElement(jclass klass
, _Jv_Constants
*pool
,
1093 unsigned char *&bytes
, unsigned char *last
)
1095 int tag
= read_u1 (bytes
, last
);
1101 int cindex
= read_u2 (bytes
, last
);
1102 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1103 result
= Byte::valueOf (pool
->data
[cindex
].i
);
1108 int cindex
= read_u2 (bytes
, last
);
1109 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1110 result
= Character::valueOf (pool
->data
[cindex
].i
);
1115 int cindex
= read_u2 (bytes
, last
);
1116 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1117 result
= Short::valueOf (pool
->data
[cindex
].i
);
1122 int cindex
= read_u2 (bytes
, last
);
1123 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1124 result
= Boolean::valueOf (jboolean (pool
->data
[cindex
].i
));
1129 int cindex
= read_u2 (bytes
, last
);
1130 check_constant (pool
, cindex
, JV_CONSTANT_Integer
);
1131 result
= Integer::valueOf (pool
->data
[cindex
].i
);
1136 int cindex
= read_u2 (bytes
, last
);
1137 check_constant (pool
, cindex
, JV_CONSTANT_Double
);
1139 memcpy (&word
, &pool
->data
[cindex
], 2 * sizeof (_Jv_word
));
1140 result
= Double::valueOf (word
.d
);
1145 int cindex
= read_u2 (bytes
, last
);
1146 check_constant (pool
, cindex
, JV_CONSTANT_Float
);
1147 result
= Float::valueOf (pool
->data
[cindex
].f
);
1152 int cindex
= read_u2 (bytes
, last
);
1153 check_constant (pool
, cindex
, JV_CONSTANT_Long
);
1155 memcpy (&word
, &pool
->data
[cindex
], 2 * sizeof (_Jv_word
));
1156 result
= Long::valueOf (word
.l
);
1161 int cindex
= read_u2 (bytes
, last
);
1162 // Despite what the JVM spec says, compilers generate a Utf8
1163 // constant here, not a String.
1164 check_constant (pool
, cindex
, JV_CONSTANT_Utf8
);
1165 result
= pool
->data
[cindex
].utf8
->toString();
1170 int type_name_index
= read_u2 (bytes
, last
);
1171 check_constant (pool
, type_name_index
, JV_CONSTANT_Utf8
);
1172 int const_name_index
= read_u2 (bytes
, last
);
1173 check_constant (pool
, const_name_index
, JV_CONSTANT_Utf8
);
1175 _Jv_Utf8Const
*u_name
= pool
->data
[type_name_index
].utf8
;
1176 _Jv_Utf8Const
*e_name
= pool
->data
[const_name_index
].utf8
;
1178 // FIXME: throw correct exceptions at the correct times.
1179 jclass e_class
= _Jv_FindClassFromSignature(u_name
->chars(),
1180 klass
->getClassLoaderInternal());
1181 result
= ::java::lang::Enum::valueOf(e_class
, e_name
->toString());
1186 int cindex
= read_u2 (bytes
, last
);
1187 check_constant (pool
, cindex
, JV_CONSTANT_Utf8
);
1188 _Jv_Utf8Const
*u_name
= pool
->data
[cindex
].utf8
;
1190 = _Jv_FindClassFromSignatureNoException(u_name
->chars(),
1191 klass
->getClassLoaderInternal());
1192 // FIXME: not correct: we should lazily do this when trying to
1193 // read the element. This means that
1194 // AnnotationInvocationHandler needs to have a special case.
1196 // FIXME: original exception...
1197 throw new TypeNotPresentException(u_name
->toString(), NULL
);
1198 result
= anno_class
;
1202 result
= parseAnnotation (klass
, pool
, bytes
, last
);
1206 int n_array_elts
= read_u2 (bytes
, last
);
1207 jobjectArray aresult
= _Jv_NewObjectArray (n_array_elts
,
1208 &Object::class$
, NULL
);
1209 jobject
*elts
= elements (aresult
);
1210 for (int i
= 0; i
< n_array_elts
; ++i
)
1211 elts
[i
] = parseAnnotationElement(klass
, pool
, bytes
, last
);
1216 throw new java::lang::InternalError();
1221 static ::java::lang::annotation::Annotation
*
1222 parseAnnotation(jclass klass
, _Jv_Constants
*pool
,
1223 unsigned char *&bytes
, unsigned char *last
)
1225 int type_index
= read_u2 (bytes
, last
);
1226 check_constant (pool
, type_index
, JV_CONSTANT_Utf8
);
1228 _Jv_Utf8Const
*u_name
= pool
->data
[type_index
].utf8
;
1229 jclass anno_class
= _Jv_FindClassFromSignatureNoException(u_name
->chars(),
1230 klass
->getClassLoaderInternal());
1231 // FIXME: what to do if anno_class==NULL?
1233 ::java::util::HashMap
*hmap
= new ::java::util::HashMap();
1234 int npairs
= read_u2 (bytes
, last
);
1235 for (int i
= 0; i
< npairs
; ++i
)
1237 int name_index
= read_u2 (bytes
, last
);
1238 check_constant (pool
, name_index
, JV_CONSTANT_Utf8
);
1239 jstring name
= _Jv_NewStringUtf8Const (pool
->data
[name_index
].utf8
);
1240 jobject value
= parseAnnotationElement (klass
, pool
, bytes
, last
);
1241 // FIXME: any checks needed for name?
1242 hmap
->put(name
, value
);
1244 using namespace ::sun::reflect::annotation
;
1245 return AnnotationInvocationHandler::create (anno_class
,
1246 (::java::util::Map
*) hmap
);
1250 parseAnnotations(jclass klass
, _Jv_Constants
*pool
,
1251 unsigned char *&bytes
, unsigned char *last
)
1253 int num
= read_u2 (bytes
, last
);
1254 jobjectArray result
= _Jv_NewObjectArray (num
,
1255 &::java::lang::annotation::Annotation::class$
,
1257 jobject
*elts
= elements (result
);
1258 for (int i
= 0; i
< num
; ++i
)
1259 elts
[i
] = parseAnnotation(klass
, pool
, bytes
, last
);
1264 parseParameterAnnotations(jclass klass
, _Jv_Constants
*pool
,
1265 unsigned char *&bytes
, unsigned char *last
)
1267 jclass anno
= &::java::lang::annotation::Annotation::class$
;
1268 jclass annoary
= _Jv_GetArrayClass (anno
, anno
->getClassLoaderInternal());
1270 // FIXME: something should check the number of params versus the
1272 int n_params
= read_u1 (bytes
, last
);
1273 jobjectArray result
= _Jv_NewObjectArray (n_params
, annoary
, NULL
);
1274 jobject
*elts
= elements (result
);
1275 for (int i
= 0; i
< n_params
; ++i
)
1276 elts
[i
] = parseAnnotations(klass
, pool
, bytes
, last
);
1281 java::lang::Class::getMethodDefaultValue(::java::lang::reflect::Method
*meth
)
1283 // FIXME: could cache the value here...
1285 unsigned char *bytes
= reflection_data
;
1289 unsigned short meth_index
= _Jv_FromReflectedMethod (meth
) - methods
;
1293 int type
= read_u1 (bytes
);
1294 if (type
== JV_DONE_ATTR
)
1296 int len
= read_4 (bytes
);
1297 unsigned char *next
= bytes
+ len
;
1298 if (type
!= JV_METHOD_ATTR
)
1303 int kind
= read_u1 (bytes
, next
);
1304 if (kind
!= JV_ANNOTATION_DEFAULT_KIND
)
1309 int index
= read_u2 (bytes
, next
);
1310 if (meth_index
!= index
)
1316 // FIXME: could cache here. If we do then we have to clone any
1318 return parseAnnotationElement(this, &this->constants
, bytes
, next
);
1323 java::lang::Class::getDeclaredAnnotations(jint
/* jv_attr_type */ member_type
,
1325 jint
/* jv_attr_kind */ kind_req
)
1327 using namespace java::lang::annotation
;
1328 jobjectArray result
;
1330 unsigned char *bytes
= reflection_data
;
1335 loader
= (ClassLoader
*)VMClassLoader::bootLoader
;
1337 result
= (loader
->getDeclaredAnnotations
1338 (this, member_type
, member_index
, kind_req
));
1344 int type
= read_u1 (bytes
);
1345 if (type
== JV_DONE_ATTR
)
1347 int len
= read_4 (bytes
);
1348 unsigned char *next
= bytes
+ len
;
1349 if (type
!= member_type
)
1354 int kind
= read_u1 (bytes
, next
);
1355 if (kind
!= kind_req
)
1360 if (member_type
!= JV_CLASS_ATTR
)
1362 int index
= read_u2 (bytes
, next
);
1363 if (member_index
!= index
)
1370 if (kind_req
== JV_PARAMETER_ANNOTATIONS_KIND
)
1371 result
= ((parseParameterAnnotations
1372 (this, &this->constants
, bytes
, next
)));
1374 result
= ((parseAnnotations (this, &this->constants
, bytes
, next
)));
1378 return (loader
->putDeclaredAnnotations
1379 (this, member_type
, member_index
, kind_req
, result
));
1383 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Method
*meth
,
1386 unsigned short meth_index
= _Jv_FromReflectedMethod (meth
) - methods
;
1387 return getDeclaredAnnotations(JV_METHOD_ATTR
, meth_index
,
1389 ? JV_PARAMETER_ANNOTATIONS_KIND
1390 : JV_ANNOTATIONS_KIND
));
1394 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Constructor
*cons
,
1397 unsigned short meth_index
= _Jv_FromReflectedConstructor (cons
) - methods
;
1398 return getDeclaredAnnotations(JV_METHOD_ATTR
, meth_index
,
1400 ? JV_PARAMETER_ANNOTATIONS_KIND
1401 : JV_ANNOTATIONS_KIND
));
1405 java::lang::Class::getDeclaredAnnotations(::java::lang::reflect::Field
*fld
)
1407 unsigned short field_index
= _Jv_FromReflectedField (fld
) - fields
;
1408 return getDeclaredAnnotations(JV_FIELD_ATTR
, field_index
,
1409 JV_ANNOTATIONS_KIND
);
1412 JArray
< ::java::lang::annotation::Annotation
*> *
1413 java::lang::Class::getDeclaredAnnotationsInternal()
1415 return (JArray
< ::java::lang::annotation::Annotation
*> *) getDeclaredAnnotations(JV_CLASS_ATTR
, 0, JV_ANNOTATIONS_KIND
);
1419 resolve_class_constant (jclass klass
, _Jv_Constants
*pool
, int cpool_index
)
1421 check_constant (pool
, cpool_index
, JV_CONSTANT_Class
);
1422 // FIXME: what is the correct thing to do with an exception here?
1423 return _Jv_Linker::resolve_pool_entry (klass
, cpool_index
, false).clazz
;
1427 java::lang::Class::findInnerClassAttribute()
1429 unsigned char *bytes
= reflection_data
;
1434 int type
= read_u1 (bytes
);
1435 if (type
== JV_DONE_ATTR
)
1437 // After the type but before the length.
1438 unsigned char *save
= bytes
;
1439 int len
= read_4 (bytes
);
1440 unsigned char *next
= bytes
+ len
;
1441 if (type
!= JV_CLASS_ATTR
)
1446 int kind
= read_u1 (bytes
, next
);
1447 if (kind
!= JV_INNER_CLASSES_KIND
)
1452 return save
- reflection_data
;
1458 java::lang::Class::findDeclaredClasses(JArray
<jclass
> *result
,
1459 jboolean publicOnly
,
1462 unsigned char *bytes
= reflection_data
+ offset
;
1463 int len
= read_4 (bytes
);
1464 unsigned char *next
= bytes
+ len
;
1466 read_u1 (bytes
, next
);
1467 int n_classes
= read_u2 (bytes
, next
);
1469 for (int i
= 0; i
< n_classes
; ++i
)
1471 int inner_class_index
= read_u2 (bytes
, next
);
1472 int outer_class_index
= read_u2 (bytes
, next
);
1473 /*int inner_name_index = */ read_u2 (bytes
, next
);
1474 int inner_flags
= read_u2 (bytes
, next
);
1476 if (inner_class_index
== 0 || outer_class_index
== 0)
1478 if (resolve_class_constant (this, &constants
, outer_class_index
) == this)
1480 jclass inner
= resolve_class_constant (this, &constants
,
1484 & java::lang::reflect::Modifier::PUBLIC
) != 0))
1488 jclass
*elts
= elements (result
);
1489 elts
[count
] = inner
;
1500 java::lang::Class::getDeclaredClasses (jboolean publicOnly
)
1502 int offset
= findInnerClassAttribute();
1506 // No InnerClasses attribute, so no declared classes.
1510 count
= findDeclaredClasses(NULL
, publicOnly
, offset
);
1511 JArray
<jclass
> *result
1512 = (JArray
<jclass
> *) JvNewObjectArray (count
, &java::lang::Class::class$
,
1515 findDeclaredClasses(result
, publicOnly
, offset
);
1520 java::lang::Class::getDeclaringClass (void)
1522 int offset
= findInnerClassAttribute();
1526 unsigned char *bytes
= reflection_data
+ offset
;
1527 int len
= read_4 (bytes
);
1528 unsigned char *next
= bytes
+ len
;
1530 read_u1 (bytes
, next
);
1531 int n_classes
= read_u2 (bytes
, next
);
1532 for (int i
= 0; i
< n_classes
; ++i
)
1534 int inner_class_index
= read_u2 (bytes
, next
);
1535 int outer_class_index
= read_u2 (bytes
, next
);
1536 /*int inner_name_index = */read_u2 (bytes
, next
);
1537 /*int inner_flags = */read_u2 (bytes
, next
);
1539 if (inner_class_index
== 0 || outer_class_index
== 0)
1541 if (resolve_class_constant (this, &constants
, inner_class_index
) == this)
1542 return resolve_class_constant (this, &constants
, outer_class_index
);
1549 java::lang::Class::isAnonymousClass()
1551 int offset
= findInnerClassAttribute();
1555 unsigned char *bytes
= reflection_data
+ offset
;
1556 int len
= read_4 (bytes
);
1557 unsigned char *next
= bytes
+ len
;
1559 read_u1 (bytes
, next
);
1560 int n_classes
= read_u2 (bytes
, next
);
1561 for (int i
= 0; i
< n_classes
; ++i
)
1563 int inner_class_index
= read_u2 (bytes
, next
);
1564 /*int outer_class_index = */read_u2 (bytes
, next
);
1565 int inner_name_index
= read_u2 (bytes
, next
);
1566 /*int inner_flags = */read_u2 (bytes
, next
);
1568 if (inner_class_index
== 0)
1570 if (resolve_class_constant (this, &constants
, inner_class_index
) == this)
1571 return inner_name_index
== 0;
1578 java::lang::Class::isLocalClass()
1581 indexes
.i
= getEnclosingMethodData();
1582 return indexes
.i
!= 0;
1586 java::lang::Class::isMemberClass()
1588 // FIXME: is this correct?
1589 return !isLocalClass() && getDeclaringClass() != NULL
;
1595 // Some class-related convenience functions.
1598 // Find a method declared in the class. If it is not declared locally
1599 // (or if it is inherited), return NULL.
1601 _Jv_GetMethodLocal (jclass klass
, _Jv_Utf8Const
*name
,
1602 _Jv_Utf8Const
*signature
)
1604 for (int i
= 0; i
< klass
->method_count
; ++i
)
1606 if (_Jv_equalUtf8Consts (name
, klass
->methods
[i
].name
)
1607 && _Jv_equalUtf8Consts (signature
, klass
->methods
[i
].signature
))
1608 return &klass
->methods
[i
];
1614 _Jv_LookupDeclaredMethod (jclass klass
, _Jv_Utf8Const
*name
,
1615 _Jv_Utf8Const
*signature
,
1616 jclass
*declarer_result
)
1618 for (; klass
; klass
= klass
->getSuperclass())
1620 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
1624 if (declarer_result
)
1625 *declarer_result
= klass
;
1635 // NOTE: MCACHE_SIZE should be a power of 2 minus one.
1636 #define MCACHE_SIZE 31
1644 static __thread _Jv_mcache
*method_cache
;
1648 _Jv_FindMethodInCache (jclass klass MAYBE_UNUSED
,
1649 _Jv_Utf8Const
*name MAYBE_UNUSED
,
1650 _Jv_Utf8Const
*signature MAYBE_UNUSED
)
1653 _Jv_mcache
*cache
= method_cache
;
1656 int index
= name
->hash16 () & MCACHE_SIZE
;
1657 _Jv_mcache
*mc
= &cache
[index
];
1658 _Jv_Method
*m
= mc
->method
;
1660 if (mc
->klass
== klass
1661 && _Jv_equalUtf8Consts (m
->name
, name
)
1662 && _Jv_equalUtf8Consts (m
->signature
, signature
))
1663 return mc
->method
->ncode
;
1670 _Jv_AddMethodToCache (jclass klass MAYBE_UNUSED
,
1671 _Jv_Method
*method MAYBE_UNUSED
)
1674 if (method_cache
== NULL
)
1675 method_cache
= (_Jv_mcache
*) _Jv_MallocUnchecked((MCACHE_SIZE
+ 1)
1676 * sizeof (_Jv_mcache
));
1677 // If the allocation failed, just keep going.
1678 if (method_cache
!= NULL
)
1680 int index
= method
->name
->hash16 () & MCACHE_SIZE
;
1681 method_cache
[index
].method
= method
;
1682 method_cache
[index
].klass
= klass
;
1687 // Free this thread's method cache. We explicitly manage this memory
1688 // as the GC does not yet know how to scan TLS on all platforms.
1690 _Jv_FreeMethodCache ()
1693 if (method_cache
!= NULL
)
1695 _Jv_Free(method_cache
);
1696 method_cache
= NULL
;
1702 _Jv_LookupInterfaceMethod (jclass klass
, _Jv_Utf8Const
*name
,
1703 _Jv_Utf8Const
*signature
)
1705 using namespace java::lang::reflect
;
1707 void *ncode
= _Jv_FindMethodInCache (klass
, name
, signature
);
1711 for (; klass
; klass
= klass
->getSuperclass())
1713 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
1717 if (Modifier::isStatic(meth
->accflags
))
1718 throw new java::lang::IncompatibleClassChangeError
1719 (_Jv_GetMethodString (klass
, meth
));
1720 if (Modifier::isAbstract(meth
->accflags
))
1721 throw new java::lang::AbstractMethodError
1722 (_Jv_GetMethodString (klass
, meth
));
1723 if (! Modifier::isPublic(meth
->accflags
))
1724 throw new java::lang::IllegalAccessError
1725 (_Jv_GetMethodString (klass
, meth
));
1727 _Jv_AddMethodToCache (klass
, meth
);
1731 throw new java::lang::IncompatibleClassChangeError
;
1734 // Fast interface method lookup by index.
1736 _Jv_LookupInterfaceMethodIdx (jclass klass
, jclass iface
, int method_idx
)
1738 _Jv_IDispatchTable
*cldt
= klass
->idt
;
1739 int idx
= iface
->ioffsets
[cldt
->iindex
] + method_idx
;
1740 return cldt
->itable
[idx
];
1744 _Jv_IsAssignableFrom (jclass source
, jclass target
)
1746 if (source
== target
)
1749 // If target is array, so must source be.
1750 while (target
->isArray ())
1752 if (! source
->isArray())
1754 target
= target
->getComponentType();
1755 source
= source
->getComponentType();
1758 if (target
->isInterface())
1760 // Abstract classes have no IDT, and IDTs provide no way to check
1761 // two interfaces for assignability.
1762 if (__builtin_expect
1763 (source
->idt
== NULL
|| source
->isInterface(), false))
1764 return _Jv_InterfaceAssignableFrom (source
, target
);
1766 _Jv_IDispatchTable
*cl_idt
= source
->idt
;
1768 if (__builtin_expect ((target
->ioffsets
== NULL
), false))
1769 return false; // No class implementing TARGET has been loaded.
1770 jshort cl_iindex
= cl_idt
->iindex
;
1771 if (cl_iindex
< target
->ioffsets
[0])
1773 jshort offset
= target
->ioffsets
[cl_iindex
];
1774 if (offset
!= -1 && offset
< cl_idt
->itable_length
1775 && cl_idt
->itable
[offset
] == target
)
1781 // Primitive TYPE classes are only assignable to themselves.
1782 if (__builtin_expect (target
->isPrimitive() || source
->isPrimitive(), false))
1785 if (target
== &java::lang::Object::class$
)
1787 else if (source
->ancestors
== NULL
|| target
->ancestors
== NULL
)
1789 // We need this case when either SOURCE or TARGET has not has
1790 // its constant-time tables prepared.
1792 // At this point we know that TARGET can't be Object, so it is
1793 // safe to use that as the termination point.
1794 while (source
&& source
!= &java::lang::Object::class$
)
1796 if (source
== target
)
1798 source
= source
->getSuperclass();
1801 else if (source
->depth
>= target
->depth
1802 && source
->ancestors
[source
->depth
- target
->depth
] == target
)
1808 // Interface type checking, the slow way. Returns TRUE if IFACE is a
1809 // superinterface of SOURCE. This is used when SOURCE is also an interface,
1810 // or a class with no interface dispatch table.
1812 _Jv_InterfaceAssignableFrom (jclass source
, jclass iface
)
1814 for (int i
= 0; i
< source
->interface_count
; i
++)
1816 jclass interface
= source
->interfaces
[i
];
1817 if (iface
== interface
1818 || _Jv_InterfaceAssignableFrom (interface
, iface
))
1822 if (!source
->isInterface()
1823 && source
->superclass
1824 && _Jv_InterfaceAssignableFrom (source
->superclass
, iface
))
1831 _Jv_IsInstanceOf(jobject obj
, jclass cl
)
1833 if (__builtin_expect (!obj
, false))
1835 return _Jv_IsAssignableFrom (JV_CLASS (obj
), cl
);
1839 _Jv_CheckCast (jclass c
, jobject obj
)
1841 if (__builtin_expect
1842 (obj
!= NULL
&& ! _Jv_IsAssignableFrom(JV_CLASS (obj
), c
), false))
1843 throw new java::lang::ClassCastException
1844 ((new java::lang::StringBuffer
1845 (obj
->getClass()->getName()))->append
1846 (JvNewStringUTF(" cannot be cast to "))->append
1847 (c
->getName())->toString());
1853 _Jv_CheckArrayStore (jobject arr
, jobject obj
)
1857 JvAssert (arr
!= NULL
);
1858 jclass elt_class
= (JV_CLASS (arr
))->getComponentType();
1859 if (elt_class
== &java::lang::Object::class$
)
1861 jclass obj_class
= JV_CLASS (obj
);
1862 if (__builtin_expect
1863 (! _Jv_IsAssignableFrom (obj_class
, elt_class
), false))
1864 throw new java::lang::ArrayStoreException
1865 ((new java::lang::StringBuffer
1866 (JvNewStringUTF("Cannot store ")))->append
1867 (obj_class
->getName())->append
1868 (JvNewStringUTF(" in array of type "))->append
1869 (elt_class
->getName())->toString());
1874 _Jv_IsAssignableFromSlow (jclass source
, jclass target
)
1876 // First, strip arrays.
1877 while (target
->isArray ())
1879 // If target is array, source must be as well.
1880 if (! source
->isArray ())
1882 target
= target
->getComponentType ();
1883 source
= source
->getComponentType ();
1887 if (target
== &java::lang::Object::class$
)
1890 // Ensure that the classes have their supers installed.
1891 _Jv_Linker::wait_for_state (source
, JV_STATE_LOADING
);
1892 _Jv_Linker::wait_for_state (target
, JV_STATE_LOADING
);
1896 if (source
== target
)
1899 if (target
->isPrimitive () || source
->isPrimitive ())
1902 if (target
->isInterface ())
1904 for (int i
= 0; i
< source
->interface_count
; ++i
)
1906 // We use a recursive call because we also need to
1907 // check superinterfaces.
1908 if (_Jv_IsAssignableFromSlow (source
->getInterface (i
), target
))
1912 source
= source
->getSuperclass ();
1914 while (source
!= NULL
);
1919 // Lookup an interface method by name. This is very similar to
1920 // purpose to _getMethod, but the interfaces are quite different. It
1921 // might be a good idea for _getMethod to call this function.
1923 // Return true of the method is found, with the class in FOUND_CLASS
1924 // and the index in INDEX.
1926 _Jv_getInterfaceMethod (jclass search_class
, jclass
&found_class
, int &index
,
1927 const _Jv_Utf8Const
*utf_name
,
1928 const _Jv_Utf8Const
*utf_sig
)
1930 for (jclass klass
= search_class
; klass
; klass
= klass
->getSuperclass())
1932 // FIXME: Throw an exception?
1933 if (!klass
->isInterface ())
1936 int max
= klass
->method_count
;
1938 for (int i
= 0; i
< max
; ++i
)
1940 // Skip <clinit> here, as it will not be in the IDT.
1941 if (klass
->methods
[i
].name
->first() == '<')
1944 if (_Jv_equalUtf8Consts (klass
->methods
[i
].name
, utf_name
)
1945 && _Jv_equalUtf8Consts (klass
->methods
[i
].signature
, utf_sig
))
1948 using namespace java::lang::reflect
;
1950 // FIXME: Method must be public. Throw an exception?
1951 if (! Modifier::isPublic (klass
->methods
[i
].accflags
))
1954 found_class
= klass
;
1955 // Interface method indexes count from 1.
1964 // If we haven't found a match, and this class is an interface, then
1965 // check all the superinterfaces.
1966 if (search_class
->isInterface())
1968 for (int i
= 0; i
< search_class
->interface_count
; ++i
)
1970 using namespace java::lang::reflect
;
1971 bool found
= _Jv_getInterfaceMethod (search_class
->interfaces
[i
],
1984 _Jv_FindInterpreterMethod (jclass klass
, jmethodID desired_method
)
1986 using namespace java::lang::reflect
;
1988 _Jv_InterpClass
*iclass
1989 = reinterpret_cast<_Jv_InterpClass
*> (klass
->aux_info
);
1990 _Jv_MethodBase
**imethods
= _Jv_GetFirstMethod (iclass
);
1992 for (int i
= 0; i
< JvNumMethods (klass
); ++i
)
1994 _Jv_MethodBase
*imeth
= imethods
[i
];
1995 if (imeth
->get_method () == desired_method
)
2003 // Return Utf8 name of a class. This function is here for code that
2004 // can't access klass->name directly.
2006 _Jv_GetClassNameUtf8 (jclass klass
)
2012 _Jv_GetMethodDeclaringClass (jmethodID method
)
2014 _Jv_StackTrace::UpdateNCodeMap ();
2015 jobject obj
= reinterpret_cast<jobject
> (method
->ncode
);
2016 return reinterpret_cast<jclass
> (_Jv_StackTrace::ncodeMap
->get (obj
));
2020 _Jv_GetClassState (jclass klass
)
2022 return klass
->state
;