| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 } | 524 } |
| 525 } | 525 } |
| 526 return result; | 526 return result; |
| 527 } | 527 } |
| 528 | 528 |
| 529 | 529 |
| 530 Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object, | 530 Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object, |
| 531 KeyCollectionType type) { | 531 KeyCollectionType type) { |
| 532 Handle<FixedArray> content = Factory::empty_fixed_array(); | 532 Handle<FixedArray> content = Factory::empty_fixed_array(); |
| 533 | 533 |
| 534 JSObject* arguments_boilerplate = | 534 // Only collect keys if access is permitted. |
| 535 Top::context()->global_context()->arguments_boilerplate(); | 535 for (Handle<Object> p = object; |
| 536 JSFunction* arguments_function = | 536 *p != Heap::null_value(); |
| 537 JSFunction::cast(arguments_boilerplate->map()->constructor()); | 537 p = Handle<Object>(p->GetPrototype())) { |
| 538 bool allow_enumeration = (object->map()->constructor() != arguments_function); | 538 Handle<JSObject> current(JSObject::cast(*p)); |
| 539 | 539 |
| 540 // Only collect keys if access is permitted. | 540 // Check access rights if required. |
| 541 if (allow_enumeration) { | 541 if (current->IsAccessCheckNeeded() && |
| 542 for (Handle<Object> p = object; | 542 !Top::MayNamedAccess(*current, Heap::undefined_value(), |
| 543 *p != Heap::null_value(); | 543 v8::ACCESS_KEYS)) { |
| 544 p = Handle<Object>(p->GetPrototype())) { | 544 Top::ReportFailedAccessCheck(*current, v8::ACCESS_KEYS); |
| 545 Handle<JSObject> current(JSObject::cast(*p)); | 545 break; |
| 546 } |
| 546 | 547 |
| 547 // Check access rights if required. | 548 // Compute the element keys. |
| 548 if (current->IsAccessCheckNeeded() && | 549 Handle<FixedArray> element_keys = |
| 549 !Top::MayNamedAccess(*current, Heap::undefined_value(), | 550 Factory::NewFixedArray(current->NumberOfEnumElements()); |
| 550 v8::ACCESS_KEYS)) { | 551 current->GetEnumElementKeys(*element_keys); |
| 551 Top::ReportFailedAccessCheck(*current, v8::ACCESS_KEYS); | 552 content = UnionOfKeys(content, element_keys); |
| 552 break; | |
| 553 } | |
| 554 | 553 |
| 555 // Compute the element keys. | 554 // Add the element keys from the interceptor. |
| 556 Handle<FixedArray> element_keys = | 555 if (current->HasIndexedInterceptor()) { |
| 557 Factory::NewFixedArray(current->NumberOfEnumElements()); | 556 v8::Handle<v8::Array> result = |
| 558 current->GetEnumElementKeys(*element_keys); | 557 GetKeysForIndexedInterceptor(object, current); |
| 559 content = UnionOfKeys(content, element_keys); | 558 if (!result.IsEmpty()) |
| 559 content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result)); |
| 560 } |
| 560 | 561 |
| 561 // Add the element keys from the interceptor. | 562 // Compute the property keys. |
| 562 if (current->HasIndexedInterceptor()) { | 563 content = UnionOfKeys(content, GetEnumPropertyKeys(current)); |
| 563 v8::Handle<v8::Array> result = | |
| 564 GetKeysForIndexedInterceptor(object, current); | |
| 565 if (!result.IsEmpty()) | |
| 566 content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result)); | |
| 567 } | |
| 568 | 564 |
| 569 // Compute the property keys. | 565 // Add the property keys from the interceptor. |
| 570 content = UnionOfKeys(content, GetEnumPropertyKeys(current)); | 566 if (current->HasNamedInterceptor()) { |
| 567 v8::Handle<v8::Array> result = |
| 568 GetKeysForNamedInterceptor(object, current); |
| 569 if (!result.IsEmpty()) |
| 570 content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result)); |
| 571 } |
| 571 | 572 |
| 572 // Add the property keys from the interceptor. | 573 // If we only want local properties we bail out after the first |
| 573 if (current->HasNamedInterceptor()) { | 574 // iteration. |
| 574 v8::Handle<v8::Array> result = | 575 if (type == LOCAL_ONLY) |
| 575 GetKeysForNamedInterceptor(object, current); | 576 break; |
| 576 if (!result.IsEmpty()) | |
| 577 content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result)); | |
| 578 } | |
| 579 | |
| 580 // If we only want local properties we bail out after the first | |
| 581 // iteration. | |
| 582 if (type == LOCAL_ONLY) | |
| 583 break; | |
| 584 } | |
| 585 } | 577 } |
| 586 return content; | 578 return content; |
| 587 } | 579 } |
| 588 | 580 |
| 589 | 581 |
| 590 Handle<JSArray> GetKeysFor(Handle<JSObject> object) { | 582 Handle<JSArray> GetKeysFor(Handle<JSObject> object) { |
| 591 Counters::for_in.Increment(); | 583 Counters::for_in.Increment(); |
| 592 Handle<FixedArray> elements = GetKeysInFixedArrayFor(object, | 584 Handle<FixedArray> elements = GetKeysInFixedArrayFor(object, |
| 593 INCLUDE_PROTOS); | 585 INCLUDE_PROTOS); |
| 594 return Factory::NewJSArrayWithElements(elements); | 586 return Factory::NewJSArrayWithElements(elements); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 Handle<Map> new_map = Factory::CopyMapDropTransitions(old_map); | 757 Handle<Map> new_map = Factory::CopyMapDropTransitions(old_map); |
| 766 obj->set_map(*new_map); | 758 obj->set_map(*new_map); |
| 767 new_map->set_needs_loading(true); | 759 new_map->set_needs_loading(true); |
| 768 // Store the lazy loading info in the constructor field. We'll | 760 // Store the lazy loading info in the constructor field. We'll |
| 769 // reestablish the constructor from the fixed array after loading. | 761 // reestablish the constructor from the fixed array after loading. |
| 770 new_map->set_constructor(*arr); | 762 new_map->set_constructor(*arr); |
| 771 ASSERT(!obj->IsLoaded()); | 763 ASSERT(!obj->IsLoaded()); |
| 772 } | 764 } |
| 773 | 765 |
| 774 } } // namespace v8::internal | 766 } } // namespace v8::internal |
| OLD | NEW |