📄 natclass.cc
字号:
}jclassjava::lang::Class::getDeclaringClass (void){ // Until we have inner classes, it makes sense to always return // NULL. return NULL;}jintjava::lang::Class::_getFields (JArray<java::lang::reflect::Field *> *result, jint offset){ int count = 0; for (int i = 0; i < field_count; i++) { _Jv_Field *field = &fields[i]; if (! (field->getModifiers() & java::lang::reflect::Modifier::PUBLIC)) continue; ++count; if (result != NULL) { java::lang::reflect::Field *rfield = new java::lang::reflect::Field (); rfield->offset = (char *) field - (char *) fields; rfield->declaringClass = this; rfield->name = _Jv_NewStringUtf8Const (field->name); (elements (result))[offset++] = rfield; } } jclass superclass = getSuperclass(); if (superclass != NULL) { int s_count = superclass->_getFields (result, offset); count += s_count; offset += s_count; } for (int i = 0; i < interface_count; ++i) { int f_count = interfaces[i]->_getFields (result, offset); count += f_count; offset += f_count; } return count;}JArray<java::lang::reflect::Field *> *java::lang::Class::getFields (void){ // FIXME: security checking. using namespace java::lang::reflect; int count = _getFields (NULL, 0); JArray<java::lang::reflect::Field *> *result = ((JArray<java::lang::reflect::Field *> *) JvNewObjectArray (count, &java::lang::reflect::Field::class$, NULL)); _getFields (result, 0); return result;}JArray<jclass> *java::lang::Class::getInterfaces (void){ jobjectArray r = JvNewObjectArray (interface_count, getClass (), NULL); jobject *data = elements (r); for (int i = 0; i < interface_count; ++i) data[i] = interfaces[i]; return reinterpret_cast<JArray<jclass> *> (r);}java::lang::reflect::Method *java::lang::Class::_getMethod (jstring name, JArray<jclass> *param_types){ jstring partial_sig = getSignature (param_types, false); jint p_len = partial_sig->length(); _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name); for (Class *klass = this; klass; klass = klass->getSuperclass()) { int i = klass->isPrimitive () ? 0 : klass->method_count; while (--i >= 0) { // FIXME: access checks. if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name) && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len) && (klass->methods[i].accflags & java::lang::reflect::Modifier::INVISIBLE) == 0) { // Found it. using namespace java::lang::reflect; // Method must be public. if (! Modifier::isPublic (klass->methods[i].accflags)) break; Method *rmethod = new Method (); rmethod->offset = ((char *) (&klass->methods[i]) - (char *) klass->methods); rmethod->declaringClass = klass; return rmethod; } } } // If we haven't found a match, and this class is an interface, then // check all the superinterfaces. if (isInterface()) { for (int i = 0; i < interface_count; ++i) { using namespace java::lang::reflect; Method *rmethod = interfaces[i]->_getMethod (name, param_types); if (rmethod != NULL) return rmethod; } } return NULL;}// This is a very slow implementation, since it re-scans all the// methods we've already listed to make sure we haven't duplicated a// method. It also over-estimates the required size, so we have to// shrink the result array later.jintjava::lang::Class::_getMethods (JArray<java::lang::reflect::Method *> *result, jint offset){ jint count = 0; // First examine all local methods for (int i = isPrimitive () ? 0 : method_count; --i >= 0; ) { _Jv_Method *method = &methods[i]; if (method->name == NULL || _Jv_equalUtf8Consts (method->name, clinit_name) || _Jv_equalUtf8Consts (method->name, init_name) || _Jv_equalUtf8Consts (method->name, finit_name) || (method->accflags & java::lang::reflect::Modifier::INVISIBLE) != 0) continue; // Only want public methods. if (! java::lang::reflect::Modifier::isPublic (method->accflags)) continue; // This is where we over-count the slots required if we aren't // filling the result for real. if (result != NULL) { jboolean add = true; java::lang::reflect::Method **mp = elements (result); // If we already have a method with this name and signature, // then ignore this one. This can happen with virtual // methods. for (int j = 0; j < offset; ++j) { _Jv_Method *meth_2 = _Jv_FromReflectedMethod (mp[j]); if (_Jv_equalUtf8Consts (method->name, meth_2->name) && _Jv_equalUtf8Consts (method->signature, meth_2->signature)) { add = false; break; } } if (! add) continue; } if (result != NULL) { using namespace java::lang::reflect; Method *rmethod = new Method (); rmethod->offset = (char *) method - (char *) methods; rmethod->declaringClass = this; Method **mp = elements (result); mp[offset + count] = rmethod; } ++count; } offset += count; // Now examine superclasses. if (getSuperclass () != NULL) { jint s_count = getSuperclass()->_getMethods (result, offset); offset += s_count; count += s_count; } // Finally, examine interfaces. for (int i = 0; i < interface_count; ++i) { int f_count = interfaces[i]->_getMethods (result, offset); count += f_count; offset += f_count; } return count;}JArray<java::lang::reflect::Method *> *java::lang::Class::getMethods (void){ using namespace java::lang::reflect; // FIXME: security checks. // This will overestimate the size we need. jint count = _getMethods (NULL, 0); JArray<Method *> *result = ((JArray<Method *> *) JvNewObjectArray (count, &Method::class$, NULL)); // When filling the array for real, we get the actual count. Then // we resize the array. jint real_count = _getMethods (result, 0); if (real_count != count) { JArray<Method *> *r2 = ((JArray<Method *> *) JvNewObjectArray (real_count, &Method::class$, NULL)); Method **destp = elements (r2); Method **srcp = elements (result); for (int i = 0; i < real_count; ++i) *destp++ = *srcp++; result = r2; } return result;}jbooleanjava::lang::Class::isAssignableFrom (jclass klass){ // Arguments may not have been initialized, given ".class" syntax. _Jv_InitClass (this); _Jv_InitClass (klass); return _Jv_IsAssignableFrom (this, klass);}jbooleanjava::lang::Class::isInstance (jobject obj){ if (! obj) return false; _Jv_InitClass (this); return _Jv_IsAssignableFrom (this, JV_CLASS (obj));}jobjectjava::lang::Class::newInstance (void){ // FIXME: do accessibility checks here. There currently doesn't // seem to be any way to do these. // FIXME: we special-case one check here just to pass a Plum Hall // test. Once access checking is implemented, remove this. if (this == &java::lang::Class::class$) throw new java::lang::IllegalAccessException; if (isPrimitive () || isInterface () || isArray () || java::lang::reflect::Modifier::isAbstract(accflags)) throw new java::lang::InstantiationException; _Jv_InitClass (this); _Jv_Method *meth = _Jv_GetMethodLocal (this, init_name, void_signature); if (! meth) throw new java::lang::NoSuchMethodException; jobject r = JvAllocObject (this); ((void (*) (jobject)) meth->ncode) (r); return r;}voidjava::lang::Class::finalize (void){#ifdef INTERPRETER JvAssert (_Jv_IsInterpretedClass (this)); _Jv_UnregisterClass (this);#endif}// This implements the initialization process for a class. From Spec// section 12.4.2.voidjava::lang::Class::initializeClass (void){ // short-circuit to avoid needless locking. if (state == JV_STATE_DONE) return; // Step 1. _Jv_MonitorEnter (this); if (state < JV_STATE_LINKED) { #ifdef INTERPRETER if (_Jv_IsInterpretedClass (this)) { // this can throw exceptions, so exit the monitor as a precaution. _Jv_MonitorExit (this); java::lang::ClassLoader::resolveClass0 (this); _Jv_MonitorEnter (this); } else#endif { _Jv_PrepareCompiledClass (this); } } if (state <= JV_STATE_LINKED) _Jv_PrepareConstantTimeTables (this); // Step 2. java::lang::Thread *self = java::lang::Thread::currentThread(); // FIXME: `self' can be null at startup. Hence this nasty trick. self = (java::lang::Thread *) ((long) self | 1); while (state == JV_STATE_IN_PROGRESS && thread && thread != self) wait (); // Steps 3 & 4. if (state == JV_STATE_DONE || state == JV_STATE_IN_PROGRESS) { _Jv_MonitorExit (this); return; } // Step 5. if (state == JV_STATE_ERROR) { _Jv_MonitorExit (this); throw new java::lang::NoClassDefFoundError (getName()); } // Step 6. thread = self; state = JV_STATE_IN_PROGRESS; _Jv_MonitorExit (this); // Step 7. if (! isInterface () && superclass) { try { _Jv_InitClass (superclass); } catch (java::lang::Throwable *except) { // Caught an exception. _Jv_MonitorEnter (this); state = JV_STATE_ERROR; notifyAll (); _Jv_MonitorExit (this); throw except; } } // Steps 8, 9, 10, 11. try { _Jv_Method *meth = _Jv_GetMethodLocal (this, clinit_name, void_signature); if (meth) ((void (*) (void)) meth->ncode) (); } catch (java::lang::Throwable *except) { if (! java::lang::Error::class$.isInstance(except)) { try { except = new ExceptionInInitializerError (except); } catch (java::lang::Throwable *t) { except = t; } } _Jv_MonitorEnter (this); state = JV_STATE_ERROR; notifyAll (); _Jv_MonitorExit (this); throw except; } _Jv_MonitorEnter (this); state = JV_STATE_DONE; notifyAll (); _Jv_MonitorExit (this);}//// Some class-related convenience functions.//// Find a method declared in the class. If it is not declared locally// (or if it is inherited), return NULL._Jv_Method *_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name, _Jv_Utf8Const *signature){ for (int i = 0; i < klass->method_count; ++i) { if (_Jv_equalUtf8Consts (name, klass->methods[i].name) && _Jv_equalUtf8Consts (signature, klass->methods[i].signature)) return &klass->methods[i]; } return NULL;}_Jv_Method *_Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name, _Jv_Utf8Const *signature){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -