blob: 8ad61f0ccee3a2d553fe3080d09533c212cd31ca [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
Mathieu Chartier76433272014-09-26 14:32:37 -070024#include "common_throws.h"
David Sehrb2ec9f52018-02-21 13:20:31 -080025#include "dex/descriptors_names.h"
David Sehr67bf42e2018-02-26 16:43:04 -080026#include "dex/primitive.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070027#include "jvalue-inl.h"
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070028#include "mirror/object-inl.h"
Mathieu Chartiera59d9b22016-09-26 18:13:17 -070029#include "obj_ptr-inl.h"
Mathieu Chartier76433272014-09-26 14:32:37 -070030
31namespace art {
32
Orion Hodsonba28f9f2016-10-26 10:56:25 +010033inline bool ConvertPrimitiveValueNoThrow(Primitive::Type srcType,
34 Primitive::Type dstType,
35 const JValue& src,
36 JValue* dst) {
Mathieu Chartier76433272014-09-26 14:32:37 -070037 DCHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot);
38 if (LIKELY(srcType == dstType)) {
39 dst->SetJ(src.GetJ());
40 return true;
41 }
42 switch (dstType) {
43 case Primitive::kPrimBoolean: // Fall-through.
44 case Primitive::kPrimChar: // Fall-through.
45 case Primitive::kPrimByte:
46 // Only expect assignment with source and destination of identical type.
47 break;
48 case Primitive::kPrimShort:
49 if (srcType == Primitive::kPrimByte) {
50 dst->SetS(src.GetI());
51 return true;
52 }
53 break;
54 case Primitive::kPrimInt:
55 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
56 srcType == Primitive::kPrimShort) {
57 dst->SetI(src.GetI());
58 return true;
59 }
60 break;
61 case Primitive::kPrimLong:
62 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
63 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
64 dst->SetJ(src.GetI());
65 return true;
66 }
67 break;
68 case Primitive::kPrimFloat:
69 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
70 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
71 dst->SetF(src.GetI());
72 return true;
73 } else if (srcType == Primitive::kPrimLong) {
74 dst->SetF(src.GetJ());
75 return true;
76 }
77 break;
78 case Primitive::kPrimDouble:
79 if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
80 srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
81 dst->SetD(src.GetI());
82 return true;
83 } else if (srcType == Primitive::kPrimLong) {
84 dst->SetD(src.GetJ());
85 return true;
86 } else if (srcType == Primitive::kPrimFloat) {
87 dst->SetD(src.GetF());
88 return true;
89 }
90 break;
91 default:
92 break;
93 }
Orion Hodsonba28f9f2016-10-26 10:56:25 +010094 return false;
95}
96
97inline bool ConvertPrimitiveValue(bool unbox_for_result,
98 Primitive::Type srcType,
99 Primitive::Type dstType,
100 const JValue& src,
101 JValue* dst) {
102 if (ConvertPrimitiveValueNoThrow(srcType, dstType, src, dst)) {
103 return true;
104 }
105
Mathieu Chartier76433272014-09-26 14:32:37 -0700106 if (!unbox_for_result) {
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800107 ThrowIllegalArgumentException(
108 android::base::StringPrintf("Invalid primitive conversion from %s to %s",
109 PrettyDescriptor(srcType).c_str(),
110 PrettyDescriptor(dstType).c_str()).c_str());
Mathieu Chartier76433272014-09-26 14:32:37 -0700111 } else {
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800112 ThrowClassCastException(android::base::StringPrintf("Couldn't convert result of type %s to %s",
113 PrettyDescriptor(srcType).c_str(),
114 PrettyDescriptor(dstType).c_str()).c_str());
Mathieu Chartier76433272014-09-26 14:32:37 -0700115 }
116 return false;
117}
118
Mathieu Chartiera59d9b22016-09-26 18:13:17 -0700119inline bool VerifyObjectIsClass(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c) {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700120 if (UNLIKELY(o == nullptr)) {
121 ThrowNullPointerException("null receiver");
122 return false;
Vladimir Markobcf17522018-06-01 13:14:32 +0100123 } else if (UNLIKELY(!o->InstanceOf(c))) {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700124 InvalidReceiverError(o, c);
125 return false;
126 }
127 return true;
128}
129
Mathieu Chartier76433272014-09-26 14:32:37 -0700130} // namespace art
131
132#endif // ART_RUNTIME_REFLECTION_INL_H_