OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1709 | 1709 |
1710 | 1710 |
1711 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) { | 1711 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) { |
1712 HandleScope scope(isolate); | 1712 HandleScope scope(isolate); |
1713 ASSERT(args.length() == 1); | 1713 ASSERT(args.length() == 1); |
1714 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); | 1714 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); |
1715 // We don't expect access checks to be needed on JSProxy objects. | 1715 // We don't expect access checks to be needed on JSProxy objects. |
1716 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); | 1716 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |
1717 do { | 1717 do { |
1718 if (obj->IsAccessCheckNeeded() && | 1718 if (obj->IsAccessCheckNeeded() && |
1719 !isolate->MayNamedAccessWrapper(Handle<JSObject>::cast(obj), | 1719 !isolate->MayNamedAccess(Handle<JSObject>::cast(obj), |
1720 isolate->factory()->proto_string(), | 1720 isolate->factory()->proto_string(), |
1721 v8::ACCESS_GET)) { | 1721 v8::ACCESS_GET)) { |
1722 isolate->ReportFailedAccessCheckWrapper(Handle<JSObject>::cast(obj), | 1722 isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj), |
1723 v8::ACCESS_GET); | 1723 v8::ACCESS_GET); |
1724 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1724 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1725 return isolate->heap()->undefined_value(); | 1725 return isolate->heap()->undefined_value(); |
1726 } | 1726 } |
1727 obj = handle(obj->GetPrototype(isolate), isolate); | 1727 obj = handle(obj->GetPrototype(isolate), isolate); |
1728 } while (obj->IsJSObject() && | 1728 } while (obj->IsJSObject() && |
1729 JSObject::cast(*obj)->map()->is_hidden_prototype()); | 1729 JSObject::cast(*obj)->map()->is_hidden_prototype()); |
1730 return *obj; | 1730 return *obj; |
1731 } | 1731 } |
1732 | 1732 |
1733 | 1733 |
1734 static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate, | 1734 static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate, |
1735 Object* receiver) { | 1735 Object* receiver) { |
1736 Object* current = receiver->GetPrototype(isolate); | 1736 Object* current = receiver->GetPrototype(isolate); |
1737 while (current->IsJSObject() && | 1737 while (current->IsJSObject() && |
1738 JSObject::cast(current)->map()->is_hidden_prototype()) { | 1738 JSObject::cast(current)->map()->is_hidden_prototype()) { |
1739 current = current->GetPrototype(isolate); | 1739 current = current->GetPrototype(isolate); |
1740 } | 1740 } |
1741 return current; | 1741 return current; |
1742 } | 1742 } |
1743 | 1743 |
1744 | 1744 |
1745 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) { | 1745 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) { |
1746 HandleScope scope(isolate); | 1746 HandleScope scope(isolate); |
1747 ASSERT(args.length() == 2); | 1747 ASSERT(args.length() == 2); |
1748 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 1748 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
1749 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); | 1749 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); |
1750 if (obj->IsAccessCheckNeeded() && | 1750 if (obj->IsAccessCheckNeeded() && |
1751 !isolate->MayNamedAccessWrapper(obj, | 1751 !isolate->MayNamedAccess( |
1752 isolate->factory()->proto_string(), | 1752 obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) { |
1753 v8::ACCESS_SET)) { | 1753 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET); |
1754 isolate->ReportFailedAccessCheckWrapper(obj, v8::ACCESS_SET); | |
1755 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1754 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1756 return isolate->heap()->undefined_value(); | 1755 return isolate->heap()->undefined_value(); |
1757 } | 1756 } |
1758 if (obj->map()->is_observed()) { | 1757 if (obj->map()->is_observed()) { |
1759 Handle<Object> old_value( | 1758 Handle<Object> old_value( |
1760 GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate); | 1759 GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate); |
1761 | 1760 |
1762 Handle<Object> result = JSObject::SetPrototype(obj, prototype, true); | 1761 Handle<Object> result = JSObject::SetPrototype(obj, prototype, true); |
1763 RETURN_IF_EMPTY_HANDLE(isolate, result); | 1762 RETURN_IF_EMPTY_HANDLE(isolate, result); |
1764 | 1763 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1843 }; | 1842 }; |
1844 | 1843 |
1845 | 1844 |
1846 static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj, | 1845 static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj, |
1847 Handle<Name> name, | 1846 Handle<Name> name, |
1848 v8::AccessType access_type) { | 1847 v8::AccessType access_type) { |
1849 uint32_t index; | 1848 uint32_t index; |
1850 if (name->AsArrayIndex(&index)) { | 1849 if (name->AsArrayIndex(&index)) { |
1851 // TODO(1095): we should traverse hidden prototype hierachy as well. | 1850 // TODO(1095): we should traverse hidden prototype hierachy as well. |
1852 if (CheckGenericAccess( | 1851 if (CheckGenericAccess( |
1853 obj, obj, index, access_type, &Isolate::MayIndexedAccessWrapper)) { | 1852 obj, obj, index, access_type, &Isolate::MayIndexedAccess)) { |
1854 return ACCESS_ALLOWED; | 1853 return ACCESS_ALLOWED; |
1855 } | 1854 } |
1856 | 1855 |
1857 obj->GetIsolate()->ReportFailedAccessCheckWrapper(obj, access_type); | 1856 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); |
1858 return ACCESS_FORBIDDEN; | 1857 return ACCESS_FORBIDDEN; |
1859 } | 1858 } |
1860 | 1859 |
1861 Isolate* isolate = obj->GetIsolate(); | 1860 Isolate* isolate = obj->GetIsolate(); |
1862 LookupResult lookup(isolate); | 1861 LookupResult lookup(isolate); |
1863 obj->LocalLookup(*name, &lookup, true); | 1862 obj->LocalLookup(*name, &lookup, true); |
1864 | 1863 |
1865 if (!lookup.IsProperty()) return ACCESS_ABSENT; | 1864 if (!lookup.IsProperty()) return ACCESS_ABSENT; |
1866 Handle<JSObject> holder(lookup.holder(), isolate); | 1865 Handle<JSObject> holder(lookup.holder(), isolate); |
1867 if (CheckGenericAccess<Handle<Object> >( | 1866 if (CheckGenericAccess<Handle<Object> >( |
1868 obj, holder, name, access_type, &Isolate::MayNamedAccessWrapper)) { | 1867 obj, holder, name, access_type, &Isolate::MayNamedAccess)) { |
1869 return ACCESS_ALLOWED; | 1868 return ACCESS_ALLOWED; |
1870 } | 1869 } |
1871 | 1870 |
1872 // Access check callback denied the access, but some properties | 1871 // Access check callback denied the access, but some properties |
1873 // can have a special permissions which override callbacks descision | 1872 // can have a special permissions which override callbacks descision |
1874 // (currently see v8::AccessControl). | 1873 // (currently see v8::AccessControl). |
1875 // API callbacks can have per callback access exceptions. | 1874 // API callbacks can have per callback access exceptions. |
1876 switch (lookup.type()) { | 1875 switch (lookup.type()) { |
1877 case CALLBACKS: | 1876 case CALLBACKS: |
1878 if (CheckAccessException(lookup.GetCallbackObject(), access_type)) { | 1877 if (CheckAccessException(lookup.GetCallbackObject(), access_type)) { |
1879 return ACCESS_ALLOWED; | 1878 return ACCESS_ALLOWED; |
1880 } | 1879 } |
1881 break; | 1880 break; |
1882 case INTERCEPTOR: | 1881 case INTERCEPTOR: |
1883 // If the object has an interceptor, try real named properties. | 1882 // If the object has an interceptor, try real named properties. |
1884 // Overwrite the result to fetch the correct property later. | 1883 // Overwrite the result to fetch the correct property later. |
1885 holder->LookupRealNamedProperty(*name, &lookup); | 1884 holder->LookupRealNamedProperty(*name, &lookup); |
1886 if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) { | 1885 if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) { |
1887 if (CheckAccessException(lookup.GetCallbackObject(), access_type)) { | 1886 if (CheckAccessException(lookup.GetCallbackObject(), access_type)) { |
1888 return ACCESS_ALLOWED; | 1887 return ACCESS_ALLOWED; |
1889 } | 1888 } |
1890 } | 1889 } |
1891 break; | 1890 break; |
1892 default: | 1891 default: |
1893 break; | 1892 break; |
1894 } | 1893 } |
1895 | 1894 |
1896 isolate->ReportFailedAccessCheckWrapper(obj, access_type); | 1895 isolate->ReportFailedAccessCheck(obj, access_type); |
1897 return ACCESS_FORBIDDEN; | 1896 return ACCESS_FORBIDDEN; |
1898 } | 1897 } |
1899 | 1898 |
1900 | 1899 |
1901 // Enumerator used as indices into the array returned from GetOwnProperty | 1900 // Enumerator used as indices into the array returned from GetOwnProperty |
1902 enum PropertyDescriptorIndices { | 1901 enum PropertyDescriptorIndices { |
1903 IS_ACCESSOR_INDEX, | 1902 IS_ACCESSOR_INDEX, |
1904 VALUE_INDEX, | 1903 VALUE_INDEX, |
1905 GETTER_INDEX, | 1904 GETTER_INDEX, |
1906 SETTER_INDEX, | 1905 SETTER_INDEX, |
(...skipping 3898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5805 } | 5804 } |
5806 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 5805 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
5807 CONVERT_SMI_ARG_CHECKED(filter_value, 1); | 5806 CONVERT_SMI_ARG_CHECKED(filter_value, 1); |
5808 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); | 5807 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); |
5809 | 5808 |
5810 // Skip the global proxy as it has no properties and always delegates to the | 5809 // Skip the global proxy as it has no properties and always delegates to the |
5811 // real global object. | 5810 // real global object. |
5812 if (obj->IsJSGlobalProxy()) { | 5811 if (obj->IsJSGlobalProxy()) { |
5813 // Only collect names if access is permitted. | 5812 // Only collect names if access is permitted. |
5814 if (obj->IsAccessCheckNeeded() && | 5813 if (obj->IsAccessCheckNeeded() && |
5815 !isolate->MayNamedAccessWrapper(obj, | 5814 !isolate->MayNamedAccess( |
5816 isolate->factory()->undefined_value(), | 5815 obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
5817 v8::ACCESS_KEYS)) { | 5816 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS); |
5818 isolate->ReportFailedAccessCheckWrapper(obj, v8::ACCESS_KEYS); | |
5819 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 5817 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
5820 return *isolate->factory()->NewJSArray(0); | 5818 return *isolate->factory()->NewJSArray(0); |
5821 } | 5819 } |
5822 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 5820 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); |
5823 } | 5821 } |
5824 | 5822 |
5825 // Find the number of objects making up this. | 5823 // Find the number of objects making up this. |
5826 int length = LocalPrototypeChainLength(*obj); | 5824 int length = LocalPrototypeChainLength(*obj); |
5827 | 5825 |
5828 // Find the number of local properties for each of the objects. | 5826 // Find the number of local properties for each of the objects. |
5829 ScopedVector<int> local_property_count(length); | 5827 ScopedVector<int> local_property_count(length); |
5830 int total_property_count = 0; | 5828 int total_property_count = 0; |
5831 Handle<JSObject> jsproto = obj; | 5829 Handle<JSObject> jsproto = obj; |
5832 for (int i = 0; i < length; i++) { | 5830 for (int i = 0; i < length; i++) { |
5833 // Only collect names if access is permitted. | 5831 // Only collect names if access is permitted. |
5834 if (jsproto->IsAccessCheckNeeded() && | 5832 if (jsproto->IsAccessCheckNeeded() && |
5835 !isolate->MayNamedAccessWrapper(jsproto, | 5833 !isolate->MayNamedAccess( |
5836 isolate->factory()->undefined_value(), | 5834 jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
5837 v8::ACCESS_KEYS)) { | 5835 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); |
5838 isolate->ReportFailedAccessCheckWrapper(jsproto, v8::ACCESS_KEYS); | |
5839 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 5836 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
5840 return *isolate->factory()->NewJSArray(0); | 5837 return *isolate->factory()->NewJSArray(0); |
5841 } | 5838 } |
5842 int n; | 5839 int n; |
5843 n = jsproto->NumberOfLocalProperties(filter); | 5840 n = jsproto->NumberOfLocalProperties(filter); |
5844 local_property_count[i] = n; | 5841 local_property_count[i] = n; |
5845 total_property_count += n; | 5842 total_property_count += n; |
5846 if (i < length - 1) { | 5843 if (i < length - 1) { |
5847 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 5844 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
5848 } | 5845 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5978 | 5975 |
5979 RUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) { | 5976 RUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) { |
5980 HandleScope scope(isolate); | 5977 HandleScope scope(isolate); |
5981 ASSERT_EQ(args.length(), 1); | 5978 ASSERT_EQ(args.length(), 1); |
5982 CONVERT_ARG_CHECKED(JSObject, raw_object, 0); | 5979 CONVERT_ARG_CHECKED(JSObject, raw_object, 0); |
5983 Handle<JSObject> object(raw_object); | 5980 Handle<JSObject> object(raw_object); |
5984 | 5981 |
5985 if (object->IsJSGlobalProxy()) { | 5982 if (object->IsJSGlobalProxy()) { |
5986 // Do access checks before going to the global object. | 5983 // Do access checks before going to the global object. |
5987 if (object->IsAccessCheckNeeded() && | 5984 if (object->IsAccessCheckNeeded() && |
5988 !isolate->MayNamedAccessWrapper(object, | 5985 !isolate->MayNamedAccess( |
5989 isolate->factory()->undefined_value(), | 5986 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
5990 v8::ACCESS_KEYS)) { | 5987 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); |
5991 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_KEYS); | |
5992 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 5988 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
5993 return *isolate->factory()->NewJSArray(0); | 5989 return *isolate->factory()->NewJSArray(0); |
5994 } | 5990 } |
5995 | 5991 |
5996 Handle<Object> proto(object->GetPrototype(), isolate); | 5992 Handle<Object> proto(object->GetPrototype(), isolate); |
5997 // If proxy is detached we simply return an empty array. | 5993 // If proxy is detached we simply return an empty array. |
5998 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); | 5994 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); |
5999 object = Handle<JSObject>::cast(proto); | 5995 object = Handle<JSObject>::cast(proto); |
6000 } | 5996 } |
6001 | 5997 |
(...skipping 8897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14899 | 14895 |
14900 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessAllowedForObserver) { | 14896 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessAllowedForObserver) { |
14901 HandleScope scope(isolate); | 14897 HandleScope scope(isolate); |
14902 ASSERT(args.length() == 3); | 14898 ASSERT(args.length() == 3); |
14903 CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0); | 14899 CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0); |
14904 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1); | 14900 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1); |
14905 ASSERT(object->map()->is_access_check_needed()); | 14901 ASSERT(object->map()->is_access_check_needed()); |
14906 Handle<Object> key = args.at<Object>(2); | 14902 Handle<Object> key = args.at<Object>(2); |
14907 SaveContext save(isolate); | 14903 SaveContext save(isolate); |
14908 isolate->set_context(observer->context()); | 14904 isolate->set_context(observer->context()); |
14909 if (!isolate->MayNamedAccessWrapper(object, | 14905 if (!isolate->MayNamedAccess( |
14910 isolate->factory()->undefined_value(), | 14906 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
14911 v8::ACCESS_KEYS)) { | |
14912 return isolate->heap()->false_value(); | 14907 return isolate->heap()->false_value(); |
14913 } | 14908 } |
14914 bool access_allowed = false; | 14909 bool access_allowed = false; |
14915 uint32_t index = 0; | 14910 uint32_t index = 0; |
14916 if (key->ToArrayIndex(&index) || | 14911 if (key->ToArrayIndex(&index) || |
14917 (key->IsString() && String::cast(*key)->AsArrayIndex(&index))) { | 14912 (key->IsString() && String::cast(*key)->AsArrayIndex(&index))) { |
14918 access_allowed = | 14913 access_allowed = |
14919 isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_GET) && | 14914 isolate->MayIndexedAccess(object, index, v8::ACCESS_GET) && |
14920 isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_HAS); | 14915 isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS); |
14921 } else { | 14916 } else { |
14922 access_allowed = | 14917 access_allowed = |
14923 isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_GET) && | 14918 isolate->MayNamedAccess(object, key, v8::ACCESS_GET) && |
14924 isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_HAS); | 14919 isolate->MayNamedAccess(object, key, v8::ACCESS_HAS); |
14925 } | 14920 } |
14926 return isolate->heap()->ToBoolean(access_allowed); | 14921 return isolate->heap()->ToBoolean(access_allowed); |
14927 } | 14922 } |
14928 | 14923 |
14929 | 14924 |
14930 static MaybeObject* ArrayConstructorCommon(Isolate* isolate, | 14925 static MaybeObject* ArrayConstructorCommon(Isolate* isolate, |
14931 Handle<JSFunction> constructor, | 14926 Handle<JSFunction> constructor, |
14932 Handle<AllocationSite> site, | 14927 Handle<AllocationSite> site, |
14933 Arguments* caller_args) { | 14928 Arguments* caller_args) { |
14934 Factory* factory = isolate->factory(); | 14929 Factory* factory = isolate->factory(); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15172 } | 15167 } |
15173 } | 15168 } |
15174 | 15169 |
15175 | 15170 |
15176 void Runtime::OutOfMemory() { | 15171 void Runtime::OutOfMemory() { |
15177 Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); | 15172 Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); |
15178 UNREACHABLE(); | 15173 UNREACHABLE(); |
15179 } | 15174 } |
15180 | 15175 |
15181 } } // namespace v8::internal | 15176 } } // namespace v8::internal |
OLD | NEW |