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 return HasOwnPropertyImplementation( |
Toon Verwaest
2014/07/16 15:41:01
The recursion isn't necessary for keys that are ar
jochen (gone - plz use gerrit)
2014/07/17 06:58:02
Done.
| |
5483 isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), | |
5484 key); | |
5482 } | 5485 } |
5483 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5486 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
5484 return isolate->heap()->false_value(); | 5487 return isolate->heap()->false_value(); |
5485 } | 5488 } |
5486 | 5489 |
5487 | 5490 |
5488 RUNTIME_FUNCTION(Runtime_HasOwnProperty) { | 5491 RUNTIME_FUNCTION(Runtime_HasOwnProperty) { |
5489 HandleScope scope(isolate); | 5492 HandleScope scope(isolate); |
5490 ASSERT(args.length() == 2); | 5493 ASSERT(args.length() == 2); |
5491 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0) | 5494 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0) |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5609 | 5612 |
5610 return *content; | 5613 return *content; |
5611 } | 5614 } |
5612 | 5615 |
5613 | 5616 |
5614 // Find the length of the prototype chain that is to be handled as one. If a | 5617 // 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 | 5618 // prototype object is hidden it is to be viewed as part of the the object it |
5616 // is prototype for. | 5619 // is prototype for. |
5617 static int OwnPrototypeChainLength(JSObject* obj) { | 5620 static int OwnPrototypeChainLength(JSObject* obj) { |
5618 int count = 1; | 5621 int count = 1; |
5619 Object* proto = obj->GetPrototype(); | 5622 for (PrototypeIterator iter(obj->GetIsolate(), obj); |
5620 while (proto->IsJSObject() && | 5623 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { |
5621 JSObject::cast(proto)->map()->is_hidden_prototype()) { | |
5622 count++; | 5624 count++; |
5623 proto = JSObject::cast(proto)->GetPrototype(); | |
5624 } | 5625 } |
5625 return count; | 5626 return count; |
5626 } | 5627 } |
5627 | 5628 |
5628 | 5629 |
5629 // Return the names of the own named properties. | 5630 // Return the names of the own named properties. |
5630 // args[0]: object | 5631 // args[0]: object |
5631 // args[1]: PropertyAttributes as int | 5632 // args[1]: PropertyAttributes as int |
5632 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { | 5633 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { |
5633 HandleScope scope(isolate); | 5634 HandleScope scope(isolate); |
5634 ASSERT(args.length() == 2); | 5635 ASSERT(args.length() == 2); |
5635 if (!args[0]->IsJSObject()) { | 5636 if (!args[0]->IsJSObject()) { |
5636 return isolate->heap()->undefined_value(); | 5637 return isolate->heap()->undefined_value(); |
5637 } | 5638 } |
5638 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 5639 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
5639 CONVERT_SMI_ARG_CHECKED(filter_value, 1); | 5640 CONVERT_SMI_ARG_CHECKED(filter_value, 1); |
5640 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); | 5641 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); |
5641 | 5642 |
5642 // Skip the global proxy as it has no properties and always delegates to the | 5643 // Skip the global proxy as it has no properties and always delegates to the |
5643 // real global object. | 5644 // real global object. |
5644 if (obj->IsJSGlobalProxy()) { | 5645 if (obj->IsJSGlobalProxy()) { |
5645 // Only collect names if access is permitted. | 5646 // Only collect names if access is permitted. |
5646 if (obj->IsAccessCheckNeeded() && | 5647 if (obj->IsAccessCheckNeeded() && |
5647 !isolate->MayNamedAccess( | 5648 !isolate->MayNamedAccess( |
5648 obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5649 obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
5649 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS); | 5650 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS); |
5650 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5651 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
5651 return *isolate->factory()->NewJSArray(0); | 5652 return *isolate->factory()->NewJSArray(0); |
5652 } | 5653 } |
5653 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 5654 PrototypeIterator iter(isolate, obj); |
5655 obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | |
5654 } | 5656 } |
5655 | 5657 |
5656 // Find the number of objects making up this. | 5658 // Find the number of objects making up this. |
5657 int length = OwnPrototypeChainLength(*obj); | 5659 int length = OwnPrototypeChainLength(*obj); |
5658 | 5660 |
5659 // Find the number of own properties for each of the objects. | 5661 // Find the number of own properties for each of the objects. |
5660 ScopedVector<int> own_property_count(length); | 5662 ScopedVector<int> own_property_count(length); |
5661 int total_property_count = 0; | 5663 int total_property_count = 0; |
5662 Handle<JSObject> jsproto = obj; | 5664 { |
5663 for (int i = 0; i < length; i++) { | 5665 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
5664 // Only collect names if access is permitted. | 5666 for (int i = 0; i < length; i++) { |
5665 if (jsproto->IsAccessCheckNeeded() && | 5667 ASSERT(!iter.IsAtEnd()); |
5666 !isolate->MayNamedAccess( | 5668 Handle<JSObject> jsproto = |
5667 jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5669 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
5668 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); | 5670 // Only collect names if access is permitted. |
5669 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5671 if (jsproto->IsAccessCheckNeeded() && |
5670 return *isolate->factory()->NewJSArray(0); | 5672 !isolate->MayNamedAccess(jsproto, |
5671 } | 5673 isolate->factory()->undefined_value(), |
5672 int n; | 5674 v8::ACCESS_KEYS)) { |
5673 n = jsproto->NumberOfOwnProperties(filter); | 5675 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); |
5674 own_property_count[i] = n; | 5676 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
5675 total_property_count += n; | 5677 return *isolate->factory()->NewJSArray(0); |
5676 if (i < length - 1) { | 5678 } |
5677 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 5679 int n; |
5680 n = jsproto->NumberOfOwnProperties(filter); | |
5681 own_property_count[i] = n; | |
5682 total_property_count += n; | |
5683 iter.Advance(); | |
5678 } | 5684 } |
5679 } | 5685 } |
5680 | 5686 |
5681 // Allocate an array with storage for all the property names. | 5687 // Allocate an array with storage for all the property names. |
5682 Handle<FixedArray> names = | 5688 Handle<FixedArray> names = |
5683 isolate->factory()->NewFixedArray(total_property_count); | 5689 isolate->factory()->NewFixedArray(total_property_count); |
5684 | 5690 |
5685 // Get the property names. | 5691 // Get the property names. |
5686 jsproto = obj; | |
5687 int next_copy_index = 0; | 5692 int next_copy_index = 0; |
5688 int hidden_strings = 0; | 5693 int hidden_strings = 0; |
5689 for (int i = 0; i < length; i++) { | 5694 { |
5690 jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); | 5695 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
5691 if (i > 0) { | 5696 for (int i = 0; i < length; i++) { |
5692 // Names from hidden prototypes may already have been added | 5697 ASSERT(!iter.IsAtEnd()); |
5693 // for inherited function template instances. Count the duplicates | 5698 Handle<JSObject> jsproto = |
5694 // and stub them out; the final copy pass at the end ignores holes. | 5699 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
5695 for (int j = next_copy_index; | 5700 jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); |
5696 j < next_copy_index + own_property_count[i]; | 5701 if (i > 0) { |
5697 j++) { | 5702 // Names from hidden prototypes may already have been added |
5698 Object* name_from_hidden_proto = names->get(j); | 5703 // for inherited function template instances. Count the duplicates |
5699 for (int k = 0; k < next_copy_index; k++) { | 5704 // and stub them out; the final copy pass at the end ignores holes. |
5700 if (names->get(k) != isolate->heap()->hidden_string()) { | 5705 for (int j = next_copy_index; |
5701 Object* name = names->get(k); | 5706 j < next_copy_index + own_property_count[i]; j++) { |
5702 if (name_from_hidden_proto == name) { | 5707 Object* name_from_hidden_proto = names->get(j); |
5703 names->set(j, isolate->heap()->hidden_string()); | 5708 for (int k = 0; k < next_copy_index; k++) { |
5704 hidden_strings++; | 5709 if (names->get(k) != isolate->heap()->hidden_string()) { |
5705 break; | 5710 Object* name = names->get(k); |
5711 if (name_from_hidden_proto == name) { | |
5712 names->set(j, isolate->heap()->hidden_string()); | |
5713 hidden_strings++; | |
5714 break; | |
5715 } | |
5706 } | 5716 } |
5707 } | 5717 } |
5708 } | 5718 } |
5709 } | 5719 } |
5710 } | 5720 next_copy_index += own_property_count[i]; |
5711 next_copy_index += own_property_count[i]; | |
5712 | 5721 |
5713 // Hidden properties only show up if the filter does not skip strings. | 5722 // Hidden properties only show up if the filter does not skip strings. |
5714 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { | 5723 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { |
5715 hidden_strings++; | 5724 hidden_strings++; |
5716 } | 5725 } |
5717 if (i < length - 1) { | 5726 iter.Advance(); |
5718 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | |
5719 } | 5727 } |
5720 } | 5728 } |
5721 | 5729 |
5722 // Filter out name of hidden properties object and | 5730 // Filter out name of hidden properties object and |
5723 // hidden prototype duplicates. | 5731 // hidden prototype duplicates. |
5724 if (hidden_strings > 0) { | 5732 if (hidden_strings > 0) { |
5725 Handle<FixedArray> old_names = names; | 5733 Handle<FixedArray> old_names = names; |
5726 names = isolate->factory()->NewFixedArray( | 5734 names = isolate->factory()->NewFixedArray( |
5727 names->length() - hidden_strings); | 5735 names->length() - hidden_strings); |
5728 int dest_pos = 0; | 5736 int dest_pos = 0; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5819 if (object->IsJSGlobalProxy()) { | 5827 if (object->IsJSGlobalProxy()) { |
5820 // Do access checks before going to the global object. | 5828 // Do access checks before going to the global object. |
5821 if (object->IsAccessCheckNeeded() && | 5829 if (object->IsAccessCheckNeeded() && |
5822 !isolate->MayNamedAccess( | 5830 !isolate->MayNamedAccess( |
5823 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5831 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
5824 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); | 5832 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); |
5825 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5833 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
5826 return *isolate->factory()->NewJSArray(0); | 5834 return *isolate->factory()->NewJSArray(0); |
5827 } | 5835 } |
5828 | 5836 |
5829 Handle<Object> proto(object->GetPrototype(), isolate); | 5837 PrototypeIterator iter(isolate, object); |
5830 // If proxy is detached we simply return an empty array. | 5838 // If proxy is detached we simply return an empty array. |
5831 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); | 5839 if (iter.IsAtEnd()) return *isolate->factory()->NewJSArray(0); |
5832 object = Handle<JSObject>::cast(proto); | 5840 object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
5833 } | 5841 } |
5834 | 5842 |
5835 Handle<FixedArray> contents; | 5843 Handle<FixedArray> contents; |
5836 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5844 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5837 isolate, contents, | 5845 isolate, contents, |
5838 JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY)); | 5846 JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY)); |
5839 | 5847 |
5840 // Some fast paths through GetKeysInFixedArrayFor reuse a cached | 5848 // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
5841 // property array and since the result is mutable we have to create | 5849 // property array and since the result is mutable we have to create |
5842 // a fresh clone on each invocation. | 5850 // a fresh clone on each invocation. |
(...skipping 4253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10096 indices->Clear(); | 10104 indices->Clear(); |
10097 } | 10105 } |
10098 for (uint32_t i = 0; i < length; i++) { | 10106 for (uint32_t i = 0; i < length; i++) { |
10099 indices->Add(i); | 10107 indices->Add(i); |
10100 } | 10108 } |
10101 if (length == range) return; // All indices accounted for already. | 10109 if (length == range) return; // All indices accounted for already. |
10102 break; | 10110 break; |
10103 } | 10111 } |
10104 } | 10112 } |
10105 | 10113 |
10106 Handle<Object> prototype(object->GetPrototype(), isolate); | 10114 PrototypeIterator iter(isolate, object); |
10107 if (prototype->IsJSObject()) { | 10115 if (!iter.IsAtEnd()) { |
10108 // The prototype will usually have no inherited element indices, | 10116 // The prototype will usually have no inherited element indices, |
10109 // but we have to check. | 10117 // but we have to check. |
10110 CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices); | 10118 CollectElementIndices( |
10119 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range, | |
10120 indices); | |
10111 } | 10121 } |
10112 } | 10122 } |
10113 | 10123 |
10114 | 10124 |
10115 /** | 10125 /** |
10116 * A helper function that visits elements of a JSArray in numerical | 10126 * A helper function that visits elements of a JSArray in numerical |
10117 * order. | 10127 * order. |
10118 * | 10128 * |
10119 * The visitor argument called for each existing element in the array | 10129 * The visitor argument called for each existing element in the array |
10120 * with the element index and the element's value. | 10130 * 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); | 10732 details->set(0, *element_or_char); |
10723 details->set( | 10733 details->set( |
10724 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); | 10734 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); |
10725 return *isolate->factory()->NewJSArrayWithElements(details); | 10735 return *isolate->factory()->NewJSArrayWithElements(details); |
10726 } | 10736 } |
10727 | 10737 |
10728 // Find the number of objects making up this. | 10738 // Find the number of objects making up this. |
10729 int length = OwnPrototypeChainLength(*obj); | 10739 int length = OwnPrototypeChainLength(*obj); |
10730 | 10740 |
10731 // Try own lookup on each of the objects. | 10741 // Try own lookup on each of the objects. |
10732 Handle<JSObject> jsproto = obj; | 10742 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
10733 for (int i = 0; i < length; i++) { | 10743 for (int i = 0; i < length; i++) { |
10744 ASSERT(!iter.IsAtEnd()); | |
10745 Handle<JSObject> jsproto = | |
10746 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | |
10734 LookupResult result(isolate); | 10747 LookupResult result(isolate); |
10735 jsproto->LookupOwn(name, &result); | 10748 jsproto->LookupOwn(name, &result); |
10736 if (result.IsFound()) { | 10749 if (result.IsFound()) { |
10737 // LookupResult is not GC safe as it holds raw object pointers. | 10750 // 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 | 10751 // GC can happen later in this code so put the required fields into |
10739 // local variables using handles when required for later use. | 10752 // local variables using handles when required for later use. |
10740 Handle<Object> result_callback_obj; | 10753 Handle<Object> result_callback_obj; |
10741 if (result.IsPropertyCallbacks()) { | 10754 if (result.IsPropertyCallbacks()) { |
10742 result_callback_obj = Handle<Object>(result.GetCallbackObject(), | 10755 result_callback_obj = Handle<Object>(result.GetCallbackObject(), |
10743 isolate); | 10756 isolate); |
(...skipping 14 matching lines...) Expand all Loading... | |
10758 details->set(1, result.GetPropertyDetails().AsSmi()); | 10771 details->set(1, result.GetPropertyDetails().AsSmi()); |
10759 if (has_js_accessors) { | 10772 if (has_js_accessors) { |
10760 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); | 10773 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); |
10761 details->set(2, isolate->heap()->ToBoolean(has_caught)); | 10774 details->set(2, isolate->heap()->ToBoolean(has_caught)); |
10762 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); | 10775 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); |
10763 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); | 10776 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); |
10764 } | 10777 } |
10765 | 10778 |
10766 return *isolate->factory()->NewJSArrayWithElements(details); | 10779 return *isolate->factory()->NewJSArrayWithElements(details); |
10767 } | 10780 } |
10768 if (i < length - 1) { | 10781 iter.Advance(); |
10769 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | |
10770 } | |
10771 } | 10782 } |
10772 | 10783 |
10773 return isolate->heap()->undefined_value(); | 10784 return isolate->heap()->undefined_value(); |
10774 } | 10785 } |
10775 | 10786 |
10776 | 10787 |
10777 RUNTIME_FUNCTION(Runtime_DebugGetProperty) { | 10788 RUNTIME_FUNCTION(Runtime_DebugGetProperty) { |
10778 HandleScope scope(isolate); | 10789 HandleScope scope(isolate); |
10779 | 10790 |
10780 ASSERT(args.length() == 2); | 10791 ASSERT(args.length() == 2); |
(...skipping 4175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14956 } | 14967 } |
14957 return NULL; | 14968 return NULL; |
14958 } | 14969 } |
14959 | 14970 |
14960 | 14971 |
14961 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 14972 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
14962 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 14973 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
14963 } | 14974 } |
14964 | 14975 |
14965 } } // namespace v8::internal | 14976 } } // namespace v8::internal |
OLD | NEW |