OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #include <stdlib.h> | 5 #include <stdlib.h> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 1994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2005 isolate, result, JSObject::PreventExtensions(obj)); | 2005 isolate, result, JSObject::PreventExtensions(obj)); |
2006 return *result; | 2006 return *result; |
2007 } | 2007 } |
2008 | 2008 |
2009 | 2009 |
2010 RUNTIME_FUNCTION(Runtime_IsExtensible) { | 2010 RUNTIME_FUNCTION(Runtime_IsExtensible) { |
2011 SealHandleScope shs(isolate); | 2011 SealHandleScope shs(isolate); |
2012 ASSERT(args.length() == 1); | 2012 ASSERT(args.length() == 1); |
2013 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 2013 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
2014 if (obj->IsJSGlobalProxy()) { | 2014 if (obj->IsJSGlobalProxy()) { |
2015 Object* proto = obj->GetPrototype(); | 2015 PrototypeIterator iter(isolate, obj); |
2016 if (proto->IsNull()) return isolate->heap()->false_value(); | 2016 if (iter.IsAtEnd()) return isolate->heap()->false_value(); |
2017 ASSERT(proto->IsJSGlobalObject()); | 2017 ASSERT(iter.GetCurrent()->IsJSGlobalObject()); |
2018 obj = JSObject::cast(proto); | 2018 obj = JSObject::cast(iter.GetCurrent()); |
2019 } | 2019 } |
2020 return isolate->heap()->ToBoolean(obj->map()->is_extensible()); | 2020 return isolate->heap()->ToBoolean(obj->map()->is_extensible()); |
2021 } | 2021 } |
2022 | 2022 |
2023 | 2023 |
2024 RUNTIME_FUNCTION(Runtime_RegExpCompile) { | 2024 RUNTIME_FUNCTION(Runtime_RegExpCompile) { |
2025 HandleScope scope(isolate); | 2025 HandleScope scope(isolate); |
2026 ASSERT(args.length() == 3); | 2026 ASSERT(args.length() == 3); |
2027 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0); | 2027 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0); |
2028 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); | 2028 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); |
(...skipping 2916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4945 // Take special care when attributes are different and there is already | 4945 // Take special care when attributes are different and there is already |
4946 // a property. For simplicity we normalize the property which enables us | 4946 // a property. For simplicity we normalize the property which enables us |
4947 // to not worry about changing the instance_descriptor and creating a new | 4947 // to not worry about changing the instance_descriptor and creating a new |
4948 // map. | 4948 // map. |
4949 if (lookup.IsFound() && | 4949 if (lookup.IsFound() && |
4950 (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) { | 4950 (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) { |
4951 // New attributes - normalize to avoid writing to instance descriptor | 4951 // New attributes - normalize to avoid writing to instance descriptor |
4952 if (js_object->IsJSGlobalProxy()) { | 4952 if (js_object->IsJSGlobalProxy()) { |
4953 // Since the result is a property, the prototype will exist so | 4953 // Since the result is a property, the prototype will exist so |
4954 // we don't have to check for null. | 4954 // we don't have to check for null. |
4955 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); | 4955 PrototypeIterator iter(isolate, js_object); |
| 4956 js_object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
4956 } | 4957 } |
4957 | 4958 |
4958 if (attr != lookup.GetAttributes() || | 4959 if (attr != lookup.GetAttributes() || |
4959 (lookup.IsPropertyCallbacks() && | 4960 (lookup.IsPropertyCallbacks() && |
4960 !lookup.GetCallbackObject()->IsAccessorInfo())) { | 4961 !lookup.GetCallbackObject()->IsAccessorInfo())) { |
4961 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 4962 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
4962 } | 4963 } |
4963 | 4964 |
4964 // Use IgnoreAttributes version since a readonly property may be | 4965 // Use IgnoreAttributes version since a readonly property may be |
4965 // overridden and SetProperty does not allow this. | 4966 // overridden and SetProperty does not allow this. |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5466 | 5467 |
5467 static Object* HasOwnPropertyImplementation(Isolate* isolate, | 5468 static Object* HasOwnPropertyImplementation(Isolate* isolate, |
5468 Handle<JSObject> object, | 5469 Handle<JSObject> object, |
5469 Handle<Name> key) { | 5470 Handle<Name> key) { |
5470 if (JSReceiver::HasOwnProperty(object, key)) { | 5471 if (JSReceiver::HasOwnProperty(object, key)) { |
5471 return isolate->heap()->true_value(); | 5472 return isolate->heap()->true_value(); |
5472 } | 5473 } |
5473 // Handle hidden prototypes. If there's a hidden prototype above this thing | 5474 // Handle hidden prototypes. If there's a hidden prototype above this thing |
5474 // then we have to check it for properties, because they are supposed to | 5475 // then we have to check it for properties, because they are supposed to |
5475 // look like they are on this object. | 5476 // look like they are on this object. |
5476 Handle<Object> proto(object->GetPrototype(), isolate); | 5477 PrototypeIterator iter(isolate, object); |
5477 if (proto->IsJSObject() && | 5478 if (!iter.IsAtEnd() && |
5478 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { | 5479 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)) |
5479 return HasOwnPropertyImplementation(isolate, | 5480 ->map() |
5480 Handle<JSObject>::cast(proto), | 5481 ->is_hidden_prototype()) { |
5481 key); | 5482 // TODO(verwaest): The recursion is not necessary for keys that are array |
| 5483 // indicies. Removing this. |
| 5484 return HasOwnPropertyImplementation( |
| 5485 isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), |
| 5486 key); |
5482 } | 5487 } |
5483 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5488 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
5484 return isolate->heap()->false_value(); | 5489 return isolate->heap()->false_value(); |
5485 } | 5490 } |
5486 | 5491 |
5487 | 5492 |
5488 RUNTIME_FUNCTION(Runtime_HasOwnProperty) { | 5493 RUNTIME_FUNCTION(Runtime_HasOwnProperty) { |
5489 HandleScope scope(isolate); | 5494 HandleScope scope(isolate); |
5490 ASSERT(args.length() == 2); | 5495 ASSERT(args.length() == 2); |
5491 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0) | 5496 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0) |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5609 | 5614 |
5610 return *content; | 5615 return *content; |
5611 } | 5616 } |
5612 | 5617 |
5613 | 5618 |
5614 // Find the length of the prototype chain that is to be handled as one. If a | 5619 // Find the length of the prototype chain that is to be handled as one. If a |
5615 // prototype object is hidden it is to be viewed as part of the the object it | 5620 // prototype object is hidden it is to be viewed as part of the the object it |
5616 // is prototype for. | 5621 // is prototype for. |
5617 static int OwnPrototypeChainLength(JSObject* obj) { | 5622 static int OwnPrototypeChainLength(JSObject* obj) { |
5618 int count = 1; | 5623 int count = 1; |
5619 Object* proto = obj->GetPrototype(); | 5624 for (PrototypeIterator iter(obj->GetIsolate(), obj); |
5620 while (proto->IsJSObject() && | 5625 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { |
5621 JSObject::cast(proto)->map()->is_hidden_prototype()) { | |
5622 count++; | 5626 count++; |
5623 proto = JSObject::cast(proto)->GetPrototype(); | |
5624 } | 5627 } |
5625 return count; | 5628 return count; |
5626 } | 5629 } |
5627 | 5630 |
5628 | 5631 |
5629 // Return the names of the own named properties. | 5632 // Return the names of the own named properties. |
5630 // args[0]: object | 5633 // args[0]: object |
5631 // args[1]: PropertyAttributes as int | 5634 // args[1]: PropertyAttributes as int |
5632 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { | 5635 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { |
5633 HandleScope scope(isolate); | 5636 HandleScope scope(isolate); |
5634 ASSERT(args.length() == 2); | 5637 ASSERT(args.length() == 2); |
5635 if (!args[0]->IsJSObject()) { | 5638 if (!args[0]->IsJSObject()) { |
5636 return isolate->heap()->undefined_value(); | 5639 return isolate->heap()->undefined_value(); |
5637 } | 5640 } |
5638 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 5641 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
5639 CONVERT_SMI_ARG_CHECKED(filter_value, 1); | 5642 CONVERT_SMI_ARG_CHECKED(filter_value, 1); |
5640 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); | 5643 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); |
5641 | 5644 |
5642 // Skip the global proxy as it has no properties and always delegates to the | 5645 // Skip the global proxy as it has no properties and always delegates to the |
5643 // real global object. | 5646 // real global object. |
5644 if (obj->IsJSGlobalProxy()) { | 5647 if (obj->IsJSGlobalProxy()) { |
5645 // Only collect names if access is permitted. | 5648 // Only collect names if access is permitted. |
5646 if (obj->IsAccessCheckNeeded() && | 5649 if (obj->IsAccessCheckNeeded() && |
5647 !isolate->MayNamedAccess( | 5650 !isolate->MayNamedAccess( |
5648 obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5651 obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
5649 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS); | 5652 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS); |
5650 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5653 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
5651 return *isolate->factory()->NewJSArray(0); | 5654 return *isolate->factory()->NewJSArray(0); |
5652 } | 5655 } |
5653 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 5656 PrototypeIterator iter(isolate, obj); |
| 5657 obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
5654 } | 5658 } |
5655 | 5659 |
5656 // Find the number of objects making up this. | 5660 // Find the number of objects making up this. |
5657 int length = OwnPrototypeChainLength(*obj); | 5661 int length = OwnPrototypeChainLength(*obj); |
5658 | 5662 |
5659 // Find the number of own properties for each of the objects. | 5663 // Find the number of own properties for each of the objects. |
5660 ScopedVector<int> own_property_count(length); | 5664 ScopedVector<int> own_property_count(length); |
5661 int total_property_count = 0; | 5665 int total_property_count = 0; |
5662 Handle<JSObject> jsproto = obj; | 5666 { |
5663 for (int i = 0; i < length; i++) { | 5667 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
5664 // Only collect names if access is permitted. | 5668 for (int i = 0; i < length; i++) { |
5665 if (jsproto->IsAccessCheckNeeded() && | 5669 ASSERT(!iter.IsAtEnd()); |
5666 !isolate->MayNamedAccess( | 5670 Handle<JSObject> jsproto = |
5667 jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5671 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
5668 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); | 5672 // Only collect names if access is permitted. |
5669 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5673 if (jsproto->IsAccessCheckNeeded() && |
5670 return *isolate->factory()->NewJSArray(0); | 5674 !isolate->MayNamedAccess(jsproto, |
5671 } | 5675 isolate->factory()->undefined_value(), |
5672 int n; | 5676 v8::ACCESS_KEYS)) { |
5673 n = jsproto->NumberOfOwnProperties(filter); | 5677 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); |
5674 own_property_count[i] = n; | 5678 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
5675 total_property_count += n; | 5679 return *isolate->factory()->NewJSArray(0); |
5676 if (i < length - 1) { | 5680 } |
5677 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 5681 int n; |
| 5682 n = jsproto->NumberOfOwnProperties(filter); |
| 5683 own_property_count[i] = n; |
| 5684 total_property_count += n; |
| 5685 iter.Advance(); |
5678 } | 5686 } |
5679 } | 5687 } |
5680 | 5688 |
5681 // Allocate an array with storage for all the property names. | 5689 // Allocate an array with storage for all the property names. |
5682 Handle<FixedArray> names = | 5690 Handle<FixedArray> names = |
5683 isolate->factory()->NewFixedArray(total_property_count); | 5691 isolate->factory()->NewFixedArray(total_property_count); |
5684 | 5692 |
5685 // Get the property names. | 5693 // Get the property names. |
5686 jsproto = obj; | |
5687 int next_copy_index = 0; | 5694 int next_copy_index = 0; |
5688 int hidden_strings = 0; | 5695 int hidden_strings = 0; |
5689 for (int i = 0; i < length; i++) { | 5696 { |
5690 jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); | 5697 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
5691 if (i > 0) { | 5698 for (int i = 0; i < length; i++) { |
5692 // Names from hidden prototypes may already have been added | 5699 ASSERT(!iter.IsAtEnd()); |
5693 // for inherited function template instances. Count the duplicates | 5700 Handle<JSObject> jsproto = |
5694 // and stub them out; the final copy pass at the end ignores holes. | 5701 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
5695 for (int j = next_copy_index; | 5702 jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); |
5696 j < next_copy_index + own_property_count[i]; | 5703 if (i > 0) { |
5697 j++) { | 5704 // Names from hidden prototypes may already have been added |
5698 Object* name_from_hidden_proto = names->get(j); | 5705 // for inherited function template instances. Count the duplicates |
5699 for (int k = 0; k < next_copy_index; k++) { | 5706 // and stub them out; the final copy pass at the end ignores holes. |
5700 if (names->get(k) != isolate->heap()->hidden_string()) { | 5707 for (int j = next_copy_index; |
5701 Object* name = names->get(k); | 5708 j < next_copy_index + own_property_count[i]; j++) { |
5702 if (name_from_hidden_proto == name) { | 5709 Object* name_from_hidden_proto = names->get(j); |
5703 names->set(j, isolate->heap()->hidden_string()); | 5710 for (int k = 0; k < next_copy_index; k++) { |
5704 hidden_strings++; | 5711 if (names->get(k) != isolate->heap()->hidden_string()) { |
5705 break; | 5712 Object* name = names->get(k); |
| 5713 if (name_from_hidden_proto == name) { |
| 5714 names->set(j, isolate->heap()->hidden_string()); |
| 5715 hidden_strings++; |
| 5716 break; |
| 5717 } |
5706 } | 5718 } |
5707 } | 5719 } |
5708 } | 5720 } |
5709 } | 5721 } |
5710 } | 5722 next_copy_index += own_property_count[i]; |
5711 next_copy_index += own_property_count[i]; | |
5712 | 5723 |
5713 // Hidden properties only show up if the filter does not skip strings. | 5724 // Hidden properties only show up if the filter does not skip strings. |
5714 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { | 5725 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { |
5715 hidden_strings++; | 5726 hidden_strings++; |
5716 } | 5727 } |
5717 if (i < length - 1) { | 5728 iter.Advance(); |
5718 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | |
5719 } | 5729 } |
5720 } | 5730 } |
5721 | 5731 |
5722 // Filter out name of hidden properties object and | 5732 // Filter out name of hidden properties object and |
5723 // hidden prototype duplicates. | 5733 // hidden prototype duplicates. |
5724 if (hidden_strings > 0) { | 5734 if (hidden_strings > 0) { |
5725 Handle<FixedArray> old_names = names; | 5735 Handle<FixedArray> old_names = names; |
5726 names = isolate->factory()->NewFixedArray( | 5736 names = isolate->factory()->NewFixedArray( |
5727 names->length() - hidden_strings); | 5737 names->length() - hidden_strings); |
5728 int dest_pos = 0; | 5738 int dest_pos = 0; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5819 if (object->IsJSGlobalProxy()) { | 5829 if (object->IsJSGlobalProxy()) { |
5820 // Do access checks before going to the global object. | 5830 // Do access checks before going to the global object. |
5821 if (object->IsAccessCheckNeeded() && | 5831 if (object->IsAccessCheckNeeded() && |
5822 !isolate->MayNamedAccess( | 5832 !isolate->MayNamedAccess( |
5823 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5833 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
5824 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); | 5834 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); |
5825 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5835 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
5826 return *isolate->factory()->NewJSArray(0); | 5836 return *isolate->factory()->NewJSArray(0); |
5827 } | 5837 } |
5828 | 5838 |
5829 Handle<Object> proto(object->GetPrototype(), isolate); | 5839 PrototypeIterator iter(isolate, object); |
5830 // If proxy is detached we simply return an empty array. | 5840 // If proxy is detached we simply return an empty array. |
5831 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); | 5841 if (iter.IsAtEnd()) return *isolate->factory()->NewJSArray(0); |
5832 object = Handle<JSObject>::cast(proto); | 5842 object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
5833 } | 5843 } |
5834 | 5844 |
5835 Handle<FixedArray> contents; | 5845 Handle<FixedArray> contents; |
5836 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5846 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5837 isolate, contents, | 5847 isolate, contents, |
5838 JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY)); | 5848 JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY)); |
5839 | 5849 |
5840 // Some fast paths through GetKeysInFixedArrayFor reuse a cached | 5850 // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
5841 // property array and since the result is mutable we have to create | 5851 // property array and since the result is mutable we have to create |
5842 // a fresh clone on each invocation. | 5852 // a fresh clone on each invocation. |
(...skipping 4253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10096 indices->Clear(); | 10106 indices->Clear(); |
10097 } | 10107 } |
10098 for (uint32_t i = 0; i < length; i++) { | 10108 for (uint32_t i = 0; i < length; i++) { |
10099 indices->Add(i); | 10109 indices->Add(i); |
10100 } | 10110 } |
10101 if (length == range) return; // All indices accounted for already. | 10111 if (length == range) return; // All indices accounted for already. |
10102 break; | 10112 break; |
10103 } | 10113 } |
10104 } | 10114 } |
10105 | 10115 |
10106 Handle<Object> prototype(object->GetPrototype(), isolate); | 10116 PrototypeIterator iter(isolate, object); |
10107 if (prototype->IsJSObject()) { | 10117 if (!iter.IsAtEnd()) { |
10108 // The prototype will usually have no inherited element indices, | 10118 // The prototype will usually have no inherited element indices, |
10109 // but we have to check. | 10119 // but we have to check. |
10110 CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices); | 10120 CollectElementIndices( |
| 10121 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range, |
| 10122 indices); |
10111 } | 10123 } |
10112 } | 10124 } |
10113 | 10125 |
10114 | 10126 |
10115 /** | 10127 /** |
10116 * A helper function that visits elements of a JSArray in numerical | 10128 * A helper function that visits elements of a JSArray in numerical |
10117 * order. | 10129 * order. |
10118 * | 10130 * |
10119 * The visitor argument called for each existing element in the array | 10131 * The visitor argument called for each existing element in the array |
10120 * with the element index and the element's value. | 10132 * with the element index and the element's value. |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10722 details->set(0, *element_or_char); | 10734 details->set(0, *element_or_char); |
10723 details->set( | 10735 details->set( |
10724 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); | 10736 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); |
10725 return *isolate->factory()->NewJSArrayWithElements(details); | 10737 return *isolate->factory()->NewJSArrayWithElements(details); |
10726 } | 10738 } |
10727 | 10739 |
10728 // Find the number of objects making up this. | 10740 // Find the number of objects making up this. |
10729 int length = OwnPrototypeChainLength(*obj); | 10741 int length = OwnPrototypeChainLength(*obj); |
10730 | 10742 |
10731 // Try own lookup on each of the objects. | 10743 // Try own lookup on each of the objects. |
10732 Handle<JSObject> jsproto = obj; | 10744 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
10733 for (int i = 0; i < length; i++) { | 10745 for (int i = 0; i < length; i++) { |
| 10746 ASSERT(!iter.IsAtEnd()); |
| 10747 Handle<JSObject> jsproto = |
| 10748 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
10734 LookupResult result(isolate); | 10749 LookupResult result(isolate); |
10735 jsproto->LookupOwn(name, &result); | 10750 jsproto->LookupOwn(name, &result); |
10736 if (result.IsFound()) { | 10751 if (result.IsFound()) { |
10737 // LookupResult is not GC safe as it holds raw object pointers. | 10752 // LookupResult is not GC safe as it holds raw object pointers. |
10738 // GC can happen later in this code so put the required fields into | 10753 // GC can happen later in this code so put the required fields into |
10739 // local variables using handles when required for later use. | 10754 // local variables using handles when required for later use. |
10740 Handle<Object> result_callback_obj; | 10755 Handle<Object> result_callback_obj; |
10741 if (result.IsPropertyCallbacks()) { | 10756 if (result.IsPropertyCallbacks()) { |
10742 result_callback_obj = Handle<Object>(result.GetCallbackObject(), | 10757 result_callback_obj = Handle<Object>(result.GetCallbackObject(), |
10743 isolate); | 10758 isolate); |
(...skipping 14 matching lines...) Expand all Loading... |
10758 details->set(1, result.GetPropertyDetails().AsSmi()); | 10773 details->set(1, result.GetPropertyDetails().AsSmi()); |
10759 if (has_js_accessors) { | 10774 if (has_js_accessors) { |
10760 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); | 10775 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); |
10761 details->set(2, isolate->heap()->ToBoolean(has_caught)); | 10776 details->set(2, isolate->heap()->ToBoolean(has_caught)); |
10762 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); | 10777 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); |
10763 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); | 10778 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); |
10764 } | 10779 } |
10765 | 10780 |
10766 return *isolate->factory()->NewJSArrayWithElements(details); | 10781 return *isolate->factory()->NewJSArrayWithElements(details); |
10767 } | 10782 } |
10768 if (i < length - 1) { | 10783 iter.Advance(); |
10769 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | |
10770 } | |
10771 } | 10784 } |
10772 | 10785 |
10773 return isolate->heap()->undefined_value(); | 10786 return isolate->heap()->undefined_value(); |
10774 } | 10787 } |
10775 | 10788 |
10776 | 10789 |
10777 RUNTIME_FUNCTION(Runtime_DebugGetProperty) { | 10790 RUNTIME_FUNCTION(Runtime_DebugGetProperty) { |
10778 HandleScope scope(isolate); | 10791 HandleScope scope(isolate); |
10779 | 10792 |
10780 ASSERT(args.length() == 2); | 10793 ASSERT(args.length() == 2); |
(...skipping 4175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14956 } | 14969 } |
14957 return NULL; | 14970 return NULL; |
14958 } | 14971 } |
14959 | 14972 |
14960 | 14973 |
14961 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 14974 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
14962 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 14975 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
14963 } | 14976 } |
14964 | 14977 |
14965 } } // namespace v8::internal | 14978 } } // namespace v8::internal |
OLD | NEW |