1 // natClass.cc - Implementation of java.lang.Class native methods.
3 /* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
16 #pragma implementation "Class.h"
20 #include <java/lang/Class.h>
21 #include <java/lang/ClassLoader.h>
22 #include <java/lang/String.h>
23 #include <java/lang/reflect/Modifier.h>
24 #include <java/lang/reflect/Member.h>
25 #include <java/lang/reflect/Method.h>
26 #include <java/lang/reflect/Field.h>
27 #include <java/lang/reflect/Constructor.h>
28 #include <java/lang/AbstractMethodError.h>
29 #include <java/lang/ClassNotFoundException.h>
30 #include <java/lang/ExceptionInInitializerError.h>
31 #include <java/lang/IllegalAccessException.h>
32 #include <java/lang/IllegalAccessError.h>
33 #include <java/lang/IncompatibleClassChangeError.h>
34 #include <java/lang/InstantiationException.h>
35 #include <java/lang/NoClassDefFoundError.h>
36 #include <java/lang/NoSuchFieldException.h>
37 #include <java/lang/NoSuchMethodException.h>
38 #include <java/lang/Thread.h>
39 #include <java/lang/NullPointerException.h>
40 #include <java/lang/System.h>
41 #include <java/lang/SecurityManager.h>
42 #include <java/lang/StringBuffer.h>
43 #include <gcj/method.h>
45 #include <java-cpool.h>
49 #define CloneableClass _CL_Q34java4lang9Cloneable
50 extern java::lang::Class CloneableClass
;
51 #define ObjectClass _CL_Q34java4lang6Object
52 extern java::lang::Class ObjectClass
;
53 #define ErrorClass _CL_Q34java4lang5Error
54 extern java::lang::Class ErrorClass
;
55 #define ClassClass _CL_Q34java4lang5Class
56 extern java::lang::Class ClassClass
;
57 #define MethodClass _CL_Q44java4lang7reflect6Method
58 extern java::lang::Class MethodClass
;
59 #define FieldClass _CL_Q44java4lang7reflect5Field
60 extern java::lang::Class FieldClass
;
61 #define ConstructorClass _CL_Q44java4lang7reflect11Constructor
62 extern java::lang::Class ConstructorClass
;
64 // Some constants we use to look up the class initializer.
65 static _Jv_Utf8Const
*void_signature
= _Jv_makeUtf8Const ("()V", 3);
66 static _Jv_Utf8Const
*clinit_name
= _Jv_makeUtf8Const ("<clinit>", 8);
67 static _Jv_Utf8Const
*init_name
= _Jv_makeUtf8Const ("<init>", 6);
68 static _Jv_Utf8Const
*finit_name
= _Jv_makeUtf8Const ("$finit$", 7);
73 java::lang::Class::forName (jstring className
)
76 JvThrow (new java::lang::NullPointerException
);
79 // FIXME: should check syntax of CLASSNAME and throw
80 // IllegalArgumentException on failure.
82 // FIXME: should use class loader from calling method.
83 jclass klass
= _Jv_FindClass (className
, NULL
);
85 jsize length
= _Jv_GetStringUTFLength (className
);
87 _Jv_GetStringUTFRegion (className
, 0, length
, buffer
);
89 // FIXME: should check syntax of CLASSNAME and throw
90 // IllegalArgumentException on failure.
91 _Jv_Utf8Const
*name
= _Jv_makeUtf8Const (buffer
, length
);
93 // FIXME: should use class loader from calling method.
94 jclass klass
= (buffer
[0] == '['
95 ? _Jv_FindClassFromSignature (name
->data
, NULL
)
96 : _Jv_FindClass (name
, NULL
));
99 JvThrow (new java::lang::ClassNotFoundException (className
));
104 java::lang::reflect::Constructor
*
105 java::lang::Class::getConstructor (JArray
<jclass
> *param_types
)
107 jstring partial_sig
= getSignature (param_types
, true);
108 jint hash
= partial_sig
->hashCode ();
110 int i
= isPrimitive () ? 0 : method_count
;
113 // FIXME: access checks.
114 if (_Jv_equalUtf8Consts (methods
[i
].name
, init_name
)
115 && _Jv_equal (methods
[i
].signature
, partial_sig
, hash
))
117 // Found it. For getConstructor, the constructor must be
119 using namespace java::lang::reflect
;
120 if (! Modifier::isPublic(methods
[i
].accflags
))
122 Constructor
*cons
= new Constructor ();
123 cons
->offset
= (char *) (&methods
[i
]) - (char *) methods
;
124 cons
->declaringClass
= this;
128 JvThrow (new java::lang::NoSuchMethodException
);
131 JArray
<java::lang::reflect::Constructor
*> *
132 java::lang::Class::_getConstructors (jboolean declared
)
134 // FIXME: this method needs access checks.
136 int numConstructors
= 0;
137 int max
= isPrimitive () ? 0 : method_count
;
139 for (i
= max
; --i
>= 0; )
141 _Jv_Method
*method
= &methods
[i
];
142 if (method
->name
== NULL
143 || ! _Jv_equalUtf8Consts (method
->name
, init_name
))
146 && ! java::lang::reflect::Modifier::isPublic(method
->accflags
))
150 JArray
<java::lang::reflect::Constructor
*> *result
151 = (JArray
<java::lang::reflect::Constructor
*> *)
152 JvNewObjectArray (numConstructors
, &ConstructorClass
, NULL
);
153 java::lang::reflect::Constructor
** cptr
= elements (result
);
154 for (i
= 0; i
< max
; i
++)
156 _Jv_Method
*method
= &methods
[i
];
157 if (method
->name
== NULL
158 || ! _Jv_equalUtf8Consts (method
->name
, init_name
))
161 && ! java::lang::reflect::Modifier::isPublic(method
->accflags
))
163 java::lang::reflect::Constructor
*cons
164 = new java::lang::reflect::Constructor ();
165 cons
->offset
= (char *) method
- (char *) methods
;
166 cons
->declaringClass
= this;
172 java::lang::reflect::Constructor
*
173 java::lang::Class::getDeclaredConstructor (JArray
<jclass
> *param_types
)
175 jstring partial_sig
= getSignature (param_types
, true);
176 jint hash
= partial_sig
->hashCode ();
178 int i
= isPrimitive () ? 0 : method_count
;
181 // FIXME: access checks.
182 if (_Jv_equalUtf8Consts (methods
[i
].name
, init_name
)
183 && _Jv_equal (methods
[i
].signature
, partial_sig
, hash
))
186 using namespace java::lang::reflect
;
187 Constructor
*cons
= new Constructor ();
188 cons
->offset
= (char *) (&methods
[i
]) - (char *) methods
;
189 cons
->declaringClass
= this;
193 JvThrow (new java::lang::NoSuchMethodException
);
196 java::lang::reflect::Field
*
197 java::lang::Class::getField (jstring name
, jint hash
)
199 java::lang::reflect::Field
* rfield
;
200 for (int i
= 0; i
< field_count
; i
++)
202 _Jv_Field
*field
= &fields
[i
];
203 if (! _Jv_equal (field
->name
, name
, hash
))
205 if (! (field
->getModifiers() & java::lang::reflect::Modifier::PUBLIC
))
207 rfield
= new java::lang::reflect::Field ();
208 rfield
->offset
= (char*) field
- (char*) fields
;
209 rfield
->declaringClass
= this;
213 jclass superclass
= getSuperclass();
214 if (superclass
== NULL
)
216 rfield
= superclass
->getField(name
, hash
);
217 for (int i
= 0; i
< interface_count
&& rfield
== NULL
; ++i
)
218 rfield
= interfaces
[i
]->getField (name
, hash
);
222 java::lang::reflect::Field
*
223 java::lang::Class::getDeclaredField (jstring name
)
225 java::lang::SecurityManager
*s
= java::lang::System::getSecurityManager();
227 s
->checkMemberAccess (this, java::lang::reflect::Member::DECLARED
);
228 int hash
= name
->hashCode();
229 for (int i
= 0; i
< field_count
; i
++)
231 _Jv_Field
*field
= &fields
[i
];
232 if (! _Jv_equal (field
->name
, name
, hash
))
234 java::lang::reflect::Field
* rfield
= new java::lang::reflect::Field ();
235 rfield
->offset
= (char*) field
- (char*) fields
;
236 rfield
->declaringClass
= this;
240 JvThrow (new java::lang::NoSuchFieldException (name
));
243 JArray
<java::lang::reflect::Field
*> *
244 java::lang::Class::getDeclaredFields (void)
246 java::lang::SecurityManager
*s
= java::lang::System::getSecurityManager();
248 s
->checkMemberAccess (this, java::lang::reflect::Member::DECLARED
);
249 JArray
<java::lang::reflect::Field
*> *result
250 = (JArray
<java::lang::reflect::Field
*> *)
251 JvNewObjectArray (field_count
, &FieldClass
, NULL
);
252 java::lang::reflect::Field
** fptr
= elements (result
);
253 for (int i
= 0; i
< field_count
; i
++)
255 _Jv_Field
*field
= &fields
[i
];
256 java::lang::reflect::Field
* rfield
= new java::lang::reflect::Field ();
257 rfield
->offset
= (char*) field
- (char*) fields
;
258 rfield
->declaringClass
= this;
265 java::lang::Class::getSignature (java::lang::StringBuffer
*buffer
)
268 buffer
->append((jchar
) method_count
);
271 jstring name
= getName();
272 if (name
->charAt(0) != '[')
273 buffer
->append((jchar
) 'L');
274 buffer
->append(name
);
275 if (name
->charAt(0) != '[')
276 buffer
->append((jchar
) ';');
280 // This doesn't have to be native. It is an implementation detail
281 // only called from the C++ code, though, so maybe this is clearer.
283 java::lang::Class::getSignature (JArray
<jclass
> *param_types
,
284 jboolean is_constructor
)
286 java::lang::StringBuffer
*buf
= new java::lang::StringBuffer ();
287 buf
->append((jchar
) '(');
288 jclass
*v
= elements (param_types
);
289 for (int i
= 0; i
< param_types
->length
; ++i
)
290 v
[i
]->getSignature(buf
);
291 buf
->append((jchar
) ')');
293 buf
->append((jchar
) 'V');
294 return buf
->toString();
297 java::lang::reflect::Method
*
298 java::lang::Class::getDeclaredMethod (jstring name
,
299 JArray
<jclass
> *param_types
)
301 jstring partial_sig
= getSignature (param_types
, false);
302 jint p_len
= partial_sig
->length();
303 _Jv_Utf8Const
*utf_name
= _Jv_makeUtf8Const (name
);
304 int i
= isPrimitive () ? 0 : method_count
;
307 // FIXME: access checks.
308 if (_Jv_equalUtf8Consts (methods
[i
].name
, utf_name
)
309 && _Jv_equaln (methods
[i
].signature
, partial_sig
, p_len
))
312 using namespace java::lang::reflect
;
313 Method
*rmethod
= new Method ();
314 rmethod
->offset
= (char*) (&methods
[i
]) - (char*) methods
;
315 rmethod
->declaringClass
= this;
319 JvThrow (new java::lang::NoSuchMethodException
);
322 JArray
<java::lang::reflect::Method
*> *
323 java::lang::Class::getDeclaredMethods (void)
326 int max
= isPrimitive () ? 0 : method_count
;
328 for (i
= max
; --i
>= 0; )
330 _Jv_Method
*method
= &methods
[i
];
331 if (method
->name
== NULL
332 || _Jv_equalUtf8Consts (method
->name
, clinit_name
)
333 || _Jv_equalUtf8Consts (method
->name
, init_name
)
334 || _Jv_equalUtf8Consts (method
->name
, finit_name
))
338 JArray
<java::lang::reflect::Method
*> *result
339 = (JArray
<java::lang::reflect::Method
*> *)
340 JvNewObjectArray (numMethods
, &MethodClass
, NULL
);
341 java::lang::reflect::Method
** mptr
= elements (result
);
342 for (i
= 0; i
< max
; i
++)
344 _Jv_Method
*method
= &methods
[i
];
345 if (method
->name
== NULL
346 || _Jv_equalUtf8Consts (method
->name
, clinit_name
)
347 || _Jv_equalUtf8Consts (method
->name
, init_name
)
348 || _Jv_equalUtf8Consts (method
->name
, finit_name
))
350 java::lang::reflect::Method
* rmethod
351 = new java::lang::reflect::Method ();
352 rmethod
->offset
= (char*) method
- (char*) methods
;
353 rmethod
->declaringClass
= this;
360 java::lang::Class::getName (void)
362 char buffer
[name
->length
+ 1];
363 memcpy (buffer
, name
->data
, name
->length
);
364 buffer
[name
->length
] = '\0';
365 return _Jv_NewStringUTF (buffer
);
369 java::lang::Class::getClasses (void)
371 // Until we have inner classes, it always makes sense to return an
373 JArray
<jclass
> *result
374 = (JArray
<jclass
> *) JvNewObjectArray (0, &ClassClass
, NULL
);
379 java::lang::Class::getDeclaredClasses (void)
381 checkMemberAccess (java::lang::reflect::Member::DECLARED
);
382 // Until we have inner classes, it always makes sense to return an
384 JArray
<jclass
> *result
385 = (JArray
<jclass
> *) JvNewObjectArray (0, &ClassClass
, NULL
);
390 java::lang::Class::getDeclaringClass (void)
392 // Until we have inner classes, it makes sense to always return
398 java::lang::Class::_getFields (JArray
<java::lang::reflect::Field
*> *result
,
402 for (int i
= 0; i
< field_count
; i
++)
404 _Jv_Field
*field
= &fields
[i
];
405 if (! (field
->getModifiers() & java::lang::reflect::Modifier::PUBLIC
))
411 java::lang::reflect::Field
*rfield
412 = new java::lang::reflect::Field ();
413 rfield
->offset
= (char *) field
- (char *) fields
;
414 rfield
->declaringClass
= this;
415 rfield
->name
= _Jv_NewStringUtf8Const (field
->name
);
416 (elements (result
))[offset
+ i
] = rfield
;
419 jclass superclass
= getSuperclass();
420 if (superclass
!= NULL
)
422 int s_count
= superclass
->_getFields (result
, offset
);
426 for (int i
= 0; i
< interface_count
; ++i
)
428 int f_count
= interfaces
[i
]->_getFields (result
, offset
);
435 JArray
<java::lang::reflect::Field
*> *
436 java::lang::Class::getFields (void)
438 using namespace java::lang::reflect
;
440 int count
= _getFields (NULL
, 0);
442 JArray
<java::lang::reflect::Field
*> *result
443 = ((JArray
<java::lang::reflect::Field
*> *)
444 JvNewObjectArray (count
, &FieldClass
, NULL
));
446 _getFields (result
, 0);
452 java::lang::Class::getInterfaces (void)
454 jobjectArray r
= JvNewObjectArray (interface_count
, getClass (), NULL
);
455 jobject
*data
= elements (r
);
456 for (int i
= 0; i
< interface_count
; ++i
)
457 data
[i
] = interfaces
[i
];
458 return reinterpret_cast<JArray
<jclass
> *> (r
);
461 java::lang::reflect::Method
*
462 java::lang::Class::getMethod (jstring name
, JArray
<jclass
> *param_types
)
464 jstring partial_sig
= getSignature (param_types
, false);
465 jint p_len
= partial_sig
->length();
466 _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 // FIXME: access checks.
473 if (_Jv_equalUtf8Consts (klass
->methods
[i
].name
, utf_name
)
474 && _Jv_equaln (klass
->methods
[i
].signature
, partial_sig
, p_len
))
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
;
491 JvThrow (new java::lang::NoSuchMethodException
);
494 // This is a very slow implementation, since it re-scans all the
495 // methods we've already listed to make sure we haven't duplicated a
496 // method. It also over-estimates the required size, so we have to
497 // shrink the result array later.
499 java::lang::Class::_getMethods (JArray
<java::lang::reflect::Method
*> *result
,
504 // First examine all local methods
505 for (int i
= isPrimitive () ? 0 : method_count
; --i
>= 0; )
507 _Jv_Method
*method
= &methods
[i
];
508 if (method
->name
== NULL
509 || _Jv_equalUtf8Consts (method
->name
, clinit_name
)
510 || _Jv_equalUtf8Consts (method
->name
, init_name
)
511 || _Jv_equalUtf8Consts (method
->name
, finit_name
))
513 // Only want public methods.
514 if (! java::lang::reflect::Modifier::isPublic (method
->accflags
))
517 // This is where we over-count the slots required if we aren't
518 // filling the result for real.
522 java::lang::reflect::Method
**mp
= elements (result
);
523 // If we already have a method with this name and signature,
524 // then ignore this one. This can happen with virtual
526 for (int j
= 0; j
< offset
; ++j
)
528 _Jv_Method
*meth_2
= _Jv_FromReflectedMethod (mp
[j
]);
529 if (_Jv_equalUtf8Consts (method
->name
, meth_2
->name
)
530 && _Jv_equalUtf8Consts (method
->signature
,
543 using namespace java::lang::reflect
;
544 Method
*rmethod
= new Method ();
545 rmethod
->offset
= (char *) method
- (char *) methods
;
546 rmethod
->declaringClass
= this;
547 Method
**mp
= elements (result
);
548 mp
[offset
+ count
] = rmethod
;
554 // Now examine superclasses.
555 if (getSuperclass () != NULL
)
557 jint s_count
= getSuperclass()->_getMethods (result
, offset
);
562 // Finally, examine interfaces.
563 for (int i
= 0; i
< interface_count
; ++i
)
565 int f_count
= interfaces
[i
]->_getMethods (result
, offset
);
573 JArray
<java::lang::reflect::Method
*> *
574 java::lang::Class::getMethods (void)
576 using namespace java::lang::reflect
;
578 // FIXME: security checks.
580 // This will overestimate the size we need.
581 jint count
= _getMethods (NULL
, 0);
583 JArray
<Method
*> *result
584 = ((JArray
<Method
*> *) JvNewObjectArray (count
, &MethodClass
, NULL
));
586 // When filling the array for real, we get the actual count. Then
587 // we resize the array.
588 jint real_count
= _getMethods (result
, 0);
590 if (real_count
!= count
)
593 = ((JArray
<Method
*> *) JvNewObjectArray (real_count
, &MethodClass
,
596 Method
**destp
= elements (r2
);
597 Method
**srcp
= elements (result
);
599 for (int i
= 0; i
< real_count
; ++i
)
609 java::lang::Class::isAssignableFrom (jclass klass
)
613 // Primitive types must be equal, which we just tested for.
614 if (isPrimitive () || ! klass
|| klass
->isPrimitive())
617 // If target is array, so must source be.
620 if (! klass
->isArray())
622 return getComponentType()->isAssignableFrom(klass
->getComponentType());
625 if (isAssignableFrom (klass
->getSuperclass()))
630 // See if source implements this interface.
631 for (int i
= 0; i
< klass
->interface_count
; ++i
)
633 jclass interface
= klass
->interfaces
[i
];
634 // FIXME: ensure that class is prepared here.
636 if (isAssignableFrom (interface
))
645 java::lang::Class::isInstance (jobject obj
)
647 if (! obj
|| isPrimitive ())
649 return isAssignableFrom (obj
->getClass());
653 java::lang::Class::isInterface (void)
655 return (accflags
& java::lang::reflect::Modifier::INTERFACE
) != 0;
659 java::lang::Class::newInstance (void)
661 // FIXME: do accessibility checks here. There currently doesn't
662 // seem to be any way to do these.
663 // FIXME: we special-case one check here just to pass a Plum Hall
664 // test. Once access checking is implemented, remove this.
665 if (this == &ClassClass
)
666 JvThrow (new java::lang::IllegalAccessException
);
671 || java::lang::reflect::Modifier::isAbstract(accflags
))
672 JvThrow (new java::lang::InstantiationException
);
674 _Jv_InitClass (this);
676 _Jv_Method
*meth
= _Jv_GetMethodLocal (this, init_name
, void_signature
);
678 JvThrow (new java::lang::NoSuchMethodException
);
680 jobject r
= JvAllocObject (this);
681 ((void (*) (jobject
)) meth
->ncode
) (r
);
686 java::lang::Class::finalize (void)
689 JvAssert (_Jv_IsInterpretedClass (this));
690 _Jv_UnregisterClass (this);
694 // This implements the initialization process for a class. From Spec
697 java::lang::Class::initializeClass (void)
699 // Short-circuit to avoid needless locking.
700 if (state
== JV_STATE_DONE
)
703 // do this before we enter the monitor below, since this can cause
704 // exceptions. Here we assume, that reading "state" is an atomic
705 // operation, I pressume that is true? --Kresten
706 if (state
< JV_STATE_LINKED
)
709 if (_Jv_IsInterpretedClass (this))
711 java::lang::ClassLoader::resolveClass0 (this);
714 _Jv_MonitorEnter (this);
720 _Jv_MonitorEnter (this);
721 _Jv_PrepareCompiledClass (this);
727 _Jv_MonitorEnter (this);
731 java::lang::Thread
*self
= java::lang::Thread::currentThread();
732 // FIXME: `self' can be null at startup. Hence this nasty trick.
733 self
= (java::lang::Thread
*) ((long) self
| 1);
734 while (state
== JV_STATE_IN_PROGRESS
&& thread
&& thread
!= self
)
738 if (state
== JV_STATE_DONE
|| state
== JV_STATE_IN_PROGRESS
|| thread
== self
)
740 _Jv_MonitorExit (this);
745 if (state
== JV_STATE_ERROR
)
747 _Jv_MonitorExit (this);
748 JvThrow (new java::lang::NoClassDefFoundError
);
753 state
= JV_STATE_IN_PROGRESS
;
754 _Jv_MonitorExit (this);
757 if (! isInterface () && superclass
)
761 superclass
->initializeClass ();
763 catch (java::lang::Throwable
*except
)
765 // Caught an exception.
766 _Jv_MonitorEnter (this);
767 state
= JV_STATE_ERROR
;
769 _Jv_MonitorExit (this);
774 // Steps 8, 9, 10, 11.
777 _Jv_Method
*meth
= _Jv_GetMethodLocal (this, clinit_name
,
780 ((void (*) (void)) meth
->ncode
) ();
782 catch (java::lang::Throwable
*except
)
784 if (! ErrorClass
.isInstance(except
))
788 except
= new ExceptionInInitializerError (except
);
790 catch (java::lang::Throwable
*t
)
795 _Jv_MonitorEnter (this);
796 state
= JV_STATE_ERROR
;
798 _Jv_MonitorExit (this);
802 _Jv_MonitorEnter (this);
803 state
= JV_STATE_DONE
;
805 _Jv_MonitorExit (this);
811 // Some class-related convenience functions.
814 // Find a method declared in the class. If it is not declared locally
815 // (or if it is inherited), return NULL.
817 _Jv_GetMethodLocal (jclass klass
, _Jv_Utf8Const
*name
,
818 _Jv_Utf8Const
*signature
)
820 for (int i
= 0; i
< klass
->method_count
; ++i
)
822 if (_Jv_equalUtf8Consts (name
, klass
->methods
[i
].name
)
823 && _Jv_equalUtf8Consts (signature
, klass
->methods
[i
].signature
))
824 return &klass
->methods
[i
];
830 _Jv_LookupDeclaredMethod (jclass klass
, _Jv_Utf8Const
*name
,
831 _Jv_Utf8Const
*signature
)
833 for (; klass
; klass
= klass
->getSuperclass())
835 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
844 // NOTE: MCACHE_SIZE should be a power of 2 minus one.
845 #define MCACHE_SIZE 1023
853 static _Jv_mcache method_cache
[MCACHE_SIZE
+ 1];
856 _Jv_FindMethodInCache (jclass klass
,
858 _Jv_Utf8Const
*signature
)
860 int index
= name
->hash
& MCACHE_SIZE
;
861 _Jv_mcache
*mc
= method_cache
+ index
;
862 _Jv_Method
*m
= mc
->method
;
864 if (mc
->klass
== klass
865 && m
!= NULL
// thread safe check
866 && _Jv_equalUtf8Consts (m
->name
, name
)
867 && _Jv_equalUtf8Consts (m
->signature
, signature
))
868 return mc
->method
->ncode
;
873 _Jv_AddMethodToCache (jclass klass
,
876 _Jv_MonitorEnter (&ClassClass
);
878 int index
= method
->name
->hash
& MCACHE_SIZE
;
880 method_cache
[index
].method
= method
;
881 method_cache
[index
].klass
= klass
;
883 _Jv_MonitorExit (&ClassClass
);
887 _Jv_LookupInterfaceMethod (jclass klass
, _Jv_Utf8Const
*name
,
888 _Jv_Utf8Const
*signature
)
890 void *ncode
= _Jv_FindMethodInCache (klass
, name
, signature
);
894 for (; klass
; klass
= klass
->getSuperclass())
896 _Jv_Method
*meth
= _Jv_GetMethodLocal (klass
, name
, signature
);
900 if (java::lang::reflect::Modifier::isStatic(meth
->accflags
))
901 JvThrow (new java::lang::IncompatibleClassChangeError
);
902 if (java::lang::reflect::Modifier::isAbstract(meth
->accflags
))
903 JvThrow (new java::lang::AbstractMethodError
);
904 if (! java::lang::reflect::Modifier::isPublic(meth
->accflags
))
905 JvThrow (new java::lang::IllegalAccessError
);
907 _Jv_AddMethodToCache (klass
, meth
);
911 JvThrow (new java::lang::IncompatibleClassChangeError
);
912 return NULL
; // Placate compiler.
916 _Jv_InitClass (jclass klass
)
918 klass
->initializeClass();
922 _Jv_IsInstanceOf(jobject obj
, jclass cl
)
924 return cl
->isInstance(obj
);