Separate annotations from dexfile reading.
Bug: 22322814
Change-Id: I867d66da407dd80394a10d19903ebbc1ec3986ff
Test: test-art
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 76cd348..ccc4c16 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -27,28 +27,20 @@
#include <memory>
#include <sstream>
-#include "art_field-inl.h"
-#include "art_method-inl.h"
#include "base/enums.h"
#include "base/file_magic.h"
#include "base/hash_map.h"
#include "base/logging.h"
#include "base/stl_util.h"
-#include "base/stringprintf.h"
#include "base/systrace.h"
#include "base/unix_file/fd_file.h"
#include "class_linker-inl.h"
#include "dex_file-inl.h"
#include "dex_file_verifier.h"
#include "globals.h"
-#include "handle_scope-inl.h"
#include "jvalue.h"
#include "leb128.h"
-#include "mirror/field.h"
-#include "mirror/method.h"
-#include "mirror/string.h"
#include "os.h"
-#include "reflection.h"
#include "safe_map.h"
#include "thread.h"
#include "type_lookup_table.h"
@@ -864,22 +856,6 @@
return Signature(this, *proto_id);
}
-int32_t DexFile::GetLineNumFromPC(ArtMethod* method, uint32_t rel_pc) const {
- // For native method, lineno should be -2 to indicate it is native. Note that
- // "line number == -2" is how libcore tells from StackTraceElement.
- if (method->GetCodeItemOffset() == 0) {
- return -2;
- }
-
- const CodeItem* code_item = GetCodeItem(method->GetCodeItemOffset());
- DCHECK(code_item != nullptr) << PrettyMethod(method) << " " << GetLocation();
-
- // A method with no line number info should return -1
- LineNumFromPcContext context(rel_pc, -1);
- DecodeDebugPositionInfo(code_item, LineNumForPcCb, &context);
- return context.line_num_;
-}
-
int32_t DexFile::FindTryItem(const CodeItem &code_item, uint32_t address) {
// Note: Signed type is important for max and min.
int32_t min = 0;
@@ -1186,7 +1162,7 @@
}
// Read a signed integer. "zwidth" is the zero-based byte count.
-static int32_t ReadSignedInt(const uint8_t* ptr, int zwidth) {
+int32_t DexFile::ReadSignedInt(const uint8_t* ptr, int zwidth) {
int32_t val = 0;
for (int i = zwidth; i >= 0; --i) {
val = ((uint32_t)val >> 8) | (((int32_t)*ptr++) << 24);
@@ -1197,7 +1173,7 @@
// Read an unsigned integer. "zwidth" is the zero-based byte count,
// "fill_on_right" indicates which side we want to zero-fill from.
-static uint32_t ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right) {
+uint32_t DexFile::ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right) {
uint32_t val = 0;
for (int i = zwidth; i >= 0; --i) {
val = (val >> 8) | (((uint32_t)*ptr++) << 24);
@@ -1209,7 +1185,7 @@
}
// Read a signed long. "zwidth" is the zero-based byte count.
-static int64_t ReadSignedLong(const uint8_t* ptr, int zwidth) {
+int64_t DexFile::ReadSignedLong(const uint8_t* ptr, int zwidth) {
int64_t val = 0;
for (int i = zwidth; i >= 0; --i) {
val = ((uint64_t)val >> 8) | (((int64_t)*ptr++) << 56);
@@ -1220,7 +1196,7 @@
// Read an unsigned long. "zwidth" is the zero-based byte count,
// "fill_on_right" indicates which side we want to zero-fill from.
-static uint64_t ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right) {
+uint64_t DexFile::ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right) {
uint64_t val = 0;
for (int i = zwidth; i >= 0; --i) {
val = (val >> 8) | (((uint64_t)*ptr++) << 56);
@@ -1233,1150 +1209,6 @@
// Checks that visibility is as expected. Includes special behavior for M and
// before to allow runtime and build visibility when expecting runtime.
-static bool IsVisibilityCompatible(uint32_t actual, uint32_t expected) {
- if (expected == DexFile::kDexVisibilityRuntime) {
- int32_t sdk_version = Runtime::Current()->GetTargetSdkVersion();
- if (sdk_version > 0 && sdk_version <= 23) {
- return actual == DexFile::kDexVisibilityRuntime || actual == DexFile::kDexVisibilityBuild;
- }
- }
- return actual == expected;
-}
-
-const DexFile::AnnotationSetItem* DexFile::FindAnnotationSetForField(ArtField* field) const {
- mirror::Class* klass = field->GetDeclaringClass();
- const AnnotationsDirectoryItem* annotations_dir = GetAnnotationsDirectory(*klass->GetClassDef());
- if (annotations_dir == nullptr) {
- return nullptr;
- }
- const FieldAnnotationsItem* field_annotations = GetFieldAnnotations(annotations_dir);
- if (field_annotations == nullptr) {
- return nullptr;
- }
- uint32_t field_index = field->GetDexFieldIndex();
- uint32_t field_count = annotations_dir->fields_size_;
- for (uint32_t i = 0; i < field_count; ++i) {
- if (field_annotations[i].field_idx_ == field_index) {
- return GetFieldAnnotationSetItem(field_annotations[i]);
- }
- }
- return nullptr;
-}
-
-mirror::Object* DexFile::GetAnnotationForField(ArtField* field,
- Handle<mirror::Class> annotation_class) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass()));
- return GetAnnotationObjectFromAnnotationSet(
- field_class, annotation_set, kDexVisibilityRuntime, annotation_class);
-}
-
-mirror::ObjectArray<mirror::Object>* DexFile::GetAnnotationsForField(ArtField* field) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass()));
- return ProcessAnnotationSet(field_class, annotation_set, kDexVisibilityRuntime);
-}
-
-mirror::ObjectArray<mirror::String>* DexFile::GetSignatureAnnotationForField(ArtField* field)
- const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass()));
- return GetSignatureValue(field_class, annotation_set);
-}
-
-bool DexFile::IsFieldAnnotationPresent(ArtField* field, Handle<mirror::Class> annotation_class)
- const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
- if (annotation_set == nullptr) {
- return false;
- }
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass()));
- const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
- field_class, annotation_set, kDexVisibilityRuntime, annotation_class);
- return annotation_item != nullptr;
-}
-
-const DexFile::AnnotationSetItem* DexFile::FindAnnotationSetForMethod(ArtMethod* method) const {
- mirror::Class* klass = method->GetDeclaringClass();
- const AnnotationsDirectoryItem* annotations_dir = GetAnnotationsDirectory(*klass->GetClassDef());
- if (annotations_dir == nullptr) {
- return nullptr;
- }
- const MethodAnnotationsItem* method_annotations = GetMethodAnnotations(annotations_dir);
- if (method_annotations == nullptr) {
- return nullptr;
- }
- uint32_t method_index = method->GetDexMethodIndex();
- uint32_t method_count = annotations_dir->methods_size_;
- for (uint32_t i = 0; i < method_count; ++i) {
- if (method_annotations[i].method_idx_ == method_index) {
- return GetMethodAnnotationSetItem(method_annotations[i]);
- }
- }
- return nullptr;
-}
-
-const DexFile::ParameterAnnotationsItem* DexFile::FindAnnotationsItemForMethod(ArtMethod* method)
- const {
- mirror::Class* klass = method->GetDeclaringClass();
- const AnnotationsDirectoryItem* annotations_dir = GetAnnotationsDirectory(*klass->GetClassDef());
- if (annotations_dir == nullptr) {
- return nullptr;
- }
- const ParameterAnnotationsItem* parameter_annotations = GetParameterAnnotations(annotations_dir);
- if (parameter_annotations == nullptr) {
- return nullptr;
- }
- uint32_t method_index = method->GetDexMethodIndex();
- uint32_t parameter_count = annotations_dir->parameters_size_;
- for (uint32_t i = 0; i < parameter_count; ++i) {
- if (parameter_annotations[i].method_idx_ == method_index) {
- return ¶meter_annotations[i];
- }
- }
- return nullptr;
-}
-
-mirror::Object* DexFile::GetAnnotationDefaultValue(ArtMethod* method) const {
- mirror::Class* klass = method->GetDeclaringClass();
- const AnnotationsDirectoryItem* annotations_dir = GetAnnotationsDirectory(*klass->GetClassDef());
- if (annotations_dir == nullptr) {
- return nullptr;
- }
- const AnnotationSetItem* annotation_set = GetClassAnnotationSet(annotations_dir);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- const AnnotationItem* annotation_item = SearchAnnotationSet(annotation_set,
- "Ldalvik/annotation/AnnotationDefault;", kDexVisibilitySystem);
- if (annotation_item == nullptr) {
- return nullptr;
- }
- const uint8_t* annotation = SearchEncodedAnnotation(annotation_item->annotation_, "value");
- if (annotation == nullptr) {
- return nullptr;
- }
- uint8_t header_byte = *(annotation++);
- if ((header_byte & kDexAnnotationValueTypeMask) != kDexAnnotationAnnotation) {
- return nullptr;
- }
- annotation = SearchEncodedAnnotation(annotation, method->GetName());
- if (annotation == nullptr) {
- return nullptr;
- }
- AnnotationValue annotation_value;
- StackHandleScope<2> hs(Thread::Current());
- Handle<mirror::Class> h_klass(hs.NewHandle(klass));
- PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
- Handle<mirror::Class> return_type(hs.NewHandle(
- method->GetReturnType(true /* resolve */, pointer_size)));
- if (!ProcessAnnotationValue(h_klass, &annotation, &annotation_value, return_type, kAllObjects)) {
- return nullptr;
- }
- return annotation_value.value_.GetL();
-}
-
-mirror::Object* DexFile::GetAnnotationForMethod(ArtMethod* method,
- Handle<mirror::Class> annotation_class) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
- return GetAnnotationObjectFromAnnotationSet(method_class, annotation_set,
- kDexVisibilityRuntime, annotation_class);
-}
-
-mirror::ObjectArray<mirror::Object>* DexFile::GetAnnotationsForMethod(ArtMethod* method) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
- return ProcessAnnotationSet(method_class, annotation_set, kDexVisibilityRuntime);
-}
-
-mirror::ObjectArray<mirror::Class>* DexFile::GetExceptionTypesForMethod(ArtMethod* method) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
- return GetThrowsValue(method_class, annotation_set);
-}
-
-mirror::ObjectArray<mirror::Object>* DexFile::GetParameterAnnotations(ArtMethod* method) const {
- const ParameterAnnotationsItem* parameter_annotations = FindAnnotationsItemForMethod(method);
- if (parameter_annotations == nullptr) {
- return nullptr;
- }
- const AnnotationSetRefList* set_ref_list =
- GetParameterAnnotationSetRefList(parameter_annotations);
- if (set_ref_list == nullptr) {
- return nullptr;
- }
- uint32_t size = set_ref_list->size_;
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
- return ProcessAnnotationSetRefList(method_class, set_ref_list, size);
-}
-
-mirror::Object* DexFile::GetAnnotationForMethodParameter(ArtMethod* method,
- uint32_t parameter_idx,
- Handle<mirror::Class> annotation_class)
- const {
- const ParameterAnnotationsItem* parameter_annotations = FindAnnotationsItemForMethod(method);
- if (parameter_annotations == nullptr) {
- return nullptr;
- }
- const AnnotationSetRefList* set_ref_list =
- GetParameterAnnotationSetRefList(parameter_annotations);
- if (set_ref_list == nullptr) {
- return nullptr;
- }
-
- if (parameter_idx >= set_ref_list->size_) {
- return nullptr;
- }
- const AnnotationSetRefItem* annotation_set_ref = &set_ref_list->list_[parameter_idx];
- const AnnotationSetItem* annotation_set = GetSetRefItemItem(annotation_set_ref);
-
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
- return GetAnnotationObjectFromAnnotationSet(method_class,
- annotation_set,
- kDexVisibilityRuntime,
- annotation_class);
-}
-
-mirror::ObjectArray<mirror::String>* DexFile::GetSignatureAnnotationForMethod(ArtMethod* method)
- const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
- return GetSignatureValue(method_class, annotation_set);
-}
-
-bool DexFile::IsMethodAnnotationPresent(ArtMethod* method,
- Handle<mirror::Class> annotation_class,
- uint32_t visibility /* = kDexVisibilityRuntime */)
- const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
- if (annotation_set == nullptr) {
- return false;
- }
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
- const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(method_class,
- annotation_set,
- visibility,
- annotation_class);
- return annotation_item != nullptr;
-}
-
-const DexFile::AnnotationSetItem* DexFile::FindAnnotationSetForClass(Handle<mirror::Class> klass)
- const {
- const AnnotationsDirectoryItem* annotations_dir = GetAnnotationsDirectory(*klass->GetClassDef());
- if (annotations_dir == nullptr) {
- return nullptr;
- }
- return GetClassAnnotationSet(annotations_dir);
-}
-
-mirror::Object* DexFile::GetAnnotationForClass(Handle<mirror::Class> klass,
- Handle<mirror::Class> annotation_class) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- return GetAnnotationObjectFromAnnotationSet(klass, annotation_set, kDexVisibilityRuntime,
- annotation_class);
-}
-
-mirror::ObjectArray<mirror::Object>* DexFile::GetAnnotationsForClass(Handle<mirror::Class> klass)
- const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
- return ProcessAnnotationSet(klass, annotation_set, kDexVisibilityRuntime);
-}
-
-mirror::ObjectArray<mirror::Class>* DexFile::GetDeclaredClasses(Handle<mirror::Class> klass) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- const AnnotationItem* annotation_item = SearchAnnotationSet(
- annotation_set, "Ldalvik/annotation/MemberClasses;", kDexVisibilitySystem);
- if (annotation_item == nullptr) {
- return nullptr;
- }
- StackHandleScope<1> hs(Thread::Current());
- mirror::Class* class_class = mirror::Class::GetJavaLangClass();
- Handle<mirror::Class> class_array_class(hs.NewHandle(
- Runtime::Current()->GetClassLinker()->FindArrayClass(hs.Self(), &class_class)));
- if (class_array_class.Get() == nullptr) {
- return nullptr;
- }
- mirror::Object* obj = GetAnnotationValue(
- klass, annotation_item, "value", class_array_class, kDexAnnotationArray);
- if (obj == nullptr) {
- return nullptr;
- }
- return obj->AsObjectArray<mirror::Class>();
-}
-
-mirror::Class* DexFile::GetDeclaringClass(Handle<mirror::Class> klass) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- const AnnotationItem* annotation_item = SearchAnnotationSet(
- annotation_set, "Ldalvik/annotation/EnclosingClass;", kDexVisibilitySystem);
- if (annotation_item == nullptr) {
- return nullptr;
- }
- mirror::Object* obj = GetAnnotationValue(klass,
- annotation_item,
- "value",
- ScopedNullHandle<mirror::Class>(),
- kDexAnnotationType);
- if (obj == nullptr) {
- return nullptr;
- }
- return obj->AsClass();
-}
-
-mirror::Class* DexFile::GetEnclosingClass(Handle<mirror::Class> klass) const {
- mirror::Class* declaring_class = GetDeclaringClass(klass);
- if (declaring_class != nullptr) {
- return declaring_class;
- }
- const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- const AnnotationItem* annotation_item = SearchAnnotationSet(
- annotation_set, "Ldalvik/annotation/EnclosingMethod;", kDexVisibilitySystem);
- if (annotation_item == nullptr) {
- return nullptr;
- }
- const uint8_t* annotation = SearchEncodedAnnotation(annotation_item->annotation_, "value");
- if (annotation == nullptr) {
- return nullptr;
- }
- AnnotationValue annotation_value;
- if (!ProcessAnnotationValue(klass,
- &annotation,
- &annotation_value,
- ScopedNullHandle<mirror::Class>(),
- kAllRaw)) {
- return nullptr;
- }
- if (annotation_value.type_ != kDexAnnotationMethod) {
- return nullptr;
- }
- StackHandleScope<2> hs(Thread::Current());
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
- ArtMethod* method = Runtime::Current()->GetClassLinker()->ResolveMethodWithoutInvokeType(
- klass->GetDexFile(), annotation_value.value_.GetI(), dex_cache, class_loader);
- if (method == nullptr) {
- return nullptr;
- }
- return method->GetDeclaringClass();
-}
-
-mirror::Object* DexFile::GetEnclosingMethod(Handle<mirror::Class> klass) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- const AnnotationItem* annotation_item = SearchAnnotationSet(
- annotation_set, "Ldalvik/annotation/EnclosingMethod;", kDexVisibilitySystem);
- if (annotation_item == nullptr) {
- return nullptr;
- }
- return GetAnnotationValue(
- klass, annotation_item, "value", ScopedNullHandle<mirror::Class>(), kDexAnnotationMethod);
-}
-
-bool DexFile::GetInnerClass(Handle<mirror::Class> klass, mirror::String** name) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
- if (annotation_set == nullptr) {
- return false;
- }
- const AnnotationItem* annotation_item = SearchAnnotationSet(
- annotation_set, "Ldalvik/annotation/InnerClass;", kDexVisibilitySystem);
- if (annotation_item == nullptr) {
- return false;
- }
- const uint8_t* annotation = SearchEncodedAnnotation(annotation_item->annotation_, "name");
- if (annotation == nullptr) {
- return false;
- }
- AnnotationValue annotation_value;
- if (!ProcessAnnotationValue(klass,
- &annotation,
- &annotation_value,
- ScopedNullHandle<mirror::Class>(),
- kAllObjects)) {
- return false;
- }
- if (annotation_value.type_ != kDexAnnotationNull &&
- annotation_value.type_ != kDexAnnotationString) {
- return false;
- }
- *name = down_cast<mirror::String*>(annotation_value.value_.GetL());
- return true;
-}
-
-bool DexFile::GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
- if (annotation_set == nullptr) {
- return false;
- }
- const AnnotationItem* annotation_item = SearchAnnotationSet(
- annotation_set, "Ldalvik/annotation/InnerClass;", kDexVisibilitySystem);
- if (annotation_item == nullptr) {
- return false;
- }
- const uint8_t* annotation = SearchEncodedAnnotation(annotation_item->annotation_, "accessFlags");
- if (annotation == nullptr) {
- return false;
- }
- AnnotationValue annotation_value;
- if (!ProcessAnnotationValue(klass,
- &annotation,
- &annotation_value,
- ScopedNullHandle<mirror::Class>(),
- kAllRaw)) {
- return false;
- }
- if (annotation_value.type_ != kDexAnnotationInt) {
- return false;
- }
- *flags = annotation_value.value_.GetI();
- return true;
-}
-
-mirror::ObjectArray<mirror::String>* DexFile::GetSignatureAnnotationForClass(
- Handle<mirror::Class> klass) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- return GetSignatureValue(klass, annotation_set);
-}
-
-bool DexFile::IsClassAnnotationPresent(Handle<mirror::Class> klass,
- Handle<mirror::Class> annotation_class) const {
- const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
- if (annotation_set == nullptr) {
- return false;
- }
- const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
- klass, annotation_set, kDexVisibilityRuntime, annotation_class);
- return annotation_item != nullptr;
-}
-
-mirror::Object* DexFile::CreateAnnotationMember(Handle<mirror::Class> klass,
- Handle<mirror::Class> annotation_class, const uint8_t** annotation) const {
- Thread* self = Thread::Current();
- ScopedObjectAccessUnchecked soa(self);
- StackHandleScope<5> hs(self);
- uint32_t element_name_index = DecodeUnsignedLeb128(annotation);
- const char* name = StringDataByIdx(element_name_index);
- Handle<mirror::String> string_name(
- hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, name)));
-
- PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
- ArtMethod* annotation_method =
- annotation_class->FindDeclaredVirtualMethodByName(name, pointer_size);
- if (annotation_method == nullptr) {
- return nullptr;
- }
- Handle<mirror::Class> method_return(hs.NewHandle(
- annotation_method->GetReturnType(true /* resolve */, pointer_size)));
-
- AnnotationValue annotation_value;
- if (!ProcessAnnotationValue(klass, annotation, &annotation_value, method_return, kAllObjects)) {
- return nullptr;
- }
- Handle<mirror::Object> value_object(hs.NewHandle(annotation_value.value_.GetL()));
-
- mirror::Class* annotation_member_class =
- WellKnownClasses::ToClass(WellKnownClasses::libcore_reflect_AnnotationMember);
- Handle<mirror::Object> new_member(hs.NewHandle(annotation_member_class->AllocObject(self)));
- mirror::Method* method_obj_ptr;
- DCHECK(!Runtime::Current()->IsActiveTransaction());
- if (pointer_size == PointerSize::k64) {
- method_obj_ptr = mirror::Method::CreateFromArtMethod<PointerSize::k64, false>(
- self, annotation_method);
- } else {
- method_obj_ptr = mirror::Method::CreateFromArtMethod<PointerSize::k32, false>(
- self, annotation_method);
- }
- Handle<mirror::Method> method_object(hs.NewHandle(method_obj_ptr));
-
- if (new_member.Get() == nullptr || string_name.Get() == nullptr ||
- method_object.Get() == nullptr || method_return.Get() == nullptr) {
- LOG(ERROR) << StringPrintf("Failed creating annotation element (m=%p n=%p a=%p r=%p",
- new_member.Get(), string_name.Get(), method_object.Get(), method_return.Get());
- return nullptr;
- }
-
- JValue result;
- ArtMethod* annotation_member_init =
- soa.DecodeMethod(WellKnownClasses::libcore_reflect_AnnotationMember_init);
- uint32_t args[5] = { static_cast<uint32_t>(reinterpret_cast<uintptr_t>(new_member.Get())),
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(string_name.Get())),
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(value_object.Get())),
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(method_return.Get())),
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(method_object.Get()))
- };
- annotation_member_init->Invoke(self, args, sizeof(args), &result, "VLLLL");
- if (self->IsExceptionPending()) {
- LOG(INFO) << "Exception in AnnotationMember.<init>";
- return nullptr;
- }
-
- return new_member.Get();
-}
-
-const DexFile::AnnotationItem* DexFile::GetAnnotationItemFromAnnotationSet(
- Handle<mirror::Class> klass, const AnnotationSetItem* annotation_set, uint32_t visibility,
- Handle<mirror::Class> annotation_class) const {
- for (uint32_t i = 0; i < annotation_set->size_; ++i) {
- const AnnotationItem* annotation_item = GetAnnotationItem(annotation_set, i);
- if (!IsVisibilityCompatible(annotation_item->visibility_, visibility)) {
- continue;
- }
- const uint8_t* annotation = annotation_item->annotation_;
- uint32_t type_index = DecodeUnsignedLeb128(&annotation);
- mirror::Class* resolved_class = Runtime::Current()->GetClassLinker()->ResolveType(
- klass->GetDexFile(), type_index, klass.Get());
- if (resolved_class == nullptr) {
- std::string temp;
- LOG(WARNING) << StringPrintf("Unable to resolve %s annotation class %d",
- klass->GetDescriptor(&temp), type_index);
- CHECK(Thread::Current()->IsExceptionPending());
- Thread::Current()->ClearException();
- continue;
- }
- if (resolved_class == annotation_class.Get()) {
- return annotation_item;
- }
- }
-
- return nullptr;
-}
-
-mirror::Object* DexFile::GetAnnotationObjectFromAnnotationSet(Handle<mirror::Class> klass,
- const AnnotationSetItem* annotation_set, uint32_t visibility,
- Handle<mirror::Class> annotation_class) const {
- const AnnotationItem* annotation_item =
- GetAnnotationItemFromAnnotationSet(klass, annotation_set, visibility, annotation_class);
- if (annotation_item == nullptr) {
- return nullptr;
- }
- const uint8_t* annotation = annotation_item->annotation_;
- return ProcessEncodedAnnotation(klass, &annotation);
-}
-
-mirror::Object* DexFile::GetAnnotationValue(Handle<mirror::Class> klass,
- const AnnotationItem* annotation_item, const char* annotation_name,
- Handle<mirror::Class> array_class, uint32_t expected_type) const {
- const uint8_t* annotation =
- SearchEncodedAnnotation(annotation_item->annotation_, annotation_name);
- if (annotation == nullptr) {
- return nullptr;
- }
- AnnotationValue annotation_value;
- if (!ProcessAnnotationValue(klass, &annotation, &annotation_value, array_class, kAllObjects)) {
- return nullptr;
- }
- if (annotation_value.type_ != expected_type) {
- return nullptr;
- }
- return annotation_value.value_.GetL();
-}
-
-mirror::ObjectArray<mirror::String>* DexFile::GetSignatureValue(Handle<mirror::Class> klass,
- const AnnotationSetItem* annotation_set) const {
- StackHandleScope<1> hs(Thread::Current());
- const AnnotationItem* annotation_item =
- SearchAnnotationSet(annotation_set, "Ldalvik/annotation/Signature;", kDexVisibilitySystem);
- if (annotation_item == nullptr) {
- return nullptr;
- }
- mirror::Class* string_class = mirror::String::GetJavaLangString();
- Handle<mirror::Class> string_array_class(hs.NewHandle(
- Runtime::Current()->GetClassLinker()->FindArrayClass(Thread::Current(), &string_class)));
- if (string_array_class.Get() == nullptr) {
- return nullptr;
- }
- mirror::Object* obj =
- GetAnnotationValue(klass, annotation_item, "value", string_array_class, kDexAnnotationArray);
- if (obj == nullptr) {
- return nullptr;
- }
- return obj->AsObjectArray<mirror::String>();
-}
-
-mirror::ObjectArray<mirror::Class>* DexFile::GetThrowsValue(Handle<mirror::Class> klass,
- const AnnotationSetItem* annotation_set) const {
- StackHandleScope<1> hs(Thread::Current());
- const AnnotationItem* annotation_item =
- SearchAnnotationSet(annotation_set, "Ldalvik/annotation/Throws;", kDexVisibilitySystem);
- if (annotation_item == nullptr) {
- return nullptr;
- }
- mirror::Class* class_class = mirror::Class::GetJavaLangClass();
- Handle<mirror::Class> class_array_class(hs.NewHandle(
- Runtime::Current()->GetClassLinker()->FindArrayClass(Thread::Current(), &class_class)));
- if (class_array_class.Get() == nullptr) {
- return nullptr;
- }
- mirror::Object* obj =
- GetAnnotationValue(klass, annotation_item, "value", class_array_class, kDexAnnotationArray);
- if (obj == nullptr) {
- return nullptr;
- }
- return obj->AsObjectArray<mirror::Class>();
-}
-
-mirror::ObjectArray<mirror::Object>* DexFile::ProcessAnnotationSet(Handle<mirror::Class> klass,
- const AnnotationSetItem* annotation_set, uint32_t visibility) const {
- Thread* self = Thread::Current();
- ScopedObjectAccessUnchecked soa(self);
- StackHandleScope<2> hs(self);
- Handle<mirror::Class> annotation_array_class(hs.NewHandle(
- soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array)));
- if (annotation_set == nullptr) {
- return mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), 0);
- }
-
- uint32_t size = annotation_set->size_;
- Handle<mirror::ObjectArray<mirror::Object>> result(hs.NewHandle(
- mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), size)));
- if (result.Get() == nullptr) {
- return nullptr;
- }
-
- uint32_t dest_index = 0;
- for (uint32_t i = 0; i < size; ++i) {
- const AnnotationItem* annotation_item = GetAnnotationItem(annotation_set, i);
- // Note that we do not use IsVisibilityCompatible here because older code
- // was correct for this case.
- if (annotation_item->visibility_ != visibility) {
- continue;
- }
- const uint8_t* annotation = annotation_item->annotation_;
- mirror::Object* annotation_obj = ProcessEncodedAnnotation(klass, &annotation);
- if (annotation_obj != nullptr) {
- result->SetWithoutChecks<false>(dest_index, annotation_obj);
- ++dest_index;
- } else if (self->IsExceptionPending()) {
- return nullptr;
- }
- }
-
- if (dest_index == size) {
- return result.Get();
- }
-
- mirror::ObjectArray<mirror::Object>* trimmed_result =
- mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), dest_index);
- if (trimmed_result == nullptr) {
- return nullptr;
- }
-
- for (uint32_t i = 0; i < dest_index; ++i) {
- mirror::Object* obj = result->GetWithoutChecks(i);
- trimmed_result->SetWithoutChecks<false>(i, obj);
- }
-
- return trimmed_result;
-}
-
-mirror::ObjectArray<mirror::Object>* DexFile::ProcessAnnotationSetRefList(
- Handle<mirror::Class> klass, const AnnotationSetRefList* set_ref_list, uint32_t size) const {
- Thread* self = Thread::Current();
- ScopedObjectAccessUnchecked soa(self);
- StackHandleScope<1> hs(self);
- mirror::Class* annotation_array_class =
- soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array);
- mirror::Class* annotation_array_array_class =
- Runtime::Current()->GetClassLinker()->FindArrayClass(self, &annotation_array_class);
- if (annotation_array_array_class == nullptr) {
- return nullptr;
- }
- Handle<mirror::ObjectArray<mirror::Object>> annotation_array_array(hs.NewHandle(
- mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_array_class, size)));
- if (annotation_array_array.Get() == nullptr) {
- LOG(ERROR) << "Annotation set ref array allocation failed";
- return nullptr;
- }
- for (uint32_t index = 0; index < size; ++index) {
- const AnnotationSetRefItem* set_ref_item = &set_ref_list->list_[index];
- const AnnotationSetItem* set_item = GetSetRefItemItem(set_ref_item);
- mirror::Object* annotation_set = ProcessAnnotationSet(klass, set_item, kDexVisibilityRuntime);
- if (annotation_set == nullptr) {
- return nullptr;
- }
- annotation_array_array->SetWithoutChecks<false>(index, annotation_set);
- }
- return annotation_array_array.Get();
-}
-
-bool DexFile::ProcessAnnotationValue(Handle<mirror::Class> klass, const uint8_t** annotation_ptr,
- AnnotationValue* annotation_value, Handle<mirror::Class> array_class,
- DexFile::AnnotationResultStyle result_style) const {
- Thread* self = Thread::Current();
- mirror::Object* element_object = nullptr;
- bool set_object = false;
- Primitive::Type primitive_type = Primitive::kPrimVoid;
- const uint8_t* annotation = *annotation_ptr;
- uint8_t header_byte = *(annotation++);
- uint8_t value_type = header_byte & kDexAnnotationValueTypeMask;
- uint8_t value_arg = header_byte >> kDexAnnotationValueArgShift;
- int32_t width = value_arg + 1;
- annotation_value->type_ = value_type;
-
- switch (value_type) {
- case kDexAnnotationByte:
- annotation_value->value_.SetB(static_cast<int8_t>(ReadSignedInt(annotation, value_arg)));
- primitive_type = Primitive::kPrimByte;
- break;
- case kDexAnnotationShort:
- annotation_value->value_.SetS(static_cast<int16_t>(ReadSignedInt(annotation, value_arg)));
- primitive_type = Primitive::kPrimShort;
- break;
- case kDexAnnotationChar:
- annotation_value->value_.SetC(static_cast<uint16_t>(ReadUnsignedInt(annotation, value_arg,
- false)));
- primitive_type = Primitive::kPrimChar;
- break;
- case kDexAnnotationInt:
- annotation_value->value_.SetI(ReadSignedInt(annotation, value_arg));
- primitive_type = Primitive::kPrimInt;
- break;
- case kDexAnnotationLong:
- annotation_value->value_.SetJ(ReadSignedLong(annotation, value_arg));
- primitive_type = Primitive::kPrimLong;
- break;
- case kDexAnnotationFloat:
- annotation_value->value_.SetI(ReadUnsignedInt(annotation, value_arg, true));
- primitive_type = Primitive::kPrimFloat;
- break;
- case kDexAnnotationDouble:
- annotation_value->value_.SetJ(ReadUnsignedLong(annotation, value_arg, true));
- primitive_type = Primitive::kPrimDouble;
- break;
- case kDexAnnotationBoolean:
- annotation_value->value_.SetZ(value_arg != 0);
- primitive_type = Primitive::kPrimBoolean;
- width = 0;
- break;
- case kDexAnnotationString: {
- uint32_t index = ReadUnsignedInt(annotation, value_arg, false);
- if (result_style == kAllRaw) {
- annotation_value->value_.SetI(index);
- } else {
- StackHandleScope<1> hs(self);
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
- element_object = Runtime::Current()->GetClassLinker()->ResolveString(
- klass->GetDexFile(), index, dex_cache);
- set_object = true;
- if (element_object == nullptr) {
- return false;
- }
- }
- break;
- }
- case kDexAnnotationType: {
- uint32_t index = ReadUnsignedInt(annotation, value_arg, false);
- if (result_style == kAllRaw) {
- annotation_value->value_.SetI(index);
- } else {
- element_object = Runtime::Current()->GetClassLinker()->ResolveType(
- klass->GetDexFile(), index, klass.Get());
- set_object = true;
- if (element_object == nullptr) {
- CHECK(self->IsExceptionPending());
- if (result_style == kAllObjects) {
- const char* msg = StringByTypeIdx(index);
- self->ThrowNewWrappedException("Ljava/lang/TypeNotPresentException;", msg);
- element_object = self->GetException();
- self->ClearException();
- } else {
- return false;
- }
- }
- }
- break;
- }
- case kDexAnnotationMethod: {
- uint32_t index = ReadUnsignedInt(annotation, value_arg, false);
- if (result_style == kAllRaw) {
- annotation_value->value_.SetI(index);
- } else {
- StackHandleScope<2> hs(self);
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- ArtMethod* method = class_linker->ResolveMethodWithoutInvokeType(
- klass->GetDexFile(), index, dex_cache, class_loader);
- if (method == nullptr) {
- return false;
- }
- PointerSize pointer_size = class_linker->GetImagePointerSize();
- set_object = true;
- DCHECK(!Runtime::Current()->IsActiveTransaction());
- if (method->IsConstructor()) {
- if (pointer_size == PointerSize::k64) {
- element_object = mirror::Constructor::CreateFromArtMethod<PointerSize::k64,
- false>(self, method);
- } else {
- element_object = mirror::Constructor::CreateFromArtMethod<PointerSize::k32,
- false>(self, method);
- }
- } else {
- if (pointer_size == PointerSize::k64) {
- element_object = mirror::Method::CreateFromArtMethod<PointerSize::k64,
- false>(self, method);
- } else {
- element_object = mirror::Method::CreateFromArtMethod<PointerSize::k32,
- false>(self, method);
- }
- }
- if (element_object == nullptr) {
- return false;
- }
- }
- break;
- }
- case kDexAnnotationField: {
- uint32_t index = ReadUnsignedInt(annotation, value_arg, false);
- if (result_style == kAllRaw) {
- annotation_value->value_.SetI(index);
- } else {
- StackHandleScope<2> hs(self);
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
- ArtField* field = Runtime::Current()->GetClassLinker()->ResolveFieldJLS(
- klass->GetDexFile(), index, dex_cache, class_loader);
- if (field == nullptr) {
- return false;
- }
- set_object = true;
- PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
- if (pointer_size == PointerSize::k64) {
- element_object = mirror::Field::CreateFromArtField<PointerSize::k64>(self, field, true);
- } else {
- element_object = mirror::Field::CreateFromArtField<PointerSize::k32>(self, field, true);
- }
- if (element_object == nullptr) {
- return false;
- }
- }
- break;
- }
- case kDexAnnotationEnum: {
- uint32_t index = ReadUnsignedInt(annotation, value_arg, false);
- if (result_style == kAllRaw) {
- annotation_value->value_.SetI(index);
- } else {
- StackHandleScope<3> hs(self);
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
- ArtField* enum_field = Runtime::Current()->GetClassLinker()->ResolveField(
- klass->GetDexFile(), index, dex_cache, class_loader, true);
- if (enum_field == nullptr) {
- return false;
- } else {
- Handle<mirror::Class> field_class(hs.NewHandle(enum_field->GetDeclaringClass()));
- Runtime::Current()->GetClassLinker()->EnsureInitialized(self, field_class, true, true);
- element_object = enum_field->GetObject(field_class.Get());
- set_object = true;
- }
- }
- break;
- }
- case kDexAnnotationArray:
- if (result_style == kAllRaw || array_class.Get() == nullptr) {
- return false;
- } else {
- ScopedObjectAccessUnchecked soa(self);
- StackHandleScope<2> hs(self);
- uint32_t size = DecodeUnsignedLeb128(&annotation);
- Handle<mirror::Class> component_type(hs.NewHandle(array_class->GetComponentType()));
- Handle<mirror::Array> new_array(hs.NewHandle(mirror::Array::Alloc<true>(
- self, array_class.Get(), size, array_class->GetComponentSizeShift(),
- Runtime::Current()->GetHeap()->GetCurrentAllocator())));
- if (new_array.Get() == nullptr) {
- LOG(ERROR) << "Annotation element array allocation failed with size " << size;
- return false;
- }
- AnnotationValue new_annotation_value;
- for (uint32_t i = 0; i < size; ++i) {
- if (!ProcessAnnotationValue(klass, &annotation, &new_annotation_value, component_type,
- kPrimitivesOrObjects)) {
- return false;
- }
- if (!component_type->IsPrimitive()) {
- mirror::Object* obj = new_annotation_value.value_.GetL();
- new_array->AsObjectArray<mirror::Object>()->SetWithoutChecks<false>(i, obj);
- } else {
- switch (new_annotation_value.type_) {
- case kDexAnnotationByte:
- new_array->AsByteArray()->SetWithoutChecks<false>(
- i, new_annotation_value.value_.GetB());
- break;
- case kDexAnnotationShort:
- new_array->AsShortArray()->SetWithoutChecks<false>(
- i, new_annotation_value.value_.GetS());
- break;
- case kDexAnnotationChar:
- new_array->AsCharArray()->SetWithoutChecks<false>(
- i, new_annotation_value.value_.GetC());
- break;
- case kDexAnnotationInt:
- new_array->AsIntArray()->SetWithoutChecks<false>(
- i, new_annotation_value.value_.GetI());
- break;
- case kDexAnnotationLong:
- new_array->AsLongArray()->SetWithoutChecks<false>(
- i, new_annotation_value.value_.GetJ());
- break;
- case kDexAnnotationFloat:
- new_array->AsFloatArray()->SetWithoutChecks<false>(
- i, new_annotation_value.value_.GetF());
- break;
- case kDexAnnotationDouble:
- new_array->AsDoubleArray()->SetWithoutChecks<false>(
- i, new_annotation_value.value_.GetD());
- break;
- case kDexAnnotationBoolean:
- new_array->AsBooleanArray()->SetWithoutChecks<false>(
- i, new_annotation_value.value_.GetZ());
- break;
- default:
- LOG(FATAL) << "Found invalid annotation value type while building annotation array";
- return false;
- }
- }
- }
- element_object = new_array.Get();
- set_object = true;
- width = 0;
- }
- break;
- case kDexAnnotationAnnotation:
- if (result_style == kAllRaw) {
- return false;
- }
- element_object = ProcessEncodedAnnotation(klass, &annotation);
- if (element_object == nullptr) {
- return false;
- }
- set_object = true;
- width = 0;
- break;
- case kDexAnnotationNull:
- if (result_style == kAllRaw) {
- annotation_value->value_.SetI(0);
- } else {
- CHECK(element_object == nullptr);
- set_object = true;
- }
- width = 0;
- break;
- default:
- LOG(ERROR) << StringPrintf("Bad annotation element value type 0x%02x", value_type);
- return false;
- }
-
- annotation += width;
- *annotation_ptr = annotation;
-
- if (result_style == kAllObjects && primitive_type != Primitive::kPrimVoid) {
- element_object = BoxPrimitive(primitive_type, annotation_value->value_);
- set_object = true;
- }
-
- if (set_object) {
- annotation_value->value_.SetL(element_object);
- }
-
- return true;
-}
-
-mirror::Object* DexFile::ProcessEncodedAnnotation(Handle<mirror::Class> klass,
- const uint8_t** annotation) const {
- uint32_t type_index = DecodeUnsignedLeb128(annotation);
- uint32_t size = DecodeUnsignedLeb128(annotation);
-
- Thread* self = Thread::Current();
- ScopedObjectAccessUnchecked soa(self);
- StackHandleScope<2> hs(self);
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Handle<mirror::Class> annotation_class(hs.NewHandle(
- class_linker->ResolveType(klass->GetDexFile(), type_index, klass.Get())));
- if (annotation_class.Get() == nullptr) {
- LOG(INFO) << "Unable to resolve " << PrettyClass(klass.Get()) << " annotation class "
- << type_index;
- DCHECK(Thread::Current()->IsExceptionPending());
- Thread::Current()->ClearException();
- return nullptr;
- }
-
- mirror::Class* annotation_member_class =
- soa.Decode<mirror::Class*>(WellKnownClasses::libcore_reflect_AnnotationMember);
- mirror::Class* annotation_member_array_class =
- class_linker->FindArrayClass(self, &annotation_member_class);
- if (annotation_member_array_class == nullptr) {
- return nullptr;
- }
- mirror::ObjectArray<mirror::Object>* element_array = nullptr;
- if (size > 0) {
- element_array =
- mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_member_array_class, size);
- if (element_array == nullptr) {
- LOG(ERROR) << "Failed to allocate annotation member array (" << size << " elements)";
- return nullptr;
- }
- }
-
- Handle<mirror::ObjectArray<mirror::Object>> h_element_array(hs.NewHandle(element_array));
- for (uint32_t i = 0; i < size; ++i) {
- mirror::Object* new_member = CreateAnnotationMember(klass, annotation_class, annotation);
- if (new_member == nullptr) {
- return nullptr;
- }
- h_element_array->SetWithoutChecks<false>(i, new_member);
- }
-
- JValue result;
- ArtMethod* create_annotation_method =
- soa.DecodeMethod(WellKnownClasses::libcore_reflect_AnnotationFactory_createAnnotation);
- uint32_t args[2] = { static_cast<uint32_t>(reinterpret_cast<uintptr_t>(annotation_class.Get())),
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_element_array.Get())) };
- create_annotation_method->Invoke(self, args, sizeof(args), &result, "LLL");
- if (self->IsExceptionPending()) {
- LOG(INFO) << "Exception in AnnotationFactory.createAnnotation";
- return nullptr;
- }
-
- return result.GetL();
-}
-
-const DexFile::AnnotationItem* DexFile::SearchAnnotationSet(const AnnotationSetItem* annotation_set,
- const char* descriptor, uint32_t visibility) const {
- const AnnotationItem* result = nullptr;
- for (uint32_t i = 0; i < annotation_set->size_; ++i) {
- const AnnotationItem* annotation_item = GetAnnotationItem(annotation_set, i);
- if (!IsVisibilityCompatible(annotation_item->visibility_, visibility)) {
- continue;
- }
- const uint8_t* annotation = annotation_item->annotation_;
- uint32_t type_index = DecodeUnsignedLeb128(&annotation);
-
- if (strcmp(descriptor, StringByTypeIdx(type_index)) == 0) {
- result = annotation_item;
- break;
- }
- }
- return result;
-}
-
-const uint8_t* DexFile::SearchEncodedAnnotation(const uint8_t* annotation, const char* name) const {
- DecodeUnsignedLeb128(&annotation); // unused type_index
- uint32_t size = DecodeUnsignedLeb128(&annotation);
-
- while (size != 0) {
- uint32_t element_name_index = DecodeUnsignedLeb128(&annotation);
- const char* element_name = GetStringData(GetStringId(element_name_index));
- if (strcmp(name, element_name) == 0) {
- return annotation;
- }
- SkipAnnotationValue(&annotation);
- size--;
- }
- return nullptr;
-}
-
-bool DexFile::SkipAnnotationValue(const uint8_t** annotation_ptr) const {
- const uint8_t* annotation = *annotation_ptr;
- uint8_t header_byte = *(annotation++);
- uint8_t value_type = header_byte & kDexAnnotationValueTypeMask;
- uint8_t value_arg = header_byte >> kDexAnnotationValueArgShift;
- int32_t width = value_arg + 1;
-
- switch (value_type) {
- case kDexAnnotationByte:
- case kDexAnnotationShort:
- case kDexAnnotationChar:
- case kDexAnnotationInt:
- case kDexAnnotationLong:
- case kDexAnnotationFloat:
- case kDexAnnotationDouble:
- case kDexAnnotationString:
- case kDexAnnotationType:
- case kDexAnnotationMethod:
- case kDexAnnotationField:
- case kDexAnnotationEnum:
- break;
- case kDexAnnotationArray:
- {
- uint32_t size = DecodeUnsignedLeb128(&annotation);
- while (size--) {
- if (!SkipAnnotationValue(&annotation)) {
- return false;
- }
- }
- width = 0;
- break;
- }
- case kDexAnnotationAnnotation:
- {
- DecodeUnsignedLeb128(&annotation); // unused type_index
- uint32_t size = DecodeUnsignedLeb128(&annotation);
- while (size--) {
- DecodeUnsignedLeb128(&annotation); // unused element_name_index
- if (!SkipAnnotationValue(&annotation)) {
- return false;
- }
- }
- width = 0;
- break;
- }
- case kDexAnnotationBoolean:
- case kDexAnnotationNull:
- width = 0;
- break;
- default:
- LOG(FATAL) << StringPrintf("Bad annotation element value byte 0x%02x", value_type);
- return false;
- }
-
- annotation += width;
- *annotation_ptr = annotation;
- return true;
-}
-
std::ostream& operator<<(std::ostream& os, const DexFile& dex_file) {
os << StringPrintf("[DexFile: %s dex-checksum=%08x location-checksum=%08x %p-%p]",
dex_file.GetLocation().c_str(),
@@ -2460,50 +1292,13 @@
}
}
-EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator(
- const DexFile& dex_file,
- const DexFile::ClassDef& class_def)
- : EncodedStaticFieldValueIterator(dex_file,
- nullptr,
- nullptr,
- nullptr,
- class_def,
- -1,
- kByte) {
-}
-
-EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator(
- const DexFile& dex_file,
- Handle<mirror::DexCache>* dex_cache,
- Handle<mirror::ClassLoader>* class_loader,
- ClassLinker* linker,
- const DexFile::ClassDef& class_def)
- : EncodedStaticFieldValueIterator(dex_file,
- dex_cache, class_loader,
- linker,
- class_def,
- -1,
- kByte) {
- DCHECK(dex_cache_ != nullptr);
- DCHECK(class_loader_ != nullptr);
-}
-
-EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator(
- const DexFile& dex_file,
- Handle<mirror::DexCache>* dex_cache,
- Handle<mirror::ClassLoader>* class_loader,
- ClassLinker* linker,
- const DexFile::ClassDef& class_def,
- size_t pos,
- ValueType type)
+EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator(const DexFile& dex_file,
+ const DexFile::ClassDef& class_def)
: dex_file_(dex_file),
- dex_cache_(dex_cache),
- class_loader_(class_loader),
- linker_(linker),
array_size_(),
- pos_(pos),
- type_(type) {
- ptr_ = dex_file.GetEncodedStaticFieldValuesArray(class_def);
+ pos_(-1),
+ type_(kByte) {
+ ptr_ = dex_file_.GetEncodedStaticFieldValuesArray(class_def);
if (ptr_ == nullptr) {
array_size_ = 0;
} else {
@@ -2529,32 +1324,32 @@
width = 0;
break;
case kByte:
- jval_.i = ReadSignedInt(ptr_, value_arg);
+ jval_.i = DexFile::ReadSignedInt(ptr_, value_arg);
CHECK(IsInt<8>(jval_.i));
break;
case kShort:
- jval_.i = ReadSignedInt(ptr_, value_arg);
+ jval_.i = DexFile::ReadSignedInt(ptr_, value_arg);
CHECK(IsInt<16>(jval_.i));
break;
case kChar:
- jval_.i = ReadUnsignedInt(ptr_, value_arg, false);
+ jval_.i = DexFile::ReadUnsignedInt(ptr_, value_arg, false);
CHECK(IsUint<16>(jval_.i));
break;
case kInt:
- jval_.i = ReadSignedInt(ptr_, value_arg);
+ jval_.i = DexFile::ReadSignedInt(ptr_, value_arg);
break;
case kLong:
- jval_.j = ReadSignedLong(ptr_, value_arg);
+ jval_.j = DexFile::ReadSignedLong(ptr_, value_arg);
break;
case kFloat:
- jval_.i = ReadUnsignedInt(ptr_, value_arg, true);
+ jval_.i = DexFile::ReadUnsignedInt(ptr_, value_arg, true);
break;
case kDouble:
- jval_.j = ReadUnsignedLong(ptr_, value_arg, true);
+ jval_.j = DexFile::ReadUnsignedLong(ptr_, value_arg, true);
break;
case kString:
case kType:
- jval_.i = ReadUnsignedInt(ptr_, value_arg, false);
+ jval_.i = DexFile::ReadUnsignedInt(ptr_, value_arg, false);
break;
case kField:
case kMethod:
@@ -2574,38 +1369,6 @@
ptr_ += width;
}
-template<bool kTransactionActive>
-void EncodedStaticFieldValueIterator::ReadValueToField(ArtField* field) const {
- DCHECK(dex_cache_ != nullptr);
- DCHECK(class_loader_ != nullptr);
- switch (type_) {
- case kBoolean: field->SetBoolean<kTransactionActive>(field->GetDeclaringClass(), jval_.z);
- break;
- case kByte: field->SetByte<kTransactionActive>(field->GetDeclaringClass(), jval_.b); break;
- case kShort: field->SetShort<kTransactionActive>(field->GetDeclaringClass(), jval_.s); break;
- case kChar: field->SetChar<kTransactionActive>(field->GetDeclaringClass(), jval_.c); break;
- case kInt: field->SetInt<kTransactionActive>(field->GetDeclaringClass(), jval_.i); break;
- case kLong: field->SetLong<kTransactionActive>(field->GetDeclaringClass(), jval_.j); break;
- case kFloat: field->SetFloat<kTransactionActive>(field->GetDeclaringClass(), jval_.f); break;
- case kDouble: field->SetDouble<kTransactionActive>(field->GetDeclaringClass(), jval_.d); break;
- case kNull: field->SetObject<kTransactionActive>(field->GetDeclaringClass(), nullptr); break;
- case kString: {
- mirror::String* resolved = linker_->ResolveString(dex_file_, jval_.i, *dex_cache_);
- field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
- break;
- }
- case kType: {
- mirror::Class* resolved = linker_->ResolveType(dex_file_, jval_.i, *dex_cache_,
- *class_loader_);
- field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
- break;
- }
- default: UNIMPLEMENTED(FATAL) << ": type " << type_;
- }
-}
-template void EncodedStaticFieldValueIterator::ReadValueToField<true>(ArtField* field) const;
-template void EncodedStaticFieldValueIterator::ReadValueToField<false>(ArtField* field) const;
-
CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address) {
handler_.address_ = -1;
int32_t offset = -1;