Add support for Executable.getParameters() metadata
java.lang.reflect.Executable native code to create Parameter
objects and supporting code for obtaining the system annotations
that hold the parameter metadata.
Bug: 30391692
Test: test-art-host and CtsLibcoreTestCases
Change-Id: I23d7e36014716967ce189fba5955cc5e064fe8d0
diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc
index c6c87fd..e0d5337 100644
--- a/runtime/dex_file_annotations.cc
+++ b/runtime/dex_file_annotations.cc
@@ -1027,6 +1027,66 @@
annotation_class);
}
+bool GetParametersMetadataForMethod(ArtMethod* method,
+ MutableHandle<mirror::ObjectArray<mirror::String>>* names,
+ MutableHandle<mirror::IntArray>* access_flags) {
+ const DexFile::AnnotationSetItem::AnnotationSetItem* annotation_set =
+ FindAnnotationSetForMethod(method);
+ if (annotation_set == nullptr) {
+ return false;
+ }
+
+ const DexFile* dex_file = method->GetDexFile();
+ const DexFile::AnnotationItem* annotation_item =
+ SearchAnnotationSet(*dex_file,
+ annotation_set,
+ "Ldalvik/annotation/MethodParameters;",
+ DexFile::kDexVisibilitySystem);
+ if (annotation_item == nullptr) {
+ return false;
+ }
+
+ StackHandleScope<5> hs(Thread::Current());
+
+ // Extract the parameters' names String[].
+ mirror::Class* string_class = mirror::String::GetJavaLangString();
+ Handle<mirror::Class> string_array_class(hs.NewHandle(
+ Runtime::Current()->GetClassLinker()->FindArrayClass(Thread::Current(), &string_class)));
+ if (UNLIKELY(string_array_class.Get() == nullptr)) {
+ return false;
+ }
+
+ Handle<mirror::Class> klass = hs.NewHandle(method->GetDeclaringClass());
+ Handle<mirror::Object> names_obj =
+ hs.NewHandle(GetAnnotationValue(klass,
+ annotation_item,
+ "names",
+ string_array_class,
+ DexFile::kDexAnnotationArray));
+ if (names_obj.Get() == nullptr) {
+ return false;
+ }
+
+ // Extract the parameters' access flags int[].
+ Handle<mirror::Class> int_array_class(hs.NewHandle(mirror::IntArray::GetArrayClass()));
+ if (UNLIKELY(int_array_class.Get() == nullptr)) {
+ return false;
+ }
+ Handle<mirror::Object> access_flags_obj =
+ hs.NewHandle(GetAnnotationValue(klass,
+ annotation_item,
+ "accessFlags",
+ int_array_class,
+ DexFile::kDexAnnotationArray));
+ if (access_flags_obj.Get() == nullptr) {
+ return false;
+ }
+
+ names->Assign(names_obj.Get()->AsObjectArray<mirror::String>());
+ access_flags->Assign(access_flags_obj.Get()->AsIntArray());
+ return true;
+}
+
mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForMethod(ArtMethod* method) {
const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
if (annotation_set == nullptr) {