1 /* 2 * Copyright (C) 2012 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_VERIFIER_REG_TYPE_INL_H_ 18 #define ART_RUNTIME_VERIFIER_REG_TYPE_INL_H_ 19 20 #include "reg_type.h" 21 22 #include "base/casts.h" 23 #include "base/scoped_arena_allocator.h" 24 #include "mirror/class.h" 25 26 namespace art { 27 namespace verifier { 28 29 inline bool RegType::CanAccess(const RegType& other) const { 30 if (Equals(other)) { 31 return true; // Trivial accessibility. 32 } else { 33 bool this_unresolved = IsUnresolvedTypes(); 34 bool other_unresolved = other.IsUnresolvedTypes(); 35 if (!this_unresolved && !other_unresolved) { 36 return GetClass()->CanAccess(other.GetClass()); 37 } else if (!other_unresolved) { 38 return other.GetClass()->IsPublic(); // Be conservative, only allow if other is public. 39 } else { 40 return false; // More complicated test not possible on unresolved types, be conservative. 41 } 42 } 43 } 44 45 inline bool RegType::CanAccessMember(mirror::Class* klass, uint32_t access_flags) const { 46 if ((access_flags & kAccPublic) != 0) { 47 return true; 48 } 49 if (!IsUnresolvedTypes()) { 50 return GetClass()->CanAccessMember(klass, access_flags); 51 } else { 52 return false; // More complicated test not possible on unresolved types, be conservative. 53 } 54 } 55 56 inline bool RegType::IsConstantBoolean() const { 57 if (!IsConstant()) { 58 return false; 59 } else { 60 const ConstantType* const_val = down_cast<const ConstantType*>(this); 61 return const_val->ConstantValue() >= 0 && const_val->ConstantValue() <= 1; 62 } 63 } 64 65 inline bool RegType::AssignableFrom(const RegType& lhs, const RegType& rhs, bool strict) { 66 if (lhs.Equals(rhs)) { 67 return true; 68 } else { 69 if (lhs.IsBoolean()) { 70 return rhs.IsBooleanTypes(); 71 } else if (lhs.IsByte()) { 72 return rhs.IsByteTypes(); 73 } else if (lhs.IsShort()) { 74 return rhs.IsShortTypes(); 75 } else if (lhs.IsChar()) { 76 return rhs.IsCharTypes(); 77 } else if (lhs.IsInteger()) { 78 return rhs.IsIntegralTypes(); 79 } else if (lhs.IsFloat()) { 80 return rhs.IsFloatTypes(); 81 } else if (lhs.IsLongLo()) { 82 return rhs.IsLongTypes(); 83 } else if (lhs.IsDoubleLo()) { 84 return rhs.IsDoubleTypes(); 85 } else if (lhs.IsConflict()) { 86 LOG(WARNING) << "RegType::AssignableFrom lhs is Conflict!"; 87 return false; 88 } else { 89 CHECK(lhs.IsReferenceTypes()) 90 << "Unexpected register type in IsAssignableFrom: '" 91 << lhs << "' := '" << rhs << "'"; 92 if (rhs.IsZero()) { 93 return true; // All reference types can be assigned null. 94 } else if (!rhs.IsReferenceTypes()) { 95 return false; // Expect rhs to be a reference type. 96 } else if (lhs.IsUninitializedTypes() || rhs.IsUninitializedTypes()) { 97 // Uninitialized types are only allowed to be assigned to themselves. 98 // TODO: Once we have a proper "reference" super type, this needs to be extended. 99 return false; 100 } else if (lhs.IsJavaLangObject()) { 101 return true; // All reference types can be assigned to Object. 102 } else if (!strict && !lhs.IsUnresolvedTypes() && lhs.GetClass()->IsInterface()) { 103 // If we're not strict allow assignment to any interface, see comment in ClassJoin. 104 return true; 105 } else if (lhs.IsJavaLangObjectArray()) { 106 return rhs.IsObjectArrayTypes(); // All reference arrays may be assigned to Object[] 107 } else if (lhs.HasClass() && rhs.HasClass() && 108 lhs.GetClass()->IsAssignableFrom(rhs.GetClass())) { 109 // We're assignable from the Class point-of-view. 110 return true; 111 } else { 112 // Unresolved types are only assignable for null and equality. 113 return false; 114 } 115 } 116 } 117 } 118 119 inline bool RegType::IsAssignableFrom(const RegType& src) const { 120 return AssignableFrom(*this, src, false); 121 } 122 123 inline bool RegType::IsStrictlyAssignableFrom(const RegType& src) const { 124 return AssignableFrom(*this, src, true); 125 } 126 127 inline const DoubleHiType* DoubleHiType::GetInstance() { 128 DCHECK(instance_ != nullptr); 129 return instance_; 130 } 131 132 inline const DoubleLoType* DoubleLoType::GetInstance() { 133 DCHECK(instance_ != nullptr); 134 return instance_; 135 } 136 137 inline const LongHiType* LongHiType::GetInstance() { 138 DCHECK(instance_ != nullptr); 139 return instance_; 140 } 141 142 inline const LongLoType* LongLoType::GetInstance() { 143 DCHECK(instance_ != nullptr); 144 return instance_; 145 } 146 147 inline const FloatType* FloatType::GetInstance() { 148 DCHECK(instance_ != nullptr); 149 return instance_; 150 } 151 152 inline const CharType* CharType::GetInstance() { 153 DCHECK(instance_ != nullptr); 154 return instance_; 155 } 156 157 inline const ShortType* ShortType::GetInstance() { 158 DCHECK(instance_ != nullptr); 159 return instance_; 160 } 161 162 inline const ByteType* ByteType::GetInstance() { 163 DCHECK(instance_ != nullptr); 164 return instance_; 165 } 166 167 168 inline const IntegerType* IntegerType::GetInstance() { 169 DCHECK(instance_ != nullptr); 170 return instance_; 171 } 172 173 inline const BooleanType* BooleanType::GetInstance() { 174 DCHECK(BooleanType::instance_ != nullptr); 175 return BooleanType::instance_; 176 } 177 178 inline const ConflictType* ConflictType::GetInstance() { 179 DCHECK(instance_ != nullptr); 180 return instance_; 181 } 182 183 inline const UndefinedType* UndefinedType::GetInstance() { 184 DCHECK(instance_ != nullptr); 185 return instance_; 186 } 187 188 inline void* RegType::operator new(size_t size, ScopedArenaAllocator* arena) { 189 return arena->Alloc(size, kArenaAllocMisc); 190 } 191 192 } // namespace verifier 193 } // namespace art 194 195 #endif // ART_RUNTIME_VERIFIER_REG_TYPE_INL_H_ 196