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 ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() ||
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<intptr_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 int ZoneTypeConfig::as_bitset(Type* type) {
91 ASSERT(is_bitset(type));
92 return static_cast<int>(reinterpret_cast<intptr_t>(type) >> 1);
93 }
94
95
96 // static
as_struct(Type * type)97 ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
98 ASSERT(!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(int bitset)111 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(int bitset) {
112 return reinterpret_cast<Type*>((bitset << 1) | 1);
113 }
114
115
116 // static
from_bitset(int bitset,Zone * Zone)117 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(int bitset, Zone* Zone) {
118 return from_bitset(bitset);
119 }
120
121
122 // static
from_struct(Struct * structure)123 ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structure) {
124 return reinterpret_cast<Type*>(structure);
125 }
126
127
128 // static
from_class(i::Handle<i::Map> map,Zone * zone)129 ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
130 i::Handle<i::Map> map, Zone* zone) {
131 return from_bitset(0);
132 }
133
134
135 // static
struct_create(int tag,int length,Zone * zone)136 ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create(
137 int tag, int length, Zone* zone) {
138 Struct* structure = reinterpret_cast<Struct*>(
139 zone->New(sizeof(void*) * (length + 2))); // NOLINT
140 structure[0] = reinterpret_cast<void*>(tag);
141 structure[1] = reinterpret_cast<void*>(length);
142 return structure;
143 }
144
145
146 // static
struct_shrink(Struct * structure,int length)147 void ZoneTypeConfig::struct_shrink(Struct* structure, int length) {
148 ASSERT(0 <= length && length <= struct_length(structure));
149 structure[1] = reinterpret_cast<void*>(length);
150 }
151
152
153 // static
struct_tag(Struct * structure)154 int ZoneTypeConfig::struct_tag(Struct* structure) {
155 return static_cast<int>(reinterpret_cast<intptr_t>(structure[0]));
156 }
157
158
159 // static
struct_length(Struct * structure)160 int ZoneTypeConfig::struct_length(Struct* structure) {
161 return static_cast<int>(reinterpret_cast<intptr_t>(structure[1]));
162 }
163
164
165 // static
struct_get(Struct * structure,int i)166 Type* ZoneTypeConfig::struct_get(Struct* structure, int i) {
167 ASSERT(0 <= i && i <= struct_length(structure));
168 return static_cast<Type*>(structure[2 + i]);
169 }
170
171
172 // static
struct_set(Struct * structure,int i,Type * x)173 void ZoneTypeConfig::struct_set(Struct* structure, int i, Type* x) {
174 ASSERT(0 <= i && i <= struct_length(structure));
175 structure[2 + i] = x;
176 }
177
178
179 // static
180 template<class V>
struct_get_value(Struct * structure,int i)181 i::Handle<V> ZoneTypeConfig::struct_get_value(Struct* structure, int i) {
182 ASSERT(0 <= i && i <= struct_length(structure));
183 return i::Handle<V>(static_cast<V**>(structure[2 + i]));
184 }
185
186
187 // static
188 template<class V>
struct_set_value(Struct * structure,int i,i::Handle<V> x)189 void ZoneTypeConfig::struct_set_value(
190 Struct* structure, int i, i::Handle<V> x) {
191 ASSERT(0 <= i && i <= struct_length(structure));
192 structure[2 + i] = x.location();
193 }
194
195
196 // -----------------------------------------------------------------------------
197 // HeapTypeConfig
198
199 // static
200 template<class T>
handle(T * type)201 i::Handle<T> HeapTypeConfig::handle(T* type) {
202 return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
203 }
204
205
206 // static
207 template<class T>
cast(i::Handle<Type> type)208 i::Handle<T> HeapTypeConfig::cast(i::Handle<Type> type) {
209 return i::Handle<T>::cast(type);
210 }
211
212
213 // static
is_bitset(Type * type)214 bool HeapTypeConfig::is_bitset(Type* type) {
215 return type->IsSmi();
216 }
217
218
219 // static
is_class(Type * type)220 bool HeapTypeConfig::is_class(Type* type) {
221 return type->IsMap();
222 }
223
224
225 // static
is_struct(Type * type,int tag)226 bool HeapTypeConfig::is_struct(Type* type, int tag) {
227 return type->IsFixedArray() && struct_tag(as_struct(type)) == tag;
228 }
229
230
231 // static
as_bitset(Type * type)232 int HeapTypeConfig::as_bitset(Type* type) {
233 return i::Smi::cast(type)->value();
234 }
235
236
237 // static
as_class(Type * type)238 i::Handle<i::Map> HeapTypeConfig::as_class(Type* type) {
239 return i::handle(i::Map::cast(type));
240 }
241
242
243 // static
as_struct(Type * type)244 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) {
245 return i::handle(Struct::cast(type));
246 }
247
248
249 // static
from_bitset(int bitset)250 HeapTypeConfig::Type* HeapTypeConfig::from_bitset(int bitset) {
251 return Type::cast(i::Smi::FromInt(bitset));
252 }
253
254
255 // static
from_bitset(int bitset,Isolate * isolate)256 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_bitset(
257 int bitset, Isolate* isolate) {
258 return i::handle(from_bitset(bitset), isolate);
259 }
260
261
262 // static
from_class(i::Handle<i::Map> map,Isolate * isolate)263 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_class(
264 i::Handle<i::Map> map, Isolate* isolate) {
265 return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
266 }
267
268
269 // static
from_struct(i::Handle<Struct> structure)270 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_struct(
271 i::Handle<Struct> structure) {
272 return i::Handle<Type>::cast(i::Handle<Object>::cast(structure));
273 }
274
275
276 // static
struct_create(int tag,int length,Isolate * isolate)277 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::struct_create(
278 int tag, int length, Isolate* isolate) {
279 i::Handle<Struct> structure = isolate->factory()->NewFixedArray(length + 1);
280 structure->set(0, i::Smi::FromInt(tag));
281 return structure;
282 }
283
284
285 // static
struct_shrink(i::Handle<Struct> structure,int length)286 void HeapTypeConfig::struct_shrink(i::Handle<Struct> structure, int length) {
287 structure->Shrink(length + 1);
288 }
289
290
291 // static
struct_tag(i::Handle<Struct> structure)292 int HeapTypeConfig::struct_tag(i::Handle<Struct> structure) {
293 return static_cast<i::Smi*>(structure->get(0))->value();
294 }
295
296
297 // static
struct_length(i::Handle<Struct> structure)298 int HeapTypeConfig::struct_length(i::Handle<Struct> structure) {
299 return structure->length() - 1;
300 }
301
302
303 // static
struct_get(i::Handle<Struct> structure,int i)304 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::struct_get(
305 i::Handle<Struct> structure, int i) {
306 Type* type = static_cast<Type*>(structure->get(i + 1));
307 return i::handle(type, structure->GetIsolate());
308 }
309
310
311 // static
struct_set(i::Handle<Struct> structure,int i,i::Handle<Type> type)312 void HeapTypeConfig::struct_set(
313 i::Handle<Struct> structure, int i, i::Handle<Type> type) {
314 structure->set(i + 1, *type);
315 }
316
317
318 // static
319 template<class V>
struct_get_value(i::Handle<Struct> structure,int i)320 i::Handle<V> HeapTypeConfig::struct_get_value(
321 i::Handle<Struct> structure, int i) {
322 V* x = static_cast<V*>(structure->get(i + 1));
323 return i::handle(x, structure->GetIsolate());
324 }
325
326
327 // static
328 template<class V>
struct_set_value(i::Handle<Struct> structure,int i,i::Handle<V> x)329 void HeapTypeConfig::struct_set_value(
330 i::Handle<Struct> structure, int i, i::Handle<V> x) {
331 structure->set(i + 1, *x);
332 }
333
334 } } // namespace v8::internal
335
336 #endif // V8_TYPES_INL_H_
337