| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 return *result; | 212 return *result; |
| 213 } | 213 } |
| 214 | 214 |
| 215 | 215 |
| 216 // Only deal with CALLBACKS and INTERCEPTOR | 216 // Only deal with CALLBACKS and INTERCEPTOR |
| 217 Object* JSObject::GetPropertyWithFailedAccessCheck( | 217 Object* JSObject::GetPropertyWithFailedAccessCheck( |
| 218 Object* receiver, | 218 Object* receiver, |
| 219 LookupResult* result, | 219 LookupResult* result, |
| 220 String* name, | 220 String* name, |
| 221 PropertyAttributes* attributes) { | 221 PropertyAttributes* attributes) { |
| 222 if (result->IsValid()) { | 222 if (result->IsProperty()) { |
| 223 switch (result->type()) { | 223 switch (result->type()) { |
| 224 case CALLBACKS: { | 224 case CALLBACKS: { |
| 225 // Only allow API accessors. | 225 // Only allow API accessors. |
| 226 Object* obj = result->GetCallbackObject(); | 226 Object* obj = result->GetCallbackObject(); |
| 227 if (obj->IsAccessorInfo()) { | 227 if (obj->IsAccessorInfo()) { |
| 228 AccessorInfo* info = AccessorInfo::cast(obj); | 228 AccessorInfo* info = AccessorInfo::cast(obj); |
| 229 if (info->all_can_read()) { | 229 if (info->all_can_read()) { |
| 230 *attributes = result->GetAttributes(); | 230 *attributes = result->GetAttributes(); |
| 231 return GetPropertyWithCallback(receiver, | 231 return GetPropertyWithCallback(receiver, |
| 232 result->GetCallbackObject(), | 232 result->GetCallbackObject(), |
| 233 name, | 233 name, |
| 234 result->holder()); | 234 result->holder()); |
| 235 } | 235 } |
| 236 } | 236 } |
| 237 break; | 237 break; |
| 238 } | 238 } |
| 239 case NORMAL: | 239 case NORMAL: |
| 240 case FIELD: | 240 case FIELD: |
| 241 case CONSTANT_FUNCTION: { | 241 case CONSTANT_FUNCTION: { |
| 242 // Search ALL_CAN_READ accessors in prototype chain. | 242 // Search ALL_CAN_READ accessors in prototype chain. |
| 243 LookupResult r; | 243 LookupResult r; |
| 244 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); | 244 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); |
| 245 if (r.IsValid()) { | 245 if (r.IsProperty()) { |
| 246 return GetPropertyWithFailedAccessCheck(receiver, | 246 return GetPropertyWithFailedAccessCheck(receiver, |
| 247 &r, | 247 &r, |
| 248 name, | 248 name, |
| 249 attributes); | 249 attributes); |
| 250 } | 250 } |
| 251 break; | 251 break; |
| 252 } | 252 } |
| 253 case INTERCEPTOR: { | 253 case INTERCEPTOR: { |
| 254 // If the object has an interceptor, try real named properties. | 254 // If the object has an interceptor, try real named properties. |
| 255 // No access check in GetPropertyAttributeWithInterceptor. | 255 // No access check in GetPropertyAttributeWithInterceptor. |
| 256 LookupResult r; | 256 LookupResult r; |
| 257 result->holder()->LookupRealNamedProperty(name, &r); | 257 result->holder()->LookupRealNamedProperty(name, &r); |
| 258 if (r.IsValid()) { | 258 if (r.IsProperty()) { |
| 259 return GetPropertyWithFailedAccessCheck(receiver, | 259 return GetPropertyWithFailedAccessCheck(receiver, |
| 260 &r, | 260 &r, |
| 261 name, | 261 name, |
| 262 attributes); | 262 attributes); |
| 263 } | 263 } |
| 264 } | 264 } |
| 265 default: { | 265 default: |
| 266 break; | 266 UNREACHABLE(); |
| 267 } | |
| 268 } | 267 } |
| 269 } | 268 } |
| 270 | 269 |
| 271 // No accessible property found. | 270 // No accessible property found. |
| 272 *attributes = ABSENT; | 271 *attributes = ABSENT; |
| 273 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); | 272 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); |
| 274 return Heap::undefined_value(); | 273 return Heap::undefined_value(); |
| 275 } | 274 } |
| 276 | 275 |
| 277 | 276 |
| 278 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( | 277 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( |
| 279 Object* receiver, | 278 Object* receiver, |
| 280 LookupResult* result, | 279 LookupResult* result, |
| 281 String* name, | 280 String* name, |
| 282 bool continue_search) { | 281 bool continue_search) { |
| 283 if (result->IsValid()) { | 282 if (result->IsProperty()) { |
| 284 switch (result->type()) { | 283 switch (result->type()) { |
| 285 case CALLBACKS: { | 284 case CALLBACKS: { |
| 286 // Only allow API accessors. | 285 // Only allow API accessors. |
| 287 Object* obj = result->GetCallbackObject(); | 286 Object* obj = result->GetCallbackObject(); |
| 288 if (obj->IsAccessorInfo()) { | 287 if (obj->IsAccessorInfo()) { |
| 289 AccessorInfo* info = AccessorInfo::cast(obj); | 288 AccessorInfo* info = AccessorInfo::cast(obj); |
| 290 if (info->all_can_read()) { | 289 if (info->all_can_read()) { |
| 291 return result->GetAttributes(); | 290 return result->GetAttributes(); |
| 292 } | 291 } |
| 293 } | 292 } |
| 294 break; | 293 break; |
| 295 } | 294 } |
| 296 | 295 |
| 297 case NORMAL: | 296 case NORMAL: |
| 298 case FIELD: | 297 case FIELD: |
| 299 case CONSTANT_FUNCTION: { | 298 case CONSTANT_FUNCTION: { |
| 300 if (!continue_search) break; | 299 if (!continue_search) break; |
| 301 // Search ALL_CAN_READ accessors in prototype chain. | 300 // Search ALL_CAN_READ accessors in prototype chain. |
| 302 LookupResult r; | 301 LookupResult r; |
| 303 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); | 302 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); |
| 304 if (r.IsValid()) { | 303 if (r.IsProperty()) { |
| 305 return GetPropertyAttributeWithFailedAccessCheck(receiver, | 304 return GetPropertyAttributeWithFailedAccessCheck(receiver, |
| 306 &r, | 305 &r, |
| 307 name, | 306 name, |
| 308 continue_search); | 307 continue_search); |
| 309 } | 308 } |
| 310 break; | 309 break; |
| 311 } | 310 } |
| 312 | 311 |
| 313 case INTERCEPTOR: { | 312 case INTERCEPTOR: { |
| 314 // If the object has an interceptor, try real named properties. | 313 // If the object has an interceptor, try real named properties. |
| 315 // No access check in GetPropertyAttributeWithInterceptor. | 314 // No access check in GetPropertyAttributeWithInterceptor. |
| 316 LookupResult r; | 315 LookupResult r; |
| 317 if (continue_search) { | 316 if (continue_search) { |
| 318 result->holder()->LookupRealNamedProperty(name, &r); | 317 result->holder()->LookupRealNamedProperty(name, &r); |
| 319 } else { | 318 } else { |
| 320 result->holder()->LocalLookupRealNamedProperty(name, &r); | 319 result->holder()->LocalLookupRealNamedProperty(name, &r); |
| 321 } | 320 } |
| 322 if (r.IsValid()) { | 321 if (r.IsProperty()) { |
| 323 return GetPropertyAttributeWithFailedAccessCheck(receiver, | 322 return GetPropertyAttributeWithFailedAccessCheck(receiver, |
| 324 &r, | 323 &r, |
| 325 name, | 324 name, |
| 326 continue_search); | 325 continue_search); |
| 327 } | 326 } |
| 328 break; | 327 break; |
| 329 } | 328 } |
| 330 | 329 |
| 331 default: { | 330 default: |
| 332 break; | 331 UNREACHABLE(); |
| 333 } | |
| 334 } | 332 } |
| 335 } | 333 } |
| 336 | 334 |
| 337 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 335 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 338 return ABSENT; | 336 return ABSENT; |
| 339 } | 337 } |
| 340 | 338 |
| 341 | 339 |
| 342 Object* JSObject::GetLazyProperty(Object* receiver, | 340 Object* JSObject::GetLazyProperty(Object* receiver, |
| 343 LookupResult* result, | 341 LookupResult* result, |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 // Make sure that the top context does not change when doing | 496 // Make sure that the top context does not change when doing |
| 499 // callbacks or interceptor calls. | 497 // callbacks or interceptor calls. |
| 500 AssertNoContextChange ncc; | 498 AssertNoContextChange ncc; |
| 501 | 499 |
| 502 // Traverse the prototype chain from the current object (this) to | 500 // Traverse the prototype chain from the current object (this) to |
| 503 // the holder and check for access rights. This avoid traversing the | 501 // the holder and check for access rights. This avoid traversing the |
| 504 // objects more than once in case of interceptors, because the | 502 // objects more than once in case of interceptors, because the |
| 505 // holder will always be the interceptor holder and the search may | 503 // holder will always be the interceptor holder and the search may |
| 506 // only continue with a current object just after the interceptor | 504 // only continue with a current object just after the interceptor |
| 507 // holder in the prototype chain. | 505 // holder in the prototype chain. |
| 508 Object* last = result->IsValid() ? result->holder() : Heap::null_value(); | 506 Object* last = result->IsProperty() ? result->holder() : Heap::null_value(); |
| 509 for (Object* current = this; true; current = current->GetPrototype()) { | 507 for (Object* current = this; true; current = current->GetPrototype()) { |
| 510 if (current->IsAccessCheckNeeded()) { | 508 if (current->IsAccessCheckNeeded()) { |
| 511 // Check if we're allowed to read from the current object. Note | 509 // Check if we're allowed to read from the current object. Note |
| 512 // that even though we may not actually end up loading the named | 510 // that even though we may not actually end up loading the named |
| 513 // property from the current object, we still check that we have | 511 // property from the current object, we still check that we have |
| 514 // access to it. | 512 // access to it. |
| 515 JSObject* checked = JSObject::cast(current); | 513 JSObject* checked = JSObject::cast(current); |
| 516 if (!Top::MayNamedAccess(checked, name, v8::ACCESS_GET)) { | 514 if (!Top::MayNamedAccess(checked, name, v8::ACCESS_GET)) { |
| 517 return checked->GetPropertyWithFailedAccessCheck(receiver, | 515 return checked->GetPropertyWithFailedAccessCheck(receiver, |
| 518 result, | 516 result, |
| (...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 return AddSlowProperty(name, value, attributes); | 1454 return AddSlowProperty(name, value, attributes); |
| 1457 } | 1455 } |
| 1458 | 1456 |
| 1459 | 1457 |
| 1460 Object* JSObject::SetPropertyPostInterceptor(String* name, | 1458 Object* JSObject::SetPropertyPostInterceptor(String* name, |
| 1461 Object* value, | 1459 Object* value, |
| 1462 PropertyAttributes attributes) { | 1460 PropertyAttributes attributes) { |
| 1463 // Check local property, ignore interceptor. | 1461 // Check local property, ignore interceptor. |
| 1464 LookupResult result; | 1462 LookupResult result; |
| 1465 LocalLookupRealNamedProperty(name, &result); | 1463 LocalLookupRealNamedProperty(name, &result); |
| 1466 if (result.IsValid()) return SetProperty(&result, name, value, attributes); | 1464 if (result.IsFound()) { |
| 1467 // Add real property. | 1465 // An existing property, a map transition or a null descriptor was |
| 1466 // found. Use set property to handle all these cases. |
| 1467 return SetProperty(&result, name, value, attributes); |
| 1468 } |
| 1469 // Add a new real property. |
| 1468 return AddProperty(name, value, attributes); | 1470 return AddProperty(name, value, attributes); |
| 1469 } | 1471 } |
| 1470 | 1472 |
| 1471 | 1473 |
| 1472 Object* JSObject::ReplaceSlowProperty(String* name, | 1474 Object* JSObject::ReplaceSlowProperty(String* name, |
| 1473 Object* value, | 1475 Object* value, |
| 1474 PropertyAttributes attributes) { | 1476 PropertyAttributes attributes) { |
| 1475 StringDictionary* dictionary = property_dictionary(); | 1477 StringDictionary* dictionary = property_dictionary(); |
| 1476 int old_index = dictionary->FindEntry(name); | 1478 int old_index = dictionary->FindEntry(name); |
| 1477 int new_enumeration_index = 0; // 0 means "Use the next available index." | 1479 int new_enumeration_index = 0; // 0 means "Use the next available index." |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1689 return *value_handle; | 1691 return *value_handle; |
| 1690 } | 1692 } |
| 1691 | 1693 |
| 1692 | 1694 |
| 1693 void JSObject::LookupCallbackSetterInPrototypes(String* name, | 1695 void JSObject::LookupCallbackSetterInPrototypes(String* name, |
| 1694 LookupResult* result) { | 1696 LookupResult* result) { |
| 1695 for (Object* pt = GetPrototype(); | 1697 for (Object* pt = GetPrototype(); |
| 1696 pt != Heap::null_value(); | 1698 pt != Heap::null_value(); |
| 1697 pt = pt->GetPrototype()) { | 1699 pt = pt->GetPrototype()) { |
| 1698 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 1700 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
| 1699 if (result->IsValid()) { | 1701 if (result->IsProperty()) { |
| 1700 if (!result->IsTransitionType() && result->IsReadOnly()) { | 1702 if (result->IsReadOnly()) { |
| 1701 result->NotFound(); | 1703 result->NotFound(); |
| 1702 return; | 1704 return; |
| 1703 } | 1705 } |
| 1704 if (result->type() == CALLBACKS) { | 1706 if (result->type() == CALLBACKS) { |
| 1705 return; | 1707 return; |
| 1706 } | 1708 } |
| 1707 } | 1709 } |
| 1708 } | 1710 } |
| 1709 result->NotFound(); | 1711 result->NotFound(); |
| 1710 } | 1712 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1751 LookupResult* result) { | 1753 LookupResult* result) { |
| 1752 if (IsJSGlobalProxy()) { | 1754 if (IsJSGlobalProxy()) { |
| 1753 Object* proto = GetPrototype(); | 1755 Object* proto = GetPrototype(); |
| 1754 if (proto->IsNull()) return result->NotFound(); | 1756 if (proto->IsNull()) return result->NotFound(); |
| 1755 ASSERT(proto->IsJSGlobalObject()); | 1757 ASSERT(proto->IsJSGlobalObject()); |
| 1756 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); | 1758 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); |
| 1757 } | 1759 } |
| 1758 | 1760 |
| 1759 if (HasFastProperties()) { | 1761 if (HasFastProperties()) { |
| 1760 LookupInDescriptor(name, result); | 1762 LookupInDescriptor(name, result); |
| 1761 if (result->IsValid()) { | 1763 if (result->IsFound()) { |
| 1764 // A property, a map transition or a null descriptor was found. |
| 1765 // We return all of these result types because |
| 1766 // LocalLookupRealNamedProperty is used when setting properties |
| 1767 // where map transitions and null descriptors are handled. |
| 1762 ASSERT(result->holder() == this && result->type() != NORMAL); | 1768 ASSERT(result->holder() == this && result->type() != NORMAL); |
| 1763 // Disallow caching for uninitialized constants. These can only | 1769 // Disallow caching for uninitialized constants. These can only |
| 1764 // occur as fields. | 1770 // occur as fields. |
| 1765 if (result->IsReadOnly() && result->type() == FIELD && | 1771 if (result->IsReadOnly() && result->type() == FIELD && |
| 1766 FastPropertyAt(result->GetFieldIndex())->IsTheHole()) { | 1772 FastPropertyAt(result->GetFieldIndex())->IsTheHole()) { |
| 1767 result->DisallowCaching(); | 1773 result->DisallowCaching(); |
| 1768 } | 1774 } |
| 1769 return; | 1775 return; |
| 1770 } | 1776 } |
| 1771 } else { | 1777 } else { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1801 LookupRealNamedPropertyInPrototypes(name, result); | 1807 LookupRealNamedPropertyInPrototypes(name, result); |
| 1802 } | 1808 } |
| 1803 | 1809 |
| 1804 | 1810 |
| 1805 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, | 1811 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, |
| 1806 LookupResult* result) { | 1812 LookupResult* result) { |
| 1807 for (Object* pt = GetPrototype(); | 1813 for (Object* pt = GetPrototype(); |
| 1808 pt != Heap::null_value(); | 1814 pt != Heap::null_value(); |
| 1809 pt = JSObject::cast(pt)->GetPrototype()) { | 1815 pt = JSObject::cast(pt)->GetPrototype()) { |
| 1810 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 1816 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
| 1811 if (result->IsValid()) { | 1817 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; |
| 1812 switch (result->type()) { | |
| 1813 case NORMAL: | |
| 1814 case FIELD: | |
| 1815 case CONSTANT_FUNCTION: | |
| 1816 case CALLBACKS: | |
| 1817 return; | |
| 1818 default: break; | |
| 1819 } | |
| 1820 } | |
| 1821 } | 1818 } |
| 1822 result->NotFound(); | 1819 result->NotFound(); |
| 1823 } | 1820 } |
| 1824 | 1821 |
| 1825 | 1822 |
| 1826 // We only need to deal with CALLBACKS and INTERCEPTORS | 1823 // We only need to deal with CALLBACKS and INTERCEPTORS |
| 1827 Object* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, | 1824 Object* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, |
| 1828 String* name, | 1825 String* name, |
| 1829 Object* value) { | 1826 Object* value) { |
| 1830 if (!result->IsProperty()) { | 1827 if (!result->IsProperty()) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1896 if (proto->IsNull()) return value; | 1893 if (proto->IsNull()) return value; |
| 1897 ASSERT(proto->IsJSGlobalObject()); | 1894 ASSERT(proto->IsJSGlobalObject()); |
| 1898 return JSObject::cast(proto)->SetProperty(result, name, value, attributes); | 1895 return JSObject::cast(proto)->SetProperty(result, name, value, attributes); |
| 1899 } | 1896 } |
| 1900 | 1897 |
| 1901 if (!result->IsProperty() && !IsJSContextExtensionObject()) { | 1898 if (!result->IsProperty() && !IsJSContextExtensionObject()) { |
| 1902 // We could not find a local property so let's check whether there is an | 1899 // We could not find a local property so let's check whether there is an |
| 1903 // accessor that wants to handle the property. | 1900 // accessor that wants to handle the property. |
| 1904 LookupResult accessor_result; | 1901 LookupResult accessor_result; |
| 1905 LookupCallbackSetterInPrototypes(name, &accessor_result); | 1902 LookupCallbackSetterInPrototypes(name, &accessor_result); |
| 1906 if (accessor_result.IsValid()) { | 1903 if (accessor_result.IsProperty()) { |
| 1907 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), | 1904 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), |
| 1908 name, | 1905 name, |
| 1909 value, | 1906 value, |
| 1910 accessor_result.holder()); | 1907 accessor_result.holder()); |
| 1911 } | 1908 } |
| 1912 } | 1909 } |
| 1913 if (result->IsNotFound()) { | 1910 if (!result->IsFound()) { |
| 1911 // Neither properties nor transitions found. |
| 1914 return AddProperty(name, value, attributes); | 1912 return AddProperty(name, value, attributes); |
| 1915 } | 1913 } |
| 1916 if (!result->IsLoaded()) { | 1914 if (!result->IsLoaded()) { |
| 1917 return SetLazyProperty(result, name, value, attributes); | 1915 return SetLazyProperty(result, name, value, attributes); |
| 1918 } | 1916 } |
| 1919 if (result->IsReadOnly() && result->IsProperty()) return value; | 1917 if (result->IsReadOnly() && result->IsProperty()) return value; |
| 1920 // This is a real property that is not read-only, or it is a | 1918 // This is a real property that is not read-only, or it is a |
| 1921 // transition or null descriptor and there are no setters in the prototypes. | 1919 // transition or null descriptor and there are no setters in the prototypes. |
| 1922 switch (result->type()) { | 1920 switch (result->type()) { |
| 1923 case NORMAL: | 1921 case NORMAL: |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1965 // callback setter removed. The two lines looking up the LookupResult | 1963 // callback setter removed. The two lines looking up the LookupResult |
| 1966 // result are also added. If one of the functions is changed, the other | 1964 // result are also added. If one of the functions is changed, the other |
| 1967 // should be. | 1965 // should be. |
| 1968 Object* JSObject::IgnoreAttributesAndSetLocalProperty( | 1966 Object* JSObject::IgnoreAttributesAndSetLocalProperty( |
| 1969 String* name, | 1967 String* name, |
| 1970 Object* value, | 1968 Object* value, |
| 1971 PropertyAttributes attributes) { | 1969 PropertyAttributes attributes) { |
| 1972 // Make sure that the top context does not change when doing callbacks or | 1970 // Make sure that the top context does not change when doing callbacks or |
| 1973 // interceptor calls. | 1971 // interceptor calls. |
| 1974 AssertNoContextChange ncc; | 1972 AssertNoContextChange ncc; |
| 1975 // ADDED TO CLONE | 1973 LookupResult result; |
| 1976 LookupResult result_struct; | 1974 LocalLookup(name, &result); |
| 1977 LocalLookup(name, &result_struct); | |
| 1978 LookupResult* result = &result_struct; | |
| 1979 // END ADDED TO CLONE | |
| 1980 // Check access rights if needed. | 1975 // Check access rights if needed. |
| 1981 if (IsAccessCheckNeeded() | 1976 if (IsAccessCheckNeeded() |
| 1982 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 1977 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 1983 return SetPropertyWithFailedAccessCheck(result, name, value); | 1978 return SetPropertyWithFailedAccessCheck(&result, name, value); |
| 1984 } | 1979 } |
| 1985 | 1980 |
| 1986 if (IsJSGlobalProxy()) { | 1981 if (IsJSGlobalProxy()) { |
| 1987 Object* proto = GetPrototype(); | 1982 Object* proto = GetPrototype(); |
| 1988 if (proto->IsNull()) return value; | 1983 if (proto->IsNull()) return value; |
| 1989 ASSERT(proto->IsJSGlobalObject()); | 1984 ASSERT(proto->IsJSGlobalObject()); |
| 1990 return JSObject::cast(proto)->IgnoreAttributesAndSetLocalProperty( | 1985 return JSObject::cast(proto)->IgnoreAttributesAndSetLocalProperty( |
| 1991 name, | 1986 name, |
| 1992 value, | 1987 value, |
| 1993 attributes); | 1988 attributes); |
| 1994 } | 1989 } |
| 1995 | 1990 |
| 1996 // Check for accessor in prototype chain removed here in clone. | 1991 // Check for accessor in prototype chain removed here in clone. |
| 1997 if (result->IsNotFound()) { | 1992 if (!result.IsFound()) { |
| 1993 // Neither properties nor transitions found. |
| 1998 return AddProperty(name, value, attributes); | 1994 return AddProperty(name, value, attributes); |
| 1999 } | 1995 } |
| 2000 if (!result->IsLoaded()) { | 1996 if (!result.IsLoaded()) { |
| 2001 return SetLazyProperty(result, name, value, attributes); | 1997 return SetLazyProperty(&result, name, value, attributes); |
| 2002 } | 1998 } |
| 2003 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 1999 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| 2004 | 2000 |
| 2005 // Check of IsReadOnly removed from here in clone. | 2001 // Check of IsReadOnly removed from here in clone. |
| 2006 switch (result->type()) { | 2002 switch (result.type()) { |
| 2007 case NORMAL: | 2003 case NORMAL: |
| 2008 return SetNormalizedProperty(name, value, details); | 2004 return SetNormalizedProperty(name, value, details); |
| 2009 case FIELD: | 2005 case FIELD: |
| 2010 return FastPropertyAtPut(result->GetFieldIndex(), value); | 2006 return FastPropertyAtPut(result.GetFieldIndex(), value); |
| 2011 case MAP_TRANSITION: | 2007 case MAP_TRANSITION: |
| 2012 if (attributes == result->GetAttributes()) { | 2008 if (attributes == result.GetAttributes()) { |
| 2013 // Only use map transition if the attributes match. | 2009 // Only use map transition if the attributes match. |
| 2014 return AddFastPropertyUsingMap(result->GetTransitionMap(), | 2010 return AddFastPropertyUsingMap(result.GetTransitionMap(), |
| 2015 name, | 2011 name, |
| 2016 value); | 2012 value); |
| 2017 } | 2013 } |
| 2018 return ConvertDescriptorToField(name, value, attributes); | 2014 return ConvertDescriptorToField(name, value, attributes); |
| 2019 case CONSTANT_FUNCTION: | 2015 case CONSTANT_FUNCTION: |
| 2020 // Only replace the function if necessary. | 2016 // Only replace the function if necessary. |
| 2021 if (value == result->GetConstantFunction()) return value; | 2017 if (value == result.GetConstantFunction()) return value; |
| 2022 // Preserve the attributes of this existing property. | 2018 // Preserve the attributes of this existing property. |
| 2023 attributes = result->GetAttributes(); | 2019 attributes = result.GetAttributes(); |
| 2024 return ConvertDescriptorToField(name, value, attributes); | 2020 return ConvertDescriptorToField(name, value, attributes); |
| 2025 case CALLBACKS: | 2021 case CALLBACKS: |
| 2026 case INTERCEPTOR: | 2022 case INTERCEPTOR: |
| 2027 // Override callback in clone | 2023 // Override callback in clone |
| 2028 return ConvertDescriptorToField(name, value, attributes); | 2024 return ConvertDescriptorToField(name, value, attributes); |
| 2029 case CONSTANT_TRANSITION: | 2025 case CONSTANT_TRANSITION: |
| 2030 // Replace with a MAP_TRANSITION to a new map with a FIELD, even | 2026 // Replace with a MAP_TRANSITION to a new map with a FIELD, even |
| 2031 // if the value is a function. | 2027 // if the value is a function. |
| 2032 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); | 2028 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); |
| 2033 case NULL_DESCRIPTOR: | 2029 case NULL_DESCRIPTOR: |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2129 String* name, | 2125 String* name, |
| 2130 bool continue_search) { | 2126 bool continue_search) { |
| 2131 // Check access rights if needed. | 2127 // Check access rights if needed. |
| 2132 if (IsAccessCheckNeeded() && | 2128 if (IsAccessCheckNeeded() && |
| 2133 !Top::MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 2129 !Top::MayNamedAccess(this, name, v8::ACCESS_HAS)) { |
| 2134 return GetPropertyAttributeWithFailedAccessCheck(receiver, | 2130 return GetPropertyAttributeWithFailedAccessCheck(receiver, |
| 2135 result, | 2131 result, |
| 2136 name, | 2132 name, |
| 2137 continue_search); | 2133 continue_search); |
| 2138 } | 2134 } |
| 2139 if (result->IsValid()) { | 2135 if (result->IsProperty()) { |
| 2140 switch (result->type()) { | 2136 switch (result->type()) { |
| 2141 case NORMAL: // fall through | 2137 case NORMAL: // fall through |
| 2142 case FIELD: | 2138 case FIELD: |
| 2143 case CONSTANT_FUNCTION: | 2139 case CONSTANT_FUNCTION: |
| 2144 case CALLBACKS: | 2140 case CALLBACKS: |
| 2145 return result->GetAttributes(); | 2141 return result->GetAttributes(); |
| 2146 case INTERCEPTOR: | 2142 case INTERCEPTOR: |
| 2147 return result->holder()-> | 2143 return result->holder()-> |
| 2148 GetPropertyAttributeWithInterceptor(receiver, name, continue_search); | 2144 GetPropertyAttributeWithInterceptor(receiver, name, continue_search); |
| 2149 case MAP_TRANSITION: | |
| 2150 case CONSTANT_TRANSITION: | |
| 2151 case NULL_DESCRIPTOR: | |
| 2152 return ABSENT; | |
| 2153 default: | 2145 default: |
| 2154 UNREACHABLE(); | 2146 UNREACHABLE(); |
| 2155 break; | |
| 2156 } | 2147 } |
| 2157 } | 2148 } |
| 2158 return ABSENT; | 2149 return ABSENT; |
| 2159 } | 2150 } |
| 2160 | 2151 |
| 2161 | 2152 |
| 2162 PropertyAttributes JSObject::GetLocalPropertyAttribute(String* name) { | 2153 PropertyAttributes JSObject::GetLocalPropertyAttribute(String* name) { |
| 2163 // Check whether the name is an array index. | 2154 // Check whether the name is an array index. |
| 2164 uint32_t index = 0; | 2155 uint32_t index = 0; |
| 2165 if (name->AsArrayIndex(&index)) { | 2156 if (name->AsArrayIndex(&index)) { |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2318 #endif | 2309 #endif |
| 2319 | 2310 |
| 2320 return this; | 2311 return this; |
| 2321 } | 2312 } |
| 2322 | 2313 |
| 2323 | 2314 |
| 2324 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) { | 2315 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) { |
| 2325 // Check local property, ignore interceptor. | 2316 // Check local property, ignore interceptor. |
| 2326 LookupResult result; | 2317 LookupResult result; |
| 2327 LocalLookupRealNamedProperty(name, &result); | 2318 LocalLookupRealNamedProperty(name, &result); |
| 2328 if (!result.IsValid()) return Heap::true_value(); | 2319 if (!result.IsProperty()) return Heap::true_value(); |
| 2329 | 2320 |
| 2330 // Normalize object if needed. | 2321 // Normalize object if needed. |
| 2331 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2322 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 2332 if (obj->IsFailure()) return obj; | 2323 if (obj->IsFailure()) return obj; |
| 2333 | 2324 |
| 2334 return DeleteNormalizedProperty(name, mode); | 2325 return DeleteNormalizedProperty(name, mode); |
| 2335 } | 2326 } |
| 2336 | 2327 |
| 2337 | 2328 |
| 2338 Object* JSObject::DeletePropertyWithInterceptor(String* name) { | 2329 Object* JSObject::DeletePropertyWithInterceptor(String* name) { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2502 ASSERT(proto->IsJSGlobalObject()); | 2493 ASSERT(proto->IsJSGlobalObject()); |
| 2503 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); | 2494 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); |
| 2504 } | 2495 } |
| 2505 | 2496 |
| 2506 uint32_t index = 0; | 2497 uint32_t index = 0; |
| 2507 if (name->AsArrayIndex(&index)) { | 2498 if (name->AsArrayIndex(&index)) { |
| 2508 return DeleteElement(index, mode); | 2499 return DeleteElement(index, mode); |
| 2509 } else { | 2500 } else { |
| 2510 LookupResult result; | 2501 LookupResult result; |
| 2511 LocalLookup(name, &result); | 2502 LocalLookup(name, &result); |
| 2512 if (!result.IsValid()) return Heap::true_value(); | 2503 if (!result.IsProperty()) return Heap::true_value(); |
| 2513 // Ignore attributes if forcing a deletion. | 2504 // Ignore attributes if forcing a deletion. |
| 2514 if (result.IsDontDelete() && mode != FORCE_DELETION) { | 2505 if (result.IsDontDelete() && mode != FORCE_DELETION) { |
| 2515 return Heap::false_value(); | 2506 return Heap::false_value(); |
| 2516 } | 2507 } |
| 2517 // Check for interceptor. | 2508 // Check for interceptor. |
| 2518 if (result.type() == INTERCEPTOR) { | 2509 if (result.type() == INTERCEPTOR) { |
| 2519 // Skip interceptor if forcing a deletion. | 2510 // Skip interceptor if forcing a deletion. |
| 2520 if (mode == FORCE_DELETION) { | 2511 if (mode == FORCE_DELETION) { |
| 2521 return DeletePropertyPostInterceptor(name, mode); | 2512 return DeletePropertyPostInterceptor(name, mode); |
| 2522 } | 2513 } |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2737 LocalLookupRealNamedProperty(name, result); | 2728 LocalLookupRealNamedProperty(name, result); |
| 2738 } | 2729 } |
| 2739 | 2730 |
| 2740 | 2731 |
| 2741 void JSObject::Lookup(String* name, LookupResult* result) { | 2732 void JSObject::Lookup(String* name, LookupResult* result) { |
| 2742 // Ecma-262 3rd 8.6.2.4 | 2733 // Ecma-262 3rd 8.6.2.4 |
| 2743 for (Object* current = this; | 2734 for (Object* current = this; |
| 2744 current != Heap::null_value(); | 2735 current != Heap::null_value(); |
| 2745 current = JSObject::cast(current)->GetPrototype()) { | 2736 current = JSObject::cast(current)->GetPrototype()) { |
| 2746 JSObject::cast(current)->LocalLookup(name, result); | 2737 JSObject::cast(current)->LocalLookup(name, result); |
| 2747 if (result->IsValid() && !result->IsTransitionType()) return; | 2738 if (result->IsProperty()) return; |
| 2748 } | 2739 } |
| 2749 result->NotFound(); | 2740 result->NotFound(); |
| 2750 } | 2741 } |
| 2751 | 2742 |
| 2752 | 2743 |
| 2753 // Search object and it's prototype chain for callback properties. | 2744 // Search object and it's prototype chain for callback properties. |
| 2754 void JSObject::LookupCallback(String* name, LookupResult* result) { | 2745 void JSObject::LookupCallback(String* name, LookupResult* result) { |
| 2755 for (Object* current = this; | 2746 for (Object* current = this; |
| 2756 current != Heap::null_value(); | 2747 current != Heap::null_value(); |
| 2757 current = JSObject::cast(current)->GetPrototype()) { | 2748 current = JSObject::cast(current)->GetPrototype()) { |
| 2758 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); | 2749 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); |
| 2759 if (result->IsValid() && result->type() == CALLBACKS) return; | 2750 if (result->IsProperty() && result->type() == CALLBACKS) return; |
| 2760 } | 2751 } |
| 2761 result->NotFound(); | 2752 result->NotFound(); |
| 2762 } | 2753 } |
| 2763 | 2754 |
| 2764 | 2755 |
| 2765 Object* JSObject::DefineGetterSetter(String* name, | 2756 Object* JSObject::DefineGetterSetter(String* name, |
| 2766 PropertyAttributes attributes) { | 2757 PropertyAttributes attributes) { |
| 2767 // Make sure that the top context does not change when doing callbacks or | 2758 // Make sure that the top context does not change when doing callbacks or |
| 2768 // interceptor calls. | 2759 // interceptor calls. |
| 2769 AssertNoContextChange ncc; | 2760 AssertNoContextChange ncc; |
| 2770 | 2761 |
| 2771 // Check access rights if needed. | 2762 // Check access rights if needed. |
| 2772 if (IsAccessCheckNeeded() && | 2763 if (IsAccessCheckNeeded() && |
| 2773 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 2764 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 2774 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 2765 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 2775 return Heap::undefined_value(); | 2766 return Heap::undefined_value(); |
| 2776 } | 2767 } |
| 2777 | 2768 |
| 2778 // Try to flatten before operating on the string. | 2769 // Try to flatten before operating on the string. |
| 2779 name->TryFlattenIfNotFlat(); | 2770 name->TryFlattenIfNotFlat(); |
| 2780 | 2771 |
| 2781 // Check if there is an API defined callback object which prohibits | 2772 // Check if there is an API defined callback object which prohibits |
| 2782 // callback overwriting in this object or it's prototype chain. | 2773 // callback overwriting in this object or it's prototype chain. |
| 2783 // This mechanism is needed for instance in a browser setting, where | 2774 // This mechanism is needed for instance in a browser setting, where |
| 2784 // certain accessors such as window.location should not be allowed | 2775 // certain accessors such as window.location should not be allowed |
| 2785 // to be overwritten because allowing overwriting could potentially | 2776 // to be overwritten because allowing overwriting could potentially |
| 2786 // cause security problems. | 2777 // cause security problems. |
| 2787 LookupResult callback_result; | 2778 LookupResult callback_result; |
| 2788 LookupCallback(name, &callback_result); | 2779 LookupCallback(name, &callback_result); |
| 2789 if (callback_result.IsValid()) { | 2780 if (callback_result.IsFound()) { |
| 2790 Object* obj = callback_result.GetCallbackObject(); | 2781 Object* obj = callback_result.GetCallbackObject(); |
| 2791 if (obj->IsAccessorInfo() && | 2782 if (obj->IsAccessorInfo() && |
| 2792 AccessorInfo::cast(obj)->prohibits_overwriting()) { | 2783 AccessorInfo::cast(obj)->prohibits_overwriting()) { |
| 2793 return Heap::undefined_value(); | 2784 return Heap::undefined_value(); |
| 2794 } | 2785 } |
| 2795 } | 2786 } |
| 2796 | 2787 |
| 2797 uint32_t index; | 2788 uint32_t index; |
| 2798 bool is_element = name->AsArrayIndex(&index); | 2789 bool is_element = name->AsArrayIndex(&index); |
| 2799 if (is_element && IsJSArray()) return Heap::undefined_value(); | 2790 if (is_element && IsJSArray()) return Heap::undefined_value(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2830 break; | 2821 break; |
| 2831 } | 2822 } |
| 2832 default: | 2823 default: |
| 2833 UNREACHABLE(); | 2824 UNREACHABLE(); |
| 2834 break; | 2825 break; |
| 2835 } | 2826 } |
| 2836 } else { | 2827 } else { |
| 2837 // Lookup the name. | 2828 // Lookup the name. |
| 2838 LookupResult result; | 2829 LookupResult result; |
| 2839 LocalLookup(name, &result); | 2830 LocalLookup(name, &result); |
| 2840 if (result.IsValid()) { | 2831 if (result.IsProperty()) { |
| 2841 if (result.IsReadOnly()) return Heap::undefined_value(); | 2832 if (result.IsReadOnly()) return Heap::undefined_value(); |
| 2842 if (result.type() == CALLBACKS) { | 2833 if (result.type() == CALLBACKS) { |
| 2843 Object* obj = result.GetCallbackObject(); | 2834 Object* obj = result.GetCallbackObject(); |
| 2844 if (obj->IsFixedArray()) { | 2835 if (obj->IsFixedArray()) { |
| 2845 // The object might be in fast mode even though it has | 2836 // The object might be in fast mode even though it has |
| 2846 // a getter/setter. | 2837 // a getter/setter. |
| 2847 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2838 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 2848 if (ok->IsFailure()) return ok; | 2839 if (ok->IsFailure()) return ok; |
| 2849 | 2840 |
| 2850 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); | 2841 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2952 } | 2943 } |
| 2953 } | 2944 } |
| 2954 } | 2945 } |
| 2955 } | 2946 } |
| 2956 } else { | 2947 } else { |
| 2957 for (Object* obj = this; | 2948 for (Object* obj = this; |
| 2958 obj != Heap::null_value(); | 2949 obj != Heap::null_value(); |
| 2959 obj = JSObject::cast(obj)->GetPrototype()) { | 2950 obj = JSObject::cast(obj)->GetPrototype()) { |
| 2960 LookupResult result; | 2951 LookupResult result; |
| 2961 JSObject::cast(obj)->LocalLookup(name, &result); | 2952 JSObject::cast(obj)->LocalLookup(name, &result); |
| 2962 if (result.IsValid()) { | 2953 if (result.IsProperty()) { |
| 2963 if (result.IsReadOnly()) return Heap::undefined_value(); | 2954 if (result.IsReadOnly()) return Heap::undefined_value(); |
| 2964 if (result.type() == CALLBACKS) { | 2955 if (result.type() == CALLBACKS) { |
| 2965 Object* obj = result.GetCallbackObject(); | 2956 Object* obj = result.GetCallbackObject(); |
| 2966 if (obj->IsFixedArray()) { | 2957 if (obj->IsFixedArray()) { |
| 2967 return FixedArray::cast(obj)->get(accessor_index); | 2958 return FixedArray::cast(obj)->get(accessor_index); |
| 2968 } | 2959 } |
| 2969 } | 2960 } |
| 2970 } | 2961 } |
| 2971 } | 2962 } |
| 2972 } | 2963 } |
| (...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4844 // Traverse the proposed prototype chain looking for setters for properties of | 4835 // Traverse the proposed prototype chain looking for setters for properties of |
| 4845 // the same names as are set by the inline constructor. | 4836 // the same names as are set by the inline constructor. |
| 4846 for (Object* obj = prototype; | 4837 for (Object* obj = prototype; |
| 4847 obj != Heap::null_value(); | 4838 obj != Heap::null_value(); |
| 4848 obj = obj->GetPrototype()) { | 4839 obj = obj->GetPrototype()) { |
| 4849 JSObject* js_object = JSObject::cast(obj); | 4840 JSObject* js_object = JSObject::cast(obj); |
| 4850 for (int i = 0; i < this_property_assignments_count(); i++) { | 4841 for (int i = 0; i < this_property_assignments_count(); i++) { |
| 4851 LookupResult result; | 4842 LookupResult result; |
| 4852 String* name = GetThisPropertyAssignmentName(i); | 4843 String* name = GetThisPropertyAssignmentName(i); |
| 4853 js_object->LocalLookupRealNamedProperty(name, &result); | 4844 js_object->LocalLookupRealNamedProperty(name, &result); |
| 4854 if (result.IsValid() && result.type() == CALLBACKS) { | 4845 if (result.IsProperty() && result.type() == CALLBACKS) { |
| 4855 return false; | 4846 return false; |
| 4856 } | 4847 } |
| 4857 } | 4848 } |
| 4858 } | 4849 } |
| 4859 | 4850 |
| 4860 return true; | 4851 return true; |
| 4861 } | 4852 } |
| 4862 | 4853 |
| 4863 | 4854 |
| 4864 void SharedFunctionInfo::SetThisPropertyAssignmentsInfo( | 4855 void SharedFunctionInfo::SetThisPropertyAssignmentsInfo( |
| (...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6245 return InterceptorInfo::cast(result); | 6236 return InterceptorInfo::cast(result); |
| 6246 } | 6237 } |
| 6247 | 6238 |
| 6248 | 6239 |
| 6249 Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver, | 6240 Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver, |
| 6250 String* name, | 6241 String* name, |
| 6251 PropertyAttributes* attributes) { | 6242 PropertyAttributes* attributes) { |
| 6252 // Check local property in holder, ignore interceptor. | 6243 // Check local property in holder, ignore interceptor. |
| 6253 LookupResult result; | 6244 LookupResult result; |
| 6254 LocalLookupRealNamedProperty(name, &result); | 6245 LocalLookupRealNamedProperty(name, &result); |
| 6255 if (result.IsValid()) return GetProperty(receiver, &result, name, attributes); | 6246 if (result.IsProperty()) { |
| 6247 return GetProperty(receiver, &result, name, attributes); |
| 6248 } |
| 6256 // Continue searching via the prototype chain. | 6249 // Continue searching via the prototype chain. |
| 6257 Object* pt = GetPrototype(); | 6250 Object* pt = GetPrototype(); |
| 6258 *attributes = ABSENT; | 6251 *attributes = ABSENT; |
| 6259 if (pt == Heap::null_value()) return Heap::undefined_value(); | 6252 if (pt == Heap::null_value()) return Heap::undefined_value(); |
| 6260 return pt->GetPropertyWithReceiver(receiver, name, attributes); | 6253 return pt->GetPropertyWithReceiver(receiver, name, attributes); |
| 6261 } | 6254 } |
| 6262 | 6255 |
| 6263 | 6256 |
| 6264 Object* JSObject::GetLocalPropertyPostInterceptor( | 6257 Object* JSObject::GetLocalPropertyPostInterceptor( |
| 6265 JSObject* receiver, | 6258 JSObject* receiver, |
| 6266 String* name, | 6259 String* name, |
| 6267 PropertyAttributes* attributes) { | 6260 PropertyAttributes* attributes) { |
| 6268 // Check local property in holder, ignore interceptor. | 6261 // Check local property in holder, ignore interceptor. |
| 6269 LookupResult result; | 6262 LookupResult result; |
| 6270 LocalLookupRealNamedProperty(name, &result); | 6263 LocalLookupRealNamedProperty(name, &result); |
| 6271 if (!result.IsValid()) return Heap::undefined_value(); | 6264 if (result.IsProperty()) { |
| 6272 return GetProperty(receiver, &result, name, attributes); | 6265 return GetProperty(receiver, &result, name, attributes); |
| 6266 } |
| 6267 return Heap::undefined_value(); |
| 6273 } | 6268 } |
| 6274 | 6269 |
| 6275 | 6270 |
| 6276 Object* JSObject::GetPropertyWithInterceptor( | 6271 Object* JSObject::GetPropertyWithInterceptor( |
| 6277 JSObject* receiver, | 6272 JSObject* receiver, |
| 6278 String* name, | 6273 String* name, |
| 6279 PropertyAttributes* attributes) { | 6274 PropertyAttributes* attributes) { |
| 6280 InterceptorInfo* interceptor = GetNamedInterceptor(); | 6275 InterceptorInfo* interceptor = GetNamedInterceptor(); |
| 6281 HandleScope scope; | 6276 HandleScope scope; |
| 6282 Handle<JSObject> receiver_handle(receiver); | 6277 Handle<JSObject> receiver_handle(receiver); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6314 bool JSObject::HasRealNamedProperty(String* key) { | 6309 bool JSObject::HasRealNamedProperty(String* key) { |
| 6315 // Check access rights if needed. | 6310 // Check access rights if needed. |
| 6316 if (IsAccessCheckNeeded() && | 6311 if (IsAccessCheckNeeded() && |
| 6317 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 6312 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 6318 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 6313 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 6319 return false; | 6314 return false; |
| 6320 } | 6315 } |
| 6321 | 6316 |
| 6322 LookupResult result; | 6317 LookupResult result; |
| 6323 LocalLookupRealNamedProperty(key, &result); | 6318 LocalLookupRealNamedProperty(key, &result); |
| 6324 if (result.IsValid()) { | 6319 return result.IsProperty() && (result.type() != INTERCEPTOR); |
| 6325 switch (result.type()) { | |
| 6326 case NORMAL: // fall through. | |
| 6327 case FIELD: // fall through. | |
| 6328 case CALLBACKS: // fall through. | |
| 6329 case CONSTANT_FUNCTION: | |
| 6330 return true; | |
| 6331 case INTERCEPTOR: | |
| 6332 case MAP_TRANSITION: | |
| 6333 case CONSTANT_TRANSITION: | |
| 6334 case NULL_DESCRIPTOR: | |
| 6335 return false; | |
| 6336 default: | |
| 6337 UNREACHABLE(); | |
| 6338 } | |
| 6339 } | |
| 6340 | |
| 6341 return false; | |
| 6342 } | 6320 } |
| 6343 | 6321 |
| 6344 | 6322 |
| 6345 bool JSObject::HasRealElementProperty(uint32_t index) { | 6323 bool JSObject::HasRealElementProperty(uint32_t index) { |
| 6346 // Check access rights if needed. | 6324 // Check access rights if needed. |
| 6347 if (IsAccessCheckNeeded() && | 6325 if (IsAccessCheckNeeded() && |
| 6348 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 6326 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 6349 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 6327 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 6350 return false; | 6328 return false; |
| 6351 } | 6329 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6393 bool JSObject::HasRealNamedCallbackProperty(String* key) { | 6371 bool JSObject::HasRealNamedCallbackProperty(String* key) { |
| 6394 // Check access rights if needed. | 6372 // Check access rights if needed. |
| 6395 if (IsAccessCheckNeeded() && | 6373 if (IsAccessCheckNeeded() && |
| 6396 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 6374 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 6397 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 6375 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 6398 return false; | 6376 return false; |
| 6399 } | 6377 } |
| 6400 | 6378 |
| 6401 LookupResult result; | 6379 LookupResult result; |
| 6402 LocalLookupRealNamedProperty(key, &result); | 6380 LocalLookupRealNamedProperty(key, &result); |
| 6403 return result.IsValid() && (result.type() == CALLBACKS); | 6381 return result.IsProperty() && (result.type() == CALLBACKS); |
| 6404 } | 6382 } |
| 6405 | 6383 |
| 6406 | 6384 |
| 6407 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { | 6385 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { |
| 6408 if (HasFastProperties()) { | 6386 if (HasFastProperties()) { |
| 6409 DescriptorArray* descs = map()->instance_descriptors(); | 6387 DescriptorArray* descs = map()->instance_descriptors(); |
| 6410 int result = 0; | 6388 int result = 0; |
| 6411 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 6389 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 6412 PropertyDetails details = descs->GetDetails(i); | 6390 PropertyDetails details = descs->GetDetails(i); |
| 6413 if (details.IsProperty() && (details.attributes() & filter) == 0) { | 6391 if (details.IsProperty() && (details.attributes() & filter) == 0) { |
| (...skipping 1968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8382 if (break_point_objects()->IsUndefined()) return 0; | 8360 if (break_point_objects()->IsUndefined()) return 0; |
| 8383 // Single beak point. | 8361 // Single beak point. |
| 8384 if (!break_point_objects()->IsFixedArray()) return 1; | 8362 if (!break_point_objects()->IsFixedArray()) return 1; |
| 8385 // Multiple break points. | 8363 // Multiple break points. |
| 8386 return FixedArray::cast(break_point_objects())->length(); | 8364 return FixedArray::cast(break_point_objects())->length(); |
| 8387 } | 8365 } |
| 8388 #endif | 8366 #endif |
| 8389 | 8367 |
| 8390 | 8368 |
| 8391 } } // namespace v8::internal | 8369 } } // namespace v8::internal |
| OLD | NEW |