reflection.cc revision c528dba35b5faece51ca658fc008b688f8b690ad
1/* 2 * Copyright (C) 2011 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 "reflection.h" 18 19#include "class_linker.h" 20#include "common_throws.h" 21#include "dex_file-inl.h" 22#include "invoke_arg_array_builder.h" 23#include "jni_internal.h" 24#include "mirror/art_field-inl.h" 25#include "mirror/art_method-inl.h" 26#include "mirror/class.h" 27#include "mirror/class-inl.h" 28#include "mirror/object_array.h" 29#include "mirror/object_array-inl.h" 30#include "object_utils.h" 31#include "scoped_thread_state_change.h" 32#include "well_known_classes.h" 33 34namespace art { 35 36jobject InvokeMethod(const ScopedObjectAccess& soa, jobject javaMethod, jobject javaReceiver, 37 jobject javaArgs) { 38 jmethodID mid = soa.Env()->FromReflectedMethod(javaMethod); 39 mirror::ArtMethod* m = soa.DecodeMethod(mid); 40 41 mirror::Class* declaring_class = m->GetDeclaringClass(); 42 if (UNLIKELY(!declaring_class->IsInitialized())) { 43 SirtRef<mirror::Class> sirt_c(soa.Self(), declaring_class); 44 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(sirt_c, true, true)) { 45 return nullptr; 46 } 47 declaring_class = sirt_c.get(); 48 } 49 50 mirror::Object* receiver = NULL; 51 if (!m->IsStatic()) { 52 // Check that the receiver is non-null and an instance of the field's declaring class. 53 receiver = soa.Decode<mirror::Object*>(javaReceiver); 54 if (!VerifyObjectInClass(receiver, declaring_class)) { 55 return NULL; 56 } 57 58 // Find the actual implementation of the virtual method. 59 m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(m); 60 mid = soa.EncodeMethod(m); 61 } 62 63 // Get our arrays of arguments and their types, and check they're the same size. 64 mirror::ObjectArray<mirror::Object>* objects = 65 soa.Decode<mirror::ObjectArray<mirror::Object>*>(javaArgs); 66 MethodHelper mh(m); 67 const DexFile::TypeList* classes = mh.GetParameterTypeList(); 68 uint32_t classes_size = classes == NULL ? 0 : classes->Size(); 69 uint32_t arg_count = (objects != NULL) ? objects->GetLength() : 0; 70 if (arg_count != classes_size) { 71 ThrowIllegalArgumentException(NULL, 72 StringPrintf("Wrong number of arguments; expected %d, got %d", 73 classes_size, arg_count).c_str()); 74 return NULL; 75 } 76 77 // Translate javaArgs to a jvalue[]. 78 UniquePtr<jvalue[]> args(new jvalue[arg_count]); 79 JValue* decoded_args = reinterpret_cast<JValue*>(args.get()); 80 for (uint32_t i = 0; i < arg_count; ++i) { 81 mirror::Object* arg = objects->Get(i); 82 mirror::Class* dst_class = mh.GetClassFromTypeIdx(classes->GetTypeItem(i).type_idx_); 83 if (!UnboxPrimitiveForArgument(arg, dst_class, decoded_args[i], m, i)) { 84 return NULL; 85 } 86 if (!dst_class->IsPrimitive()) { 87 args[i].l = soa.AddLocalReference<jobject>(arg); 88 } 89 } 90 91 // Invoke the method. 92 JValue value(InvokeWithJValues(soa, javaReceiver, mid, args.get())); 93 94 // Wrap any exception with "Ljava/lang/reflect/InvocationTargetException;" and return early. 95 if (soa.Self()->IsExceptionPending()) { 96 jthrowable th = soa.Env()->ExceptionOccurred(); 97 soa.Env()->ExceptionClear(); 98 jclass exception_class = soa.Env()->FindClass("java/lang/reflect/InvocationTargetException"); 99 jmethodID mid = soa.Env()->GetMethodID(exception_class, "<init>", "(Ljava/lang/Throwable;)V"); 100 jobject exception_instance = soa.Env()->NewObject(exception_class, mid, th); 101 soa.Env()->Throw(reinterpret_cast<jthrowable>(exception_instance)); 102 return NULL; 103 } 104 105 // Box if necessary and return. 106 return soa.AddLocalReference<jobject>(BoxPrimitive(mh.GetReturnType()->GetPrimitiveType(), value)); 107} 108 109bool VerifyObjectInClass(mirror::Object* o, mirror::Class* c) { 110 if (o == NULL) { 111 ThrowNullPointerException(NULL, "null receiver"); 112 return false; 113 } else if (!o->InstanceOf(c)) { 114 std::string expected_class_name(PrettyDescriptor(c)); 115 std::string actual_class_name(PrettyTypeOf(o)); 116 ThrowIllegalArgumentException(NULL, 117 StringPrintf("Expected receiver of type %s, but got %s", 118 expected_class_name.c_str(), 119 actual_class_name.c_str()).c_str()); 120 return false; 121 } 122 return true; 123} 124 125bool ConvertPrimitiveValue(const ThrowLocation* throw_location, bool unbox_for_result, 126 Primitive::Type srcType, Primitive::Type dstType, 127 const JValue& src, JValue& dst) { 128 CHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot); 129 switch (dstType) { 130 case Primitive::kPrimBoolean: 131 if (srcType == Primitive::kPrimBoolean) { 132 dst.SetZ(src.GetZ()); 133 return true; 134 } 135 break; 136 case Primitive::kPrimChar: 137 if (srcType == Primitive::kPrimChar) { 138 dst.SetC(src.GetC()); 139 return true; 140 } 141 break; 142 case Primitive::kPrimByte: 143 if (srcType == Primitive::kPrimByte) { 144 dst.SetB(src.GetB()); 145 return true; 146 } 147 break; 148 case Primitive::kPrimShort: 149 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimShort) { 150 dst.SetS(src.GetI()); 151 return true; 152 } 153 break; 154 case Primitive::kPrimInt: 155 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || 156 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) { 157 dst.SetI(src.GetI()); 158 return true; 159 } 160 break; 161 case Primitive::kPrimLong: 162 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || 163 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) { 164 dst.SetJ(src.GetI()); 165 return true; 166 } else if (srcType == Primitive::kPrimLong) { 167 dst.SetJ(src.GetJ()); 168 return true; 169 } 170 break; 171 case Primitive::kPrimFloat: 172 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || 173 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) { 174 dst.SetF(src.GetI()); 175 return true; 176 } else if (srcType == Primitive::kPrimLong) { 177 dst.SetF(src.GetJ()); 178 return true; 179 } else if (srcType == Primitive::kPrimFloat) { 180 dst.SetF(src.GetF()); 181 return true; 182 } 183 break; 184 case Primitive::kPrimDouble: 185 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || 186 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) { 187 dst.SetD(src.GetI()); 188 return true; 189 } else if (srcType == Primitive::kPrimLong) { 190 dst.SetD(src.GetJ()); 191 return true; 192 } else if (srcType == Primitive::kPrimFloat) { 193 dst.SetD(src.GetF()); 194 return true; 195 } else if (srcType == Primitive::kPrimDouble) { 196 dst.SetJ(src.GetJ()); 197 return true; 198 } 199 break; 200 default: 201 break; 202 } 203 if (!unbox_for_result) { 204 ThrowIllegalArgumentException(throw_location, 205 StringPrintf("Invalid primitive conversion from %s to %s", 206 PrettyDescriptor(srcType).c_str(), 207 PrettyDescriptor(dstType).c_str()).c_str()); 208 } else { 209 ThrowClassCastException(throw_location, 210 StringPrintf("Couldn't convert result of type %s to %s", 211 PrettyDescriptor(srcType).c_str(), 212 PrettyDescriptor(dstType).c_str()).c_str()); 213 } 214 return false; 215} 216 217mirror::Object* BoxPrimitive(Primitive::Type src_class, const JValue& value) { 218 if (src_class == Primitive::kPrimNot) { 219 return value.GetL(); 220 } 221 222 jmethodID m = NULL; 223 switch (src_class) { 224 case Primitive::kPrimBoolean: 225 m = WellKnownClasses::java_lang_Boolean_valueOf; 226 break; 227 case Primitive::kPrimByte: 228 m = WellKnownClasses::java_lang_Byte_valueOf; 229 break; 230 case Primitive::kPrimChar: 231 m = WellKnownClasses::java_lang_Character_valueOf; 232 break; 233 case Primitive::kPrimDouble: 234 m = WellKnownClasses::java_lang_Double_valueOf; 235 break; 236 case Primitive::kPrimFloat: 237 m = WellKnownClasses::java_lang_Float_valueOf; 238 break; 239 case Primitive::kPrimInt: 240 m = WellKnownClasses::java_lang_Integer_valueOf; 241 break; 242 case Primitive::kPrimLong: 243 m = WellKnownClasses::java_lang_Long_valueOf; 244 break; 245 case Primitive::kPrimShort: 246 m = WellKnownClasses::java_lang_Short_valueOf; 247 break; 248 case Primitive::kPrimVoid: 249 // There's no such thing as a void field, and void methods invoked via reflection return null. 250 return NULL; 251 default: 252 LOG(FATAL) << static_cast<int>(src_class); 253 } 254 255 ScopedObjectAccessUnchecked soa(Thread::Current()); 256 if (kIsDebugBuild) { 257 CHECK_EQ(soa.Self()->GetState(), kRunnable); 258 } 259 260 ArgArray arg_array(NULL, 0); 261 JValue result; 262 if (src_class == Primitive::kPrimDouble || src_class == Primitive::kPrimLong) { 263 arg_array.AppendWide(value.GetJ()); 264 } else { 265 arg_array.Append(value.GetI()); 266 } 267 268 soa.DecodeMethod(m)->Invoke(soa.Self(), arg_array.GetArray(), arg_array.GetNumBytes(), 269 &result, 'L'); 270 return result.GetL(); 271} 272 273static std::string UnboxingFailureKind(mirror::ArtMethod* m, int index, mirror::ArtField* f) 274 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 275 if (m != NULL && index != -1) { 276 ++index; // Humans count from 1. 277 return StringPrintf("method %s argument %d", PrettyMethod(m, false).c_str(), index); 278 } 279 if (f != NULL) { 280 return "field " + PrettyField(f, false); 281 } 282 return "result"; 283} 284 285static bool UnboxPrimitive(const ThrowLocation* throw_location, mirror::Object* o, 286 mirror::Class* dst_class, JValue& unboxed_value, 287 mirror::ArtMethod* m, int index, mirror::ArtField* f) 288 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 289 bool unbox_for_result = (f == NULL) && (index == -1); 290 if (!dst_class->IsPrimitive()) { 291 if (UNLIKELY(o != NULL && !o->InstanceOf(dst_class))) { 292 if (!unbox_for_result) { 293 ThrowIllegalArgumentException(throw_location, 294 StringPrintf("%s has type %s, got %s", 295 UnboxingFailureKind(m, index, f).c_str(), 296 PrettyDescriptor(dst_class).c_str(), 297 PrettyTypeOf(o).c_str()).c_str()); 298 } else { 299 ThrowClassCastException(throw_location, 300 StringPrintf("Couldn't convert result of type %s to %s", 301 PrettyTypeOf(o).c_str(), 302 PrettyDescriptor(dst_class).c_str()).c_str()); 303 } 304 return false; 305 } 306 unboxed_value.SetL(o); 307 return true; 308 } 309 if (UNLIKELY(dst_class->GetPrimitiveType() == Primitive::kPrimVoid)) { 310 ThrowIllegalArgumentException(throw_location, 311 StringPrintf("Can't unbox %s to void", 312 UnboxingFailureKind(m, index, f).c_str()).c_str()); 313 return false; 314 } 315 if (UNLIKELY(o == NULL)) { 316 if (!unbox_for_result) { 317 ThrowIllegalArgumentException(throw_location, 318 StringPrintf("%s has type %s, got null", 319 UnboxingFailureKind(m, index, f).c_str(), 320 PrettyDescriptor(dst_class).c_str()).c_str()); 321 } else { 322 ThrowNullPointerException(throw_location, 323 StringPrintf("Expected to unbox a '%s' primitive type but was returned null", 324 PrettyDescriptor(dst_class).c_str()).c_str()); 325 } 326 return false; 327 } 328 329 JValue boxed_value; 330 const StringPiece src_descriptor(ClassHelper(o->GetClass()).GetDescriptor()); 331 mirror::Class* src_class = NULL; 332 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 333 mirror::ArtField* primitive_field = o->GetClass()->GetIFields()->Get(0); 334 if (src_descriptor == "Ljava/lang/Boolean;") { 335 src_class = class_linker->FindPrimitiveClass('Z'); 336 boxed_value.SetZ(primitive_field->GetBoolean(o)); 337 } else if (src_descriptor == "Ljava/lang/Byte;") { 338 src_class = class_linker->FindPrimitiveClass('B'); 339 boxed_value.SetB(primitive_field->GetByte(o)); 340 } else if (src_descriptor == "Ljava/lang/Character;") { 341 src_class = class_linker->FindPrimitiveClass('C'); 342 boxed_value.SetC(primitive_field->GetChar(o)); 343 } else if (src_descriptor == "Ljava/lang/Float;") { 344 src_class = class_linker->FindPrimitiveClass('F'); 345 boxed_value.SetF(primitive_field->GetFloat(o)); 346 } else if (src_descriptor == "Ljava/lang/Double;") { 347 src_class = class_linker->FindPrimitiveClass('D'); 348 boxed_value.SetD(primitive_field->GetDouble(o)); 349 } else if (src_descriptor == "Ljava/lang/Integer;") { 350 src_class = class_linker->FindPrimitiveClass('I'); 351 boxed_value.SetI(primitive_field->GetInt(o)); 352 } else if (src_descriptor == "Ljava/lang/Long;") { 353 src_class = class_linker->FindPrimitiveClass('J'); 354 boxed_value.SetJ(primitive_field->GetLong(o)); 355 } else if (src_descriptor == "Ljava/lang/Short;") { 356 src_class = class_linker->FindPrimitiveClass('S'); 357 boxed_value.SetS(primitive_field->GetShort(o)); 358 } else { 359 ThrowIllegalArgumentException(throw_location, 360 StringPrintf("%s has type %s, got %s", 361 UnboxingFailureKind(m, index, f).c_str(), 362 PrettyDescriptor(dst_class).c_str(), 363 PrettyDescriptor(src_descriptor.data()).c_str()).c_str()); 364 return false; 365 } 366 367 return ConvertPrimitiveValue(throw_location, unbox_for_result, 368 src_class->GetPrimitiveType(), dst_class->GetPrimitiveType(), 369 boxed_value, unboxed_value); 370} 371 372bool UnboxPrimitiveForArgument(mirror::Object* o, mirror::Class* dst_class, JValue& unboxed_value, 373 mirror::ArtMethod* m, size_t index) { 374 CHECK(m != NULL); 375 return UnboxPrimitive(NULL, o, dst_class, unboxed_value, m, index, NULL); 376} 377 378bool UnboxPrimitiveForField(mirror::Object* o, mirror::Class* dst_class, JValue& unboxed_value, 379 mirror::ArtField* f) { 380 CHECK(f != NULL); 381 return UnboxPrimitive(NULL, o, dst_class, unboxed_value, NULL, -1, f); 382} 383 384bool UnboxPrimitiveForResult(const ThrowLocation& throw_location, mirror::Object* o, 385 mirror::Class* dst_class, JValue& unboxed_value) { 386 return UnboxPrimitive(&throw_location, o, dst_class, unboxed_value, NULL, -1, NULL); 387} 388 389} // namespace art 390