📄 natclass.cc
字号:
// natClass.cc - Implementation of java.lang.Class native methods./* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation This file is part of libgcj.This software is copyrighted work licensed under the terms of theLibgcj License. Please consult the file "LIBGCJ_LICENSE" fordetails. */#include <config.h>#include <limits.h>#include <string.h>#include <stddef.h>#include <stdio.h>#pragma implementation "Class.h"#include <gcj/cni.h>#include <jvm.h>#include <java-threads.h>#include <java/lang/Class.h>#include <java/lang/ClassLoader.h>#include <java/lang/String.h>#include <java/lang/reflect/Modifier.h>#include <java/lang/reflect/Member.h>#include <java/lang/reflect/Method.h>#include <java/lang/reflect/Field.h>#include <java/lang/reflect/Constructor.h>#include <java/lang/AbstractMethodError.h>#include <java/lang/ArrayStoreException.h>#include <java/lang/ClassCastException.h>#include <java/lang/ClassNotFoundException.h>#include <java/lang/ExceptionInInitializerError.h>#include <java/lang/IllegalAccessException.h>#include <java/lang/IllegalAccessError.h>#include <java/lang/IllegalArgumentException.h>#include <java/lang/IncompatibleClassChangeError.h>#include <java/lang/NoSuchFieldError.h>#include <java/lang/ArrayIndexOutOfBoundsException.h>#include <java/lang/InstantiationException.h>#include <java/lang/NoClassDefFoundError.h>#include <java/lang/NoSuchFieldException.h>#include <java/lang/NoSuchMethodError.h>#include <java/lang/NoSuchMethodException.h>#include <java/lang/Thread.h>#include <java/lang/NullPointerException.h>#include <java/lang/RuntimePermission.h>#include <java/lang/System.h>#include <java/lang/SecurityManager.h>#include <java/lang/StringBuffer.h>#include <java/lang/VMClassLoader.h>#include <gcj/method.h>#include <gnu/gcj/RawData.h>#include <java/lang/VerifyError.h>#include <java-cpool.h>#include <java-interp.h>#include <java-assert.h>#include <java-stack.h>#include <execution.h>using namespace gcj;jclassjava::lang::Class::forName (jstring className, jboolean initialize, java::lang::ClassLoader *loader){ if (! className) throw new java::lang::NullPointerException; jsize length = _Jv_GetStringUTFLength (className); char buffer[length]; _Jv_GetStringUTFRegion (className, 0, className->length(), buffer); _Jv_Utf8Const *name = _Jv_makeUtf8Const (buffer, length); if (! _Jv_VerifyClassName (name)) throw new java::lang::ClassNotFoundException (className); jclass klass = (buffer[0] == '[' ? _Jv_FindClassFromSignature (name->chars(), loader) : _Jv_FindClass (name, loader)); if (klass == NULL) throw new java::lang::ClassNotFoundException (className); if (initialize) _Jv_InitClass (klass); return klass;}jclassjava::lang::Class::forName (jstring className){ java::lang::ClassLoader *loader = NULL; jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$); if (caller) loader = caller->getClassLoaderInternal(); return forName (className, true, loader);}java::lang::ClassLoader *java::lang::Class::getClassLoader (void){ java::lang::SecurityManager *s = java::lang::System::getSecurityManager(); if (s != NULL) { jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$); ClassLoader *caller_loader = NULL; if (caller) caller_loader = caller->getClassLoaderInternal(); // If the caller has a non-null class loader, and that loader // is not this class' loader or an ancestor thereof, then do a // security check. if (caller_loader != NULL && ! caller_loader->isAncestorOf(loader)) s->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader"))); } return loader;}java::lang::reflect::Constructor *java::lang::Class::getConstructor (JArray<jclass> *param_types){ memberAccessCheck(java::lang::reflect::Member::PUBLIC); jstring partial_sig = getSignature (param_types, true); jint hash = partial_sig->hashCode (); int i = isPrimitive () ? 0 : method_count; while (--i >= 0) { if (_Jv_equalUtf8Consts (methods[i].name, init_name) && _Jv_equal (methods[i].signature, partial_sig, hash)) { // Found it. For getConstructor, the constructor must be // public. using namespace java::lang::reflect; if (! Modifier::isPublic(methods[i].accflags)) break; Constructor *cons = new Constructor (); cons->offset = (char *) (&methods[i]) - (char *) methods; cons->declaringClass = this; return cons; } } throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name));}JArray<java::lang::reflect::Constructor *> *java::lang::Class::getDeclaredConstructors (jboolean publicOnly){ int numConstructors = 0; int max = isPrimitive () ? 0 : method_count; int i; for (i = max; --i >= 0; ) { _Jv_Method *method = &methods[i]; if (method->name == NULL || ! _Jv_equalUtf8Consts (method->name, init_name)) continue; if (publicOnly && ! java::lang::reflect::Modifier::isPublic(method->accflags)) continue; numConstructors++; } JArray<java::lang::reflect::Constructor *> *result = (JArray<java::lang::reflect::Constructor *> *) JvNewObjectArray (numConstructors, &java::lang::reflect::Constructor::class$, NULL); java::lang::reflect::Constructor** cptr = elements (result); for (i = 0; i < max; i++) { _Jv_Method *method = &methods[i]; if (method->name == NULL || ! _Jv_equalUtf8Consts (method->name, init_name)) continue; if (publicOnly && ! java::lang::reflect::Modifier::isPublic(method->accflags)) continue; java::lang::reflect::Constructor *cons = new java::lang::reflect::Constructor (); cons->offset = (char *) method - (char *) methods; cons->declaringClass = this; *cptr++ = cons; } return result;}java::lang::reflect::Constructor *java::lang::Class::getDeclaredConstructor (JArray<jclass> *param_types){ memberAccessCheck(java::lang::reflect::Member::DECLARED); jstring partial_sig = getSignature (param_types, true); jint hash = partial_sig->hashCode (); int i = isPrimitive () ? 0 : method_count; while (--i >= 0) { if (_Jv_equalUtf8Consts (methods[i].name, init_name) && _Jv_equal (methods[i].signature, partial_sig, hash)) { // Found it. using namespace java::lang::reflect; Constructor *cons = new Constructor (); cons->offset = (char *) (&methods[i]) - (char *) methods; cons->declaringClass = this; return cons; } } throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name));}java::lang::reflect::Field *java::lang::Class::getField (jstring name, jint hash){ java::lang::reflect::Field* rfield; for (int i = 0; i < field_count; i++) { _Jv_Field *field = &fields[i]; if (! _Jv_equal (field->name, name, hash)) continue; if (! (field->getModifiers() & java::lang::reflect::Modifier::PUBLIC)) continue; rfield = new java::lang::reflect::Field (); rfield->offset = (char*) field - (char*) fields; rfield->declaringClass = this; rfield->name = name; return rfield; } jclass superclass = getSuperclass(); if (superclass == NULL) return NULL; rfield = superclass->getField(name, hash); for (int i = 0; i < interface_count && rfield == NULL; ++i) rfield = interfaces[i]->getField (name, hash); return rfield;}java::lang::reflect::Field *java::lang::Class::getDeclaredField (jstring name){ memberAccessCheck(java::lang::reflect::Member::DECLARED); int hash = name->hashCode(); for (int i = 0; i < field_count; i++) { _Jv_Field *field = &fields[i]; if (! _Jv_equal (field->name, name, hash)) continue; java::lang::reflect::Field* rfield = new java::lang::reflect::Field (); rfield->offset = (char*) field - (char*) fields; rfield->declaringClass = this; rfield->name = name; return rfield; } throw new java::lang::NoSuchFieldException (name);}JArray<java::lang::reflect::Field *> *java::lang::Class::getDeclaredFields (jboolean public_only){ int size; if (public_only) { size = 0; for (int i = 0; i < field_count; ++i) { _Jv_Field *field = &fields[i]; if ((field->flags & java::lang::reflect::Modifier::PUBLIC)) ++size; } } else size = field_count; JArray<java::lang::reflect::Field *> *result = (JArray<java::lang::reflect::Field *> *) JvNewObjectArray (size, &java::lang::reflect::Field::class$, NULL); java::lang::reflect::Field** fptr = elements (result); for (int i = 0; i < field_count; i++) { _Jv_Field *field = &fields[i]; if (public_only && ! (field->flags & java::lang::reflect::Modifier::PUBLIC)) continue; java::lang::reflect::Field* rfield = new java::lang::reflect::Field (); rfield->offset = (char*) field - (char*) fields; rfield->declaringClass = this; *fptr++ = rfield; } return result;}voidjava::lang::Class::getSignature (java::lang::StringBuffer *buffer){ if (isPrimitive()) buffer->append((jchar) method_count); else { jstring name = getName(); if (name->charAt(0) != '[') buffer->append((jchar) 'L'); buffer->append(name); if (name->charAt(0) != '[') buffer->append((jchar) ';'); }}// This doesn't have to be native. It is an implementation detail// only called from the C++ code, though, so maybe this is clearer.jstringjava::lang::Class::getSignature (JArray<jclass> *param_types, jboolean is_constructor){ java::lang::StringBuffer *buf = new java::lang::StringBuffer (); buf->append((jchar) '('); // A NULL param_types means "no parameters". if (param_types != NULL) { jclass *v = elements (param_types); for (int i = 0; i < param_types->length; ++i) v[i]->getSignature(buf); } buf->append((jchar) ')'); if (is_constructor) buf->append((jchar) 'V'); return buf->toString();}java::lang::reflect::Method *java::lang::Class::_getDeclaredMethod (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); int i = isPrimitive () ? 0 : method_count; while (--i >= 0) { if (_Jv_equalUtf8Consts (methods[i].name, utf_name) && _Jv_equaln (methods[i].signature, partial_sig, p_len) && (methods[i].accflags & java::lang::reflect::Modifier::INVISIBLE) == 0) { // Found it. using namespace java::lang::reflect; Method *rmethod = new Method (); rmethod->offset = (char*) (&methods[i]) - (char*) methods; rmethod->declaringClass = this; return rmethod; } } return NULL;}JArray<java::lang::reflect::Method *> *java::lang::Class::getDeclaredMethods (void){ memberAccessCheck(java::lang::reflect::Member::DECLARED); int numMethods = 0; int max = isPrimitive () ? 0 : method_count; int i; for (i = max; --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) || (methods[i].accflags & java::lang::reflect::Modifier::INVISIBLE) != 0) continue; numMethods++; } JArray<java::lang::reflect::Method *> *result = (JArray<java::lang::reflect::Method *> *) JvNewObjectArray (numMethods, &java::lang::reflect::Method::class$, NULL); java::lang::reflect::Method** mptr = elements (result); for (i = 0; i < max; i++) { _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) || (methods[i].accflags & java::lang::reflect::Modifier::INVISIBLE) != 0) continue; java::lang::reflect::Method* rmethod = new java::lang::reflect::Method (); rmethod->offset = (char*) method - (char*) methods; rmethod->declaringClass = this; *mptr++ = rmethod; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -