blob: 26fb021903f3b834208ab25d546a11b8a61277f8 [file] [log] [blame]
Mathieu Chartier76433272014-09-26 14:32:37 -07001/*
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
Andreas Gampe46ee31b2016-12-14 10:11:49 -080022#include "android-base/stringprintf.h"
23
David Sehr8f4b0562018-03-02 12:01:51 -080024#include "base/utils.h"
Mathieu Chartier76433272014-09-26 14:32:37 -070025#include "common_throws.h"
David Sehrb2ec9f52018-02-21 13:20:31 -080026#include "dex/descriptors_names.h"
David Sehr67bf42e2018-02-26 16:43:04 -080027#include "dex/primitive.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070028#include "jvalue-inl.h"
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070029#include "mirror/object-inl.h"
Mathieu Chartiera59d9b22016-09-26 18:13:17 -070030#include "obj_ptr-inl.h"
Mathieu Chartier76433272014-09-26 14:32:37 -070031
32namespace art {
33
Orion Hodsonba28f9f2016-10-26 10:56:25 +010034inline bool ConvertPrimitiveValueNoThrow(Primitive::Type srcType,
35 Primitive::Type dstType,
36 const JValue& src,
37 JValue* dst) {
Mathieu Chartier76433272014-09-26 14:32:37 -070038 DCHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot);
39 if (LIKELY(srcType == dstType)) {
40 dst->SetJ(src.GetJ());
41 return true;
42 }
43 switch (dstType) {
44 case Primitive::kPrimBoolean: // Fall-through.
45 case Primitive::kPrimChar: // Fall-through.
46 case Primitive::kPrimByte:
47 // Only expect assignment with source and destination of identical type.
48 break;
49 case Primitive::kPrimShort:
50 if (srcType == Primitive::kPrimByte) {
51 dst->SetS(src.GetI());
52 return true;
53 }
54 break;
55 case Primitive::kPrimInt:
56 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
57 srcType == Primitive::kPrimShort) {
58 dst->SetI(src.GetI());
59 return true;
60 }
61 break;
62 case Primitive::kPrimLong:
63 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
64 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
65 dst->SetJ(src.GetI());
66 return true;
67 }
68 break;
69 case Primitive::kPrimFloat:
70 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
71 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
72 dst->SetF(src.GetI());
73 return true;
74 } else if (srcType == Primitive::kPrimLong) {
75 dst->SetF(src.GetJ());
76 return true;
77 }
78 break;
79 case Primitive::kPrimDouble:
80 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
81 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
82 dst->SetD(src.GetI());
83 return true;
84 } else if (srcType == Primitive::kPrimLong) {
85 dst->SetD(src.GetJ());
86 return true;
87 } else if (srcType == Primitive::kPrimFloat) {
88 dst->SetD(src.GetF());
89 return true;
90 }
91 break;
92 default:
93 break;
94 }
Orion Hodsonba28f9f2016-10-26 10:56:25 +010095 return false;
96}
97
98inline bool ConvertPrimitiveValue(bool unbox_for_result,
99 Primitive::Type srcType,
100 Primitive::Type dstType,
101 const JValue& src,
102 JValue* dst) {
103 if (ConvertPrimitiveValueNoThrow(srcType, dstType, src, dst)) {
104 return true;
105 }
106
Mathieu Chartier76433272014-09-26 14:32:37 -0700107 if (!unbox_for_result) {
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800108 ThrowIllegalArgumentException(
109 android::base::StringPrintf("Invalid primitive conversion from %s to %s",
110 PrettyDescriptor(srcType).c_str(),
111 PrettyDescriptor(dstType).c_str()).c_str());
Mathieu Chartier76433272014-09-26 14:32:37 -0700112 } else {
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800113 ThrowClassCastException(android::base::StringPrintf("Couldn't convert result of type %s to %s",
114 PrettyDescriptor(srcType).c_str(),
115 PrettyDescriptor(dstType).c_str()).c_str());
Mathieu Chartier76433272014-09-26 14:32:37 -0700116 }
117 return false;
118}
119
Mathieu Chartiera59d9b22016-09-26 18:13:17 -0700120inline bool VerifyObjectIsClass(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c) {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700121 if (UNLIKELY(o == nullptr)) {
122 ThrowNullPointerException("null receiver");
123 return false;
Mathieu Chartier1cc62e42016-10-03 18:01:28 -0700124 } else if (UNLIKELY(!o->InstanceOf(c.Ptr()))) {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700125 InvalidReceiverError(o, c);
126 return false;
127 }
128 return true;
129}
130
Mathieu Chartier76433272014-09-26 14:32:37 -0700131} // namespace art
132
133#endif // ART_RUNTIME_REFLECTION_INL_H_