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 |