1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_TYPES_INL_H_
6 #define V8_TYPES_INL_H_
7 
8 #include "src/types.h"
9 
10 #include "src/factory.h"
11 #include "src/handles-inl.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 // -----------------------------------------------------------------------------
17 // TypeImpl
18 
19 template<class Config>
cast(typename Config::Base * object)20 TypeImpl<Config>* TypeImpl<Config>::cast(typename Config::Base* object) {
21   TypeImpl* t = static_cast<TypeImpl*>(object);
22   DCHECK(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsRange() ||
23          t->IsUnion() || t->IsArray() || t->IsFunction() || t->IsContext());
24   return t;
25 }
26 
27 
28 // Most precise _current_ type of a value (usually its class).
29 template<class Config>
NowOf(i::Object * value,Region * region)30 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf(
31     i::Object* value, Region* region) {
32   if (value->IsSmi() ||
33       i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
34     return Of(value, region);
35   }
36   return Class(i::handle(i::HeapObject::cast(value)->map()), region);
37 }
38 
39 
40 template<class Config>
NowContains(i::Object * value)41 bool TypeImpl<Config>::NowContains(i::Object* value) {
42   DisallowHeapAllocation no_allocation;
43   if (this->IsAny()) return true;
44   if (value->IsHeapObject()) {
45     i::Map* map = i::HeapObject::cast(value)->map();
46     for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
47       if (*it.Current() == map) return true;
48     }
49   }
50   return this->Contains(value);
51 }
52 
53 
54 // -----------------------------------------------------------------------------
55 // ZoneTypeConfig
56 
57 // static
58 template<class T>
handle(T * type)59 T* ZoneTypeConfig::handle(T* type) {
60   return type;
61 }
62 
63 
64 // static
65 template<class T>
cast(Type * type)66 T* ZoneTypeConfig::cast(Type* type) {
67   return static_cast<T*>(type);
68 }
69 
70 
71 // static
is_bitset(Type * type)72 bool ZoneTypeConfig::is_bitset(Type* type) {
73   return reinterpret_cast<uintptr_t>(type) & 1;
74 }
75 
76 
77 // static
is_struct(Type * type,int tag)78 bool ZoneTypeConfig::is_struct(Type* type, int tag) {
79   return !is_bitset(type) && struct_tag(as_struct(type)) == tag;
80 }
81 
82 
83 // static
is_class(Type * type)84 bool ZoneTypeConfig::is_class(Type* type) {
85   return false;
86 }
87 
88 
89 // static
as_bitset(Type * type)90 ZoneTypeConfig::Type::bitset ZoneTypeConfig::as_bitset(Type* type) {
91   DCHECK(is_bitset(type));
92   return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type) ^ 1u);
93 }
94 
95 
96 // static
as_struct(Type * type)97 ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
98   DCHECK(!is_bitset(type));
99   return reinterpret_cast<Struct*>(type);
100 }
101 
102 
103 // static
as_class(Type * type)104 i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
105   UNREACHABLE();
106   return i::Handle<i::Map>();
107 }
108 
109 
110 // static
from_bitset(Type::bitset bitset)111 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(Type::bitset bitset) {
112   return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset | 1u));
113 }
114 
115 
116 // static
from_bitset(Type::bitset bitset,Zone * Zone)117 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(
118     Type::bitset bitset, Zone* Zone) {
119   return from_bitset(bitset);
120 }
121 
122 
123 // static
from_struct(Struct * structure)124 ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structure) {
125   return reinterpret_cast<Type*>(structure);
126 }
127 
128 
129 // static
from_class(i::Handle<i::Map> map,Zone * zone)130 ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
131     i::Handle<i::Map> map, Zone* zone) {
132   return from_bitset(0);
133 }
134 
135 
136 // static
struct_create(int tag,int length,Zone * zone)137 ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create(
138     int tag, int length, Zone* zone) {
139   Struct* structure = reinterpret_cast<Struct*>(
140       zone->New(sizeof(void*) * (length + 2)));  // NOLINT
141   structure[0] = reinterpret_cast<void*>(tag);
142   structure[1] = reinterpret_cast<void*>(length);
143   return structure;
144 }
145 
146 
147 // static
struct_shrink(Struct * structure,int length)148 void ZoneTypeConfig::struct_shrink(Struct* structure, int length) {
149   DCHECK(0 <= length && length <= struct_length(structure));
150   structure[1] = reinterpret_cast<void*>(length);
151 }
152 
153 
154 // static
struct_tag(Struct * structure)155 int ZoneTypeConfig::struct_tag(Struct* structure) {
156   return static_cast<int>(reinterpret_cast<intptr_t>(structure[0]));
157 }
158 
159 
160 // static
struct_length(Struct * structure)161 int ZoneTypeConfig::struct_length(Struct* structure) {
162   return static_cast<int>(reinterpret_cast<intptr_t>(structure[1]));
163 }
164 
165 
166 // static
struct_get(Struct * structure,int i)167 Type* ZoneTypeConfig::struct_get(Struct* structure, int i) {
168   DCHECK(0 <= i && i <= struct_length(structure));
169   return static_cast<Type*>(structure[2 + i]);
170 }
171 
172 
173 // static
struct_set(Struct * structure,int i,Type * x)174 void ZoneTypeConfig::struct_set(Struct* structure, int i, Type* x) {
175   DCHECK(0 <= i && i <= struct_length(structure));
176   structure[2 + i] = x;
177 }
178 
179 
180 // static
181 template<class V>
struct_get_value(Struct * structure,int i)182 i::Handle<V> ZoneTypeConfig::struct_get_value(Struct* structure, int i) {
183   DCHECK(0 <= i && i <= struct_length(structure));
184   return i::Handle<V>(static_cast<V**>(structure[2 + i]));
185 }
186 
187 
188 // static
189 template<class V>
struct_set_value(Struct * structure,int i,i::Handle<V> x)190 void ZoneTypeConfig::struct_set_value(
191     Struct* structure, int i, i::Handle<V> x) {
192   DCHECK(0 <= i && i <= struct_length(structure));
193   structure[2 + i] = x.location();
194 }
195 
196 
197 // -----------------------------------------------------------------------------
198 // HeapTypeConfig
199 
200 // static
201 template<class T>
handle(T * type)202 i::Handle<T> HeapTypeConfig::handle(T* type) {
203   return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
204 }
205 
206 
207 // static
208 template<class T>
cast(i::Handle<Type> type)209 i::Handle<T> HeapTypeConfig::cast(i::Handle<Type> type) {
210   return i::Handle<T>::cast(type);
211 }
212 
213 
214 // static
is_bitset(Type * type)215 bool HeapTypeConfig::is_bitset(Type* type) {
216   return type->IsSmi();
217 }
218 
219 
220 // static
is_class(Type * type)221 bool HeapTypeConfig::is_class(Type* type) {
222   return type->IsMap();
223 }
224 
225 
226 // static
is_struct(Type * type,int tag)227 bool HeapTypeConfig::is_struct(Type* type, int tag) {
228   return type->IsFixedArray() && struct_tag(as_struct(type)) == tag;
229 }
230 
231 
232 // static
as_bitset(Type * type)233 HeapTypeConfig::Type::bitset HeapTypeConfig::as_bitset(Type* type) {
234   // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
235   return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type));
236 }
237 
238 
239 // static
as_class(Type * type)240 i::Handle<i::Map> HeapTypeConfig::as_class(Type* type) {
241   return i::handle(i::Map::cast(type));
242 }
243 
244 
245 // static
as_struct(Type * type)246 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) {
247   return i::handle(Struct::cast(type));
248 }
249 
250 
251 // static
from_bitset(Type::bitset bitset)252 HeapTypeConfig::Type* HeapTypeConfig::from_bitset(Type::bitset bitset) {
253   // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
254   return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset));
255 }
256 
257 
258 // static
from_bitset(Type::bitset bitset,Isolate * isolate)259 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_bitset(
260     Type::bitset bitset, Isolate* isolate) {
261   return i::handle(from_bitset(bitset), isolate);
262 }
263 
264 
265 // static
from_class(i::Handle<i::Map> map,Isolate * isolate)266 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_class(
267     i::Handle<i::Map> map, Isolate* isolate) {
268   return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
269 }
270 
271 
272 // static
from_struct(i::Handle<Struct> structure)273 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_struct(
274     i::Handle<Struct> structure) {
275   return i::Handle<Type>::cast(i::Handle<Object>::cast(structure));
276 }
277 
278 
279 // static
struct_create(int tag,int length,Isolate * isolate)280 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::struct_create(
281     int tag, int length, Isolate* isolate) {
282   i::Handle<Struct> structure = isolate->factory()->NewFixedArray(length + 1);
283   structure->set(0, i::Smi::FromInt(tag));
284   return structure;
285 }
286 
287 
288 // static
struct_shrink(i::Handle<Struct> structure,int length)289 void HeapTypeConfig::struct_shrink(i::Handle<Struct> structure, int length) {
290   structure->Shrink(length + 1);
291 }
292 
293 
294 // static
struct_tag(i::Handle<Struct> structure)295 int HeapTypeConfig::struct_tag(i::Handle<Struct> structure) {
296   return static_cast<i::Smi*>(structure->get(0))->value();
297 }
298 
299 
300 // static
struct_length(i::Handle<Struct> structure)301 int HeapTypeConfig::struct_length(i::Handle<Struct> structure) {
302   return structure->length() - 1;
303 }
304 
305 
306 // static
struct_get(i::Handle<Struct> structure,int i)307 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::struct_get(
308     i::Handle<Struct> structure, int i) {
309   Type* type = static_cast<Type*>(structure->get(i + 1));
310   return i::handle(type, structure->GetIsolate());
311 }
312 
313 
314 // static
struct_set(i::Handle<Struct> structure,int i,i::Handle<Type> type)315 void HeapTypeConfig::struct_set(
316     i::Handle<Struct> structure, int i, i::Handle<Type> type) {
317   structure->set(i + 1, *type);
318 }
319 
320 
321 // static
322 template<class V>
struct_get_value(i::Handle<Struct> structure,int i)323 i::Handle<V> HeapTypeConfig::struct_get_value(
324     i::Handle<Struct> structure, int i) {
325   V* x = static_cast<V*>(structure->get(i + 1));
326   return i::handle(x, structure->GetIsolate());
327 }
328 
329 
330 // static
331 template<class V>
struct_set_value(i::Handle<Struct> structure,int i,i::Handle<V> x)332 void HeapTypeConfig::struct_set_value(
333     i::Handle<Struct> structure, int i, i::Handle<V> x) {
334   structure->set(i + 1, *x);
335 }
336 
337 } }  // namespace v8::internal
338 
339 #endif  // V8_TYPES_INL_H_
340