|  | /* | 
|  | * Copyright (C) 2014 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. | 
|  | */ | 
|  |  | 
|  | #ifndef ART_RUNTIME_REFLECTION_INL_H_ | 
|  | #define ART_RUNTIME_REFLECTION_INL_H_ | 
|  |  | 
|  | #include "reflection.h" | 
|  |  | 
|  | #include "android-base/stringprintf.h" | 
|  |  | 
|  | #include "common_throws.h" | 
|  | #include "dex/descriptors_names.h" | 
|  | #include "dex/primitive.h" | 
|  | #include "jvalue-inl.h" | 
|  | #include "mirror/object-inl.h" | 
|  | #include "obj_ptr-inl.h" | 
|  |  | 
|  | namespace art { | 
|  |  | 
|  | inline bool ConvertPrimitiveValueNoThrow(Primitive::Type srcType, | 
|  | Primitive::Type dstType, | 
|  | const JValue& src, | 
|  | JValue* dst) { | 
|  | DCHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot); | 
|  | if (LIKELY(srcType == dstType)) { | 
|  | dst->SetJ(src.GetJ()); | 
|  | return true; | 
|  | } | 
|  | switch (dstType) { | 
|  | case Primitive::kPrimBoolean:  // Fall-through. | 
|  | case Primitive::kPrimChar:  // Fall-through. | 
|  | case Primitive::kPrimByte: | 
|  | // Only expect assignment with source and destination of identical type. | 
|  | break; | 
|  | case Primitive::kPrimShort: | 
|  | if (srcType == Primitive::kPrimByte) { | 
|  | dst->SetS(src.GetI()); | 
|  | return true; | 
|  | } | 
|  | break; | 
|  | case Primitive::kPrimInt: | 
|  | if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || | 
|  | srcType == Primitive::kPrimShort) { | 
|  | dst->SetI(src.GetI()); | 
|  | return true; | 
|  | } | 
|  | break; | 
|  | case Primitive::kPrimLong: | 
|  | if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || | 
|  | srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) { | 
|  | dst->SetJ(src.GetI()); | 
|  | return true; | 
|  | } | 
|  | break; | 
|  | case Primitive::kPrimFloat: | 
|  | if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || | 
|  | srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) { | 
|  | dst->SetF(src.GetI()); | 
|  | return true; | 
|  | } else if (srcType == Primitive::kPrimLong) { | 
|  | dst->SetF(src.GetJ()); | 
|  | return true; | 
|  | } | 
|  | break; | 
|  | case Primitive::kPrimDouble: | 
|  | if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || | 
|  | srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) { | 
|  | dst->SetD(src.GetI()); | 
|  | return true; | 
|  | } else if (srcType == Primitive::kPrimLong) { | 
|  | dst->SetD(src.GetJ()); | 
|  | return true; | 
|  | } else if (srcType == Primitive::kPrimFloat) { | 
|  | dst->SetD(src.GetF()); | 
|  | return true; | 
|  | } | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | inline bool ConvertPrimitiveValue(bool unbox_for_result, | 
|  | Primitive::Type srcType, | 
|  | Primitive::Type dstType, | 
|  | const JValue& src, | 
|  | JValue* dst) { | 
|  | if (ConvertPrimitiveValueNoThrow(srcType, dstType, src, dst)) { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | if (!unbox_for_result) { | 
|  | ThrowIllegalArgumentException( | 
|  | android::base::StringPrintf("Invalid primitive conversion from %s to %s", | 
|  | PrettyDescriptor(srcType).c_str(), | 
|  | PrettyDescriptor(dstType).c_str()).c_str()); | 
|  | } else { | 
|  | ThrowClassCastException(android::base::StringPrintf("Couldn't convert result of type %s to %s", | 
|  | PrettyDescriptor(srcType).c_str(), | 
|  | PrettyDescriptor(dstType).c_str()).c_str()); | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | inline bool VerifyObjectIsClass(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c) { | 
|  | if (UNLIKELY(o == nullptr)) { | 
|  | ThrowNullPointerException("null receiver"); | 
|  | return false; | 
|  | } else if (UNLIKELY(!o->InstanceOf(c))) { | 
|  | InvalidReceiverError(o, c); | 
|  | return false; | 
|  | } | 
|  | return true; | 
|  | } | 
|  |  | 
|  | }  // namespace art | 
|  |  | 
|  | #endif  // ART_RUNTIME_REFLECTION_INL_H_ |