1 /* 2 * Copyright (C) 2011 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_PRIMITIVE_H_ 18 #define ART_RUNTIME_PRIMITIVE_H_ 19 20 #include <sys/types.h> 21 22 #include "base/logging.h" 23 #include "base/macros.h" 24 25 namespace art { 26 27 static constexpr size_t kObjectReferenceSize = 4; 28 29 constexpr size_t ComponentSizeShiftWidth(size_t component_size) { 30 return component_size == 1u ? 0u : 31 component_size == 2u ? 1u : 32 component_size == 4u ? 2u : 33 component_size == 8u ? 3u : 0u; 34 } 35 36 class Primitive { 37 public: 38 enum Type { 39 kPrimNot = 0, 40 kPrimBoolean, 41 kPrimByte, 42 kPrimChar, 43 kPrimShort, 44 kPrimInt, 45 kPrimLong, 46 kPrimFloat, 47 kPrimDouble, 48 kPrimVoid, 49 kPrimLast = kPrimVoid 50 }; 51 52 static Type GetType(char type) { 53 switch (type) { 54 case 'B': 55 return kPrimByte; 56 case 'C': 57 return kPrimChar; 58 case 'D': 59 return kPrimDouble; 60 case 'F': 61 return kPrimFloat; 62 case 'I': 63 return kPrimInt; 64 case 'J': 65 return kPrimLong; 66 case 'S': 67 return kPrimShort; 68 case 'Z': 69 return kPrimBoolean; 70 case 'V': 71 return kPrimVoid; 72 default: 73 return kPrimNot; 74 } 75 } 76 77 static size_t ComponentSizeShift(Type type) { 78 switch (type) { 79 case kPrimVoid: 80 case kPrimBoolean: 81 case kPrimByte: return 0; 82 case kPrimChar: 83 case kPrimShort: return 1; 84 case kPrimInt: 85 case kPrimFloat: return 2; 86 case kPrimLong: 87 case kPrimDouble: return 3; 88 case kPrimNot: return ComponentSizeShiftWidth(kObjectReferenceSize); 89 default: 90 LOG(FATAL) << "Invalid type " << static_cast<int>(type); 91 return 0; 92 } 93 } 94 95 static size_t ComponentSize(Type type) { 96 switch (type) { 97 case kPrimVoid: return 0; 98 case kPrimBoolean: 99 case kPrimByte: return 1; 100 case kPrimChar: 101 case kPrimShort: return 2; 102 case kPrimInt: 103 case kPrimFloat: return 4; 104 case kPrimLong: 105 case kPrimDouble: return 8; 106 case kPrimNot: return kObjectReferenceSize; 107 default: 108 LOG(FATAL) << "Invalid type " << static_cast<int>(type); 109 return 0; 110 } 111 } 112 113 static const char* Descriptor(Type type) { 114 switch (type) { 115 case kPrimBoolean: 116 return "Z"; 117 case kPrimByte: 118 return "B"; 119 case kPrimChar: 120 return "C"; 121 case kPrimShort: 122 return "S"; 123 case kPrimInt: 124 return "I"; 125 case kPrimFloat: 126 return "F"; 127 case kPrimLong: 128 return "J"; 129 case kPrimDouble: 130 return "D"; 131 case kPrimVoid: 132 return "V"; 133 default: 134 LOG(FATAL) << "Primitive char conversion on invalid type " << static_cast<int>(type); 135 return nullptr; 136 } 137 } 138 139 static const char* PrettyDescriptor(Type type); 140 141 static bool IsFloatingPointType(Type type) { 142 return type == kPrimFloat || type == kPrimDouble; 143 } 144 145 static bool IsIntegralType(Type type) { 146 // The Java language does not allow treating boolean as an integral type but 147 // our bit representation makes it safe. 148 switch (type) { 149 case kPrimBoolean: 150 case kPrimByte: 151 case kPrimChar: 152 case kPrimShort: 153 case kPrimInt: 154 case kPrimLong: 155 return true; 156 default: 157 return false; 158 } 159 } 160 161 static bool IsIntOrLongType(Type type) { 162 return type == kPrimInt || type == kPrimLong; 163 } 164 165 static bool Is64BitType(Type type) { 166 return type == kPrimLong || type == kPrimDouble; 167 } 168 169 // Return the general kind of `type`, fusing integer-like types as kPrimInt. 170 static Type PrimitiveKind(Type type) { 171 switch (type) { 172 case kPrimBoolean: 173 case kPrimByte: 174 case kPrimShort: 175 case kPrimChar: 176 case kPrimInt: 177 return kPrimInt; 178 default: 179 return type; 180 } 181 } 182 183 static int64_t MinValueOfIntegralType(Type type) { 184 switch (type) { 185 case kPrimBoolean: 186 return std::numeric_limits<bool>::min(); 187 case kPrimByte: 188 return std::numeric_limits<int8_t>::min(); 189 case kPrimChar: 190 return std::numeric_limits<uint16_t>::min(); 191 case kPrimShort: 192 return std::numeric_limits<int16_t>::min(); 193 case kPrimInt: 194 return std::numeric_limits<int32_t>::min(); 195 case kPrimLong: 196 return std::numeric_limits<int64_t>::min(); 197 default: 198 LOG(FATAL) << "non integral type"; 199 } 200 return 0; 201 } 202 203 static int64_t MaxValueOfIntegralType(Type type) { 204 switch (type) { 205 case kPrimBoolean: 206 return std::numeric_limits<bool>::max(); 207 case kPrimByte: 208 return std::numeric_limits<int8_t>::max(); 209 case kPrimChar: 210 return std::numeric_limits<uint16_t>::max(); 211 case kPrimShort: 212 return std::numeric_limits<int16_t>::max(); 213 case kPrimInt: 214 return std::numeric_limits<int32_t>::max(); 215 case kPrimLong: 216 return std::numeric_limits<int64_t>::max(); 217 default: 218 LOG(FATAL) << "non integral type"; 219 } 220 return 0; 221 } 222 223 private: 224 DISALLOW_IMPLICIT_CONSTRUCTORS(Primitive); 225 }; 226 227 std::ostream& operator<<(std::ostream& os, const Primitive::Type& state); 228 229 } // namespace art 230 231 #endif // ART_RUNTIME_PRIMITIVE_H_ 232