inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(dex::TypeIndex type_idx,
ObjPtr<mirror::Class> referrer) {
ObjPtr<mirror::Class> type = referrer->GetDexCache()->GetResolvedType(type_idx); if (type == nullptr) {
type = DoLookupResolvedType(type_idx, referrer);
} return type;
}
inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(dex::TypeIndex type_idx,
ArtField* referrer) { // We do not need the read barrier for getting the DexCache for the initial resolved type // lookup as both from-space and to-space copies point to the same native resolved types array.
ObjPtr<mirror::Class> type = referrer->GetDexCache()->GetResolvedType(type_idx); if (type == nullptr) {
type = DoLookupResolvedType(type_idx, referrer->GetDeclaringClass());
} return type;
}
inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(dex::TypeIndex type_idx,
ArtMethod* referrer) { // We do not need the read barrier for getting the DexCache for the initial resolved type // lookup as both from-space and to-space copies point to the same native resolved types array.
ObjPtr<mirror::Class> type = referrer->GetDexCache()->GetResolvedType(type_idx); if (type == nullptr) {
type = DoLookupResolvedType(type_idx, referrer->GetDeclaringClass());
} return type;
}
// For a Proxy constructor, we need to do the lookup in the context of the original method // from where it steals the code.
referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
if (resolved != nullptr) {
ObjPtr<mirror::Class> methods_class = resolved->GetDeclaringClass();
ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass(); if (UNLIKELY(!referring_class->CanAccess(methods_class))) { // The referrer class can't access the method's declaring class but may still be able // to access the method if the MethodId specifies an accessible subclass of the declaring // class rather than the declaring class itself. if (UNLIKELY(!referring_class->CanAccess(klass))) {
ThrowIllegalAccessErrorClassForMethodDispatch(referring_class,
klass,
resolved,
type); return nullptr;
}
} if (UNLIKELY(!referring_class->CanAccessMember(methods_class, resolved->GetAccessFlags()))) {
ThrowIllegalAccessErrorMethod(referring_class, resolved); return nullptr;
}
// We failed to find the method (using all lookup types), so throw a NoSuchMethodError. constchar* name = referrer->GetDexFile()->GetStringData(method_id.name_idx_); const Signature signature = referrer->GetDexFile()->GetMethodSignature(method_id);
ThrowNoSuchMethodError(type, klass, name, signature); return nullptr;
}
inline ArtField* ClassLinker::ResolveField(uint32_t field_idx,
ArtMethod* referrer, bool is_static) {
Thread::PoisonObjectPointersOnCurrentThread();
ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache();
ArtField* resolved_field = dex_cache->GetResolvedField(field_idx); // If `resolved_field->IsStatic()` is different than `is_static` we know that we will return // nullptr. In this case we still fall into the if case below and make the call in order to throw // the right exception. if (UNLIKELY(resolved_field == nullptr || resolved_field->IsStatic() != is_static)) {
StackHandleScope<2> hs(Thread::Current());
referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(dex_cache));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(referring_class->GetClassLoader()));
resolved_field = ResolveField(field_idx, h_dex_cache, class_loader, is_static); // Note: We cannot check here to see whether we added the field to the cache. The type // might be an erroneous class, which results in it being hidden from us.
} return resolved_field;
}
// If `resolved->IsStatic()` is different than `is_static` we know that we will return // nullptr. In this case we still continue forward in order to throw the right exception. if (resolved != nullptr && resolved->IsStatic() == is_static) { return resolved;
} const DexFile& dex_file = *dex_cache->GetDexFile(); const dex::FieldId& field_id = dex_file.GetFieldId(field_idx);
ObjPtr<mirror::Class> klass = ResolveType(field_id.class_idx_, dex_cache, class_loader); if (klass == nullptr) {
DCHECK(Thread::Current()->IsExceptionPending()); return nullptr;
}
// Look for the field again in case the type resolution updated the cache.
resolved = dex_cache->GetResolvedField(field_idx); if (resolved != nullptr && resolved->IsStatic() == is_static) { return resolved;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.