| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1449 ASSERT(args.length() == 1); | 1449 ASSERT(args.length() == 1); |
| 1450 CONVERT_ARG_CHECKED(Object, obj, 0); | 1450 CONVERT_ARG_CHECKED(Object, obj, 0); |
| 1451 // We don't expect access checks to be needed on JSProxy objects. | 1451 // We don't expect access checks to be needed on JSProxy objects. |
| 1452 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); | 1452 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |
| 1453 do { | 1453 do { |
| 1454 if (obj->IsAccessCheckNeeded() && | 1454 if (obj->IsAccessCheckNeeded() && |
| 1455 !isolate->MayNamedAccess(JSObject::cast(obj), | 1455 !isolate->MayNamedAccess(JSObject::cast(obj), |
| 1456 isolate->heap()->proto_string(), | 1456 isolate->heap()->proto_string(), |
| 1457 v8::ACCESS_GET)) { | 1457 v8::ACCESS_GET)) { |
| 1458 isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET); | 1458 isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET); |
| 1459 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1459 return isolate->heap()->undefined_value(); | 1460 return isolate->heap()->undefined_value(); |
| 1460 } | 1461 } |
| 1461 obj = obj->GetPrototype(isolate); | 1462 obj = obj->GetPrototype(isolate); |
| 1462 } while (obj->IsJSObject() && | 1463 } while (obj->IsJSObject() && |
| 1463 JSObject::cast(obj)->map()->is_hidden_prototype()); | 1464 JSObject::cast(obj)->map()->is_hidden_prototype()); |
| 1464 return obj; | 1465 return obj; |
| 1465 } | 1466 } |
| 1466 | 1467 |
| 1467 | 1468 |
| 1468 static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate, | 1469 static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1553 } | 1554 } |
| 1554 | 1555 |
| 1555 | 1556 |
| 1556 enum AccessCheckResult { | 1557 enum AccessCheckResult { |
| 1557 ACCESS_FORBIDDEN, | 1558 ACCESS_FORBIDDEN, |
| 1558 ACCESS_ALLOWED, | 1559 ACCESS_ALLOWED, |
| 1559 ACCESS_ABSENT | 1560 ACCESS_ABSENT |
| 1560 }; | 1561 }; |
| 1561 | 1562 |
| 1562 | 1563 |
| 1563 static AccessCheckResult CheckElementAccess( | |
| 1564 JSObject* obj, | |
| 1565 uint32_t index, | |
| 1566 v8::AccessType access_type) { | |
| 1567 // TODO(1095): we should traverse hidden prototype hierachy as well. | |
| 1568 if (CheckGenericAccess( | |
| 1569 obj, obj, index, access_type, &Isolate::MayIndexedAccess)) { | |
| 1570 return ACCESS_ALLOWED; | |
| 1571 } | |
| 1572 | |
| 1573 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); | |
| 1574 return ACCESS_FORBIDDEN; | |
| 1575 } | |
| 1576 | |
| 1577 | |
| 1578 static AccessCheckResult CheckPropertyAccess( | 1564 static AccessCheckResult CheckPropertyAccess( |
| 1579 JSObject* obj, | 1565 JSObject* obj, |
| 1580 Name* name, | 1566 Name* name, |
| 1581 v8::AccessType access_type) { | 1567 v8::AccessType access_type) { |
| 1582 uint32_t index; | 1568 uint32_t index; |
| 1583 if (name->AsArrayIndex(&index)) { | 1569 if (name->AsArrayIndex(&index)) { |
| 1584 return CheckElementAccess(obj, index, access_type); | 1570 // TODO(1095): we should traverse hidden prototype hierachy as well. |
| 1571 if (CheckGenericAccess( |
| 1572 obj, obj, index, access_type, &Isolate::MayIndexedAccess)) { |
| 1573 return ACCESS_ALLOWED; |
| 1574 } |
| 1575 |
| 1576 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); |
| 1577 return ACCESS_FORBIDDEN; |
| 1585 } | 1578 } |
| 1586 | 1579 |
| 1587 LookupResult lookup(obj->GetIsolate()); | 1580 LookupResult lookup(obj->GetIsolate()); |
| 1588 obj->LocalLookup(name, &lookup, true); | 1581 obj->LocalLookup(name, &lookup, true); |
| 1589 | 1582 |
| 1590 if (!lookup.IsProperty()) return ACCESS_ABSENT; | 1583 if (!lookup.IsProperty()) return ACCESS_ABSENT; |
| 1591 if (CheckGenericAccess<Object*>( | 1584 if (CheckGenericAccess<Object*>( |
| 1592 obj, lookup.holder(), name, access_type, &Isolate::MayNamedAccess)) { | 1585 obj, lookup.holder(), name, access_type, &Isolate::MayNamedAccess)) { |
| 1593 return ACCESS_ALLOWED; | 1586 return ACCESS_ALLOWED; |
| 1594 } | 1587 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 DESCRIPTOR_SIZE | 1627 DESCRIPTOR_SIZE |
| 1635 }; | 1628 }; |
| 1636 | 1629 |
| 1637 | 1630 |
| 1638 static MaybeObject* GetOwnProperty(Isolate* isolate, | 1631 static MaybeObject* GetOwnProperty(Isolate* isolate, |
| 1639 Handle<JSObject> obj, | 1632 Handle<JSObject> obj, |
| 1640 Handle<Name> name) { | 1633 Handle<Name> name) { |
| 1641 Heap* heap = isolate->heap(); | 1634 Heap* heap = isolate->heap(); |
| 1642 // Due to some WebKit tests, we want to make sure that we do not log | 1635 // Due to some WebKit tests, we want to make sure that we do not log |
| 1643 // more than one access failure here. | 1636 // more than one access failure here. |
| 1644 switch (CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS)) { | 1637 AccessCheckResult access_check_result = |
| 1638 CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS); |
| 1639 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1640 switch (access_check_result) { |
| 1645 case ACCESS_FORBIDDEN: return heap->false_value(); | 1641 case ACCESS_FORBIDDEN: return heap->false_value(); |
| 1646 case ACCESS_ALLOWED: break; | 1642 case ACCESS_ALLOWED: break; |
| 1647 case ACCESS_ABSENT: return heap->undefined_value(); | 1643 case ACCESS_ABSENT: return heap->undefined_value(); |
| 1648 } | 1644 } |
| 1649 | 1645 |
| 1650 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); | 1646 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); |
| 1651 if (attrs == ABSENT) return heap->undefined_value(); | 1647 if (attrs == ABSENT) { |
| 1648 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1649 return heap->undefined_value(); |
| 1650 } |
| 1651 ASSERT(!isolate->has_scheduled_exception()); |
| 1652 AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name); | 1652 AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name); |
| 1653 Handle<AccessorPair> accessors(raw_accessors, isolate); | 1653 Handle<AccessorPair> accessors(raw_accessors, isolate); |
| 1654 | 1654 |
| 1655 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); | 1655 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); |
| 1656 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); | 1656 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); |
| 1657 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); | 1657 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); |
| 1658 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL)); | 1658 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL)); |
| 1659 | 1659 |
| 1660 if (raw_accessors == NULL) { | 1660 if (raw_accessors == NULL) { |
| 1661 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); | 1661 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); |
| 1662 // GetProperty does access check. | 1662 // GetProperty does access check. |
| 1663 Handle<Object> value = GetProperty(isolate, obj, name); | 1663 Handle<Object> value = GetProperty(isolate, obj, name); |
| 1664 RETURN_IF_EMPTY_HANDLE(isolate, value); | 1664 RETURN_IF_EMPTY_HANDLE(isolate, value); |
| 1665 elms->set(VALUE_INDEX, *value); | 1665 elms->set(VALUE_INDEX, *value); |
| 1666 } else { | 1666 } else { |
| 1667 // Access checks are performed for both accessors separately. | 1667 // Access checks are performed for both accessors separately. |
| 1668 // When they fail, the respective field is not set in the descriptor. | 1668 // When they fail, the respective field is not set in the descriptor. |
| 1669 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); | 1669 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); |
| 1670 Object* setter = accessors->GetComponent(ACCESSOR_SETTER); | 1670 Object* setter = accessors->GetComponent(ACCESSOR_SETTER); |
| 1671 if (!getter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_GET)) { | 1671 if (!getter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_GET)) { |
| 1672 ASSERT(!isolate->has_scheduled_exception()); |
| 1672 elms->set(GETTER_INDEX, getter); | 1673 elms->set(GETTER_INDEX, getter); |
| 1674 } else { |
| 1675 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1673 } | 1676 } |
| 1674 if (!setter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_SET)) { | 1677 if (!setter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_SET)) { |
| 1678 ASSERT(!isolate->has_scheduled_exception()); |
| 1675 elms->set(SETTER_INDEX, setter); | 1679 elms->set(SETTER_INDEX, setter); |
| 1680 } else { |
| 1681 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1676 } | 1682 } |
| 1677 } | 1683 } |
| 1678 | 1684 |
| 1679 return *isolate->factory()->NewJSArrayWithElements(elms); | 1685 return *isolate->factory()->NewJSArrayWithElements(elms); |
| 1680 } | 1686 } |
| 1681 | 1687 |
| 1682 | 1688 |
| 1683 // Returns an array with the property description: | 1689 // Returns an array with the property description: |
| 1684 // if args[1] is not a property on args[0] | 1690 // if args[1] is not a property on args[0] |
| 1685 // returns undefined | 1691 // returns undefined |
| (...skipping 3120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4806 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); | 4812 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); |
| 4807 RUNTIME_ASSERT(IsValidAccessor(getter)); | 4813 RUNTIME_ASSERT(IsValidAccessor(getter)); |
| 4808 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); | 4814 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); |
| 4809 RUNTIME_ASSERT(IsValidAccessor(setter)); | 4815 RUNTIME_ASSERT(IsValidAccessor(setter)); |
| 4810 CONVERT_SMI_ARG_CHECKED(unchecked, 4); | 4816 CONVERT_SMI_ARG_CHECKED(unchecked, 4); |
| 4811 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4817 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 4812 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 4818 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
| 4813 | 4819 |
| 4814 bool fast = obj->HasFastProperties(); | 4820 bool fast = obj->HasFastProperties(); |
| 4815 JSObject::DefineAccessor(obj, name, getter, setter, attr); | 4821 JSObject::DefineAccessor(obj, name, getter, setter, attr); |
| 4822 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 4816 if (fast) JSObject::TransformToFastProperties(obj, 0); | 4823 if (fast) JSObject::TransformToFastProperties(obj, 0); |
| 4817 return isolate->heap()->undefined_value(); | 4824 return isolate->heap()->undefined_value(); |
| 4818 } | 4825 } |
| 4819 | 4826 |
| 4820 | 4827 |
| 4821 // Implements part of 8.12.9 DefineOwnProperty. | 4828 // Implements part of 8.12.9 DefineOwnProperty. |
| 4822 // There are 3 cases that lead here: | 4829 // There are 3 cases that lead here: |
| 4823 // Step 4a - define a new data property. | 4830 // Step 4a - define a new data property. |
| 4824 // Steps 9b & 12 - replace an existing accessor property with a data property. | 4831 // Steps 9b & 12 - replace an existing accessor property with a data property. |
| 4825 // Step 12 - update an existing data property with a data or generic | 4832 // Step 12 - update an existing data property with a data or generic |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5332 | 5339 |
| 5333 CONVERT_ARG_CHECKED(JSReceiver, object, 0); | 5340 CONVERT_ARG_CHECKED(JSReceiver, object, 0); |
| 5334 CONVERT_ARG_CHECKED(Name, key, 1); | 5341 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5335 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); | 5342 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); |
| 5336 return object->DeleteProperty(key, (strict_mode == kStrictMode) | 5343 return object->DeleteProperty(key, (strict_mode == kStrictMode) |
| 5337 ? JSReceiver::STRICT_DELETION | 5344 ? JSReceiver::STRICT_DELETION |
| 5338 : JSReceiver::NORMAL_DELETION); | 5345 : JSReceiver::NORMAL_DELETION); |
| 5339 } | 5346 } |
| 5340 | 5347 |
| 5341 | 5348 |
| 5342 static Object* HasLocalPropertyImplementation(Isolate* isolate, | 5349 static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate, |
| 5343 Handle<JSObject> object, | 5350 Handle<JSObject> object, |
| 5344 Handle<Name> key) { | 5351 Handle<Name> key) { |
| 5345 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); | 5352 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); |
| 5346 // Handle hidden prototypes. If there's a hidden prototype above this thing | 5353 // Handle hidden prototypes. If there's a hidden prototype above this thing |
| 5347 // then we have to check it for properties, because they are supposed to | 5354 // then we have to check it for properties, because they are supposed to |
| 5348 // look like they are on this object. | 5355 // look like they are on this object. |
| 5349 Handle<Object> proto(object->GetPrototype(), isolate); | 5356 Handle<Object> proto(object->GetPrototype(), isolate); |
| 5350 if (proto->IsJSObject() && | 5357 if (proto->IsJSObject() && |
| 5351 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { | 5358 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { |
| 5352 return HasLocalPropertyImplementation(isolate, | 5359 return HasLocalPropertyImplementation(isolate, |
| 5353 Handle<JSObject>::cast(proto), | 5360 Handle<JSObject>::cast(proto), |
| 5354 key); | 5361 key); |
| 5355 } | 5362 } |
| 5363 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5356 return isolate->heap()->false_value(); | 5364 return isolate->heap()->false_value(); |
| 5357 } | 5365 } |
| 5358 | 5366 |
| 5359 | 5367 |
| 5360 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) { | 5368 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) { |
| 5361 SealHandleScope shs(isolate); | 5369 SealHandleScope shs(isolate); |
| 5362 ASSERT(args.length() == 2); | 5370 ASSERT(args.length() == 2); |
| 5363 CONVERT_ARG_CHECKED(Name, key, 1); | 5371 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5364 | 5372 |
| 5365 uint32_t index; | 5373 uint32_t index; |
| 5366 const bool key_is_array_index = key->AsArrayIndex(&index); | 5374 const bool key_is_array_index = key->AsArrayIndex(&index); |
| 5367 | 5375 |
| 5368 Object* obj = args[0]; | 5376 Object* obj = args[0]; |
| 5369 // Only JS objects can have properties. | 5377 // Only JS objects can have properties. |
| 5370 if (obj->IsJSObject()) { | 5378 if (obj->IsJSObject()) { |
| 5371 JSObject* object = JSObject::cast(obj); | 5379 JSObject* object = JSObject::cast(obj); |
| 5372 // Fast case: either the key is a real named property or it is not | 5380 // Fast case: either the key is a real named property or it is not |
| 5373 // an array index and there are no interceptors or hidden | 5381 // an array index and there are no interceptors or hidden |
| 5374 // prototypes. | 5382 // prototypes. |
| 5375 if (object->HasRealNamedProperty(isolate, key)) | 5383 if (object->HasRealNamedProperty(isolate, key)) { |
| 5384 ASSERT(!isolate->has_scheduled_exception()); |
| 5376 return isolate->heap()->true_value(); | 5385 return isolate->heap()->true_value(); |
| 5386 } else { |
| 5387 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5388 } |
| 5377 Map* map = object->map(); | 5389 Map* map = object->map(); |
| 5378 if (!key_is_array_index && | 5390 if (!key_is_array_index && |
| 5379 !map->has_named_interceptor() && | 5391 !map->has_named_interceptor() && |
| 5380 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { | 5392 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { |
| 5381 return isolate->heap()->false_value(); | 5393 return isolate->heap()->false_value(); |
| 5382 } | 5394 } |
| 5383 // Slow case. | 5395 // Slow case. |
| 5384 HandleScope scope(isolate); | 5396 HandleScope scope(isolate); |
| 5385 return HasLocalPropertyImplementation(isolate, | 5397 return HasLocalPropertyImplementation(isolate, |
| 5386 Handle<JSObject>(object), | 5398 Handle<JSObject>(object), |
| 5387 Handle<Name>(key)); | 5399 Handle<Name>(key)); |
| 5388 } else if (obj->IsString() && key_is_array_index) { | 5400 } else if (obj->IsString() && key_is_array_index) { |
| 5389 // Well, there is one exception: Handle [] on strings. | 5401 // Well, there is one exception: Handle [] on strings. |
| 5390 String* string = String::cast(obj); | 5402 String* string = String::cast(obj); |
| 5391 if (index < static_cast<uint32_t>(string->length())) { | 5403 if (index < static_cast<uint32_t>(string->length())) { |
| 5392 return isolate->heap()->true_value(); | 5404 return isolate->heap()->true_value(); |
| 5393 } | 5405 } |
| 5394 } | 5406 } |
| 5395 return isolate->heap()->false_value(); | 5407 return isolate->heap()->false_value(); |
| 5396 } | 5408 } |
| 5397 | 5409 |
| 5398 | 5410 |
| 5399 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { | 5411 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { |
| 5400 SealHandleScope shs(isolate); | 5412 SealHandleScope shs(isolate); |
| 5401 ASSERT(args.length() == 2); | 5413 ASSERT(args.length() == 2); |
| 5402 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 5414 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
| 5403 CONVERT_ARG_CHECKED(Name, key, 1); | 5415 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5404 | 5416 |
| 5405 bool result = receiver->HasProperty(key); | 5417 bool result = receiver->HasProperty(key); |
| 5418 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5406 if (isolate->has_pending_exception()) return Failure::Exception(); | 5419 if (isolate->has_pending_exception()) return Failure::Exception(); |
| 5407 return isolate->heap()->ToBoolean(result); | 5420 return isolate->heap()->ToBoolean(result); |
| 5408 } | 5421 } |
| 5409 | 5422 |
| 5410 | 5423 |
| 5411 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { | 5424 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { |
| 5412 SealHandleScope shs(isolate); | 5425 SealHandleScope shs(isolate); |
| 5413 ASSERT(args.length() == 2); | 5426 ASSERT(args.length() == 2); |
| 5414 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 5427 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
| 5415 CONVERT_SMI_ARG_CHECKED(index, 1); | 5428 CONVERT_SMI_ARG_CHECKED(index, 1); |
| 5416 | 5429 |
| 5417 bool result = receiver->HasElement(index); | 5430 bool result = receiver->HasElement(index); |
| 5431 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5418 if (isolate->has_pending_exception()) return Failure::Exception(); | 5432 if (isolate->has_pending_exception()) return Failure::Exception(); |
| 5419 return isolate->heap()->ToBoolean(result); | 5433 return isolate->heap()->ToBoolean(result); |
| 5420 } | 5434 } |
| 5421 | 5435 |
| 5422 | 5436 |
| 5423 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { | 5437 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { |
| 5424 SealHandleScope shs(isolate); | 5438 SealHandleScope shs(isolate); |
| 5425 ASSERT(args.length() == 2); | 5439 ASSERT(args.length() == 2); |
| 5426 | 5440 |
| 5427 CONVERT_ARG_CHECKED(JSObject, object, 0); | 5441 CONVERT_ARG_CHECKED(JSObject, object, 0); |
| 5428 CONVERT_ARG_CHECKED(Name, key, 1); | 5442 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5429 | 5443 |
| 5430 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 5444 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
| 5431 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 5445 if (att == ABSENT || (att & DONT_ENUM) != 0) { |
| 5446 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5447 return isolate->heap()->false_value(); |
| 5448 } |
| 5449 ASSERT(!isolate->has_scheduled_exception()); |
| 5450 return isolate->heap()->true_value(); |
| 5432 } | 5451 } |
| 5433 | 5452 |
| 5434 | 5453 |
| 5435 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { | 5454 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { |
| 5436 HandleScope scope(isolate); | 5455 HandleScope scope(isolate); |
| 5437 ASSERT(args.length() == 1); | 5456 ASSERT(args.length() == 1); |
| 5438 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); | 5457 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); |
| 5439 bool threw = false; | 5458 bool threw = false; |
| 5440 Handle<JSArray> result = GetKeysFor(object, &threw); | 5459 Handle<JSArray> result = GetKeysFor(object, &threw); |
| 5441 if (threw) return Failure::Exception(); | 5460 if (threw) return Failure::Exception(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5499 | 5518 |
| 5500 // Skip the global proxy as it has no properties and always delegates to the | 5519 // Skip the global proxy as it has no properties and always delegates to the |
| 5501 // real global object. | 5520 // real global object. |
| 5502 if (obj->IsJSGlobalProxy()) { | 5521 if (obj->IsJSGlobalProxy()) { |
| 5503 // Only collect names if access is permitted. | 5522 // Only collect names if access is permitted. |
| 5504 if (obj->IsAccessCheckNeeded() && | 5523 if (obj->IsAccessCheckNeeded() && |
| 5505 !isolate->MayNamedAccess(*obj, | 5524 !isolate->MayNamedAccess(*obj, |
| 5506 isolate->heap()->undefined_value(), | 5525 isolate->heap()->undefined_value(), |
| 5507 v8::ACCESS_KEYS)) { | 5526 v8::ACCESS_KEYS)) { |
| 5508 isolate->ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS); | 5527 isolate->ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS); |
| 5528 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5509 return *isolate->factory()->NewJSArray(0); | 5529 return *isolate->factory()->NewJSArray(0); |
| 5510 } | 5530 } |
| 5511 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 5531 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); |
| 5512 } | 5532 } |
| 5513 | 5533 |
| 5514 // Find the number of objects making up this. | 5534 // Find the number of objects making up this. |
| 5515 int length = LocalPrototypeChainLength(*obj); | 5535 int length = LocalPrototypeChainLength(*obj); |
| 5516 | 5536 |
| 5517 // Find the number of local properties for each of the objects. | 5537 // Find the number of local properties for each of the objects. |
| 5518 ScopedVector<int> local_property_count(length); | 5538 ScopedVector<int> local_property_count(length); |
| 5519 int total_property_count = 0; | 5539 int total_property_count = 0; |
| 5520 Handle<JSObject> jsproto = obj; | 5540 Handle<JSObject> jsproto = obj; |
| 5521 for (int i = 0; i < length; i++) { | 5541 for (int i = 0; i < length; i++) { |
| 5522 // Only collect names if access is permitted. | 5542 // Only collect names if access is permitted. |
| 5523 if (jsproto->IsAccessCheckNeeded() && | 5543 if (jsproto->IsAccessCheckNeeded() && |
| 5524 !isolate->MayNamedAccess(*jsproto, | 5544 !isolate->MayNamedAccess(*jsproto, |
| 5525 isolate->heap()->undefined_value(), | 5545 isolate->heap()->undefined_value(), |
| 5526 v8::ACCESS_KEYS)) { | 5546 v8::ACCESS_KEYS)) { |
| 5527 isolate->ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS); | 5547 isolate->ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS); |
| 5548 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5528 return *isolate->factory()->NewJSArray(0); | 5549 return *isolate->factory()->NewJSArray(0); |
| 5529 } | 5550 } |
| 5530 int n; | 5551 int n; |
| 5531 n = jsproto->NumberOfLocalProperties(filter); | 5552 n = jsproto->NumberOfLocalProperties(filter); |
| 5532 local_property_count[i] = n; | 5553 local_property_count[i] = n; |
| 5533 total_property_count += n; | 5554 total_property_count += n; |
| 5534 if (i < length - 1) { | 5555 if (i < length - 1) { |
| 5535 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 5556 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
| 5536 } | 5557 } |
| 5537 } | 5558 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5644 ASSERT_EQ(args.length(), 1); | 5665 ASSERT_EQ(args.length(), 1); |
| 5645 CONVERT_ARG_CHECKED(JSObject, raw_object, 0); | 5666 CONVERT_ARG_CHECKED(JSObject, raw_object, 0); |
| 5646 Handle<JSObject> object(raw_object); | 5667 Handle<JSObject> object(raw_object); |
| 5647 | 5668 |
| 5648 if (object->IsJSGlobalProxy()) { | 5669 if (object->IsJSGlobalProxy()) { |
| 5649 // Do access checks before going to the global object. | 5670 // Do access checks before going to the global object. |
| 5650 if (object->IsAccessCheckNeeded() && | 5671 if (object->IsAccessCheckNeeded() && |
| 5651 !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(), | 5672 !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(), |
| 5652 v8::ACCESS_KEYS)) { | 5673 v8::ACCESS_KEYS)) { |
| 5653 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); | 5674 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); |
| 5675 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5654 return *isolate->factory()->NewJSArray(0); | 5676 return *isolate->factory()->NewJSArray(0); |
| 5655 } | 5677 } |
| 5656 | 5678 |
| 5657 Handle<Object> proto(object->GetPrototype(), isolate); | 5679 Handle<Object> proto(object->GetPrototype(), isolate); |
| 5658 // If proxy is detached we simply return an empty array. | 5680 // If proxy is detached we simply return an empty array. |
| 5659 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); | 5681 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); |
| 5660 object = Handle<JSObject>::cast(proto); | 5682 object = Handle<JSObject>::cast(proto); |
| 5661 } | 5683 } |
| 5662 | 5684 |
| 5663 bool threw = false; | 5685 bool threw = false; |
| (...skipping 8352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14016 // Handle last resort GC and make sure to allow future allocations | 14038 // Handle last resort GC and make sure to allow future allocations |
| 14017 // to grow the heap without causing GCs (if possible). | 14039 // to grow the heap without causing GCs (if possible). |
| 14018 isolate->counters()->gc_last_resort_from_js()->Increment(); | 14040 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 14019 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 14041 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 14020 "Runtime::PerformGC"); | 14042 "Runtime::PerformGC"); |
| 14021 } | 14043 } |
| 14022 } | 14044 } |
| 14023 | 14045 |
| 14024 | 14046 |
| 14025 } } // namespace v8::internal | 14047 } } // namespace v8::internal |
| OLD | NEW |