| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_PROPERTY_H_ | 28 #ifndef V8_PROPERTY_H_ |
| 29 #define V8_PROPERTY_H_ | 29 #define V8_PROPERTY_H_ |
| 30 | 30 |
| 31 #include "allocation.h" | 31 #include "allocation.h" |
| 32 #include "transitions.h" |
| 32 | 33 |
| 33 namespace v8 { | 34 namespace v8 { |
| 34 namespace internal { | 35 namespace internal { |
| 35 | 36 |
| 36 | 37 |
| 37 // Abstraction for elements in instance-descriptor arrays. | 38 // Abstraction for elements in instance-descriptor arrays. |
| 38 // | 39 // |
| 39 // Each descriptor has a key, property attributes, property type, | 40 // Each descriptor has a key, property attributes, property type, |
| 40 // property index (in the actual instance-descriptor array) and | 41 // property index (in the actual instance-descriptor array) and |
| 41 // optionally a piece of data. | 42 // optionally a piece of data. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 61 | 62 |
| 62 #ifdef OBJECT_PRINT | 63 #ifdef OBJECT_PRINT |
| 63 void Print(FILE* out); | 64 void Print(FILE* out); |
| 64 #endif | 65 #endif |
| 65 | 66 |
| 66 void SetEnumerationIndex(int index) { | 67 void SetEnumerationIndex(int index) { |
| 67 ASSERT(PropertyDetails::IsValidIndex(index)); | 68 ASSERT(PropertyDetails::IsValidIndex(index)); |
| 68 details_ = PropertyDetails(details_.attributes(), details_.type(), index); | 69 details_ = PropertyDetails(details_.attributes(), details_.type(), index); |
| 69 } | 70 } |
| 70 | 71 |
| 71 bool ContainsTransition(); | |
| 72 | |
| 73 private: | 72 private: |
| 74 String* key_; | 73 String* key_; |
| 75 Object* value_; | 74 Object* value_; |
| 76 PropertyDetails details_; | 75 PropertyDetails details_; |
| 77 | 76 |
| 78 protected: | 77 protected: |
| 79 Descriptor() : details_(Smi::FromInt(0)) {} | 78 Descriptor() : details_(Smi::FromInt(0)) {} |
| 80 | 79 |
| 81 void Init(String* key, Object* value, PropertyDetails details) { | 80 void Init(String* key, Object* value, PropertyDetails details) { |
| 82 key_ = key; | 81 key_ = key; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 94 PropertyAttributes attributes, | 93 PropertyAttributes attributes, |
| 95 PropertyType type, | 94 PropertyType type, |
| 96 int index = 0) | 95 int index = 0) |
| 97 : key_(key), | 96 : key_(key), |
| 98 value_(value), | 97 value_(value), |
| 99 details_(attributes, type, index) { } | 98 details_(attributes, type, index) { } |
| 100 | 99 |
| 101 friend class DescriptorArray; | 100 friend class DescriptorArray; |
| 102 }; | 101 }; |
| 103 | 102 |
| 104 // A pointer from a map to the new map that is created by adding | |
| 105 // a named property. These are key to the speed and functioning of V8. | |
| 106 // The two maps should always have the same prototype, since | |
| 107 // MapSpace::CreateBackPointers depends on this. | |
| 108 class MapTransitionDescriptor: public Descriptor { | |
| 109 public: | |
| 110 MapTransitionDescriptor(String* key, Map* map, PropertyAttributes attributes) | |
| 111 : Descriptor(key, map, attributes, MAP_TRANSITION) { } | |
| 112 }; | |
| 113 | |
| 114 // Marks a field name in a map so that adding the field is guaranteed | |
| 115 // to create a FIELD descriptor in the new map. Used after adding | |
| 116 // a constant function the first time, creating a CONSTANT_FUNCTION | |
| 117 // descriptor in the new map. This avoids creating multiple maps with | |
| 118 // the same CONSTANT_FUNCTION field. | |
| 119 class ConstTransitionDescriptor: public Descriptor { | |
| 120 public: | |
| 121 explicit ConstTransitionDescriptor(String* key, Map* map) | |
| 122 : Descriptor(key, map, NONE, CONSTANT_TRANSITION) { } | |
| 123 }; | |
| 124 | |
| 125 | 103 |
| 126 class FieldDescriptor: public Descriptor { | 104 class FieldDescriptor: public Descriptor { |
| 127 public: | 105 public: |
| 128 FieldDescriptor(String* key, | 106 FieldDescriptor(String* key, |
| 129 int field_index, | 107 int field_index, |
| 130 PropertyAttributes attributes, | 108 PropertyAttributes attributes, |
| 131 int index = 0) | 109 int index = 0) |
| 132 : Descriptor(key, Smi::FromInt(field_index), attributes, FIELD, index) {} | 110 : Descriptor(key, Smi::FromInt(field_index), attributes, FIELD, index) {} |
| 133 }; | 111 }; |
| 134 | 112 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 146 class CallbacksDescriptor: public Descriptor { | 124 class CallbacksDescriptor: public Descriptor { |
| 147 public: | 125 public: |
| 148 CallbacksDescriptor(String* key, | 126 CallbacksDescriptor(String* key, |
| 149 Object* foreign, | 127 Object* foreign, |
| 150 PropertyAttributes attributes, | 128 PropertyAttributes attributes, |
| 151 int index = 0) | 129 int index = 0) |
| 152 : Descriptor(key, foreign, attributes, CALLBACKS, index) {} | 130 : Descriptor(key, foreign, attributes, CALLBACKS, index) {} |
| 153 }; | 131 }; |
| 154 | 132 |
| 155 | 133 |
| 156 template <class T> | |
| 157 bool IsPropertyDescriptor(T* desc) { | |
| 158 switch (desc->type()) { | |
| 159 case NORMAL: | |
| 160 case FIELD: | |
| 161 case CONSTANT_FUNCTION: | |
| 162 case HANDLER: | |
| 163 case INTERCEPTOR: | |
| 164 return true; | |
| 165 case CALLBACKS: { | |
| 166 Object* callback_object = desc->GetCallbackObject(); | |
| 167 // Non-JavaScript (i.e. native) accessors are always a property, otherwise | |
| 168 // either the getter or the setter must be an accessor. Put another way: | |
| 169 // If we only see map transitions and holes in a pair, this is not a | |
| 170 // property. | |
| 171 return (!callback_object->IsAccessorPair() || | |
| 172 AccessorPair::cast(callback_object)->ContainsAccessor()); | |
| 173 } | |
| 174 case MAP_TRANSITION: | |
| 175 case CONSTANT_TRANSITION: | |
| 176 return false; | |
| 177 case NONEXISTENT: | |
| 178 UNREACHABLE(); | |
| 179 break; | |
| 180 } | |
| 181 UNREACHABLE(); // keep the compiler happy | |
| 182 return false; | |
| 183 } | |
| 184 | |
| 185 | |
| 186 class LookupResult BASE_EMBEDDED { | 134 class LookupResult BASE_EMBEDDED { |
| 187 public: | 135 public: |
| 188 explicit LookupResult(Isolate* isolate) | 136 explicit LookupResult(Isolate* isolate) |
| 189 : isolate_(isolate), | 137 : isolate_(isolate), |
| 190 next_(isolate->top_lookup_result()), | 138 next_(isolate->top_lookup_result()), |
| 191 lookup_type_(NOT_FOUND), | 139 lookup_type_(NOT_FOUND), |
| 192 holder_(NULL), | 140 holder_(NULL), |
| 193 cacheable_(true), | 141 cacheable_(true), |
| 194 details_(NONE, NONEXISTENT) { | 142 details_(NONE, NONEXISTENT) { |
| 195 isolate->SetTopLookupResult(this); | 143 isolate->SetTopLookupResult(this); |
| 196 } | 144 } |
| 197 | 145 |
| 198 ~LookupResult() { | 146 ~LookupResult() { |
| 199 ASSERT(isolate_->top_lookup_result() == this); | 147 ASSERT(isolate_->top_lookup_result() == this); |
| 200 isolate_->SetTopLookupResult(next_); | 148 isolate_->SetTopLookupResult(next_); |
| 201 } | 149 } |
| 202 | 150 |
| 203 void DescriptorResult(JSObject* holder, PropertyDetails details, int number) { | 151 void DescriptorResult(JSObject* holder, PropertyDetails details, int number) { |
| 204 lookup_type_ = DESCRIPTOR_TYPE; | 152 lookup_type_ = DESCRIPTOR_TYPE; |
| 205 holder_ = holder; | 153 holder_ = holder; |
| 206 details_ = details; | 154 details_ = details; |
| 207 number_ = number; | 155 number_ = number; |
| 208 } | 156 } |
| 209 | 157 |
| 158 void TransitionResult(JSObject* holder, int number) { |
| 159 lookup_type_ = TRANSITION_TYPE; |
| 160 details_ = PropertyDetails(NONE, TRANSITION); |
| 161 holder_ = holder; |
| 162 number_ = number; |
| 163 } |
| 164 |
| 210 void ConstantResult(JSObject* holder) { | 165 void ConstantResult(JSObject* holder) { |
| 211 lookup_type_ = CONSTANT_TYPE; | 166 lookup_type_ = CONSTANT_TYPE; |
| 212 holder_ = holder; | 167 holder_ = holder; |
| 213 details_ = | 168 details_ = |
| 214 PropertyDetails(static_cast<PropertyAttributes>(DONT_ENUM | | 169 PropertyDetails(static_cast<PropertyAttributes>(DONT_ENUM | |
| 215 DONT_DELETE), | 170 DONT_DELETE), |
| 216 CALLBACKS); | 171 CALLBACKS); |
| 217 number_ = -1; | 172 number_ = -1; |
| 218 } | 173 } |
| 219 | 174 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 ASSERT(IsFound()); | 207 ASSERT(IsFound()); |
| 253 return JSProxy::cast(holder_); | 208 return JSProxy::cast(holder_); |
| 254 } | 209 } |
| 255 | 210 |
| 256 PropertyType type() { | 211 PropertyType type() { |
| 257 ASSERT(IsFound()); | 212 ASSERT(IsFound()); |
| 258 return details_.type(); | 213 return details_.type(); |
| 259 } | 214 } |
| 260 | 215 |
| 261 PropertyAttributes GetAttributes() { | 216 PropertyAttributes GetAttributes() { |
| 217 ASSERT(!IsTransition()); |
| 262 ASSERT(IsFound()); | 218 ASSERT(IsFound()); |
| 219 ASSERT(details_.type() != NONEXISTENT); |
| 263 return details_.attributes(); | 220 return details_.attributes(); |
| 264 } | 221 } |
| 265 | 222 |
| 266 PropertyDetails GetPropertyDetails() { | 223 PropertyDetails GetPropertyDetails() { |
| 224 ASSERT(!IsTransition()); |
| 267 return details_; | 225 return details_; |
| 268 } | 226 } |
| 269 | 227 |
| 270 bool IsFastPropertyType() { | 228 bool IsFastPropertyType() { |
| 271 ASSERT(IsFound()); | 229 ASSERT(IsFound()); |
| 272 return type() != NORMAL; | 230 return IsTransition() || type() != NORMAL; |
| 231 } |
| 232 |
| 233 // Property callbacks does not include transitions to callbacks. |
| 234 bool IsPropertyCallbacks() { |
| 235 ASSERT(!(details_.type() == CALLBACKS && !IsFound())); |
| 236 return details_.type() == CALLBACKS; |
| 237 } |
| 238 |
| 239 // Is callbacks contains both property callbacks and transitions to callbacks. |
| 240 bool IsCallbacks() { |
| 241 return IsPropertyCallbacks() || |
| 242 (IsTransition() && GetTransitionValue()->IsAccessorPair()); |
| 273 } | 243 } |
| 274 | 244 |
| 275 bool IsReadOnly() { | 245 bool IsReadOnly() { |
| 276 ASSERT(IsFound()); | 246 ASSERT(IsFound()); |
| 247 ASSERT(!IsTransition()); |
| 248 ASSERT(details_.type() != NONEXISTENT); |
| 277 return details_.IsReadOnly(); | 249 return details_.IsReadOnly(); |
| 278 } | 250 } |
| 279 | 251 |
| 280 bool IsCallbacks() { | |
| 281 ASSERT(!(details_.type() == CALLBACKS && !IsFound())); | |
| 282 return details_.type() == CALLBACKS; | |
| 283 } | |
| 284 | |
| 285 bool IsField() { | 252 bool IsField() { |
| 286 ASSERT(!(details_.type() == FIELD && !IsFound())); | 253 ASSERT(!(details_.type() == FIELD && !IsFound())); |
| 287 return details_.type() == FIELD; | 254 return details_.type() == FIELD; |
| 288 } | 255 } |
| 289 | 256 |
| 290 bool IsNormal() { | 257 bool IsNormal() { |
| 291 ASSERT(!(details_.type() == NORMAL && !IsFound())); | 258 ASSERT(!(details_.type() == NORMAL && !IsFound())); |
| 292 return details_.type() == NORMAL; | 259 return details_.type() == NORMAL; |
| 293 } | 260 } |
| 294 | 261 |
| 295 bool IsConstantFunction() { | 262 bool IsConstantFunction() { |
| 296 ASSERT(!(details_.type() == CONSTANT_FUNCTION && !IsFound())); | 263 ASSERT(!(details_.type() == CONSTANT_FUNCTION && !IsFound())); |
| 297 return details_.type() == CONSTANT_FUNCTION; | 264 return details_.type() == CONSTANT_FUNCTION; |
| 298 } | 265 } |
| 299 | 266 |
| 300 bool IsMapTransition() { | |
| 301 ASSERT(!(details_.type() == MAP_TRANSITION && !IsFound())); | |
| 302 return details_.type() == MAP_TRANSITION; | |
| 303 } | |
| 304 | |
| 305 bool IsDontDelete() { return details_.IsDontDelete(); } | 267 bool IsDontDelete() { return details_.IsDontDelete(); } |
| 306 bool IsDontEnum() { return details_.IsDontEnum(); } | 268 bool IsDontEnum() { return details_.IsDontEnum(); } |
| 307 bool IsDeleted() { return details_.IsDeleted(); } | 269 bool IsDeleted() { return details_.IsDeleted(); } |
| 308 bool IsFound() { return lookup_type_ != NOT_FOUND; } | 270 bool IsFound() { return lookup_type_ != NOT_FOUND; } |
| 271 bool IsTransition() { return lookup_type_ == TRANSITION_TYPE; } |
| 309 bool IsHandler() { return lookup_type_ == HANDLER_TYPE; } | 272 bool IsHandler() { return lookup_type_ == HANDLER_TYPE; } |
| 310 bool IsInterceptor() { return lookup_type_ == INTERCEPTOR_TYPE; } | 273 bool IsInterceptor() { return lookup_type_ == INTERCEPTOR_TYPE; } |
| 311 | 274 |
| 312 // Is the result is a property excluding transitions and the null descriptor? | 275 // Is the result is a property excluding transitions and the null descriptor? |
| 313 bool IsProperty() { | 276 bool IsProperty() { |
| 314 return IsFound() && IsPropertyDescriptor(this); | 277 return IsFound() && !IsTransition(); |
| 315 } | 278 } |
| 316 | 279 |
| 317 bool IsCacheable() { return cacheable_; } | 280 bool IsCacheable() { return cacheable_; } |
| 318 void DisallowCaching() { cacheable_ = false; } | 281 void DisallowCaching() { cacheable_ = false; } |
| 319 | 282 |
| 320 Object* GetLazyValue() { | 283 Object* GetLazyValue() { |
| 321 switch (type()) { | 284 switch (type()) { |
| 322 case FIELD: | 285 case FIELD: |
| 323 return holder()->FastPropertyAt(GetFieldIndex()); | 286 return holder()->FastPropertyAt(GetFieldIndex()); |
| 324 case NORMAL: { | 287 case NORMAL: { |
| 325 Object* value; | 288 Object* value; |
| 326 value = holder()->property_dictionary()->ValueAt(GetDictionaryEntry()); | 289 value = holder()->property_dictionary()->ValueAt(GetDictionaryEntry()); |
| 327 if (holder()->IsGlobalObject()) { | 290 if (holder()->IsGlobalObject()) { |
| 328 value = JSGlobalPropertyCell::cast(value)->value(); | 291 value = JSGlobalPropertyCell::cast(value)->value(); |
| 329 } | 292 } |
| 330 return value; | 293 return value; |
| 331 } | 294 } |
| 332 case CONSTANT_FUNCTION: | 295 case CONSTANT_FUNCTION: |
| 333 return GetConstantFunction(); | 296 return GetConstantFunction(); |
| 334 default: | 297 default: |
| 335 return Smi::FromInt(0); | 298 return Smi::FromInt(0); |
| 336 } | 299 } |
| 337 } | 300 } |
| 338 | 301 |
| 302 Object* GetTransitionValue() { |
| 303 ASSERT(IsTransition()); |
| 304 TransitionArray* transitions = holder()->map()->transitions(); |
| 305 Object* value = transitions->GetValue(number_); |
| 306 return value; |
| 307 } |
| 308 |
| 309 PropertyDetails GetTransitionDetails(Map* map) { |
| 310 ASSERT(IsTransition()); |
| 311 TransitionArray* transitions = map->transitions(); |
| 312 return transitions->GetTargetDetails(number_); |
| 313 } |
| 314 |
| 315 PropertyDetails GetTransitionDetails() { |
| 316 return GetTransitionDetails(holder()->map()); |
| 317 } |
| 318 |
| 319 bool IsTransitionToField(Map* map) { |
| 320 return IsTransition() && GetTransitionDetails(map).type() == FIELD; |
| 321 } |
| 322 |
| 339 Map* GetTransitionMap() { | 323 Map* GetTransitionMap() { |
| 340 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); | 324 ASSERT(IsTransition()); |
| 341 ASSERT(type() == MAP_TRANSITION || | |
| 342 type() == CONSTANT_TRANSITION); | |
| 343 return Map::cast(GetValue()); | 325 return Map::cast(GetValue()); |
| 344 } | 326 } |
| 345 | 327 |
| 346 Map* GetTransitionMapFromMap(Map* map) { | 328 Map* GetTransitionMapFromMap(Map* map) { |
| 347 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); | 329 ASSERT(IsTransition()); |
| 348 ASSERT(type() == MAP_TRANSITION); | 330 return Map::cast(map->transitions()->GetValue(number_)); |
| 349 return Map::cast(map->instance_descriptors()->GetValue(number_)); | |
| 350 } | 331 } |
| 351 | 332 |
| 352 int GetFieldIndex() { | 333 int GetFieldIndex() { |
| 353 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); | 334 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); |
| 354 ASSERT(IsField()); | 335 ASSERT(IsField()); |
| 355 return Descriptor::IndexFromValue(GetValue()); | 336 return Descriptor::IndexFromValue(GetValue()); |
| 356 } | 337 } |
| 357 | 338 |
| 358 int GetLocalFieldIndexFromMap(Map* map) { | 339 int GetLocalFieldIndexFromMap(Map* map) { |
| 359 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); | 340 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 373 return JSFunction::cast(GetValue()); | 354 return JSFunction::cast(GetValue()); |
| 374 } | 355 } |
| 375 | 356 |
| 376 JSFunction* GetConstantFunctionFromMap(Map* map) { | 357 JSFunction* GetConstantFunctionFromMap(Map* map) { |
| 377 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); | 358 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); |
| 378 ASSERT(type() == CONSTANT_FUNCTION); | 359 ASSERT(type() == CONSTANT_FUNCTION); |
| 379 return JSFunction::cast(map->instance_descriptors()->GetValue(number_)); | 360 return JSFunction::cast(map->instance_descriptors()->GetValue(number_)); |
| 380 } | 361 } |
| 381 | 362 |
| 382 Object* GetCallbackObject() { | 363 Object* GetCallbackObject() { |
| 383 if (lookup_type_ == CONSTANT_TYPE) { | 364 switch (lookup_type_) { |
| 384 // For now we only have the __proto__ as constant type. | 365 case CONSTANT_TYPE: |
| 385 return HEAP->prototype_accessors(); | 366 return HEAP->prototype_accessors(); |
| 367 case TRANSITION_TYPE: |
| 368 return GetTransitionValue(); |
| 369 default: |
| 370 return GetValue(); |
| 386 } | 371 } |
| 387 return GetValue(); | |
| 388 } | 372 } |
| 389 | 373 |
| 390 #ifdef OBJECT_PRINT | 374 #ifdef OBJECT_PRINT |
| 391 void Print(FILE* out); | 375 void Print(FILE* out); |
| 392 #endif | 376 #endif |
| 393 | 377 |
| 394 Object* GetValue() { | 378 Object* GetValue() { |
| 395 if (lookup_type_ == DESCRIPTOR_TYPE) { | 379 if (lookup_type_ == DESCRIPTOR_TYPE) { |
| 396 DescriptorArray* descriptors = holder()->map()->instance_descriptors(); | 380 DescriptorArray* descriptors = holder()->map()->instance_descriptors(); |
| 397 return descriptors->GetValue(number_); | 381 return descriptors->GetValue(number_); |
| 398 } | 382 } |
| 399 // In the dictionary case, the data is held in the value field. | 383 // In the dictionary case, the data is held in the value field. |
| 400 ASSERT(lookup_type_ == DICTIONARY_TYPE); | 384 ASSERT(lookup_type_ == DICTIONARY_TYPE); |
| 401 return holder()->GetNormalizedProperty(this); | 385 return holder()->GetNormalizedProperty(this); |
| 402 } | 386 } |
| 403 | 387 |
| 404 void Iterate(ObjectVisitor* visitor); | 388 void Iterate(ObjectVisitor* visitor); |
| 405 | 389 |
| 406 private: | 390 private: |
| 407 Isolate* isolate_; | 391 Isolate* isolate_; |
| 408 LookupResult* next_; | 392 LookupResult* next_; |
| 409 | 393 |
| 410 // Where did we find the result; | 394 // Where did we find the result; |
| 411 enum { | 395 enum { |
| 412 NOT_FOUND, | 396 NOT_FOUND, |
| 413 DESCRIPTOR_TYPE, | 397 DESCRIPTOR_TYPE, |
| 398 TRANSITION_TYPE, |
| 414 DICTIONARY_TYPE, | 399 DICTIONARY_TYPE, |
| 415 HANDLER_TYPE, | 400 HANDLER_TYPE, |
| 416 INTERCEPTOR_TYPE, | 401 INTERCEPTOR_TYPE, |
| 417 CONSTANT_TYPE | 402 CONSTANT_TYPE |
| 418 } lookup_type_; | 403 } lookup_type_; |
| 419 | 404 |
| 420 JSReceiver* holder_; | 405 JSReceiver* holder_; |
| 421 int number_; | 406 int number_; |
| 422 bool cacheable_; | 407 bool cacheable_; |
| 423 PropertyDetails details_; | 408 PropertyDetails details_; |
| 424 }; | 409 }; |
| 425 | 410 |
| 426 | 411 |
| 427 } } // namespace v8::internal | 412 } } // namespace v8::internal |
| 428 | 413 |
| 429 #endif // V8_PROPERTY_H_ | 414 #endif // V8_PROPERTY_H_ |
| OLD | NEW |