1 /* 2 * Copyright (C) 2014 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 #ifndef ART_RUNTIME_REFLECTION_INL_H_ 18 #define ART_RUNTIME_REFLECTION_INL_H_ 19 20 #include "reflection.h" 21 22 #include "base/stringprintf.h" 23 #include "common_throws.h" 24 #include "jvalue.h" 25 #include "primitive.h" 26 #include "utils.h" 27 28 namespace art { 29 30 inline bool ConvertPrimitiveValue(const ThrowLocation* throw_location, bool unbox_for_result, 31 Primitive::Type srcType, Primitive::Type dstType, 32 const JValue& src, JValue* dst) { 33 DCHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot); 34 if (LIKELY(srcType == dstType)) { 35 dst->SetJ(src.GetJ()); 36 return true; 37 } 38 switch (dstType) { 39 case Primitive::kPrimBoolean: // Fall-through. 40 case Primitive::kPrimChar: // Fall-through. 41 case Primitive::kPrimByte: 42 // Only expect assignment with source and destination of identical type. 43 break; 44 case Primitive::kPrimShort: 45 if (srcType == Primitive::kPrimByte) { 46 dst->SetS(src.GetI()); 47 return true; 48 } 49 break; 50 case Primitive::kPrimInt: 51 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || 52 srcType == Primitive::kPrimShort) { 53 dst->SetI(src.GetI()); 54 return true; 55 } 56 break; 57 case Primitive::kPrimLong: 58 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || 59 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) { 60 dst->SetJ(src.GetI()); 61 return true; 62 } 63 break; 64 case Primitive::kPrimFloat: 65 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || 66 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) { 67 dst->SetF(src.GetI()); 68 return true; 69 } else if (srcType == Primitive::kPrimLong) { 70 dst->SetF(src.GetJ()); 71 return true; 72 } 73 break; 74 case Primitive::kPrimDouble: 75 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar || 76 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) { 77 dst->SetD(src.GetI()); 78 return true; 79 } else if (srcType == Primitive::kPrimLong) { 80 dst->SetD(src.GetJ()); 81 return true; 82 } else if (srcType == Primitive::kPrimFloat) { 83 dst->SetD(src.GetF()); 84 return true; 85 } 86 break; 87 default: 88 break; 89 } 90 if (!unbox_for_result) { 91 ThrowIllegalArgumentException(throw_location, 92 StringPrintf("Invalid primitive conversion from %s to %s", 93 PrettyDescriptor(srcType).c_str(), 94 PrettyDescriptor(dstType).c_str()).c_str()); 95 } else { 96 ThrowClassCastException(throw_location, 97 StringPrintf("Couldn't convert result of type %s to %s", 98 PrettyDescriptor(srcType).c_str(), 99 PrettyDescriptor(dstType).c_str()).c_str()); 100 } 101 return false; 102 } 103 104 } // namespace art 105 106 #endif // ART_RUNTIME_REFLECTION_INL_H_ 107