Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(664)

Side by Side Diff: src/objects.cc

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 }
265 default: {
266 break; 264 break;
267 } 265 }
266 default:
267 UNREACHABLE();
268 } 268 }
269 } 269 }
270 270
271 // No accessible property found. 271 // No accessible property found.
272 *attributes = ABSENT; 272 *attributes = ABSENT;
273 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); 273 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET);
274 return Heap::undefined_value(); 274 return Heap::undefined_value();
275 } 275 }
276 276
277 277
278 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( 278 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
279 Object* receiver, 279 Object* receiver,
280 LookupResult* result, 280 LookupResult* result,
281 String* name, 281 String* name,
282 bool continue_search) { 282 bool continue_search) {
283 if (result->IsValid()) { 283 if (result->IsProperty()) {
284 switch (result->type()) { 284 switch (result->type()) {
285 case CALLBACKS: { 285 case CALLBACKS: {
286 // Only allow API accessors. 286 // Only allow API accessors.
287 Object* obj = result->GetCallbackObject(); 287 Object* obj = result->GetCallbackObject();
288 if (obj->IsAccessorInfo()) { 288 if (obj->IsAccessorInfo()) {
289 AccessorInfo* info = AccessorInfo::cast(obj); 289 AccessorInfo* info = AccessorInfo::cast(obj);
290 if (info->all_can_read()) { 290 if (info->all_can_read()) {
291 return result->GetAttributes(); 291 return result->GetAttributes();
292 } 292 }
293 } 293 }
294 break; 294 break;
295 } 295 }
296 296
297 case NORMAL: 297 case NORMAL:
298 case FIELD: 298 case FIELD:
299 case CONSTANT_FUNCTION: { 299 case CONSTANT_FUNCTION: {
300 if (!continue_search) break; 300 if (!continue_search) break;
301 // Search ALL_CAN_READ accessors in prototype chain. 301 // Search ALL_CAN_READ accessors in prototype chain.
302 LookupResult r; 302 LookupResult r;
303 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); 303 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
304 if (r.IsValid()) { 304 if (r.IsProperty()) {
305 return GetPropertyAttributeWithFailedAccessCheck(receiver, 305 return GetPropertyAttributeWithFailedAccessCheck(receiver,
306 &r, 306 &r,
307 name, 307 name,
308 continue_search); 308 continue_search);
309 } 309 }
310 break; 310 break;
311 } 311 }
312 312
313 case INTERCEPTOR: { 313 case INTERCEPTOR: {
314 // If the object has an interceptor, try real named properties. 314 // If the object has an interceptor, try real named properties.
315 // No access check in GetPropertyAttributeWithInterceptor. 315 // No access check in GetPropertyAttributeWithInterceptor.
316 LookupResult r; 316 LookupResult r;
317 if (continue_search) { 317 if (continue_search) {
318 result->holder()->LookupRealNamedProperty(name, &r); 318 result->holder()->LookupRealNamedProperty(name, &r);
319 } else { 319 } else {
320 result->holder()->LocalLookupRealNamedProperty(name, &r); 320 result->holder()->LocalLookupRealNamedProperty(name, &r);
321 } 321 }
322 if (r.IsValid()) { 322 if (r.IsProperty()) {
323 return GetPropertyAttributeWithFailedAccessCheck(receiver, 323 return GetPropertyAttributeWithFailedAccessCheck(receiver,
324 &r, 324 &r,
325 name, 325 name,
326 continue_search); 326 continue_search);
327 } 327 }
328 break; 328 break;
329 } 329 }
330 330
331 default: { 331 default:
332 break; 332 UNREACHABLE();
333 }
334 } 333 }
335 } 334 }
336 335
337 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 336 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS);
338 return ABSENT; 337 return ABSENT;
339 } 338 }
340 339
341 340
342 Object* JSObject::GetNormalizedProperty(LookupResult* result) { 341 Object* JSObject::GetNormalizedProperty(LookupResult* result) {
343 ASSERT(!HasFastProperties()); 342 ASSERT(!HasFastProperties());
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 // Make sure that the top context does not change when doing 448 // Make sure that the top context does not change when doing
450 // callbacks or interceptor calls. 449 // callbacks or interceptor calls.
451 AssertNoContextChange ncc; 450 AssertNoContextChange ncc;
452 451
453 // Traverse the prototype chain from the current object (this) to 452 // Traverse the prototype chain from the current object (this) to
454 // the holder and check for access rights. This avoid traversing the 453 // the holder and check for access rights. This avoid traversing the
455 // objects more than once in case of interceptors, because the 454 // objects more than once in case of interceptors, because the
456 // holder will always be the interceptor holder and the search may 455 // holder will always be the interceptor holder and the search may
457 // only continue with a current object just after the interceptor 456 // only continue with a current object just after the interceptor
458 // holder in the prototype chain. 457 // holder in the prototype chain.
459 Object* last = result->IsValid() ? result->holder() : Heap::null_value(); 458 Object* last = result->IsProperty() ? result->holder() : Heap::null_value();
460 for (Object* current = this; true; current = current->GetPrototype()) { 459 for (Object* current = this; true; current = current->GetPrototype()) {
461 if (current->IsAccessCheckNeeded()) { 460 if (current->IsAccessCheckNeeded()) {
462 // Check if we're allowed to read from the current object. Note 461 // Check if we're allowed to read from the current object. Note
463 // that even though we may not actually end up loading the named 462 // that even though we may not actually end up loading the named
464 // property from the current object, we still check that we have 463 // property from the current object, we still check that we have
465 // access to it. 464 // access to it.
466 JSObject* checked = JSObject::cast(current); 465 JSObject* checked = JSObject::cast(current);
467 if (!Top::MayNamedAccess(checked, name, v8::ACCESS_GET)) { 466 if (!Top::MayNamedAccess(checked, name, v8::ACCESS_GET)) {
468 return checked->GetPropertyWithFailedAccessCheck(receiver, 467 return checked->GetPropertyWithFailedAccessCheck(receiver,
469 result, 468 result,
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 return AddSlowProperty(name, value, attributes); 1400 return AddSlowProperty(name, value, attributes);
1402 } 1401 }
1403 1402
1404 1403
1405 Object* JSObject::SetPropertyPostInterceptor(String* name, 1404 Object* JSObject::SetPropertyPostInterceptor(String* name,
1406 Object* value, 1405 Object* value,
1407 PropertyAttributes attributes) { 1406 PropertyAttributes attributes) {
1408 // Check local property, ignore interceptor. 1407 // Check local property, ignore interceptor.
1409 LookupResult result; 1408 LookupResult result;
1410 LocalLookupRealNamedProperty(name, &result); 1409 LocalLookupRealNamedProperty(name, &result);
1411 if (result.IsValid()) return SetProperty(&result, name, value, attributes); 1410 if (result.IsFound()) {
1412 // Add real property. 1411 // An existing property, a map transition or a null descriptor was
1412 // found. Use set property to handle all these cases.
1413 return SetProperty(&result, name, value, attributes);
1414 }
1415 // Add a new real property.
1413 return AddProperty(name, value, attributes); 1416 return AddProperty(name, value, attributes);
1414 } 1417 }
1415 1418
1416 1419
1417 Object* JSObject::ReplaceSlowProperty(String* name, 1420 Object* JSObject::ReplaceSlowProperty(String* name,
1418 Object* value, 1421 Object* value,
1419 PropertyAttributes attributes) { 1422 PropertyAttributes attributes) {
1420 StringDictionary* dictionary = property_dictionary(); 1423 StringDictionary* dictionary = property_dictionary();
1421 int old_index = dictionary->FindEntry(name); 1424 int old_index = dictionary->FindEntry(name);
1422 int new_enumeration_index = 0; // 0 means "Use the next available index." 1425 int new_enumeration_index = 0; // 0 means "Use the next available index."
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 return *value_handle; 1637 return *value_handle;
1635 } 1638 }
1636 1639
1637 1640
1638 void JSObject::LookupCallbackSetterInPrototypes(String* name, 1641 void JSObject::LookupCallbackSetterInPrototypes(String* name,
1639 LookupResult* result) { 1642 LookupResult* result) {
1640 for (Object* pt = GetPrototype(); 1643 for (Object* pt = GetPrototype();
1641 pt != Heap::null_value(); 1644 pt != Heap::null_value();
1642 pt = pt->GetPrototype()) { 1645 pt = pt->GetPrototype()) {
1643 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); 1646 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
1644 if (result->IsValid()) { 1647 if (result->IsProperty()) {
1645 if (!result->IsTransitionType() && result->IsReadOnly()) { 1648 if (result->IsReadOnly()) {
1646 result->NotFound(); 1649 result->NotFound();
1647 return; 1650 return;
1648 } 1651 }
1649 if (result->type() == CALLBACKS) { 1652 if (result->type() == CALLBACKS) {
1650 return; 1653 return;
1651 } 1654 }
1652 } 1655 }
1653 } 1656 }
1654 result->NotFound(); 1657 result->NotFound();
1655 } 1658 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 LookupResult* result) { 1699 LookupResult* result) {
1697 if (IsJSGlobalProxy()) { 1700 if (IsJSGlobalProxy()) {
1698 Object* proto = GetPrototype(); 1701 Object* proto = GetPrototype();
1699 if (proto->IsNull()) return result->NotFound(); 1702 if (proto->IsNull()) return result->NotFound();
1700 ASSERT(proto->IsJSGlobalObject()); 1703 ASSERT(proto->IsJSGlobalObject());
1701 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); 1704 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result);
1702 } 1705 }
1703 1706
1704 if (HasFastProperties()) { 1707 if (HasFastProperties()) {
1705 LookupInDescriptor(name, result); 1708 LookupInDescriptor(name, result);
1706 if (result->IsValid()) { 1709 if (result->IsFound()) {
1710 // A property, a map transition or a null descriptor was found.
1711 // We return all of these result types because
1712 // LocalLookupRealNamedProperty is used when setting properties
1713 // where map transitions and null descriptors are handled.
1707 ASSERT(result->holder() == this && result->type() != NORMAL); 1714 ASSERT(result->holder() == this && result->type() != NORMAL);
1708 // Disallow caching for uninitialized constants. These can only 1715 // Disallow caching for uninitialized constants. These can only
1709 // occur as fields. 1716 // occur as fields.
1710 if (result->IsReadOnly() && result->type() == FIELD && 1717 if (result->IsReadOnly() && result->type() == FIELD &&
1711 FastPropertyAt(result->GetFieldIndex())->IsTheHole()) { 1718 FastPropertyAt(result->GetFieldIndex())->IsTheHole()) {
1712 result->DisallowCaching(); 1719 result->DisallowCaching();
1713 } 1720 }
1714 return; 1721 return;
1715 } 1722 }
1716 } else { 1723 } else {
(...skipping 28 matching lines...) Expand all
1745 LookupRealNamedPropertyInPrototypes(name, result); 1752 LookupRealNamedPropertyInPrototypes(name, result);
1746 } 1753 }
1747 1754
1748 1755
1749 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, 1756 void JSObject::LookupRealNamedPropertyInPrototypes(String* name,
1750 LookupResult* result) { 1757 LookupResult* result) {
1751 for (Object* pt = GetPrototype(); 1758 for (Object* pt = GetPrototype();
1752 pt != Heap::null_value(); 1759 pt != Heap::null_value();
1753 pt = JSObject::cast(pt)->GetPrototype()) { 1760 pt = JSObject::cast(pt)->GetPrototype()) {
1754 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); 1761 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
1755 if (result->IsValid()) { 1762 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return;
1756 switch (result->type()) {
1757 case NORMAL:
1758 case FIELD:
1759 case CONSTANT_FUNCTION:
1760 case CALLBACKS:
1761 return;
1762 default: break;
1763 }
1764 }
1765 } 1763 }
1766 result->NotFound(); 1764 result->NotFound();
1767 } 1765 }
1768 1766
1769 1767
1770 // We only need to deal with CALLBACKS and INTERCEPTORS 1768 // We only need to deal with CALLBACKS and INTERCEPTORS
1771 Object* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, 1769 Object* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result,
1772 String* name, 1770 String* name,
1773 Object* value) { 1771 Object* value) {
1774 if (!result->IsProperty()) { 1772 if (!result->IsProperty()) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 if (proto->IsNull()) return value; 1838 if (proto->IsNull()) return value;
1841 ASSERT(proto->IsJSGlobalObject()); 1839 ASSERT(proto->IsJSGlobalObject());
1842 return JSObject::cast(proto)->SetProperty(result, name, value, attributes); 1840 return JSObject::cast(proto)->SetProperty(result, name, value, attributes);
1843 } 1841 }
1844 1842
1845 if (!result->IsProperty() && !IsJSContextExtensionObject()) { 1843 if (!result->IsProperty() && !IsJSContextExtensionObject()) {
1846 // We could not find a local property so let's check whether there is an 1844 // We could not find a local property so let's check whether there is an
1847 // accessor that wants to handle the property. 1845 // accessor that wants to handle the property.
1848 LookupResult accessor_result; 1846 LookupResult accessor_result;
1849 LookupCallbackSetterInPrototypes(name, &accessor_result); 1847 LookupCallbackSetterInPrototypes(name, &accessor_result);
1850 if (accessor_result.IsValid()) { 1848 if (accessor_result.IsProperty()) {
1851 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), 1849 return SetPropertyWithCallback(accessor_result.GetCallbackObject(),
1852 name, 1850 name,
1853 value, 1851 value,
1854 accessor_result.holder()); 1852 accessor_result.holder());
1855 } 1853 }
1856 } 1854 }
1857 if (result->IsNotFound()) { 1855 if (!result->IsFound()) {
1856 // Neither properties nor transitions found.
1858 return AddProperty(name, value, attributes); 1857 return AddProperty(name, value, attributes);
1859 } 1858 }
1860 if (result->IsReadOnly() && result->IsProperty()) return value; 1859 if (result->IsReadOnly() && result->IsProperty()) return value;
1861 // This is a real property that is not read-only, or it is a 1860 // This is a real property that is not read-only, or it is a
1862 // transition or null descriptor and there are no setters in the prototypes. 1861 // transition or null descriptor and there are no setters in the prototypes.
1863 switch (result->type()) { 1862 switch (result->type()) {
1864 case NORMAL: 1863 case NORMAL:
1865 return SetNormalizedProperty(result, value); 1864 return SetNormalizedProperty(result, value);
1866 case FIELD: 1865 case FIELD:
1867 return FastPropertyAtPut(result->GetFieldIndex(), value); 1866 return FastPropertyAtPut(result->GetFieldIndex(), value);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1906 // callback setter removed. The two lines looking up the LookupResult 1905 // callback setter removed. The two lines looking up the LookupResult
1907 // result are also added. If one of the functions is changed, the other 1906 // result are also added. If one of the functions is changed, the other
1908 // should be. 1907 // should be.
1909 Object* JSObject::IgnoreAttributesAndSetLocalProperty( 1908 Object* JSObject::IgnoreAttributesAndSetLocalProperty(
1910 String* name, 1909 String* name,
1911 Object* value, 1910 Object* value,
1912 PropertyAttributes attributes) { 1911 PropertyAttributes attributes) {
1913 // Make sure that the top context does not change when doing callbacks or 1912 // Make sure that the top context does not change when doing callbacks or
1914 // interceptor calls. 1913 // interceptor calls.
1915 AssertNoContextChange ncc; 1914 AssertNoContextChange ncc;
1916 // ADDED TO CLONE 1915 LookupResult result;
1917 LookupResult result_struct; 1916 LocalLookup(name, &result);
1918 LocalLookup(name, &result_struct);
1919 LookupResult* result = &result_struct;
1920 // END ADDED TO CLONE
1921 // Check access rights if needed. 1917 // Check access rights if needed.
1922 if (IsAccessCheckNeeded() 1918 if (IsAccessCheckNeeded()
1923 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { 1919 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
1924 return SetPropertyWithFailedAccessCheck(result, name, value); 1920 return SetPropertyWithFailedAccessCheck(&result, name, value);
1925 } 1921 }
1926 1922
1927 if (IsJSGlobalProxy()) { 1923 if (IsJSGlobalProxy()) {
1928 Object* proto = GetPrototype(); 1924 Object* proto = GetPrototype();
1929 if (proto->IsNull()) return value; 1925 if (proto->IsNull()) return value;
1930 ASSERT(proto->IsJSGlobalObject()); 1926 ASSERT(proto->IsJSGlobalObject());
1931 return JSObject::cast(proto)->IgnoreAttributesAndSetLocalProperty( 1927 return JSObject::cast(proto)->IgnoreAttributesAndSetLocalProperty(
1932 name, 1928 name,
1933 value, 1929 value,
1934 attributes); 1930 attributes);
1935 } 1931 }
1936 1932
1937 // Check for accessor in prototype chain removed here in clone. 1933 // Check for accessor in prototype chain removed here in clone.
1938 if (result->IsNotFound()) { 1934 if (!result.IsFound()) {
1935 // Neither properties nor transitions found.
1939 return AddProperty(name, value, attributes); 1936 return AddProperty(name, value, attributes);
1940 } 1937 }
1938 PropertyDetails details = PropertyDetails(attributes, NORMAL);
1939
1941 // Check of IsReadOnly removed from here in clone. 1940 // Check of IsReadOnly removed from here in clone.
1942 switch (result->type()) { 1941 switch (result.type()) {
1943 case NORMAL: 1942 case NORMAL:
1944 return SetNormalizedProperty(result, value); 1943 return SetNormalizedProperty(name, value, details);
1945 case FIELD: 1944 case FIELD:
1946 return FastPropertyAtPut(result->GetFieldIndex(), value); 1945 return FastPropertyAtPut(result.GetFieldIndex(), value);
1947 case MAP_TRANSITION: 1946 case MAP_TRANSITION:
1948 if (attributes == result->GetAttributes()) { 1947 if (attributes == result.GetAttributes()) {
1949 // Only use map transition if the attributes match. 1948 // Only use map transition if the attributes match.
1950 return AddFastPropertyUsingMap(result->GetTransitionMap(), 1949 return AddFastPropertyUsingMap(result.GetTransitionMap(),
1951 name, 1950 name,
1952 value); 1951 value);
1953 } 1952 }
1954 return ConvertDescriptorToField(name, value, attributes); 1953 return ConvertDescriptorToField(name, value, attributes);
1955 case CONSTANT_FUNCTION: 1954 case CONSTANT_FUNCTION:
1956 // Only replace the function if necessary. 1955 // Only replace the function if necessary.
1957 if (value == result->GetConstantFunction()) return value; 1956 if (value == result.GetConstantFunction()) return value;
1958 // Preserve the attributes of this existing property. 1957 // Preserve the attributes of this existing property.
1959 attributes = result->GetAttributes(); 1958 attributes = result.GetAttributes();
1960 return ConvertDescriptorToField(name, value, attributes); 1959 return ConvertDescriptorToField(name, value, attributes);
1961 case CALLBACKS: 1960 case CALLBACKS:
1962 case INTERCEPTOR: 1961 case INTERCEPTOR:
1963 // Override callback in clone 1962 // Override callback in clone
1964 return ConvertDescriptorToField(name, value, attributes); 1963 return ConvertDescriptorToField(name, value, attributes);
1965 case CONSTANT_TRANSITION: 1964 case CONSTANT_TRANSITION:
1966 // Replace with a MAP_TRANSITION to a new map with a FIELD, even 1965 // Replace with a MAP_TRANSITION to a new map with a FIELD, even
1967 // if the value is a function. 1966 // if the value is a function.
1968 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); 1967 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
1969 case NULL_DESCRIPTOR: 1968 case NULL_DESCRIPTOR:
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
2065 String* name, 2064 String* name,
2066 bool continue_search) { 2065 bool continue_search) {
2067 // Check access rights if needed. 2066 // Check access rights if needed.
2068 if (IsAccessCheckNeeded() && 2067 if (IsAccessCheckNeeded() &&
2069 !Top::MayNamedAccess(this, name, v8::ACCESS_HAS)) { 2068 !Top::MayNamedAccess(this, name, v8::ACCESS_HAS)) {
2070 return GetPropertyAttributeWithFailedAccessCheck(receiver, 2069 return GetPropertyAttributeWithFailedAccessCheck(receiver,
2071 result, 2070 result,
2072 name, 2071 name,
2073 continue_search); 2072 continue_search);
2074 } 2073 }
2075 if (result->IsValid()) { 2074 if (result->IsProperty()) {
2076 switch (result->type()) { 2075 switch (result->type()) {
2077 case NORMAL: // fall through 2076 case NORMAL: // fall through
2078 case FIELD: 2077 case FIELD:
2079 case CONSTANT_FUNCTION: 2078 case CONSTANT_FUNCTION:
2080 case CALLBACKS: 2079 case CALLBACKS:
2081 return result->GetAttributes(); 2080 return result->GetAttributes();
2082 case INTERCEPTOR: 2081 case INTERCEPTOR:
2083 return result->holder()-> 2082 return result->holder()->
2084 GetPropertyAttributeWithInterceptor(receiver, name, continue_search); 2083 GetPropertyAttributeWithInterceptor(receiver, name, continue_search);
2085 case MAP_TRANSITION:
2086 case CONSTANT_TRANSITION:
2087 case NULL_DESCRIPTOR:
2088 return ABSENT;
2089 default: 2084 default:
2090 UNREACHABLE(); 2085 UNREACHABLE();
2091 break;
2092 } 2086 }
2093 } 2087 }
2094 return ABSENT; 2088 return ABSENT;
2095 } 2089 }
2096 2090
2097 2091
2098 PropertyAttributes JSObject::GetLocalPropertyAttribute(String* name) { 2092 PropertyAttributes JSObject::GetLocalPropertyAttribute(String* name) {
2099 // Check whether the name is an array index. 2093 // Check whether the name is an array index.
2100 uint32_t index = 0; 2094 uint32_t index = 0;
2101 if (name->AsArrayIndex(&index)) { 2095 if (name->AsArrayIndex(&index)) {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
2254 #endif 2248 #endif
2255 2249
2256 return this; 2250 return this;
2257 } 2251 }
2258 2252
2259 2253
2260 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) { 2254 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) {
2261 // Check local property, ignore interceptor. 2255 // Check local property, ignore interceptor.
2262 LookupResult result; 2256 LookupResult result;
2263 LocalLookupRealNamedProperty(name, &result); 2257 LocalLookupRealNamedProperty(name, &result);
2264 if (!result.IsValid()) return Heap::true_value(); 2258 if (!result.IsProperty()) return Heap::true_value();
2265 2259
2266 // Normalize object if needed. 2260 // Normalize object if needed.
2267 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2261 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2268 if (obj->IsFailure()) return obj; 2262 if (obj->IsFailure()) return obj;
2269 2263
2270 return DeleteNormalizedProperty(name, mode); 2264 return DeleteNormalizedProperty(name, mode);
2271 } 2265 }
2272 2266
2273 2267
2274 Object* JSObject::DeletePropertyWithInterceptor(String* name) { 2268 Object* JSObject::DeletePropertyWithInterceptor(String* name) {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2438 ASSERT(proto->IsJSGlobalObject()); 2432 ASSERT(proto->IsJSGlobalObject());
2439 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); 2433 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode);
2440 } 2434 }
2441 2435
2442 uint32_t index = 0; 2436 uint32_t index = 0;
2443 if (name->AsArrayIndex(&index)) { 2437 if (name->AsArrayIndex(&index)) {
2444 return DeleteElement(index, mode); 2438 return DeleteElement(index, mode);
2445 } else { 2439 } else {
2446 LookupResult result; 2440 LookupResult result;
2447 LocalLookup(name, &result); 2441 LocalLookup(name, &result);
2448 if (!result.IsValid()) return Heap::true_value(); 2442 if (!result.IsProperty()) return Heap::true_value();
2449 // Ignore attributes if forcing a deletion. 2443 // Ignore attributes if forcing a deletion.
2450 if (result.IsDontDelete() && mode != FORCE_DELETION) { 2444 if (result.IsDontDelete() && mode != FORCE_DELETION) {
2451 return Heap::false_value(); 2445 return Heap::false_value();
2452 } 2446 }
2453 // Check for interceptor. 2447 // Check for interceptor.
2454 if (result.type() == INTERCEPTOR) { 2448 if (result.type() == INTERCEPTOR) {
2455 // Skip interceptor if forcing a deletion. 2449 // Skip interceptor if forcing a deletion.
2456 if (mode == FORCE_DELETION) { 2450 if (mode == FORCE_DELETION) {
2457 return DeletePropertyPostInterceptor(name, mode); 2451 return DeletePropertyPostInterceptor(name, mode);
2458 } 2452 }
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
2668 LocalLookupRealNamedProperty(name, result); 2662 LocalLookupRealNamedProperty(name, result);
2669 } 2663 }
2670 2664
2671 2665
2672 void JSObject::Lookup(String* name, LookupResult* result) { 2666 void JSObject::Lookup(String* name, LookupResult* result) {
2673 // Ecma-262 3rd 8.6.2.4 2667 // Ecma-262 3rd 8.6.2.4
2674 for (Object* current = this; 2668 for (Object* current = this;
2675 current != Heap::null_value(); 2669 current != Heap::null_value();
2676 current = JSObject::cast(current)->GetPrototype()) { 2670 current = JSObject::cast(current)->GetPrototype()) {
2677 JSObject::cast(current)->LocalLookup(name, result); 2671 JSObject::cast(current)->LocalLookup(name, result);
2678 if (result->IsValid() && !result->IsTransitionType()) return; 2672 if (result->IsProperty()) return;
2679 } 2673 }
2680 result->NotFound(); 2674 result->NotFound();
2681 } 2675 }
2682 2676
2683 2677
2684 // Search object and it's prototype chain for callback properties. 2678 // Search object and it's prototype chain for callback properties.
2685 void JSObject::LookupCallback(String* name, LookupResult* result) { 2679 void JSObject::LookupCallback(String* name, LookupResult* result) {
2686 for (Object* current = this; 2680 for (Object* current = this;
2687 current != Heap::null_value(); 2681 current != Heap::null_value();
2688 current = JSObject::cast(current)->GetPrototype()) { 2682 current = JSObject::cast(current)->GetPrototype()) {
2689 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); 2683 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
2690 if (result->IsValid() && result->type() == CALLBACKS) return; 2684 if (result->IsProperty() && result->type() == CALLBACKS) return;
2691 } 2685 }
2692 result->NotFound(); 2686 result->NotFound();
2693 } 2687 }
2694 2688
2695 2689
2696 Object* JSObject::DefineGetterSetter(String* name, 2690 Object* JSObject::DefineGetterSetter(String* name,
2697 PropertyAttributes attributes) { 2691 PropertyAttributes attributes) {
2698 // Make sure that the top context does not change when doing callbacks or 2692 // Make sure that the top context does not change when doing callbacks or
2699 // interceptor calls. 2693 // interceptor calls.
2700 AssertNoContextChange ncc; 2694 AssertNoContextChange ncc;
2701 2695
2702 // Check access rights if needed. 2696 // Check access rights if needed.
2703 if (IsAccessCheckNeeded() && 2697 if (IsAccessCheckNeeded() &&
2704 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { 2698 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
2705 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); 2699 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET);
2706 return Heap::undefined_value(); 2700 return Heap::undefined_value();
2707 } 2701 }
2708 2702
2709 // Try to flatten before operating on the string. 2703 // Try to flatten before operating on the string.
2710 name->TryFlattenIfNotFlat(); 2704 name->TryFlattenIfNotFlat();
2711 2705
2712 // Check if there is an API defined callback object which prohibits 2706 // Check if there is an API defined callback object which prohibits
2713 // callback overwriting in this object or it's prototype chain. 2707 // callback overwriting in this object or it's prototype chain.
2714 // This mechanism is needed for instance in a browser setting, where 2708 // This mechanism is needed for instance in a browser setting, where
2715 // certain accessors such as window.location should not be allowed 2709 // certain accessors such as window.location should not be allowed
2716 // to be overwritten because allowing overwriting could potentially 2710 // to be overwritten because allowing overwriting could potentially
2717 // cause security problems. 2711 // cause security problems.
2718 LookupResult callback_result; 2712 LookupResult callback_result;
2719 LookupCallback(name, &callback_result); 2713 LookupCallback(name, &callback_result);
2720 if (callback_result.IsValid()) { 2714 if (callback_result.IsFound()) {
2721 Object* obj = callback_result.GetCallbackObject(); 2715 Object* obj = callback_result.GetCallbackObject();
2722 if (obj->IsAccessorInfo() && 2716 if (obj->IsAccessorInfo() &&
2723 AccessorInfo::cast(obj)->prohibits_overwriting()) { 2717 AccessorInfo::cast(obj)->prohibits_overwriting()) {
2724 return Heap::undefined_value(); 2718 return Heap::undefined_value();
2725 } 2719 }
2726 } 2720 }
2727 2721
2728 uint32_t index; 2722 uint32_t index;
2729 bool is_element = name->AsArrayIndex(&index); 2723 bool is_element = name->AsArrayIndex(&index);
2730 if (is_element && IsJSArray()) return Heap::undefined_value(); 2724 if (is_element && IsJSArray()) return Heap::undefined_value();
(...skipping 30 matching lines...) Expand all
2761 break; 2755 break;
2762 } 2756 }
2763 default: 2757 default:
2764 UNREACHABLE(); 2758 UNREACHABLE();
2765 break; 2759 break;
2766 } 2760 }
2767 } else { 2761 } else {
2768 // Lookup the name. 2762 // Lookup the name.
2769 LookupResult result; 2763 LookupResult result;
2770 LocalLookup(name, &result); 2764 LocalLookup(name, &result);
2771 if (result.IsValid()) { 2765 if (result.IsProperty()) {
2772 if (result.IsReadOnly()) return Heap::undefined_value(); 2766 if (result.IsReadOnly()) return Heap::undefined_value();
2773 if (result.type() == CALLBACKS) { 2767 if (result.type() == CALLBACKS) {
2774 Object* obj = result.GetCallbackObject(); 2768 Object* obj = result.GetCallbackObject();
2775 if (obj->IsFixedArray()) { 2769 if (obj->IsFixedArray()) {
2770 // The object might be in fast mode even though it has
2771 // a getter/setter.
2772 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2773 if (ok->IsFailure()) return ok;
2774
2776 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); 2775 PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
2777 SetNormalizedProperty(name, obj, details); 2776 SetNormalizedProperty(name, obj, details);
2778 return obj; 2777 return obj;
2779 } 2778 }
2780 } 2779 }
2781 } 2780 }
2782 } 2781 }
2783 2782
2784 // Allocate the fixed array to hold getter and setter. 2783 // Allocate the fixed array to hold getter and setter.
2785 Object* structure = Heap::AllocateFixedArray(2, TENURED); 2784 Object* structure = Heap::AllocateFixedArray(2, TENURED);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2878 } 2877 }
2879 } 2878 }
2880 } 2879 }
2881 } 2880 }
2882 } else { 2881 } else {
2883 for (Object* obj = this; 2882 for (Object* obj = this;
2884 obj != Heap::null_value(); 2883 obj != Heap::null_value();
2885 obj = JSObject::cast(obj)->GetPrototype()) { 2884 obj = JSObject::cast(obj)->GetPrototype()) {
2886 LookupResult result; 2885 LookupResult result;
2887 JSObject::cast(obj)->LocalLookup(name, &result); 2886 JSObject::cast(obj)->LocalLookup(name, &result);
2888 if (result.IsValid()) { 2887 if (result.IsProperty()) {
2889 if (result.IsReadOnly()) return Heap::undefined_value(); 2888 if (result.IsReadOnly()) return Heap::undefined_value();
2890 if (result.type() == CALLBACKS) { 2889 if (result.type() == CALLBACKS) {
2891 Object* obj = result.GetCallbackObject(); 2890 Object* obj = result.GetCallbackObject();
2892 if (obj->IsFixedArray()) { 2891 if (obj->IsFixedArray()) {
2893 return FixedArray::cast(obj)->get(accessor_index); 2892 return FixedArray::cast(obj)->get(accessor_index);
2894 } 2893 }
2895 } 2894 }
2896 } 2895 }
2897 } 2896 }
2898 } 2897 }
(...skipping 1847 matching lines...) Expand 10 before | Expand all | Expand 10 after
4746 } 4745 }
4747 return instance_size; 4746 return instance_size;
4748 } 4747 }
4749 4748
4750 4749
4751 int SharedFunctionInfo::CalculateInObjectProperties() { 4750 int SharedFunctionInfo::CalculateInObjectProperties() {
4752 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; 4751 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize;
4753 } 4752 }
4754 4753
4755 4754
4755 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) {
4756 // Check the basic conditions for generating inline constructor code.
4757 if (!FLAG_inline_new
4758 || !has_only_simple_this_property_assignments()
4759 || this_property_assignments_count() == 0) {
4760 return false;
4761 }
4762
4763 // If the prototype is null inline constructors cause no problems.
4764 if (!prototype->IsJSObject()) {
4765 ASSERT(prototype->IsNull());
4766 return true;
4767 }
4768
4769 // Traverse the proposed prototype chain looking for setters for properties of
4770 // the same names as are set by the inline constructor.
4771 for (Object* obj = prototype;
4772 obj != Heap::null_value();
4773 obj = obj->GetPrototype()) {
4774 JSObject* js_object = JSObject::cast(obj);
4775 for (int i = 0; i < this_property_assignments_count(); i++) {
4776 LookupResult result;
4777 String* name = GetThisPropertyAssignmentName(i);
4778 js_object->LocalLookupRealNamedProperty(name, &result);
4779 if (result.IsProperty() && result.type() == CALLBACKS) {
4780 return false;
4781 }
4782 }
4783 }
4784
4785 return true;
4786 }
4787
4788
4756 void SharedFunctionInfo::SetThisPropertyAssignmentsInfo( 4789 void SharedFunctionInfo::SetThisPropertyAssignmentsInfo(
4757 bool only_simple_this_property_assignments, 4790 bool only_simple_this_property_assignments,
4758 FixedArray* assignments) { 4791 FixedArray* assignments) {
4759 set_compiler_hints(BooleanBit::set(compiler_hints(), 4792 set_compiler_hints(BooleanBit::set(compiler_hints(),
4760 kHasOnlySimpleThisPropertyAssignments, 4793 kHasOnlySimpleThisPropertyAssignments,
4761 only_simple_this_property_assignments)); 4794 only_simple_this_property_assignments));
4762 set_this_property_assignments(assignments); 4795 set_this_property_assignments(assignments);
4763 set_this_property_assignments_count(assignments->length() / 3); 4796 set_this_property_assignments_count(assignments->length() / 3);
4764 } 4797 }
4765 4798
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4801 4834
4802 4835
4803 Object* SharedFunctionInfo::GetThisPropertyAssignmentConstant(int index) { 4836 Object* SharedFunctionInfo::GetThisPropertyAssignmentConstant(int index) {
4804 ASSERT(!IsThisPropertyAssignmentArgument(index)); 4837 ASSERT(!IsThisPropertyAssignmentArgument(index));
4805 Object* obj = 4838 Object* obj =
4806 FixedArray::cast(this_property_assignments())->get(index * 3 + 2); 4839 FixedArray::cast(this_property_assignments())->get(index * 3 + 2);
4807 return obj; 4840 return obj;
4808 } 4841 }
4809 4842
4810 4843
4811
4812 // Support function for printing the source code to a StringStream 4844 // Support function for printing the source code to a StringStream
4813 // without any allocation in the heap. 4845 // without any allocation in the heap.
4814 void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator, 4846 void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator,
4815 int max_length) { 4847 int max_length) {
4816 // For some native functions there is no source. 4848 // For some native functions there is no source.
4817 if (script()->IsUndefined() || 4849 if (script()->IsUndefined() ||
4818 Script::cast(script())->source()->IsUndefined()) { 4850 Script::cast(script())->source()->IsUndefined()) {
4819 accumulator->Add("<No Source>"); 4851 accumulator->Add("<No Source>");
4820 return; 4852 return;
4821 } 4853 }
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
5199 5231
5200 static Object* ArrayLengthRangeError() { 5232 static Object* ArrayLengthRangeError() {
5201 HandleScope scope; 5233 HandleScope scope;
5202 return Top::Throw(*Factory::NewRangeError("invalid_array_length", 5234 return Top::Throw(*Factory::NewRangeError("invalid_array_length",
5203 HandleVector<Object>(NULL, 0))); 5235 HandleVector<Object>(NULL, 0)));
5204 } 5236 }
5205 5237
5206 5238
5207 Object* JSObject::SetElementsLength(Object* len) { 5239 Object* JSObject::SetElementsLength(Object* len) {
5208 // We should never end in here with a pixel or external array. 5240 // We should never end in here with a pixel or external array.
5209 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); 5241 ASSERT(AllowsSetElementsLength());
5210 5242
5211 Object* smi_length = len->ToSmi(); 5243 Object* smi_length = len->ToSmi();
5212 if (smi_length->IsSmi()) { 5244 if (smi_length->IsSmi()) {
5213 int value = Smi::cast(smi_length)->value(); 5245 int value = Smi::cast(smi_length)->value();
5214 if (value < 0) return ArrayLengthRangeError(); 5246 if (value < 0) return ArrayLengthRangeError();
5215 switch (GetElementsKind()) { 5247 switch (GetElementsKind()) {
5216 case FAST_ELEMENTS: { 5248 case FAST_ELEMENTS: {
5217 int old_capacity = FixedArray::cast(elements())->length(); 5249 int old_capacity = FixedArray::cast(elements())->length();
5218 if (value <= old_capacity) { 5250 if (value <= old_capacity) {
5219 if (IsJSArray()) { 5251 if (IsJSArray()) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
5279 // set only element to len. 5311 // set only element to len.
5280 Object* obj = Heap::AllocateFixedArray(1); 5312 Object* obj = Heap::AllocateFixedArray(1);
5281 if (obj->IsFailure()) return obj; 5313 if (obj->IsFailure()) return obj;
5282 FixedArray::cast(obj)->set(0, len); 5314 FixedArray::cast(obj)->set(0, len);
5283 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); 5315 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1));
5284 set_elements(FixedArray::cast(obj)); 5316 set_elements(FixedArray::cast(obj));
5285 return this; 5317 return this;
5286 } 5318 }
5287 5319
5288 5320
5321 Object* JSObject::SetPrototype(Object* value,
5322 bool skip_hidden_prototypes) {
5323 // Silently ignore the change if value is not a JSObject or null.
5324 // SpiderMonkey behaves this way.
5325 if (!value->IsJSObject() && !value->IsNull()) return value;
5326
5327 // Before we can set the prototype we need to be sure
5328 // prototype cycles are prevented.
5329 // It is sufficient to validate that the receiver is not in the new prototype
5330 // chain.
5331 for (Object* pt = value; pt != Heap::null_value(); pt = pt->GetPrototype()) {
5332 if (JSObject::cast(pt) == this) {
5333 // Cycle detected.
5334 HandleScope scope;
5335 return Top::Throw(*Factory::NewError("cyclic_proto",
5336 HandleVector<Object>(NULL, 0)));
5337 }
5338 }
5339
5340 JSObject* real_receiver = this;
5341
5342 if (skip_hidden_prototypes) {
5343 // Find the first object in the chain whose prototype object is not
5344 // hidden and set the new prototype on that object.
5345 Object* current_proto = real_receiver->GetPrototype();
5346 while (current_proto->IsJSObject() &&
5347 JSObject::cast(current_proto)->map()->is_hidden_prototype()) {
5348 real_receiver = JSObject::cast(current_proto);
5349 current_proto = current_proto->GetPrototype();
5350 }
5351 }
5352
5353 // Set the new prototype of the object.
5354 Object* new_map = real_receiver->map()->CopyDropTransitions();
5355 if (new_map->IsFailure()) return new_map;
5356 Map::cast(new_map)->set_prototype(value);
5357 real_receiver->set_map(Map::cast(new_map));
5358
5359 return value;
5360 }
5361
5362
5289 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { 5363 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
5290 switch (GetElementsKind()) { 5364 switch (GetElementsKind()) {
5291 case FAST_ELEMENTS: { 5365 case FAST_ELEMENTS: {
5292 uint32_t length = IsJSArray() ? 5366 uint32_t length = IsJSArray() ?
5293 static_cast<uint32_t> 5367 static_cast<uint32_t>
5294 (Smi::cast(JSArray::cast(this)->length())->value()) : 5368 (Smi::cast(JSArray::cast(this)->length())->value()) :
5295 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 5369 static_cast<uint32_t>(FixedArray::cast(elements())->length());
5296 if ((index < length) && 5370 if ((index < length) &&
5297 !FixedArray::cast(elements())->get(index)->IsTheHole()) { 5371 !FixedArray::cast(elements())->get(index)->IsTheHole()) {
5298 return true; 5372 return true;
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
6096 return InterceptorInfo::cast(result); 6170 return InterceptorInfo::cast(result);
6097 } 6171 }
6098 6172
6099 6173
6100 Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver, 6174 Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver,
6101 String* name, 6175 String* name,
6102 PropertyAttributes* attributes) { 6176 PropertyAttributes* attributes) {
6103 // Check local property in holder, ignore interceptor. 6177 // Check local property in holder, ignore interceptor.
6104 LookupResult result; 6178 LookupResult result;
6105 LocalLookupRealNamedProperty(name, &result); 6179 LocalLookupRealNamedProperty(name, &result);
6106 if (result.IsValid()) return GetProperty(receiver, &result, name, attributes); 6180 if (result.IsProperty()) {
6181 return GetProperty(receiver, &result, name, attributes);
6182 }
6107 // Continue searching via the prototype chain. 6183 // Continue searching via the prototype chain.
6108 Object* pt = GetPrototype(); 6184 Object* pt = GetPrototype();
6109 *attributes = ABSENT; 6185 *attributes = ABSENT;
6110 if (pt == Heap::null_value()) return Heap::undefined_value(); 6186 if (pt == Heap::null_value()) return Heap::undefined_value();
6111 return pt->GetPropertyWithReceiver(receiver, name, attributes); 6187 return pt->GetPropertyWithReceiver(receiver, name, attributes);
6112 } 6188 }
6113 6189
6114 6190
6115 Object* JSObject::GetLocalPropertyPostInterceptor( 6191 Object* JSObject::GetLocalPropertyPostInterceptor(
6116 JSObject* receiver, 6192 JSObject* receiver,
6117 String* name, 6193 String* name,
6118 PropertyAttributes* attributes) { 6194 PropertyAttributes* attributes) {
6119 // Check local property in holder, ignore interceptor. 6195 // Check local property in holder, ignore interceptor.
6120 LookupResult result; 6196 LookupResult result;
6121 LocalLookupRealNamedProperty(name, &result); 6197 LocalLookupRealNamedProperty(name, &result);
6122 if (!result.IsValid()) return Heap::undefined_value(); 6198 if (result.IsProperty()) {
6123 return GetProperty(receiver, &result, name, attributes); 6199 return GetProperty(receiver, &result, name, attributes);
6200 }
6201 return Heap::undefined_value();
6124 } 6202 }
6125 6203
6126 6204
6127 Object* JSObject::GetPropertyWithInterceptor( 6205 Object* JSObject::GetPropertyWithInterceptor(
6128 JSObject* receiver, 6206 JSObject* receiver,
6129 String* name, 6207 String* name,
6130 PropertyAttributes* attributes) { 6208 PropertyAttributes* attributes) {
6131 InterceptorInfo* interceptor = GetNamedInterceptor(); 6209 InterceptorInfo* interceptor = GetNamedInterceptor();
6132 HandleScope scope; 6210 HandleScope scope;
6133 Handle<JSObject> receiver_handle(receiver); 6211 Handle<JSObject> receiver_handle(receiver);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
6165 bool JSObject::HasRealNamedProperty(String* key) { 6243 bool JSObject::HasRealNamedProperty(String* key) {
6166 // Check access rights if needed. 6244 // Check access rights if needed.
6167 if (IsAccessCheckNeeded() && 6245 if (IsAccessCheckNeeded() &&
6168 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { 6246 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) {
6169 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 6247 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS);
6170 return false; 6248 return false;
6171 } 6249 }
6172 6250
6173 LookupResult result; 6251 LookupResult result;
6174 LocalLookupRealNamedProperty(key, &result); 6252 LocalLookupRealNamedProperty(key, &result);
6175 if (result.IsValid()) { 6253 return result.IsProperty() && (result.type() != INTERCEPTOR);
6176 switch (result.type()) {
6177 case NORMAL: // fall through.
6178 case FIELD: // fall through.
6179 case CALLBACKS: // fall through.
6180 case CONSTANT_FUNCTION:
6181 return true;
6182 case INTERCEPTOR:
6183 case MAP_TRANSITION:
6184 case CONSTANT_TRANSITION:
6185 case NULL_DESCRIPTOR:
6186 return false;
6187 default:
6188 UNREACHABLE();
6189 }
6190 }
6191
6192 return false;
6193 } 6254 }
6194 6255
6195 6256
6196 bool JSObject::HasRealElementProperty(uint32_t index) { 6257 bool JSObject::HasRealElementProperty(uint32_t index) {
6197 // Check access rights if needed. 6258 // Check access rights if needed.
6198 if (IsAccessCheckNeeded() && 6259 if (IsAccessCheckNeeded() &&
6199 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 6260 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
6200 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 6261 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS);
6201 return false; 6262 return false;
6202 } 6263 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
6244 bool JSObject::HasRealNamedCallbackProperty(String* key) { 6305 bool JSObject::HasRealNamedCallbackProperty(String* key) {
6245 // Check access rights if needed. 6306 // Check access rights if needed.
6246 if (IsAccessCheckNeeded() && 6307 if (IsAccessCheckNeeded() &&
6247 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { 6308 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) {
6248 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 6309 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS);
6249 return false; 6310 return false;
6250 } 6311 }
6251 6312
6252 LookupResult result; 6313 LookupResult result;
6253 LocalLookupRealNamedProperty(key, &result); 6314 LocalLookupRealNamedProperty(key, &result);
6254 return result.IsValid() && (result.type() == CALLBACKS); 6315 return result.IsProperty() && (result.type() == CALLBACKS);
6255 } 6316 }
6256 6317
6257 6318
6258 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { 6319 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
6259 if (HasFastProperties()) { 6320 if (HasFastProperties()) {
6260 DescriptorArray* descs = map()->instance_descriptors(); 6321 DescriptorArray* descs = map()->instance_descriptors();
6261 int result = 0; 6322 int result = 0;
6262 for (int i = 0; i < descs->number_of_descriptors(); i++) { 6323 for (int i = 0; i < descs->number_of_descriptors(); i++) {
6263 PropertyDetails details = descs->GetDetails(i); 6324 PropertyDetails details = descs->GetDetails(i);
6264 if (details.IsProperty() && (details.attributes() & filter) == 0) { 6325 if (details.IsProperty() && (details.attributes() & filter) == 0) {
(...skipping 1968 matching lines...) Expand 10 before | Expand all | Expand 10 after
8233 if (break_point_objects()->IsUndefined()) return 0; 8294 if (break_point_objects()->IsUndefined()) return 0;
8234 // Single beak point. 8295 // Single beak point.
8235 if (!break_point_objects()->IsFixedArray()) return 1; 8296 if (!break_point_objects()->IsFixedArray()) return 1;
8236 // Multiple break points. 8297 // Multiple break points.
8237 return FixedArray::cast(break_point_objects())->length(); 8298 return FixedArray::cast(break_point_objects())->length();
8238 } 8299 }
8239 #endif 8300 #endif
8240 8301
8241 8302
8242 } } // namespace v8::internal 8303 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698