| 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 16 matching lines...) Expand all Loading... |
| 27 #include "src/global-handles.h" | 27 #include "src/global-handles.h" |
| 28 #include "src/isolate-inl.h" | 28 #include "src/isolate-inl.h" |
| 29 #include "src/json-parser.h" | 29 #include "src/json-parser.h" |
| 30 #include "src/json-stringifier.h" | 30 #include "src/json-stringifier.h" |
| 31 #include "src/jsregexp-inl.h" | 31 #include "src/jsregexp-inl.h" |
| 32 #include "src/jsregexp.h" | 32 #include "src/jsregexp.h" |
| 33 #include "src/liveedit.h" | 33 #include "src/liveedit.h" |
| 34 #include "src/misc-intrinsics.h" | 34 #include "src/misc-intrinsics.h" |
| 35 #include "src/parser.h" | 35 #include "src/parser.h" |
| 36 #include "src/platform.h" | 36 #include "src/platform.h" |
| 37 #include "src/prototype-iterator.h" |
| 37 #include "src/runtime.h" | 38 #include "src/runtime.h" |
| 38 #include "src/runtime-profiler.h" | 39 #include "src/runtime-profiler.h" |
| 39 #include "src/scopeinfo.h" | 40 #include "src/scopeinfo.h" |
| 40 #include "src/smart-pointers.h" | 41 #include "src/smart-pointers.h" |
| 41 #include "src/string-search.h" | 42 #include "src/string-search.h" |
| 42 #include "src/stub-cache.h" | 43 #include "src/stub-cache.h" |
| 43 #include "src/uri.h" | 44 #include "src/uri.h" |
| 44 #include "src/v8threads.h" | 45 #include "src/v8threads.h" |
| 45 #include "src/vm-state-inl.h" | 46 #include "src/vm-state-inl.h" |
| 46 | 47 |
| (...skipping 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1802 return JSObject::cast(obj)->class_name(); | 1803 return JSObject::cast(obj)->class_name(); |
| 1803 } | 1804 } |
| 1804 | 1805 |
| 1805 | 1806 |
| 1806 RUNTIME_FUNCTION(Runtime_GetPrototype) { | 1807 RUNTIME_FUNCTION(Runtime_GetPrototype) { |
| 1807 HandleScope scope(isolate); | 1808 HandleScope scope(isolate); |
| 1808 ASSERT(args.length() == 1); | 1809 ASSERT(args.length() == 1); |
| 1809 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); | 1810 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); |
| 1810 // We don't expect access checks to be needed on JSProxy objects. | 1811 // We don't expect access checks to be needed on JSProxy objects. |
| 1811 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); | 1812 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |
| 1813 PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_NON_HIDDEN> iter( |
| 1814 isolate, obj); |
| 1812 do { | 1815 do { |
| 1813 if (obj->IsAccessCheckNeeded() && | 1816 if (iter.GetCurrent()->IsAccessCheckNeeded() && |
| 1814 !isolate->MayNamedAccess(Handle<JSObject>::cast(obj), | 1817 !isolate->MayNamedAccess(Handle<JSObject>::cast(iter.GetCurrent()), |
| 1815 isolate->factory()->proto_string(), | 1818 isolate->factory()->proto_string(), |
| 1816 v8::ACCESS_GET)) { | 1819 v8::ACCESS_GET)) { |
| 1817 isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj), | 1820 isolate->ReportFailedAccessCheck( |
| 1818 v8::ACCESS_GET); | 1821 Handle<JSObject>::cast(iter.GetCurrent()), v8::ACCESS_GET); |
| 1819 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 1822 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
| 1820 return isolate->heap()->undefined_value(); | 1823 return isolate->heap()->undefined_value(); |
| 1821 } | 1824 } |
| 1822 obj = Object::GetPrototype(isolate, obj); | 1825 iter.Advance(); |
| 1823 } while (obj->IsJSObject() && | 1826 } while (!iter.IsAtEnd()); |
| 1824 JSObject::cast(*obj)->map()->is_hidden_prototype()); | 1827 return *iter.GetCurrent(); |
| 1825 return *obj; | |
| 1826 } | 1828 } |
| 1827 | 1829 |
| 1828 | 1830 |
| 1829 static inline Handle<Object> GetPrototypeSkipHiddenPrototypes( | 1831 static inline Handle<Object> GetPrototypeSkipHiddenPrototypes( |
| 1830 Isolate* isolate, Handle<Object> receiver) { | 1832 Isolate* isolate, Handle<Object> receiver) { |
| 1831 Handle<Object> current = Object::GetPrototype(isolate, receiver); | 1833 PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_NON_HIDDEN> iter( |
| 1832 while (current->IsJSObject() && | 1834 isolate, receiver); |
| 1833 JSObject::cast(*current)->map()->is_hidden_prototype()) { | 1835 while (!iter.IsAtEnd()) iter.Advance(); |
| 1834 current = Object::GetPrototype(isolate, current); | 1836 return iter.GetCurrent(); |
| 1835 } | |
| 1836 return current; | |
| 1837 } | 1837 } |
| 1838 | 1838 |
| 1839 | 1839 |
| 1840 RUNTIME_FUNCTION(Runtime_SetPrototype) { | 1840 RUNTIME_FUNCTION(Runtime_SetPrototype) { |
| 1841 HandleScope scope(isolate); | 1841 HandleScope scope(isolate); |
| 1842 ASSERT(args.length() == 2); | 1842 ASSERT(args.length() == 2); |
| 1843 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 1843 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
| 1844 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); | 1844 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); |
| 1845 if (obj->IsAccessCheckNeeded() && | 1845 if (obj->IsAccessCheckNeeded() && |
| 1846 !isolate->MayNamedAccess( | 1846 !isolate->MayNamedAccess( |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1871 return *result; | 1871 return *result; |
| 1872 } | 1872 } |
| 1873 | 1873 |
| 1874 | 1874 |
| 1875 RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) { | 1875 RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) { |
| 1876 HandleScope shs(isolate); | 1876 HandleScope shs(isolate); |
| 1877 ASSERT(args.length() == 2); | 1877 ASSERT(args.length() == 2); |
| 1878 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). | 1878 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). |
| 1879 CONVERT_ARG_HANDLE_CHECKED(Object, O, 0); | 1879 CONVERT_ARG_HANDLE_CHECKED(Object, O, 0); |
| 1880 CONVERT_ARG_HANDLE_CHECKED(Object, V, 1); | 1880 CONVERT_ARG_HANDLE_CHECKED(Object, V, 1); |
| 1881 while (true) { | 1881 PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_GIVEN_OBJECT> iter( |
| 1882 Handle<Object> prototype = Object::GetPrototype(isolate, V); | 1882 isolate, V, O); |
| 1883 if (prototype->IsNull()) return isolate->heap()->false_value(); | 1883 while (!iter.IsAtEnd()) iter.Advance(); |
| 1884 if (*O == *prototype) return isolate->heap()->true_value(); | 1884 if (iter.GetCurrent()->IsNull()) return isolate->heap()->false_value(); |
| 1885 V = prototype; | 1885 return isolate->heap()->true_value(); |
| 1886 } | |
| 1887 } | 1886 } |
| 1888 | 1887 |
| 1889 | 1888 |
| 1890 // Enumerator used as indices into the array returned from GetOwnProperty | 1889 // Enumerator used as indices into the array returned from GetOwnProperty |
| 1891 enum PropertyDescriptorIndices { | 1890 enum PropertyDescriptorIndices { |
| 1892 IS_ACCESSOR_INDEX, | 1891 IS_ACCESSOR_INDEX, |
| 1893 VALUE_INDEX, | 1892 VALUE_INDEX, |
| 1894 GETTER_INDEX, | 1893 GETTER_INDEX, |
| 1895 SETTER_INDEX, | 1894 SETTER_INDEX, |
| 1896 WRITABLE_INDEX, | 1895 WRITABLE_INDEX, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1999 isolate, result, JSObject::PreventExtensions(obj)); | 1998 isolate, result, JSObject::PreventExtensions(obj)); |
| 2000 return *result; | 1999 return *result; |
| 2001 } | 2000 } |
| 2002 | 2001 |
| 2003 | 2002 |
| 2004 RUNTIME_FUNCTION(Runtime_IsExtensible) { | 2003 RUNTIME_FUNCTION(Runtime_IsExtensible) { |
| 2005 SealHandleScope shs(isolate); | 2004 SealHandleScope shs(isolate); |
| 2006 ASSERT(args.length() == 1); | 2005 ASSERT(args.length() == 1); |
| 2007 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 2006 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 2008 if (obj->IsJSGlobalProxy()) { | 2007 if (obj->IsJSGlobalProxy()) { |
| 2009 Object* proto = obj->GetPrototype(); | 2008 Object* proto = SAFE_GET_PROTOTYPE_FAST(obj); |
| 2010 if (proto->IsNull()) return isolate->heap()->false_value(); | 2009 if (proto->IsNull()) return isolate->heap()->false_value(); |
| 2011 ASSERT(proto->IsJSGlobalObject()); | 2010 ASSERT(proto->IsJSGlobalObject()); |
| 2012 obj = JSObject::cast(proto); | 2011 obj = JSObject::cast(proto); |
| 2013 } | 2012 } |
| 2014 return isolate->heap()->ToBoolean(obj->map()->is_extensible()); | 2013 return isolate->heap()->ToBoolean(obj->map()->is_extensible()); |
| 2015 } | 2014 } |
| 2016 | 2015 |
| 2017 | 2016 |
| 2018 RUNTIME_FUNCTION(Runtime_RegExpCompile) { | 2017 RUNTIME_FUNCTION(Runtime_RegExpCompile) { |
| 2019 HandleScope scope(isolate); | 2018 HandleScope scope(isolate); |
| (...skipping 2806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4826 // Handle [] indexing on String objects | 4825 // Handle [] indexing on String objects |
| 4827 if (object->IsStringObjectWithCharacterAt(index)) { | 4826 if (object->IsStringObjectWithCharacterAt(index)) { |
| 4828 Handle<JSValue> js_value = Handle<JSValue>::cast(object); | 4827 Handle<JSValue> js_value = Handle<JSValue>::cast(object); |
| 4829 Handle<Object> result = | 4828 Handle<Object> result = |
| 4830 GetCharAt(Handle<String>(String::cast(js_value->value())), index); | 4829 GetCharAt(Handle<String>(String::cast(js_value->value())), index); |
| 4831 if (!result->IsUndefined()) return result; | 4830 if (!result->IsUndefined()) return result; |
| 4832 } | 4831 } |
| 4833 | 4832 |
| 4834 Handle<Object> result; | 4833 Handle<Object> result; |
| 4835 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { | 4834 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { |
| 4836 Handle<Object> proto(object->GetPrototype(isolate), isolate); | 4835 Handle<Object> proto(SAFE_GET_PROTOTYPE(isolate, *object), isolate); |
| 4837 return Object::GetElement(isolate, proto, index); | 4836 return Object::GetElement(isolate, proto, index); |
| 4838 } else { | 4837 } else { |
| 4839 return Object::GetElement(isolate, object, index); | 4838 return Object::GetElement(isolate, object, index); |
| 4840 } | 4839 } |
| 4841 } | 4840 } |
| 4842 | 4841 |
| 4843 | 4842 |
| 4844 MUST_USE_RESULT | 4843 MUST_USE_RESULT |
| 4845 static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) { | 4844 static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) { |
| 4846 if (key->IsName()) { | 4845 if (key->IsName()) { |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5090 // to not worry about changing the instance_descriptor and creating a new | 5089 // to not worry about changing the instance_descriptor and creating a new |
| 5091 // map. The current version of SetObjectProperty does not handle attributes | 5090 // map. The current version of SetObjectProperty does not handle attributes |
| 5092 // correctly in the case where a property is a field and is reset with | 5091 // correctly in the case where a property is a field and is reset with |
| 5093 // new attributes. | 5092 // new attributes. |
| 5094 if (lookup.IsFound() && | 5093 if (lookup.IsFound() && |
| 5095 (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) { | 5094 (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) { |
| 5096 // New attributes - normalize to avoid writing to instance descriptor | 5095 // New attributes - normalize to avoid writing to instance descriptor |
| 5097 if (js_object->IsJSGlobalProxy()) { | 5096 if (js_object->IsJSGlobalProxy()) { |
| 5098 // Since the result is a property, the prototype will exist so | 5097 // Since the result is a property, the prototype will exist so |
| 5099 // we don't have to check for null. | 5098 // we don't have to check for null. |
| 5100 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); | 5099 js_object = |
| 5100 Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE_FAST(*js_object))); |
| 5101 } | 5101 } |
| 5102 | 5102 |
| 5103 if (attr != lookup.GetAttributes() || | 5103 if (attr != lookup.GetAttributes() || |
| 5104 (lookup.IsPropertyCallbacks() && | 5104 (lookup.IsPropertyCallbacks() && |
| 5105 !lookup.GetCallbackObject()->IsAccessorInfo())) { | 5105 !lookup.GetCallbackObject()->IsAccessorInfo())) { |
| 5106 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 5106 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 5107 } | 5107 } |
| 5108 | 5108 |
| 5109 // Use IgnoreAttributes version since a readonly property may be | 5109 // Use IgnoreAttributes version since a readonly property may be |
| 5110 // overridden and SetProperty does not allow this. | 5110 // overridden and SetProperty does not allow this. |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5565 | 5565 |
| 5566 static Object* HasOwnPropertyImplementation(Isolate* isolate, | 5566 static Object* HasOwnPropertyImplementation(Isolate* isolate, |
| 5567 Handle<JSObject> object, | 5567 Handle<JSObject> object, |
| 5568 Handle<Name> key) { | 5568 Handle<Name> key) { |
| 5569 if (JSReceiver::HasOwnProperty(object, key)) { | 5569 if (JSReceiver::HasOwnProperty(object, key)) { |
| 5570 return isolate->heap()->true_value(); | 5570 return isolate->heap()->true_value(); |
| 5571 } | 5571 } |
| 5572 // Handle hidden prototypes. If there's a hidden prototype above this thing | 5572 // Handle hidden prototypes. If there's a hidden prototype above this thing |
| 5573 // then we have to check it for properties, because they are supposed to | 5573 // then we have to check it for properties, because they are supposed to |
| 5574 // look like they are on this object. | 5574 // look like they are on this object. |
| 5575 Handle<Object> proto(object->GetPrototype(), isolate); | 5575 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 5576 if (proto->IsJSObject() && | 5576 if (proto->IsJSObject() && |
| 5577 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { | 5577 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { |
| 5578 return HasOwnPropertyImplementation(isolate, | 5578 return HasOwnPropertyImplementation(isolate, |
| 5579 Handle<JSObject>::cast(proto), | 5579 Handle<JSObject>::cast(proto), |
| 5580 key); | 5580 key); |
| 5581 } | 5581 } |
| 5582 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5582 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
| 5583 return isolate->heap()->false_value(); | 5583 return isolate->heap()->false_value(); |
| 5584 } | 5584 } |
| 5585 | 5585 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5707 if (object->IsSimpleEnum()) return object->map(); | 5707 if (object->IsSimpleEnum()) return object->map(); |
| 5708 | 5708 |
| 5709 return *content; | 5709 return *content; |
| 5710 } | 5710 } |
| 5711 | 5711 |
| 5712 | 5712 |
| 5713 // Find the length of the prototype chain that is to be handled as one. If a | 5713 // Find the length of the prototype chain that is to be handled as one. If a |
| 5714 // prototype object is hidden it is to be viewed as part of the the object it | 5714 // prototype object is hidden it is to be viewed as part of the the object it |
| 5715 // is prototype for. | 5715 // is prototype for. |
| 5716 static int OwnPrototypeChainLength(JSObject* obj) { | 5716 static int OwnPrototypeChainLength(JSObject* obj) { |
| 5717 int count = 1; | 5717 int count = 0; |
| 5718 Object* proto = obj->GetPrototype(); | 5718 for (PrototypeIterator<STORE_AS_POINTER, MAP_BASED_WALK, END_AT_NON_HIDDEN> |
| 5719 while (proto->IsJSObject() && | 5719 iter(obj); !iter.IsAtEnd(); iter.Advance()) { |
| 5720 JSObject::cast(proto)->map()->is_hidden_prototype()) { | 5720 ++count; |
| 5721 count++; | |
| 5722 proto = JSObject::cast(proto)->GetPrototype(); | |
| 5723 } | 5721 } |
| 5724 return count; | 5722 return count; |
| 5725 } | 5723 } |
| 5726 | 5724 |
| 5727 | 5725 |
| 5728 // Return the names of the own named properties. | 5726 // Return the names of the own named properties. |
| 5729 // args[0]: object | 5727 // args[0]: object |
| 5730 // args[1]: PropertyAttributes as int | 5728 // args[1]: PropertyAttributes as int |
| 5731 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { | 5729 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { |
| 5732 HandleScope scope(isolate); | 5730 HandleScope scope(isolate); |
| 5733 ASSERT(args.length() == 2); | 5731 ASSERT(args.length() == 2); |
| 5734 if (!args[0]->IsJSObject()) { | 5732 if (!args[0]->IsJSObject()) { |
| 5735 return isolate->heap()->undefined_value(); | 5733 return isolate->heap()->undefined_value(); |
| 5736 } | 5734 } |
| 5737 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 5735 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
| 5738 CONVERT_SMI_ARG_CHECKED(filter_value, 1); | 5736 CONVERT_SMI_ARG_CHECKED(filter_value, 1); |
| 5739 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); | 5737 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); |
| 5740 | 5738 |
| 5741 // Skip the global proxy as it has no properties and always delegates to the | 5739 // Skip the global proxy as it has no properties and always delegates to the |
| 5742 // real global object. | 5740 // real global object. |
| 5743 if (obj->IsJSGlobalProxy()) { | 5741 if (obj->IsJSGlobalProxy()) { |
| 5744 // Only collect names if access is permitted. | 5742 // Only collect names if access is permitted. |
| 5745 if (obj->IsAccessCheckNeeded() && | 5743 if (obj->IsAccessCheckNeeded() && |
| 5746 !isolate->MayNamedAccess( | 5744 !isolate->MayNamedAccess( |
| 5747 obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5745 obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
| 5748 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS); | 5746 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS); |
| 5749 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5747 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
| 5750 return *isolate->factory()->NewJSArray(0); | 5748 return *isolate->factory()->NewJSArray(0); |
| 5751 } | 5749 } |
| 5752 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 5750 obj = Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE_FAST(*obj))); |
| 5753 } | 5751 } |
| 5754 | 5752 |
| 5755 // Find the number of objects making up this. | 5753 // Find the number of objects making up this. |
| 5756 int length = OwnPrototypeChainLength(*obj); | 5754 int length = OwnPrototypeChainLength(*obj); |
| 5757 | 5755 |
| 5758 // Find the number of own properties for each of the objects. | 5756 // Find the number of own properties for each of the objects. |
| 5759 ScopedVector<int> own_property_count(length); | 5757 ScopedVector<int> own_property_count(length); |
| 5760 int total_property_count = 0; | 5758 int total_property_count = 0; |
| 5761 Handle<JSObject> jsproto = obj; | 5759 Handle<JSObject> jsproto = obj; |
| 5762 for (int i = 0; i < length; i++) { | 5760 for (int i = 0; i < length; i++) { |
| 5763 // Only collect names if access is permitted. | 5761 // Only collect names if access is permitted. |
| 5764 if (jsproto->IsAccessCheckNeeded() && | 5762 if (jsproto->IsAccessCheckNeeded() && |
| 5765 !isolate->MayNamedAccess( | 5763 !isolate->MayNamedAccess( |
| 5766 jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5764 jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
| 5767 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); | 5765 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); |
| 5768 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5766 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
| 5769 return *isolate->factory()->NewJSArray(0); | 5767 return *isolate->factory()->NewJSArray(0); |
| 5770 } | 5768 } |
| 5771 int n; | 5769 int n; |
| 5772 n = jsproto->NumberOfOwnProperties(filter); | 5770 n = jsproto->NumberOfOwnProperties(filter); |
| 5773 own_property_count[i] = n; | 5771 own_property_count[i] = n; |
| 5774 total_property_count += n; | 5772 total_property_count += n; |
| 5775 if (i < length - 1) { | 5773 if (i < length - 1) { |
| 5776 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 5774 jsproto = |
| 5775 Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE_FAST(*jsproto))); |
| 5777 } | 5776 } |
| 5778 } | 5777 } |
| 5779 | 5778 |
| 5780 // Allocate an array with storage for all the property names. | 5779 // Allocate an array with storage for all the property names. |
| 5781 Handle<FixedArray> names = | 5780 Handle<FixedArray> names = |
| 5782 isolate->factory()->NewFixedArray(total_property_count); | 5781 isolate->factory()->NewFixedArray(total_property_count); |
| 5783 | 5782 |
| 5784 // Get the property names. | 5783 // Get the property names. |
| 5785 jsproto = obj; | 5784 jsproto = obj; |
| 5786 int next_copy_index = 0; | 5785 int next_copy_index = 0; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 5807 } | 5806 } |
| 5808 } | 5807 } |
| 5809 } | 5808 } |
| 5810 next_copy_index += own_property_count[i]; | 5809 next_copy_index += own_property_count[i]; |
| 5811 | 5810 |
| 5812 // Hidden properties only show up if the filter does not skip strings. | 5811 // Hidden properties only show up if the filter does not skip strings. |
| 5813 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { | 5812 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { |
| 5814 hidden_strings++; | 5813 hidden_strings++; |
| 5815 } | 5814 } |
| 5816 if (i < length - 1) { | 5815 if (i < length - 1) { |
| 5817 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 5816 jsproto = |
| 5817 Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE_FAST(*jsproto))); |
| 5818 } | 5818 } |
| 5819 } | 5819 } |
| 5820 | 5820 |
| 5821 // Filter out name of hidden properties object and | 5821 // Filter out name of hidden properties object and |
| 5822 // hidden prototype duplicates. | 5822 // hidden prototype duplicates. |
| 5823 if (hidden_strings > 0) { | 5823 if (hidden_strings > 0) { |
| 5824 Handle<FixedArray> old_names = names; | 5824 Handle<FixedArray> old_names = names; |
| 5825 names = isolate->factory()->NewFixedArray( | 5825 names = isolate->factory()->NewFixedArray( |
| 5826 names->length() - hidden_strings); | 5826 names->length() - hidden_strings); |
| 5827 int dest_pos = 0; | 5827 int dest_pos = 0; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5918 if (object->IsJSGlobalProxy()) { | 5918 if (object->IsJSGlobalProxy()) { |
| 5919 // Do access checks before going to the global object. | 5919 // Do access checks before going to the global object. |
| 5920 if (object->IsAccessCheckNeeded() && | 5920 if (object->IsAccessCheckNeeded() && |
| 5921 !isolate->MayNamedAccess( | 5921 !isolate->MayNamedAccess( |
| 5922 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5922 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
| 5923 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); | 5923 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); |
| 5924 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5924 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
| 5925 return *isolate->factory()->NewJSArray(0); | 5925 return *isolate->factory()->NewJSArray(0); |
| 5926 } | 5926 } |
| 5927 | 5927 |
| 5928 Handle<Object> proto(object->GetPrototype(), isolate); | 5928 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 5929 // If proxy is detached we simply return an empty array. | 5929 // If proxy is detached we simply return an empty array. |
| 5930 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); | 5930 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); |
| 5931 object = Handle<JSObject>::cast(proto); | 5931 object = Handle<JSObject>::cast(proto); |
| 5932 } | 5932 } |
| 5933 | 5933 |
| 5934 Handle<FixedArray> contents; | 5934 Handle<FixedArray> contents; |
| 5935 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5935 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 5936 isolate, contents, | 5936 isolate, contents, |
| 5937 JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY)); | 5937 JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY)); |
| 5938 | 5938 |
| (...skipping 4266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10205 indices->Clear(); | 10205 indices->Clear(); |
| 10206 } | 10206 } |
| 10207 for (uint32_t i = 0; i < length; i++) { | 10207 for (uint32_t i = 0; i < length; i++) { |
| 10208 indices->Add(i); | 10208 indices->Add(i); |
| 10209 } | 10209 } |
| 10210 if (length == range) return; // All indices accounted for already. | 10210 if (length == range) return; // All indices accounted for already. |
| 10211 break; | 10211 break; |
| 10212 } | 10212 } |
| 10213 } | 10213 } |
| 10214 | 10214 |
| 10215 Handle<Object> prototype(object->GetPrototype(), isolate); | 10215 Handle<Object> prototype(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 10216 if (prototype->IsJSObject()) { | 10216 if (prototype->IsJSObject()) { |
| 10217 // The prototype will usually have no inherited element indices, | 10217 // The prototype will usually have no inherited element indices, |
| 10218 // but we have to check. | 10218 // but we have to check. |
| 10219 CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices); | 10219 CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices); |
| 10220 } | 10220 } |
| 10221 } | 10221 } |
| 10222 | 10222 |
| 10223 | 10223 |
| 10224 /** | 10224 /** |
| 10225 * A helper function that visits elements of a JSArray in numerical | 10225 * A helper function that visits elements of a JSArray in numerical |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10638 // or undefined) or a number representing the positive length of an interval | 10638 // or undefined) or a number representing the positive length of an interval |
| 10639 // starting at index 0. | 10639 // starting at index 0. |
| 10640 // Intervals can span over some keys that are not in the object. | 10640 // Intervals can span over some keys that are not in the object. |
| 10641 RUNTIME_FUNCTION(Runtime_GetArrayKeys) { | 10641 RUNTIME_FUNCTION(Runtime_GetArrayKeys) { |
| 10642 HandleScope scope(isolate); | 10642 HandleScope scope(isolate); |
| 10643 ASSERT(args.length() == 2); | 10643 ASSERT(args.length() == 2); |
| 10644 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); | 10644 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); |
| 10645 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 10645 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
| 10646 if (array->elements()->IsDictionary()) { | 10646 if (array->elements()->IsDictionary()) { |
| 10647 Handle<FixedArray> keys = isolate->factory()->empty_fixed_array(); | 10647 Handle<FixedArray> keys = isolate->factory()->empty_fixed_array(); |
| 10648 for (Handle<Object> p = array; | 10648 for (PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_NULL_VALUE> |
| 10649 !p->IsNull(); | 10649 iter(isolate, array); !iter.IsAtEnd(); iter.Advance()) { |
| 10650 p = Handle<Object>(p->GetPrototype(isolate), isolate)) { | 10650 if (iter.GetCurrent()->IsJSProxy() || |
| 10651 if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) { | 10651 JSObject::cast(*iter.GetCurrent())->HasIndexedInterceptor()) { |
| 10652 // Bail out if we find a proxy or interceptor, likely not worth | 10652 // Bail out if we find a proxy or interceptor, likely not worth |
| 10653 // collecting keys in that case. | 10653 // collecting keys in that case. |
| 10654 return *isolate->factory()->NewNumberFromUint(length); | 10654 return *isolate->factory()->NewNumberFromUint(length); |
| 10655 } | 10655 } |
| 10656 Handle<JSObject> current = Handle<JSObject>::cast(p); | 10656 Handle<JSObject> current = Handle<JSObject>::cast(iter.GetCurrent()); |
| 10657 Handle<FixedArray> current_keys = | 10657 Handle<FixedArray> current_keys = |
| 10658 isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE)); | 10658 isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE)); |
| 10659 current->GetOwnElementKeys(*current_keys, NONE); | 10659 current->GetOwnElementKeys(*current_keys, NONE); |
| 10660 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 10660 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 10661 isolate, keys, FixedArray::UnionOfKeys(keys, current_keys)); | 10661 isolate, keys, FixedArray::UnionOfKeys(keys, current_keys)); |
| 10662 } | 10662 } |
| 10663 // Erase any keys >= length. | 10663 // Erase any keys >= length. |
| 10664 // TODO(adamk): Remove this step when the contract of %GetArrayKeys | 10664 // TODO(adamk): Remove this step when the contract of %GetArrayKeys |
| 10665 // is changed to let this happen on the JS side. | 10665 // is changed to let this happen on the JS side. |
| 10666 for (int i = 0; i < keys->length(); i++) { | 10666 for (int i = 0; i < keys->length(); i++) { |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10865 if (has_js_accessors) { | 10865 if (has_js_accessors) { |
| 10866 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); | 10866 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); |
| 10867 details->set(2, isolate->heap()->ToBoolean(has_caught)); | 10867 details->set(2, isolate->heap()->ToBoolean(has_caught)); |
| 10868 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); | 10868 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); |
| 10869 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); | 10869 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); |
| 10870 } | 10870 } |
| 10871 | 10871 |
| 10872 return *isolate->factory()->NewJSArrayWithElements(details); | 10872 return *isolate->factory()->NewJSArrayWithElements(details); |
| 10873 } | 10873 } |
| 10874 if (i < length - 1) { | 10874 if (i < length - 1) { |
| 10875 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 10875 jsproto = |
| 10876 Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE_FAST(*jsproto))); |
| 10876 } | 10877 } |
| 10877 } | 10878 } |
| 10878 | 10879 |
| 10879 return isolate->heap()->undefined_value(); | 10880 return isolate->heap()->undefined_value(); |
| 10880 } | 10881 } |
| 10881 | 10882 |
| 10882 | 10883 |
| 10883 RUNTIME_FUNCTION(Runtime_DebugGetProperty) { | 10884 RUNTIME_FUNCTION(Runtime_DebugGetProperty) { |
| 10884 HandleScope scope(isolate); | 10885 HandleScope scope(isolate); |
| 10885 | 10886 |
| (...skipping 1927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12813 | 12814 |
| 12814 Handle<Object> result; | 12815 Handle<Object> result; |
| 12815 ASSIGN_RETURN_ON_EXCEPTION( | 12816 ASSIGN_RETURN_ON_EXCEPTION( |
| 12816 isolate, result, | 12817 isolate, result, |
| 12817 Execution::Call(isolate, eval_fun, receiver, 0, NULL), | 12818 Execution::Call(isolate, eval_fun, receiver, 0, NULL), |
| 12818 Object); | 12819 Object); |
| 12819 | 12820 |
| 12820 // Skip the global proxy as it has no properties and always delegates to the | 12821 // Skip the global proxy as it has no properties and always delegates to the |
| 12821 // real global object. | 12822 // real global object. |
| 12822 if (result->IsJSGlobalProxy()) { | 12823 if (result->IsJSGlobalProxy()) { |
| 12823 result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate))); | 12824 result = |
| 12825 Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE(isolate, *result))); |
| 12824 } | 12826 } |
| 12825 | 12827 |
| 12826 // Clear the oneshot breakpoints so that the debugger does not step further. | 12828 // Clear the oneshot breakpoints so that the debugger does not step further. |
| 12827 isolate->debug()->ClearStepping(); | 12829 isolate->debug()->ClearStepping(); |
| 12828 return result; | 12830 return result; |
| 12829 } | 12831 } |
| 12830 | 12832 |
| 12831 | 12833 |
| 12832 // Evaluate a piece of JavaScript in the context of a stack frame for | 12834 // Evaluate a piece of JavaScript in the context of a stack frame for |
| 12833 // debugging. Things that need special attention are: | 12835 // debugging. Things that need special attention are: |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12989 if (obj->IsJSContextExtensionObject() || | 12991 if (obj->IsJSContextExtensionObject() || |
| 12990 obj->map()->constructor() == arguments_function) { | 12992 obj->map()->constructor() == arguments_function) { |
| 12991 continue; | 12993 continue; |
| 12992 } | 12994 } |
| 12993 | 12995 |
| 12994 // Check if the JS object has a reference to the object looked for. | 12996 // Check if the JS object has a reference to the object looked for. |
| 12995 if (obj->ReferencesObject(target)) { | 12997 if (obj->ReferencesObject(target)) { |
| 12996 // Check instance filter if supplied. This is normally used to avoid | 12998 // Check instance filter if supplied. This is normally used to avoid |
| 12997 // references from mirror objects (see Runtime_IsInPrototypeChain). | 12999 // references from mirror objects (see Runtime_IsInPrototypeChain). |
| 12998 if (!instance_filter->IsUndefined()) { | 13000 if (!instance_filter->IsUndefined()) { |
| 12999 Object* V = obj; | 13001 for (PrototypeIterator<STORE_AS_POINTER, TYPE_BASED_WALK, |
| 13000 while (true) { | 13002 END_AT_NULL_VALUE> iter(isolate, obj); |
| 13001 Object* prototype = V->GetPrototype(isolate); | 13003 !iter.IsAtEnd(); iter.Advance()) { |
| 13002 if (prototype->IsNull()) { | 13004 if (instance_filter == iter.GetCurrent()) { |
| 13005 obj = NULL; |
| 13003 break; | 13006 break; |
| 13004 } | 13007 } |
| 13005 if (instance_filter == prototype) { | |
| 13006 obj = NULL; // Don't add this object. | |
| 13007 break; | |
| 13008 } | |
| 13009 V = prototype; | |
| 13010 } | 13008 } |
| 13011 } | 13009 } |
| 13012 | 13010 |
| 13013 if (obj != NULL) { | 13011 if (obj != NULL) { |
| 13014 // Valid reference found add to instance array if supplied an update | 13012 // Valid reference found add to instance array if supplied an update |
| 13015 // count. | 13013 // count. |
| 13016 if (instances != NULL && count < instances_size) { | 13014 if (instances != NULL && count < instances_size) { |
| 13017 instances->set(count, obj); | 13015 instances->set(count, obj); |
| 13018 } | 13016 } |
| 13019 last = obj; | 13017 last = obj; |
| (...skipping 2089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15109 } | 15107 } |
| 15110 return NULL; | 15108 return NULL; |
| 15111 } | 15109 } |
| 15112 | 15110 |
| 15113 | 15111 |
| 15114 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15112 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
| 15115 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15113 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
| 15116 } | 15114 } |
| 15117 | 15115 |
| 15118 } } // namespace v8::internal | 15116 } } // namespace v8::internal |
| OLD | NEW |