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 "mirror/object-inl.h"
26 #include "primitive.h"
27 #include "utils.h"
28 
29 namespace art {
30 
ConvertPrimitiveValue(bool unbox_for_result,Primitive::Type srcType,Primitive::Type dstType,const JValue & src,JValue * dst)31 inline bool ConvertPrimitiveValue(bool unbox_for_result,
32                                   Primitive::Type srcType, Primitive::Type dstType,
33                                   const JValue& src, JValue* dst) {
34   DCHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot);
35   if (LIKELY(srcType == dstType)) {
36     dst->SetJ(src.GetJ());
37     return true;
38   }
39   switch (dstType) {
40   case Primitive::kPrimBoolean:  // Fall-through.
41   case Primitive::kPrimChar:  // Fall-through.
42   case Primitive::kPrimByte:
43     // Only expect assignment with source and destination of identical type.
44     break;
45   case Primitive::kPrimShort:
46     if (srcType == Primitive::kPrimByte) {
47       dst->SetS(src.GetI());
48       return true;
49     }
50     break;
51   case Primitive::kPrimInt:
52     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
53         srcType == Primitive::kPrimShort) {
54       dst->SetI(src.GetI());
55       return true;
56     }
57     break;
58   case Primitive::kPrimLong:
59     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
60         srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
61       dst->SetJ(src.GetI());
62       return true;
63     }
64     break;
65   case Primitive::kPrimFloat:
66     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
67         srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
68       dst->SetF(src.GetI());
69       return true;
70     } else if (srcType == Primitive::kPrimLong) {
71       dst->SetF(src.GetJ());
72       return true;
73     }
74     break;
75   case Primitive::kPrimDouble:
76     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
77         srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
78       dst->SetD(src.GetI());
79       return true;
80     } else if (srcType == Primitive::kPrimLong) {
81       dst->SetD(src.GetJ());
82       return true;
83     } else if (srcType == Primitive::kPrimFloat) {
84       dst->SetD(src.GetF());
85       return true;
86     }
87     break;
88   default:
89     break;
90   }
91   if (!unbox_for_result) {
92     ThrowIllegalArgumentException(StringPrintf("Invalid primitive conversion from %s to %s",
93                                                PrettyDescriptor(srcType).c_str(),
94                                                PrettyDescriptor(dstType).c_str()).c_str());
95   } else {
96     ThrowClassCastException(StringPrintf("Couldn't convert result of type %s to %s",
97                                          PrettyDescriptor(srcType).c_str(),
98                                          PrettyDescriptor(dstType).c_str()).c_str());
99   }
100   return false;
101 }
102 
VerifyObjectIsClass(mirror::Object * o,mirror::Class * c)103 inline bool VerifyObjectIsClass(mirror::Object* o, mirror::Class* c) {
104   if (UNLIKELY(o == nullptr)) {
105     ThrowNullPointerException("null receiver");
106     return false;
107   } else if (UNLIKELY(!o->InstanceOf(c))) {
108     InvalidReceiverError(o, c);
109     return false;
110   }
111   return true;
112 }
113 
114 }  // namespace art
115 
116 #endif  // ART_RUNTIME_REFLECTION_INL_H_
117