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.
5 #ifndef V8_TYPES_INL_H_
6 #define V8_TYPES_INL_H_
10 #include "src/factory.h"
11 #include "src/handles-inl.h"
16 // -----------------------------------------------------------------------------
19 template<class Config>
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());
28 // Most precise _current_ type of a value (usually its class).
29 template<class Config>
30 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf(
31 i::Object* value, Region* region) {
33 i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
34 return Of(value, region);
36 return Class(i::handle(i::HeapObject::cast(value)->map()), region);
40 template<class Config>
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;
50 return this->Contains(value);
54 // -----------------------------------------------------------------------------
59 T* ZoneTypeConfig::null_handle() {
66 T* ZoneTypeConfig::handle(T* type) {
73 T* ZoneTypeConfig::cast(Type* type) {
74 return static_cast<T*>(type);
79 bool ZoneTypeConfig::is_bitset(Type* type) {
80 return reinterpret_cast<uintptr_t>(type) & 1;
85 bool ZoneTypeConfig::is_struct(Type* type, int tag) {
86 return !is_bitset(type) && struct_tag(as_struct(type)) == tag;
91 bool ZoneTypeConfig::is_class(Type* type) {
97 ZoneTypeConfig::Type::bitset ZoneTypeConfig::as_bitset(Type* type) {
98 DCHECK(is_bitset(type));
99 return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type) ^ 1u);
104 ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
105 DCHECK(!is_bitset(type));
106 return reinterpret_cast<Struct*>(type);
111 i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
113 return i::Handle<i::Map>();
118 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(Type::bitset bitset) {
119 return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset | 1u));
124 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(
125 Type::bitset bitset, Zone* Zone) {
126 return from_bitset(bitset);
131 ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structure) {
132 return reinterpret_cast<Type*>(structure);
137 ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
138 i::Handle<i::Map> map, Zone* zone) {
139 return from_bitset(0);
144 ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create(
145 int tag, int length, Zone* zone) {
146 Struct* structure = reinterpret_cast<Struct*>(
147 zone->New(sizeof(void*) * (length + 2))); // NOLINT
148 structure[0] = reinterpret_cast<void*>(tag);
149 structure[1] = reinterpret_cast<void*>(length);
155 void ZoneTypeConfig::struct_shrink(Struct* structure, int length) {
156 DCHECK(0 <= length && length <= struct_length(structure));
157 structure[1] = reinterpret_cast<void*>(length);
162 int ZoneTypeConfig::struct_tag(Struct* structure) {
163 return static_cast<int>(reinterpret_cast<intptr_t>(structure[0]));
168 int ZoneTypeConfig::struct_length(Struct* structure) {
169 return static_cast<int>(reinterpret_cast<intptr_t>(structure[1]));
174 Type* ZoneTypeConfig::struct_get(Struct* structure, int i) {
175 DCHECK(0 <= i && i <= struct_length(structure));
176 return static_cast<Type*>(structure[2 + i]);
181 void ZoneTypeConfig::struct_set(Struct* structure, int i, Type* x) {
182 DCHECK(0 <= i && i <= struct_length(structure));
183 structure[2 + i] = x;
189 i::Handle<V> ZoneTypeConfig::struct_get_value(Struct* structure, int i) {
190 DCHECK(0 <= i && i <= struct_length(structure));
191 return i::Handle<V>(static_cast<V**>(structure[2 + i]));
197 void ZoneTypeConfig::struct_set_value(
198 Struct* structure, int i, i::Handle<V> x) {
199 DCHECK(0 <= i && i <= struct_length(structure));
200 structure[2 + i] = x.location();
204 // -----------------------------------------------------------------------------
209 i::Handle<T> HeapTypeConfig::null_handle() {
210 return i::Handle<T>();
216 i::Handle<T> HeapTypeConfig::handle(T* type) {
217 return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
223 i::Handle<T> HeapTypeConfig::cast(i::Handle<Type> type) {
224 return i::Handle<T>::cast(type);
229 bool HeapTypeConfig::is_bitset(Type* type) {
230 return type->IsSmi();
235 bool HeapTypeConfig::is_class(Type* type) {
236 return type->IsMap();
241 bool HeapTypeConfig::is_struct(Type* type, int tag) {
242 return type->IsFixedArray() && struct_tag(as_struct(type)) == tag;
247 HeapTypeConfig::Type::bitset HeapTypeConfig::as_bitset(Type* type) {
248 // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
249 return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type));
254 i::Handle<i::Map> HeapTypeConfig::as_class(Type* type) {
255 return i::handle(i::Map::cast(type));
260 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) {
261 return i::handle(Struct::cast(type));
266 HeapTypeConfig::Type* HeapTypeConfig::from_bitset(Type::bitset bitset) {
267 // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
268 return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset));
273 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_bitset(
274 Type::bitset bitset, Isolate* isolate) {
275 return i::handle(from_bitset(bitset), isolate);
280 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_class(
281 i::Handle<i::Map> map, Isolate* isolate) {
282 return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
287 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_struct(
288 i::Handle<Struct> structure) {
289 return i::Handle<Type>::cast(i::Handle<Object>::cast(structure));
294 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::struct_create(
295 int tag, int length, Isolate* isolate) {
296 i::Handle<Struct> structure = isolate->factory()->NewFixedArray(length + 1);
297 structure->set(0, i::Smi::FromInt(tag));
303 void HeapTypeConfig::struct_shrink(i::Handle<Struct> structure, int length) {
304 structure->Shrink(length + 1);
309 int HeapTypeConfig::struct_tag(i::Handle<Struct> structure) {
310 return static_cast<i::Smi*>(structure->get(0))->value();
315 int HeapTypeConfig::struct_length(i::Handle<Struct> structure) {
316 return structure->length() - 1;
321 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::struct_get(
322 i::Handle<Struct> structure, int i) {
323 Type* type = static_cast<Type*>(structure->get(i + 1));
324 return i::handle(type, structure->GetIsolate());
329 void HeapTypeConfig::struct_set(
330 i::Handle<Struct> structure, int i, i::Handle<Type> type) {
331 structure->set(i + 1, *type);
337 i::Handle<V> HeapTypeConfig::struct_get_value(
338 i::Handle<Struct> structure, int i) {
339 V* x = static_cast<V*>(structure->get(i + 1));
340 return i::handle(x, structure->GetIsolate());
346 void HeapTypeConfig::struct_set_value(
347 i::Handle<Struct> structure, int i, i::Handle<V> x) {
348 structure->set(i + 1, *x);
351 } } // namespace v8::internal
353 #endif // V8_TYPES_INL_H_