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