1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "common_helper.h"
18
19 #include "jni.h"
20 #include "jvmti.h"
21
22 #include "jvmti_helper.h"
23 #include "scoped_local_ref.h"
24 #include "test_env.h"
25
26 namespace art {
27 namespace common_locals {
28
DeallocateContents(jvmtiLocalVariableEntry * vars,jint nvars)29 static void DeallocateContents(jvmtiLocalVariableEntry* vars, jint nvars) {
30 for (jint i = 0; i < nvars; i++) {
31 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars[i].name));
32 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars[i].signature));
33 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars[i].generic_signature));
34 }
35 }
36
Java_art_Locals_EnableLocalVariableAccess(JNIEnv * env,jclass)37 extern "C" JNIEXPORT void Java_art_Locals_EnableLocalVariableAccess(JNIEnv* env, jclass) {
38 jvmtiCapabilities caps;
39 if (JvmtiErrorToException(env, jvmti_env, jvmti_env->GetCapabilities(&caps))) {
40 return;
41 }
42 caps.can_access_local_variables = 1;
43 JvmtiErrorToException(env, jvmti_env, jvmti_env->AddCapabilities(&caps));
44 }
45
Java_art_Locals_SetLocalVariableObject(JNIEnv * env,jclass,jthread t,jint depth,jint slot,jobject val)46 extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableObject(JNIEnv* env,
47 jclass,
48 jthread t,
49 jint depth,
50 jint slot,
51 jobject val) {
52 JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalObject(t, depth, slot, val));
53 }
54
Java_art_Locals_SetLocalVariableDouble(JNIEnv * env,jclass,jthread t,jint depth,jint slot,jdouble val)55 extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableDouble(JNIEnv* env,
56 jclass,
57 jthread t,
58 jint depth,
59 jint slot,
60 jdouble val) {
61 JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalDouble(t, depth, slot, val));
62 }
63
Java_art_Locals_SetLocalVariableFloat(JNIEnv * env,jclass,jthread t,jint depth,jint slot,jfloat val)64 extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableFloat(JNIEnv* env,
65 jclass,
66 jthread t,
67 jint depth,
68 jint slot,
69 jfloat val) {
70 JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalFloat(t, depth, slot, val));
71 }
72
Java_art_Locals_SetLocalVariableLong(JNIEnv * env,jclass,jthread t,jint depth,jint slot,jlong val)73 extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableLong(JNIEnv* env,
74 jclass,
75 jthread t,
76 jint depth,
77 jint slot,
78 jlong val) {
79 JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalLong(t, depth, slot, val));
80 }
81
Java_art_Locals_SetLocalVariableInt(JNIEnv * env,jclass,jthread t,jint depth,jint slot,jint val)82 extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableInt(JNIEnv* env,
83 jclass,
84 jthread t,
85 jint depth,
86 jint slot,
87 jint val) {
88 JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalInt(t, depth, slot, val));
89 }
90
Java_art_Locals_GetLocalVariableDouble(JNIEnv * env,jclass,jthread t,jint depth,jint slot)91 extern "C" JNIEXPORT jdouble Java_art_Locals_GetLocalVariableDouble(JNIEnv* env,
92 jclass,
93 jthread t,
94 jint depth,
95 jint slot) {
96 jdouble ret = 0;
97 JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalDouble(t, depth, slot, &ret));
98 return ret;
99 }
100
Java_art_Locals_GetLocalVariableFloat(JNIEnv * env,jclass,jthread t,jint depth,jint slot)101 extern "C" JNIEXPORT jfloat Java_art_Locals_GetLocalVariableFloat(JNIEnv* env,
102 jclass,
103 jthread t,
104 jint depth,
105 jint slot) {
106 jfloat ret = 0;
107 JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalFloat(t, depth, slot, &ret));
108 return ret;
109 }
110
Java_art_Locals_GetLocalVariableLong(JNIEnv * env,jclass,jthread t,jint depth,jint slot)111 extern "C" JNIEXPORT jlong Java_art_Locals_GetLocalVariableLong(JNIEnv* env,
112 jclass,
113 jthread t,
114 jint depth,
115 jint slot) {
116 jlong ret = 0;
117 JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalLong(t, depth, slot, &ret));
118 return ret;
119 }
120
Java_art_Locals_GetLocalVariableInt(JNIEnv * env,jclass,jthread t,jint depth,jint slot)121 extern "C" JNIEXPORT jint Java_art_Locals_GetLocalVariableInt(JNIEnv* env,
122 jclass,
123 jthread t,
124 jint depth,
125 jint slot) {
126 jint ret = 0;
127 JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalInt(t, depth, slot, &ret));
128 return ret;
129 }
130
Java_art_Locals_GetLocalInstance(JNIEnv * env,jclass,jthread t,jint depth)131 extern "C" JNIEXPORT jobject Java_art_Locals_GetLocalInstance(JNIEnv* env,
132 jclass,
133 jthread t,
134 jint depth) {
135 jobject ret = nullptr;
136 JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalInstance(t, depth, &ret));
137 return ret;
138 }
139
Java_art_Locals_GetLocalVariableObject(JNIEnv * env,jclass,jthread t,jint depth,jint slot)140 extern "C" JNIEXPORT jobject Java_art_Locals_GetLocalVariableObject(JNIEnv* env,
141 jclass,
142 jthread t,
143 jint depth,
144 jint slot) {
145 jobject ret = nullptr;
146 JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalObject(t, depth, slot, &ret));
147 return ret;
148 }
149
Java_art_Locals_GetLocalVariableTable(JNIEnv * env,jclass,jobject m)150 extern "C" JNIEXPORT jobjectArray Java_art_Locals_GetLocalVariableTable(JNIEnv* env,
151 jclass,
152 jobject m) {
153 jmethodID method = env->FromReflectedMethod(m);
154 if (env->ExceptionCheck()) {
155 return nullptr;
156 }
157 ScopedLocalRef<jclass> klass(env, env->FindClass("art/Locals$VariableDescription"));
158 if (env->ExceptionCheck()) {
159 return nullptr;
160 }
161 jint nvars;
162 jvmtiLocalVariableEntry* vars = nullptr;
163 if (JvmtiErrorToException(env, jvmti_env,
164 jvmti_env->GetLocalVariableTable(method, &nvars, &vars))) {
165 return nullptr;
166 }
167 jobjectArray vars_array = env->NewObjectArray(nvars, klass.get(), nullptr);
168 if (env->ExceptionCheck()) {
169 DeallocateContents(vars, nvars);
170 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
171 return nullptr;
172 }
173
174 jmethodID constructor = env->GetMethodID(
175 klass.get(), "<init>", "(JILjava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
176 if (env->ExceptionCheck()) {
177 return nullptr;
178 }
179 for (jint i = 0; i < nvars; i++) {
180 ScopedLocalRef<jstring> name_string(env, env->NewStringUTF(vars[i].name));
181 ScopedLocalRef<jstring> sig_string(env, env->NewStringUTF(vars[i].signature));
182 ScopedLocalRef<jstring> generic_sig_string(env, env->NewStringUTF(vars[i].generic_signature));
183 jobject var_obj = env->NewObject(klass.get(),
184 constructor,
185 vars[i].start_location,
186 vars[i].length,
187 name_string.get(),
188 sig_string.get(),
189 generic_sig_string.get(),
190 vars[i].slot);
191 if (env->ExceptionCheck()) {
192 DeallocateContents(vars, nvars);
193 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
194 return nullptr;
195 }
196 env->SetObjectArrayElement(vars_array, i, var_obj);
197 if (env->ExceptionCheck()) {
198 DeallocateContents(vars, nvars);
199 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
200 return nullptr;
201 }
202 }
203
204 DeallocateContents(vars, nvars);
205 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
206 return vars_array;
207 }
208
209 } // namespace common_locals
210 } // namespace art
211