}
static jvmtiError GetClassModifiers(jvmtiEnv* env, jclass klass, jint* modifiers_ptr) {
- return ERR(NOT_IMPLEMENTED);
+ return ClassUtil::GetClassModifiers(env, klass, modifiers_ptr);
}
static jvmtiError GetClassMethods(jvmtiEnv* env,
return ClassIsT(jklass, test, is_array_class_ptr);
}
+// Keep this in sync with Class.getModifiers().
+static uint32_t ClassGetModifiers(art::Thread* self, art::ObjPtr<art::mirror::Class> klass)
+ REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ if (klass->IsArrayClass()) {
+ uint32_t component_modifiers = ClassGetModifiers(self, klass->GetComponentType());
+ if ((component_modifiers & art::kAccInterface) != 0) {
+ component_modifiers &= ~(art::kAccInterface | art::kAccStatic);
+ }
+ return art::kAccAbstract | art::kAccFinal | component_modifiers;
+ }
+
+ uint32_t modifiers = klass->GetAccessFlags() & art::kAccJavaFlagsMask;
+
+ art::StackHandleScope<1> hs(self);
+ art::Handle<art::mirror::Class> h_klass(hs.NewHandle(klass));
+ return art::mirror::Class::GetInnerClassFlags(h_klass, modifiers);
+}
+
+jvmtiError ClassUtil::GetClassModifiers(jvmtiEnv* env ATTRIBUTE_UNUSED,
+ jclass jklass,
+ jint* modifiers_ptr) {
+ art::ScopedObjectAccess soa(art::Thread::Current());
+ art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass);
+ if (klass == nullptr) {
+ return ERR(INVALID_CLASS);
+ }
+
+ if (modifiers_ptr == nullptr) {
+ return ERR(NULL_POINTER);
+ }
+
+ *modifiers_ptr = ClassGetModifiers(soa.Self(), klass);
+
+ return ERR(NONE);
+}
+
} // namespace openjdkjvmti
jint* method_count_ptr,
jmethodID** methods_ptr);
+ static jvmtiError GetClassModifiers(jvmtiEnv* env, jclass klass, jint* modifiers_ptr);
+
static jvmtiError GetClassSignature(jvmtiEnv* env,
jclass klass,
char** signature_ptr,
return is_array_class;
}
+extern "C" JNIEXPORT jint JNICALL Java_Main_getClassModifiers(
+ JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
+ jint mod;
+ jvmtiError result = jvmti_env->GetClassModifiers(klass, &mod);
+ if (result != JVMTI_ERROR_NONE) {
+ char* err;
+ jvmti_env->GetErrorName(result, &err);
+ printf("Failure running GetClassModifiers: %s\n", err);
+ return JNI_FALSE;
+ }
+ return mod;
+}
+
extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassFields(
JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
jint count = 0;
[Ljava/lang/Object;, null]
+1
[Ljava/lang/String;, null]
+11
[Ljava/lang/Math;, null]
+11
[Ljava/util/List;, null]
+601
[L$Proxy0;, null]
+11
[I, null]
+411
[[D, null]
+411
int interface=false array=false
$Proxy0 interface=false array=false
java.lang.Runnable interface=true array=false
private static void testClass(Class<?> base) throws Exception {
String[] result = getClassSignature(base);
System.out.println(Arrays.toString(result));
+ int mod = getClassModifiers(base);
+ if (mod != base.getModifiers()) {
+ throw new RuntimeException("Unexpected modifiers: " + base.getModifiers() + " vs " + mod);
+ }
+ System.out.println(Integer.toHexString(mod));
}
private static void testClassType(Class<?> c) throws Exception {
private static native boolean isInterface(Class<?> c);
private static native boolean isArrayClass(Class<?> c);
+ private static native int getClassModifiers(Class<?> c);
+
private static native Object[] getClassFields(Class<?> c);
private static native Object[] getClassMethods(Class<?> c);