211 lines
9.4 KiB
C++
211 lines
9.4 KiB
C++
/*
|
|
* Copyright (C) 2017 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "common_helper.h"
|
|
|
|
#include "jni.h"
|
|
#include "jvmti.h"
|
|
|
|
#include "jvmti_helper.h"
|
|
#include "scoped_local_ref.h"
|
|
#include "test_env.h"
|
|
|
|
namespace art {
|
|
namespace common_locals {
|
|
|
|
static void DeallocateContents(jvmtiLocalVariableEntry* vars, jint nvars) {
|
|
for (jint i = 0; i < nvars; i++) {
|
|
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars[i].name));
|
|
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars[i].signature));
|
|
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars[i].generic_signature));
|
|
}
|
|
}
|
|
|
|
extern "C" JNIEXPORT void Java_art_Locals_EnableLocalVariableAccess(JNIEnv* env, jclass) {
|
|
jvmtiCapabilities caps;
|
|
if (JvmtiErrorToException(env, jvmti_env, jvmti_env->GetCapabilities(&caps))) {
|
|
return;
|
|
}
|
|
caps.can_access_local_variables = 1;
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->AddCapabilities(&caps));
|
|
}
|
|
|
|
extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableObject(JNIEnv* env,
|
|
jclass,
|
|
jthread t,
|
|
jint depth,
|
|
jint slot,
|
|
jobject val) {
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalObject(t, depth, slot, val));
|
|
}
|
|
|
|
extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableDouble(JNIEnv* env,
|
|
jclass,
|
|
jthread t,
|
|
jint depth,
|
|
jint slot,
|
|
jdouble val) {
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalDouble(t, depth, slot, val));
|
|
}
|
|
|
|
extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableFloat(JNIEnv* env,
|
|
jclass,
|
|
jthread t,
|
|
jint depth,
|
|
jint slot,
|
|
jfloat val) {
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalFloat(t, depth, slot, val));
|
|
}
|
|
|
|
extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableLong(JNIEnv* env,
|
|
jclass,
|
|
jthread t,
|
|
jint depth,
|
|
jint slot,
|
|
jlong val) {
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalLong(t, depth, slot, val));
|
|
}
|
|
|
|
extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableInt(JNIEnv* env,
|
|
jclass,
|
|
jthread t,
|
|
jint depth,
|
|
jint slot,
|
|
jint val) {
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalInt(t, depth, slot, val));
|
|
}
|
|
|
|
extern "C" JNIEXPORT jdouble Java_art_Locals_GetLocalVariableDouble(JNIEnv* env,
|
|
jclass,
|
|
jthread t,
|
|
jint depth,
|
|
jint slot) {
|
|
jdouble ret = 0;
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalDouble(t, depth, slot, &ret));
|
|
return ret;
|
|
}
|
|
|
|
extern "C" JNIEXPORT jfloat Java_art_Locals_GetLocalVariableFloat(JNIEnv* env,
|
|
jclass,
|
|
jthread t,
|
|
jint depth,
|
|
jint slot) {
|
|
jfloat ret = 0;
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalFloat(t, depth, slot, &ret));
|
|
return ret;
|
|
}
|
|
|
|
extern "C" JNIEXPORT jlong Java_art_Locals_GetLocalVariableLong(JNIEnv* env,
|
|
jclass,
|
|
jthread t,
|
|
jint depth,
|
|
jint slot) {
|
|
jlong ret = 0;
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalLong(t, depth, slot, &ret));
|
|
return ret;
|
|
}
|
|
|
|
extern "C" JNIEXPORT jint Java_art_Locals_GetLocalVariableInt(JNIEnv* env,
|
|
jclass,
|
|
jthread t,
|
|
jint depth,
|
|
jint slot) {
|
|
jint ret = 0;
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalInt(t, depth, slot, &ret));
|
|
return ret;
|
|
}
|
|
|
|
extern "C" JNIEXPORT jobject Java_art_Locals_GetLocalInstance(JNIEnv* env,
|
|
jclass,
|
|
jthread t,
|
|
jint depth) {
|
|
jobject ret = nullptr;
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalInstance(t, depth, &ret));
|
|
return ret;
|
|
}
|
|
|
|
extern "C" JNIEXPORT jobject Java_art_Locals_GetLocalVariableObject(JNIEnv* env,
|
|
jclass,
|
|
jthread t,
|
|
jint depth,
|
|
jint slot) {
|
|
jobject ret = nullptr;
|
|
JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalObject(t, depth, slot, &ret));
|
|
return ret;
|
|
}
|
|
|
|
extern "C" JNIEXPORT jobjectArray Java_art_Locals_GetLocalVariableTable(JNIEnv* env,
|
|
jclass,
|
|
jobject m) {
|
|
jmethodID method = env->FromReflectedMethod(m);
|
|
if (env->ExceptionCheck()) {
|
|
return nullptr;
|
|
}
|
|
ScopedLocalRef<jclass> klass(env, env->FindClass("art/Locals$VariableDescription"));
|
|
if (env->ExceptionCheck()) {
|
|
return nullptr;
|
|
}
|
|
jint nvars;
|
|
jvmtiLocalVariableEntry* vars = nullptr;
|
|
if (JvmtiErrorToException(env, jvmti_env,
|
|
jvmti_env->GetLocalVariableTable(method, &nvars, &vars))) {
|
|
return nullptr;
|
|
}
|
|
jobjectArray vars_array = env->NewObjectArray(nvars, klass.get(), nullptr);
|
|
if (env->ExceptionCheck()) {
|
|
DeallocateContents(vars, nvars);
|
|
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
|
|
return nullptr;
|
|
}
|
|
|
|
jmethodID constructor = env->GetMethodID(
|
|
klass.get(), "<init>", "(JILjava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
|
|
if (env->ExceptionCheck()) {
|
|
return nullptr;
|
|
}
|
|
for (jint i = 0; i < nvars; i++) {
|
|
ScopedLocalRef<jstring> name_string(env, env->NewStringUTF(vars[i].name));
|
|
ScopedLocalRef<jstring> sig_string(env, env->NewStringUTF(vars[i].signature));
|
|
ScopedLocalRef<jstring> generic_sig_string(env, env->NewStringUTF(vars[i].generic_signature));
|
|
jobject var_obj = env->NewObject(klass.get(),
|
|
constructor,
|
|
vars[i].start_location,
|
|
vars[i].length,
|
|
name_string.get(),
|
|
sig_string.get(),
|
|
generic_sig_string.get(),
|
|
vars[i].slot);
|
|
if (env->ExceptionCheck()) {
|
|
DeallocateContents(vars, nvars);
|
|
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
|
|
return nullptr;
|
|
}
|
|
env->SetObjectArrayElement(vars_array, i, var_obj);
|
|
if (env->ExceptionCheck()) {
|
|
DeallocateContents(vars, nvars);
|
|
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
DeallocateContents(vars, nvars);
|
|
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
|
|
return vars_array;
|
|
}
|
|
|
|
} // namespace common_locals
|
|
} // namespace art
|