📄 natclass.cc
字号:
} } throw new java::lang::NoSuchMethodException (name);}// Private accessor method for Java code to retrieve the protection domain.java::security::ProtectionDomain *java::lang::Class::getProtectionDomain0 (){ return protectionDomain;}JArray<jobject> *java::lang::Class::getSigners(){ return hack_signers;}voidjava::lang::Class::setSigners(JArray<jobject> *s){ hack_signers = s;}//// 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, jclass *declarer_result){ for (; klass; klass = klass->getSuperclass()) { _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature); if (meth) { if (declarer_result) *declarer_result = klass; return meth; } } return NULL;}#ifdef HAVE_TLS// NOTE: MCACHE_SIZE should be a power of 2 minus one.#define MCACHE_SIZE 31struct _Jv_mcache{ jclass klass; _Jv_Method *method;};static __thread _Jv_mcache *method_cache;#endif // HAVE_TLSstatic void *_Jv_FindMethodInCache (jclass klass, _Jv_Utf8Const *name, _Jv_Utf8Const *signature){#ifdef HAVE_TLS _Jv_mcache *cache = method_cache; if (cache) { int index = name->hash16 () & MCACHE_SIZE; _Jv_mcache *mc = &cache[index]; _Jv_Method *m = mc->method; if (mc->klass == klass && _Jv_equalUtf8Consts (m->name, name) && _Jv_equalUtf8Consts (m->signature, signature)) return mc->method->ncode; }#endif // HAVE_TLS return NULL;}static void_Jv_AddMethodToCache (jclass klass, _Jv_Method *method){#ifdef HAVE_TLS if (method_cache == NULL) method_cache = (_Jv_mcache *) _Jv_MallocUnchecked((MCACHE_SIZE + 1) * sizeof (_Jv_mcache)); // If the allocation failed, just keep going. if (method_cache != NULL) { int index = method->name->hash16 () & MCACHE_SIZE; method_cache[index].method = method; method_cache[index].klass = klass; }#endif // HAVE_TLS}// Free this thread's method cache. We explicitly manage this memory// as the GC does not yet know how to scan TLS on all platforms.void_Jv_FreeMethodCache (){#ifdef HAVE_TLS if (method_cache != NULL) { _Jv_Free(method_cache); method_cache = NULL; }#endif // HAVE_TLS}void *_Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name, _Jv_Utf8Const *signature){ using namespace java::lang::reflect; void *ncode = _Jv_FindMethodInCache (klass, name, signature); if (ncode != 0) return ncode; for (; klass; klass = klass->getSuperclass()) { _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature); if (! meth) continue; if (Modifier::isStatic(meth->accflags)) throw new java::lang::IncompatibleClassChangeError (_Jv_GetMethodString (klass, meth)); if (Modifier::isAbstract(meth->accflags)) throw new java::lang::AbstractMethodError (_Jv_GetMethodString (klass, meth)); if (! Modifier::isPublic(meth->accflags)) throw new java::lang::IllegalAccessError (_Jv_GetMethodString (klass, meth)); _Jv_AddMethodToCache (klass, meth); return meth->ncode; } throw new java::lang::IncompatibleClassChangeError;}// Fast interface method lookup by index.void *_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface, int method_idx){ _Jv_IDispatchTable *cldt = klass->idt; int idx = iface->idt->iface.ioffsets[cldt->cls.iindex] + method_idx; return cldt->cls.itable[idx];}jboolean_Jv_IsAssignableFrom (jclass source, jclass target){ if (source == target) return true; // If target is array, so must source be. while (target->isArray ()) { if (! source->isArray()) return false; target = target->getComponentType(); source = source->getComponentType(); } if (target->isInterface()) { // Abstract classes have no IDT, and IDTs provide no way to check // two interfaces for assignability. if (__builtin_expect (source->idt == NULL || source->isInterface(), false)) return _Jv_InterfaceAssignableFrom (source, target); _Jv_IDispatchTable *cl_idt = source->idt; _Jv_IDispatchTable *if_idt = target->idt; if (__builtin_expect ((if_idt == NULL), false)) return false; // No class implementing TARGET has been loaded. jshort cl_iindex = cl_idt->cls.iindex; if (cl_iindex < if_idt->iface.ioffsets[0]) { jshort offset = if_idt->iface.ioffsets[cl_iindex]; if (offset != -1 && offset < cl_idt->cls.itable_length && cl_idt->cls.itable[offset] == target) return true; } return false; } // Primitive TYPE classes are only assignable to themselves. if (__builtin_expect (target->isPrimitive() || source->isPrimitive(), false)) return false; if (target == &java::lang::Object::class$) return true; else if (source->ancestors == NULL || target->ancestors == NULL) { // We need this case when either SOURCE or TARGET has not has // its constant-time tables prepared. // At this point we know that TARGET can't be Object, so it is // safe to use that as the termination point. while (source && source != &java::lang::Object::class$) { if (source == target) return true; source = source->getSuperclass(); } } else if (source->depth >= target->depth && source->ancestors[source->depth - target->depth] == target) return true; return false;}// Interface type checking, the slow way. Returns TRUE if IFACE is a // superinterface of SOURCE. This is used when SOURCE is also an interface,// or a class with no interface dispatch table.jboolean_Jv_InterfaceAssignableFrom (jclass source, jclass iface){ for (int i = 0; i < source->interface_count; i++) { jclass interface = source->interfaces[i]; if (iface == interface || _Jv_InterfaceAssignableFrom (interface, iface)) return true; } if (!source->isInterface() && source->superclass && _Jv_InterfaceAssignableFrom (source->superclass, iface)) return true; return false;}jboolean_Jv_IsInstanceOf(jobject obj, jclass cl){ if (__builtin_expect (!obj, false)) return false; return _Jv_IsAssignableFrom (JV_CLASS (obj), cl);}void *_Jv_CheckCast (jclass c, jobject obj){ if (__builtin_expect (obj != NULL && ! _Jv_IsAssignableFrom(JV_CLASS (obj), c), false)) throw new java::lang::ClassCastException ((new java::lang::StringBuffer (obj->getClass()->getName()))->append (JvNewStringUTF(" cannot be cast to "))->append (c->getName())->toString()); return obj;}void_Jv_CheckArrayStore (jobject arr, jobject obj){ if (obj) { JvAssert (arr != NULL); jclass elt_class = (JV_CLASS (arr))->getComponentType(); if (elt_class == &java::lang::Object::class$) return; jclass obj_class = JV_CLASS (obj); if (__builtin_expect (! _Jv_IsAssignableFrom (obj_class, elt_class), false)) throw new java::lang::ArrayStoreException ((new java::lang::StringBuffer (JvNewStringUTF("Cannot store ")))->append (obj_class->getName())->append (JvNewStringUTF(" in array of type "))->append (elt_class->getName())->toString()); }}jboolean_Jv_IsAssignableFromSlow (jclass source, jclass target){ // First, strip arrays. while (target->isArray ()) { // If target is array, source must be as well. if (! source->isArray ()) return false; target = target->getComponentType (); source = source->getComponentType (); } // Quick success. if (target == &java::lang::Object::class$) return true; // Ensure that the classes have their supers installed. _Jv_Linker::wait_for_state (source, JV_STATE_LOADING); _Jv_Linker::wait_for_state (target, JV_STATE_LOADING); do { if (source == target) return true; if (target->isPrimitive () || source->isPrimitive ()) return false; if (target->isInterface ()) { for (int i = 0; i < source->interface_count; ++i) { // We use a recursive call because we also need to // check superinterfaces. if (_Jv_IsAssignableFromSlow (source->getInterface (i), target)) return true; } } source = source->getSuperclass (); } while (source != NULL); return false;}// Lookup an interface method by name. This is very similar to// purpose to _getMethod, but the interfaces are quite different. It// might be a good idea for _getMethod to call this function.//// Return true of the method is found, with the class in FOUND_CLASS// and the index in INDEX.bool_Jv_getInterfaceMethod (jclass search_class, jclass &found_class, int &index, const _Jv_Utf8Const *utf_name, const _Jv_Utf8Const *utf_sig){ for (jclass klass = search_class; klass; klass = klass->getSuperclass()) { // FIXME: Throw an exception? if (!klass->isInterface ()) return false; int i = klass->method_count; while (--i >= 0) { if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name) && _Jv_equalUtf8Consts (klass->methods[i].signature, utf_sig)) { // Found it. using namespace java::lang::reflect; // FIXME: Method must be public. Throw an exception? if (! Modifier::isPublic (klass->methods[i].accflags)) break; found_class = klass; // Interface method indexes count from 1. index = i+1; return true; } } } // If we haven't found a match, and this class is an interface, then // check all the superinterfaces. if (search_class->isInterface()) { for (int i = 0; i < search_class->interface_count; ++i) { using namespace java::lang::reflect; bool found = _Jv_getInterfaceMethod (search_class->interfaces[i], found_class, index, utf_name, utf_sig); if (found) return true; } } return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -