| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_PROPERTY_H_ | 5 #ifndef V8_PROPERTY_H_ |
| 6 #define V8_PROPERTY_H_ | 6 #define V8_PROPERTY_H_ |
| 7 | 7 |
| 8 #include "src/factory.h" | 8 #include "src/factory.h" |
| 9 #include "src/field-index.h" | 9 #include "src/field-index.h" |
| 10 #include "src/field-index-inl.h" | 10 #include "src/field-index-inl.h" |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 number_ = number; | 139 number_ = number; |
| 140 } | 140 } |
| 141 | 141 |
| 142 bool CanHoldValue(Handle<Object> value) const { | 142 bool CanHoldValue(Handle<Object> value) const { |
| 143 switch (type()) { | 143 switch (type()) { |
| 144 case NORMAL: | 144 case NORMAL: |
| 145 return true; | 145 return true; |
| 146 case FIELD: | 146 case FIELD: |
| 147 return value->FitsRepresentation(representation()) && | 147 return value->FitsRepresentation(representation()) && |
| 148 GetFieldType()->NowContains(value); | 148 GetFieldType()->NowContains(value); |
| 149 case CONSTANT: | 149 case CONSTANT: { |
| 150 DCHECK(GetConstant() != *value || | 150 Map* map = |
| 151 lookup_type_ == DESCRIPTOR_TYPE ? holder_->map() : transition_; |
| 152 Object* constant = GetConstantFromMap(map); |
| 153 DCHECK(constant != *value || |
| 151 value->FitsRepresentation(representation())); | 154 value->FitsRepresentation(representation())); |
| 152 return GetConstant() == *value; | 155 return constant == *value; |
| 156 } |
| 153 case CALLBACKS: | 157 case CALLBACKS: |
| 154 case HANDLER: | 158 case HANDLER: |
| 155 case INTERCEPTOR: | 159 case INTERCEPTOR: |
| 156 return true; | 160 return true; |
| 157 case NONEXISTENT: | 161 case NONEXISTENT: |
| 158 UNREACHABLE(); | 162 UNREACHABLE(); |
| 159 } | 163 } |
| 160 UNREACHABLE(); | 164 UNREACHABLE(); |
| 161 return true; | 165 return true; |
| 162 } | 166 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 bool IsNormal() const { | 259 bool IsNormal() const { |
| 256 DCHECK(!(details_.type() == NORMAL && !IsFound())); | 260 DCHECK(!(details_.type() == NORMAL && !IsFound())); |
| 257 return IsDescriptorOrDictionary() && type() == NORMAL; | 261 return IsDescriptorOrDictionary() && type() == NORMAL; |
| 258 } | 262 } |
| 259 | 263 |
| 260 bool IsConstant() const { | 264 bool IsConstant() const { |
| 261 DCHECK(!(details_.type() == CONSTANT && !IsFound())); | 265 DCHECK(!(details_.type() == CONSTANT && !IsFound())); |
| 262 return IsDescriptorOrDictionary() && type() == CONSTANT; | 266 return IsDescriptorOrDictionary() && type() == CONSTANT; |
| 263 } | 267 } |
| 264 | 268 |
| 265 bool IsConstantFunction() const { | |
| 266 return IsConstant() && GetConstant()->IsJSFunction(); | |
| 267 } | |
| 268 | |
| 269 bool IsDontDelete() const { return details_.IsDontDelete(); } | 269 bool IsDontDelete() const { return details_.IsDontDelete(); } |
| 270 bool IsDontEnum() const { return details_.IsDontEnum(); } | 270 bool IsDontEnum() const { return details_.IsDontEnum(); } |
| 271 bool IsFound() const { return lookup_type_ != NOT_FOUND; } | 271 bool IsFound() const { return lookup_type_ != NOT_FOUND; } |
| 272 bool IsDescriptorOrDictionary() const { | 272 bool IsDescriptorOrDictionary() const { |
| 273 return lookup_type_ == DESCRIPTOR_TYPE || lookup_type_ == DICTIONARY_TYPE; | 273 return lookup_type_ == DESCRIPTOR_TYPE || lookup_type_ == DICTIONARY_TYPE; |
| 274 } | 274 } |
| 275 bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; } | 275 bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; } |
| 276 bool IsHandler() const { return lookup_type_ == HANDLER_TYPE; } | 276 bool IsHandler() const { return lookup_type_ == HANDLER_TYPE; } |
| 277 bool IsInterceptor() const { return lookup_type_ == INTERCEPTOR_TYPE; } | 277 bool IsInterceptor() const { return lookup_type_ == INTERCEPTOR_TYPE; } |
| 278 | 278 |
| 279 // Is the result is a property excluding transitions and the null descriptor? | 279 // Is the result is a property excluding transitions and the null descriptor? |
| 280 bool IsProperty() const { | 280 bool IsProperty() const { |
| 281 return IsFound() && !IsTransition(); | 281 return IsFound() && !IsTransition(); |
| 282 } | 282 } |
| 283 | 283 |
| 284 bool IsDataProperty() const { | |
| 285 switch (lookup_type_) { | |
| 286 case NOT_FOUND: | |
| 287 case TRANSITION_TYPE: | |
| 288 case HANDLER_TYPE: | |
| 289 case INTERCEPTOR_TYPE: | |
| 290 return false; | |
| 291 | |
| 292 case DESCRIPTOR_TYPE: | |
| 293 case DICTIONARY_TYPE: | |
| 294 switch (type()) { | |
| 295 case FIELD: | |
| 296 case NORMAL: | |
| 297 case CONSTANT: | |
| 298 return true; | |
| 299 case CALLBACKS: { | |
| 300 Object* callback = GetCallbackObject(); | |
| 301 DCHECK(!callback->IsForeign()); | |
| 302 return callback->IsAccessorInfo(); | |
| 303 } | |
| 304 case HANDLER: | |
| 305 case INTERCEPTOR: | |
| 306 case NONEXISTENT: | |
| 307 UNREACHABLE(); | |
| 308 return false; | |
| 309 } | |
| 310 } | |
| 311 UNREACHABLE(); | |
| 312 return false; | |
| 313 } | |
| 314 | |
| 315 bool IsCacheable() const { return cacheable_; } | 284 bool IsCacheable() const { return cacheable_; } |
| 316 void DisallowCaching() { cacheable_ = false; } | 285 void DisallowCaching() { cacheable_ = false; } |
| 317 | 286 |
| 318 Object* GetLazyValue() const { | |
| 319 switch (lookup_type_) { | |
| 320 case NOT_FOUND: | |
| 321 case TRANSITION_TYPE: | |
| 322 case HANDLER_TYPE: | |
| 323 case INTERCEPTOR_TYPE: | |
| 324 return isolate()->heap()->the_hole_value(); | |
| 325 | |
| 326 case DESCRIPTOR_TYPE: | |
| 327 case DICTIONARY_TYPE: | |
| 328 switch (type()) { | |
| 329 case FIELD: | |
| 330 return holder()->RawFastPropertyAt(GetFieldIndex()); | |
| 331 case NORMAL: { | |
| 332 Object* value = holder()->property_dictionary()->ValueAt( | |
| 333 GetDictionaryEntry()); | |
| 334 if (holder()->IsGlobalObject()) { | |
| 335 value = PropertyCell::cast(value)->value(); | |
| 336 } | |
| 337 return value; | |
| 338 } | |
| 339 case CONSTANT: | |
| 340 return GetConstant(); | |
| 341 case CALLBACKS: | |
| 342 return isolate()->heap()->the_hole_value(); | |
| 343 case HANDLER: | |
| 344 case INTERCEPTOR: | |
| 345 case NONEXISTENT: | |
| 346 UNREACHABLE(); | |
| 347 return NULL; | |
| 348 } | |
| 349 } | |
| 350 UNREACHABLE(); | |
| 351 return NULL; | |
| 352 } | |
| 353 | |
| 354 Map* GetTransitionTarget() const { | 287 Map* GetTransitionTarget() const { |
| 355 DCHECK(IsTransition()); | 288 DCHECK(IsTransition()); |
| 356 return transition_; | 289 return transition_; |
| 357 } | 290 } |
| 358 | 291 |
| 359 bool IsTransitionToField() const { | 292 bool IsTransitionToField() const { |
| 360 return IsTransition() && details_.type() == FIELD; | 293 return IsTransition() && details_.type() == FIELD; |
| 361 } | 294 } |
| 362 | 295 |
| 363 bool IsTransitionToConstant() const { | 296 bool IsTransitionToConstant() const { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 377 | 310 |
| 378 int GetLocalFieldIndexFromMap(Map* map) const { | 311 int GetLocalFieldIndexFromMap(Map* map) const { |
| 379 return GetFieldIndexFromMap(map) - map->inobject_properties(); | 312 return GetFieldIndexFromMap(map) - map->inobject_properties(); |
| 380 } | 313 } |
| 381 | 314 |
| 382 int GetDictionaryEntry() const { | 315 int GetDictionaryEntry() const { |
| 383 DCHECK(lookup_type_ == DICTIONARY_TYPE); | 316 DCHECK(lookup_type_ == DICTIONARY_TYPE); |
| 384 return number_; | 317 return number_; |
| 385 } | 318 } |
| 386 | 319 |
| 387 JSFunction* GetConstantFunction() const { | |
| 388 DCHECK(type() == CONSTANT); | |
| 389 return JSFunction::cast(GetValue()); | |
| 390 } | |
| 391 | |
| 392 Object* GetConstantFromMap(Map* map) const { | 320 Object* GetConstantFromMap(Map* map) const { |
| 393 DCHECK(type() == CONSTANT); | 321 DCHECK(type() == CONSTANT); |
| 394 return GetValueFromMap(map); | 322 return GetValueFromMap(map); |
| 395 } | 323 } |
| 396 | 324 |
| 397 JSFunction* GetConstantFunctionFromMap(Map* map) const { | |
| 398 return JSFunction::cast(GetConstantFromMap(map)); | |
| 399 } | |
| 400 | |
| 401 Object* GetConstant() const { | |
| 402 DCHECK(type() == CONSTANT); | |
| 403 return GetValue(); | |
| 404 } | |
| 405 | |
| 406 Object* GetCallbackObject() const { | |
| 407 DCHECK(!IsTransition()); | |
| 408 DCHECK(type() == CALLBACKS); | |
| 409 return GetValue(); | |
| 410 } | |
| 411 | |
| 412 Object* GetValue() const { | |
| 413 if (lookup_type_ == DESCRIPTOR_TYPE) { | |
| 414 return GetValueFromMap(holder()->map()); | |
| 415 } else if (lookup_type_ == TRANSITION_TYPE) { | |
| 416 return GetValueFromMap(transition_); | |
| 417 } | |
| 418 // In the dictionary case, the data is held in the value field. | |
| 419 DCHECK(lookup_type_ == DICTIONARY_TYPE); | |
| 420 return holder()->GetNormalizedProperty(this); | |
| 421 } | |
| 422 | |
| 423 Object* GetValueFromMap(Map* map) const { | 325 Object* GetValueFromMap(Map* map) const { |
| 424 DCHECK(lookup_type_ == DESCRIPTOR_TYPE || | 326 DCHECK(lookup_type_ == DESCRIPTOR_TYPE || |
| 425 lookup_type_ == TRANSITION_TYPE); | 327 lookup_type_ == TRANSITION_TYPE); |
| 426 DCHECK(number_ < map->NumberOfOwnDescriptors()); | 328 DCHECK(number_ < map->NumberOfOwnDescriptors()); |
| 427 return map->instance_descriptors()->GetValue(number_); | 329 return map->instance_descriptors()->GetValue(number_); |
| 428 } | 330 } |
| 429 | 331 |
| 430 int GetFieldIndexFromMap(Map* map) const { | 332 int GetFieldIndexFromMap(Map* map) const { |
| 431 DCHECK(lookup_type_ == DESCRIPTOR_TYPE || | 333 DCHECK(lookup_type_ == DESCRIPTOR_TYPE || |
| 432 lookup_type_ == TRANSITION_TYPE); | 334 lookup_type_ == TRANSITION_TYPE); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 int number_; | 390 int number_; |
| 489 bool cacheable_; | 391 bool cacheable_; |
| 490 PropertyDetails details_; | 392 PropertyDetails details_; |
| 491 }; | 393 }; |
| 492 | 394 |
| 493 | 395 |
| 494 OStream& operator<<(OStream& os, const LookupResult& r); | 396 OStream& operator<<(OStream& os, const LookupResult& r); |
| 495 } } // namespace v8::internal | 397 } } // namespace v8::internal |
| 496 | 398 |
| 497 #endif // V8_PROPERTY_H_ | 399 #endif // V8_PROPERTY_H_ |
| OLD | NEW |