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 
ComponentSizeShiftWidth(size_t component_size)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   };
50 
GetType(char type)51   static Type GetType(char type) {
52     switch (type) {
53       case 'B':
54         return kPrimByte;
55       case 'C':
56         return kPrimChar;
57       case 'D':
58         return kPrimDouble;
59       case 'F':
60         return kPrimFloat;
61       case 'I':
62         return kPrimInt;
63       case 'J':
64         return kPrimLong;
65       case 'S':
66         return kPrimShort;
67       case 'Z':
68         return kPrimBoolean;
69       case 'V':
70         return kPrimVoid;
71       default:
72         return kPrimNot;
73     }
74   }
75 
ComponentSizeShift(Type type)76   static size_t ComponentSizeShift(Type type) {
77     switch (type) {
78       case kPrimVoid:
79       case kPrimBoolean:
80       case kPrimByte:    return 0;
81       case kPrimChar:
82       case kPrimShort:   return 1;
83       case kPrimInt:
84       case kPrimFloat:   return 2;
85       case kPrimLong:
86       case kPrimDouble:  return 3;
87       case kPrimNot:     return ComponentSizeShiftWidth(kObjectReferenceSize);
88       default:
89         LOG(FATAL) << "Invalid type " << static_cast<int>(type);
90         return 0;
91     }
92   }
93 
ComponentSize(Type type)94   static size_t ComponentSize(Type type) {
95     switch (type) {
96       case kPrimVoid:    return 0;
97       case kPrimBoolean:
98       case kPrimByte:    return 1;
99       case kPrimChar:
100       case kPrimShort:   return 2;
101       case kPrimInt:
102       case kPrimFloat:   return 4;
103       case kPrimLong:
104       case kPrimDouble:  return 8;
105       case kPrimNot:     return kObjectReferenceSize;
106       default:
107         LOG(FATAL) << "Invalid type " << static_cast<int>(type);
108         return 0;
109     }
110   }
111 
Descriptor(Type type)112   static const char* Descriptor(Type type) {
113     switch (type) {
114       case kPrimBoolean:
115         return "Z";
116       case kPrimByte:
117         return "B";
118       case kPrimChar:
119         return "C";
120       case kPrimShort:
121         return "S";
122       case kPrimInt:
123         return "I";
124       case kPrimFloat:
125         return "F";
126       case kPrimLong:
127         return "J";
128       case kPrimDouble:
129         return "D";
130       case kPrimVoid:
131         return "V";
132       default:
133         LOG(FATAL) << "Primitive char conversion on invalid type " << static_cast<int>(type);
134         return nullptr;
135     }
136   }
137 
138   static const char* PrettyDescriptor(Type type);
139 
IsFloatingPointType(Type type)140   static bool IsFloatingPointType(Type type) {
141     return type == kPrimFloat || type == kPrimDouble;
142   }
143 
IsIntegralType(Type type)144   static bool IsIntegralType(Type type) {
145     // The Java language does not allow treating boolean as an integral type but
146     // our bit representation makes it safe.
147     switch (type) {
148       case kPrimBoolean:
149       case kPrimByte:
150       case kPrimChar:
151       case kPrimShort:
152       case kPrimInt:
153       case kPrimLong:
154         return true;
155       default:
156         return false;
157     }
158   }
159 
IsIntOrLongType(Type type)160   static bool IsIntOrLongType(Type type) {
161     return type == kPrimInt || type == kPrimLong;
162   }
163 
Is64BitType(Type type)164   static bool Is64BitType(Type type) {
165     return type == kPrimLong || type == kPrimDouble;
166   }
167 
168  private:
169   DISALLOW_IMPLICIT_CONSTRUCTORS(Primitive);
170 };
171 
172 std::ostream& operator<<(std::ostream& os, const Primitive::Type& state);
173 
174 }  // namespace art
175 
176 #endif  // ART_RUNTIME_PRIMITIVE_H_
177