| 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 } |
| 1652 AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name); | 1651 AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name); |
| 1653 Handle<AccessorPair> accessors(raw_accessors, isolate); | 1652 Handle<AccessorPair> accessors(raw_accessors, isolate); |
| 1654 | 1653 |
| 1655 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); | 1654 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); |
| 1656 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); | 1655 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); |
| 1657 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); | 1656 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); |
| 1658 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL)); | 1657 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL)); |
| 1659 | 1658 |
| 1660 if (raw_accessors == NULL) { | 1659 if (raw_accessors == NULL) { |
| 1661 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); | 1660 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); |
| 1662 // GetProperty does access check. | 1661 // GetProperty does access check. |
| 1663 Handle<Object> value = GetProperty(isolate, obj, name); | 1662 Handle<Object> value = GetProperty(isolate, obj, name); |
| 1664 RETURN_IF_EMPTY_HANDLE(isolate, value); | 1663 RETURN_IF_EMPTY_HANDLE(isolate, value); |
| 1665 elms->set(VALUE_INDEX, *value); | 1664 elms->set(VALUE_INDEX, *value); |
| 1666 } else { | 1665 } else { |
| 1667 // Access checks are performed for both accessors separately. | 1666 // Access checks are performed for both accessors separately. |
| 1668 // When they fail, the respective field is not set in the descriptor. | 1667 // When they fail, the respective field is not set in the descriptor. |
| 1669 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); | 1668 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); |
| 1670 Object* setter = accessors->GetComponent(ACCESSOR_SETTER); | 1669 Object* setter = accessors->GetComponent(ACCESSOR_SETTER); |
| 1671 if (!getter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_GET)) { | 1670 if (!getter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_GET)) { |
| 1672 elms->set(GETTER_INDEX, getter); | 1671 elms->set(GETTER_INDEX, getter); |
| 1672 } else { |
| 1673 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1673 } | 1674 } |
| 1674 if (!setter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_SET)) { | 1675 if (!setter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_SET)) { |
| 1675 elms->set(SETTER_INDEX, setter); | 1676 elms->set(SETTER_INDEX, setter); |
| 1677 } else { |
| 1678 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1676 } | 1679 } |
| 1677 } | 1680 } |
| 1678 | 1681 |
| 1679 return *isolate->factory()->NewJSArrayWithElements(elms); | 1682 return *isolate->factory()->NewJSArrayWithElements(elms); |
| 1680 } | 1683 } |
| 1681 | 1684 |
| 1682 | 1685 |
| 1683 // Returns an array with the property description: | 1686 // Returns an array with the property description: |
| 1684 // if args[1] is not a property on args[0] | 1687 // if args[1] is not a property on args[0] |
| 1685 // returns undefined | 1688 // returns undefined |
| (...skipping 3120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4806 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); | 4809 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); |
| 4807 RUNTIME_ASSERT(IsValidAccessor(getter)); | 4810 RUNTIME_ASSERT(IsValidAccessor(getter)); |
| 4808 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); | 4811 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); |
| 4809 RUNTIME_ASSERT(IsValidAccessor(setter)); | 4812 RUNTIME_ASSERT(IsValidAccessor(setter)); |
| 4810 CONVERT_SMI_ARG_CHECKED(unchecked, 4); | 4813 CONVERT_SMI_ARG_CHECKED(unchecked, 4); |
| 4811 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4814 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 4812 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 4815 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
| 4813 | 4816 |
| 4814 bool fast = obj->HasFastProperties(); | 4817 bool fast = obj->HasFastProperties(); |
| 4815 JSObject::DefineAccessor(obj, name, getter, setter, attr); | 4818 JSObject::DefineAccessor(obj, name, getter, setter, attr); |
| 4819 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 4816 if (fast) JSObject::TransformToFastProperties(obj, 0); | 4820 if (fast) JSObject::TransformToFastProperties(obj, 0); |
| 4817 return isolate->heap()->undefined_value(); | 4821 return isolate->heap()->undefined_value(); |
| 4818 } | 4822 } |
| 4819 | 4823 |
| 4820 | 4824 |
| 4821 // Implements part of 8.12.9 DefineOwnProperty. | 4825 // Implements part of 8.12.9 DefineOwnProperty. |
| 4822 // There are 3 cases that lead here: | 4826 // There are 3 cases that lead here: |
| 4823 // Step 4a - define a new data property. | 4827 // Step 4a - define a new data property. |
| 4824 // Steps 9b & 12 - replace an existing accessor property with a data property. | 4828 // 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 | 4829 // 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 | 5336 |
| 5333 CONVERT_ARG_CHECKED(JSReceiver, object, 0); | 5337 CONVERT_ARG_CHECKED(JSReceiver, object, 0); |
| 5334 CONVERT_ARG_CHECKED(Name, key, 1); | 5338 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5335 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); | 5339 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); |
| 5336 return object->DeleteProperty(key, (strict_mode == kStrictMode) | 5340 return object->DeleteProperty(key, (strict_mode == kStrictMode) |
| 5337 ? JSReceiver::STRICT_DELETION | 5341 ? JSReceiver::STRICT_DELETION |
| 5338 : JSReceiver::NORMAL_DELETION); | 5342 : JSReceiver::NORMAL_DELETION); |
| 5339 } | 5343 } |
| 5340 | 5344 |
| 5341 | 5345 |
| 5342 static Object* HasLocalPropertyImplementation(Isolate* isolate, | 5346 static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate, |
| 5343 Handle<JSObject> object, | 5347 Handle<JSObject> object, |
| 5344 Handle<Name> key) { | 5348 Handle<Name> key) { |
| 5345 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); | 5349 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); |
| 5346 // Handle hidden prototypes. If there's a hidden prototype above this thing | 5350 // 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 | 5351 // then we have to check it for properties, because they are supposed to |
| 5348 // look like they are on this object. | 5352 // look like they are on this object. |
| 5349 Handle<Object> proto(object->GetPrototype(), isolate); | 5353 Handle<Object> proto(object->GetPrototype(), isolate); |
| 5350 if (proto->IsJSObject() && | 5354 if (proto->IsJSObject() && |
| 5351 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { | 5355 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { |
| 5352 return HasLocalPropertyImplementation(isolate, | 5356 return HasLocalPropertyImplementation(isolate, |
| 5353 Handle<JSObject>::cast(proto), | 5357 Handle<JSObject>::cast(proto), |
| 5354 key); | 5358 key); |
| 5355 } | 5359 } |
| 5360 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5356 return isolate->heap()->false_value(); | 5361 return isolate->heap()->false_value(); |
| 5357 } | 5362 } |
| 5358 | 5363 |
| 5359 | 5364 |
| 5360 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) { | 5365 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) { |
| 5361 SealHandleScope shs(isolate); | 5366 SealHandleScope shs(isolate); |
| 5362 ASSERT(args.length() == 2); | 5367 ASSERT(args.length() == 2); |
| 5363 CONVERT_ARG_CHECKED(Name, key, 1); | 5368 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5364 | 5369 |
| 5365 uint32_t index; | 5370 uint32_t index; |
| 5366 const bool key_is_array_index = key->AsArrayIndex(&index); | 5371 const bool key_is_array_index = key->AsArrayIndex(&index); |
| 5367 | 5372 |
| 5368 Object* obj = args[0]; | 5373 Object* obj = args[0]; |
| 5369 // Only JS objects can have properties. | 5374 // Only JS objects can have properties. |
| 5370 if (obj->IsJSObject()) { | 5375 if (obj->IsJSObject()) { |
| 5371 JSObject* object = JSObject::cast(obj); | 5376 JSObject* object = JSObject::cast(obj); |
| 5372 // Fast case: either the key is a real named property or it is not | 5377 // 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 | 5378 // an array index and there are no interceptors or hidden |
| 5374 // prototypes. | 5379 // prototypes. |
| 5375 if (object->HasRealNamedProperty(isolate, key)) | 5380 if (object->HasRealNamedProperty(isolate, key)) { |
| 5376 return isolate->heap()->true_value(); | 5381 return isolate->heap()->true_value(); |
| 5382 } else { |
| 5383 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5384 } |
| 5377 Map* map = object->map(); | 5385 Map* map = object->map(); |
| 5378 if (!key_is_array_index && | 5386 if (!key_is_array_index && |
| 5379 !map->has_named_interceptor() && | 5387 !map->has_named_interceptor() && |
| 5380 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { | 5388 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { |
| 5381 return isolate->heap()->false_value(); | 5389 return isolate->heap()->false_value(); |
| 5382 } | 5390 } |
| 5383 // Slow case. | 5391 // Slow case. |
| 5384 HandleScope scope(isolate); | 5392 HandleScope scope(isolate); |
| 5385 return HasLocalPropertyImplementation(isolate, | 5393 return HasLocalPropertyImplementation(isolate, |
| 5386 Handle<JSObject>(object), | 5394 Handle<JSObject>(object), |
| 5387 Handle<Name>(key)); | 5395 Handle<Name>(key)); |
| 5388 } else if (obj->IsString() && key_is_array_index) { | 5396 } else if (obj->IsString() && key_is_array_index) { |
| 5389 // Well, there is one exception: Handle [] on strings. | 5397 // Well, there is one exception: Handle [] on strings. |
| 5390 String* string = String::cast(obj); | 5398 String* string = String::cast(obj); |
| 5391 if (index < static_cast<uint32_t>(string->length())) { | 5399 if (index < static_cast<uint32_t>(string->length())) { |
| 5392 return isolate->heap()->true_value(); | 5400 return isolate->heap()->true_value(); |
| 5393 } | 5401 } |
| 5394 } | 5402 } |
| 5395 return isolate->heap()->false_value(); | 5403 return isolate->heap()->false_value(); |
| 5396 } | 5404 } |
| 5397 | 5405 |
| 5398 | 5406 |
| 5399 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { | 5407 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { |
| 5400 SealHandleScope shs(isolate); | 5408 SealHandleScope shs(isolate); |
| 5401 ASSERT(args.length() == 2); | 5409 ASSERT(args.length() == 2); |
| 5402 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 5410 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
| 5403 CONVERT_ARG_CHECKED(Name, key, 1); | 5411 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5404 | 5412 |
| 5405 bool result = receiver->HasProperty(key); | 5413 bool result = receiver->HasProperty(key); |
| 5414 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5406 if (isolate->has_pending_exception()) return Failure::Exception(); | 5415 if (isolate->has_pending_exception()) return Failure::Exception(); |
| 5407 return isolate->heap()->ToBoolean(result); | 5416 return isolate->heap()->ToBoolean(result); |
| 5408 } | 5417 } |
| 5409 | 5418 |
| 5410 | 5419 |
| 5411 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { | 5420 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { |
| 5412 SealHandleScope shs(isolate); | 5421 SealHandleScope shs(isolate); |
| 5413 ASSERT(args.length() == 2); | 5422 ASSERT(args.length() == 2); |
| 5414 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 5423 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
| 5415 CONVERT_SMI_ARG_CHECKED(index, 1); | 5424 CONVERT_SMI_ARG_CHECKED(index, 1); |
| 5416 | 5425 |
| 5417 bool result = receiver->HasElement(index); | 5426 bool result = receiver->HasElement(index); |
| 5427 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5418 if (isolate->has_pending_exception()) return Failure::Exception(); | 5428 if (isolate->has_pending_exception()) return Failure::Exception(); |
| 5419 return isolate->heap()->ToBoolean(result); | 5429 return isolate->heap()->ToBoolean(result); |
| 5420 } | 5430 } |
| 5421 | 5431 |
| 5422 | 5432 |
| 5423 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { | 5433 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { |
| 5424 SealHandleScope shs(isolate); | 5434 SealHandleScope shs(isolate); |
| 5425 ASSERT(args.length() == 2); | 5435 ASSERT(args.length() == 2); |
| 5426 | 5436 |
| 5427 CONVERT_ARG_CHECKED(JSObject, object, 0); | 5437 CONVERT_ARG_CHECKED(JSObject, object, 0); |
| 5428 CONVERT_ARG_CHECKED(Name, key, 1); | 5438 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5429 | 5439 |
| 5430 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 5440 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
| 5431 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 5441 if (att == ABSENT || (att & DONT_ENUM) != 0) { |
| 5442 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5443 return isolate->heap()->false_value(); |
| 5444 } |
| 5445 return isolate->heap()->true_value(); |
| 5432 } | 5446 } |
| 5433 | 5447 |
| 5434 | 5448 |
| 5435 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { | 5449 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { |
| 5436 HandleScope scope(isolate); | 5450 HandleScope scope(isolate); |
| 5437 ASSERT(args.length() == 1); | 5451 ASSERT(args.length() == 1); |
| 5438 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); | 5452 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); |
| 5439 bool threw = false; | 5453 bool threw = false; |
| 5440 Handle<JSArray> result = GetKeysFor(object, &threw); | 5454 Handle<JSArray> result = GetKeysFor(object, &threw); |
| 5441 if (threw) return Failure::Exception(); | 5455 if (threw) return Failure::Exception(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5499 | 5513 |
| 5500 // Skip the global proxy as it has no properties and always delegates to the | 5514 // Skip the global proxy as it has no properties and always delegates to the |
| 5501 // real global object. | 5515 // real global object. |
| 5502 if (obj->IsJSGlobalProxy()) { | 5516 if (obj->IsJSGlobalProxy()) { |
| 5503 // Only collect names if access is permitted. | 5517 // Only collect names if access is permitted. |
| 5504 if (obj->IsAccessCheckNeeded() && | 5518 if (obj->IsAccessCheckNeeded() && |
| 5505 !isolate->MayNamedAccess(*obj, | 5519 !isolate->MayNamedAccess(*obj, |
| 5506 isolate->heap()->undefined_value(), | 5520 isolate->heap()->undefined_value(), |
| 5507 v8::ACCESS_KEYS)) { | 5521 v8::ACCESS_KEYS)) { |
| 5508 isolate->ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS); | 5522 isolate->ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS); |
| 5523 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5509 return *isolate->factory()->NewJSArray(0); | 5524 return *isolate->factory()->NewJSArray(0); |
| 5510 } | 5525 } |
| 5511 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 5526 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); |
| 5512 } | 5527 } |
| 5513 | 5528 |
| 5514 // Find the number of objects making up this. | 5529 // Find the number of objects making up this. |
| 5515 int length = LocalPrototypeChainLength(*obj); | 5530 int length = LocalPrototypeChainLength(*obj); |
| 5516 | 5531 |
| 5517 // Find the number of local properties for each of the objects. | 5532 // Find the number of local properties for each of the objects. |
| 5518 ScopedVector<int> local_property_count(length); | 5533 ScopedVector<int> local_property_count(length); |
| 5519 int total_property_count = 0; | 5534 int total_property_count = 0; |
| 5520 Handle<JSObject> jsproto = obj; | 5535 Handle<JSObject> jsproto = obj; |
| 5521 for (int i = 0; i < length; i++) { | 5536 for (int i = 0; i < length; i++) { |
| 5522 // Only collect names if access is permitted. | 5537 // Only collect names if access is permitted. |
| 5523 if (jsproto->IsAccessCheckNeeded() && | 5538 if (jsproto->IsAccessCheckNeeded() && |
| 5524 !isolate->MayNamedAccess(*jsproto, | 5539 !isolate->MayNamedAccess(*jsproto, |
| 5525 isolate->heap()->undefined_value(), | 5540 isolate->heap()->undefined_value(), |
| 5526 v8::ACCESS_KEYS)) { | 5541 v8::ACCESS_KEYS)) { |
| 5527 isolate->ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS); | 5542 isolate->ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS); |
| 5543 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5528 return *isolate->factory()->NewJSArray(0); | 5544 return *isolate->factory()->NewJSArray(0); |
| 5529 } | 5545 } |
| 5530 int n; | 5546 int n; |
| 5531 n = jsproto->NumberOfLocalProperties(filter); | 5547 n = jsproto->NumberOfLocalProperties(filter); |
| 5532 local_property_count[i] = n; | 5548 local_property_count[i] = n; |
| 5533 total_property_count += n; | 5549 total_property_count += n; |
| 5534 if (i < length - 1) { | 5550 if (i < length - 1) { |
| 5535 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 5551 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
| 5536 } | 5552 } |
| 5537 } | 5553 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5644 ASSERT_EQ(args.length(), 1); | 5660 ASSERT_EQ(args.length(), 1); |
| 5645 CONVERT_ARG_CHECKED(JSObject, raw_object, 0); | 5661 CONVERT_ARG_CHECKED(JSObject, raw_object, 0); |
| 5646 Handle<JSObject> object(raw_object); | 5662 Handle<JSObject> object(raw_object); |
| 5647 | 5663 |
| 5648 if (object->IsJSGlobalProxy()) { | 5664 if (object->IsJSGlobalProxy()) { |
| 5649 // Do access checks before going to the global object. | 5665 // Do access checks before going to the global object. |
| 5650 if (object->IsAccessCheckNeeded() && | 5666 if (object->IsAccessCheckNeeded() && |
| 5651 !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(), | 5667 !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(), |
| 5652 v8::ACCESS_KEYS)) { | 5668 v8::ACCESS_KEYS)) { |
| 5653 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); | 5669 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); |
| 5670 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5654 return *isolate->factory()->NewJSArray(0); | 5671 return *isolate->factory()->NewJSArray(0); |
| 5655 } | 5672 } |
| 5656 | 5673 |
| 5657 Handle<Object> proto(object->GetPrototype(), isolate); | 5674 Handle<Object> proto(object->GetPrototype(), isolate); |
| 5658 // If proxy is detached we simply return an empty array. | 5675 // If proxy is detached we simply return an empty array. |
| 5659 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); | 5676 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); |
| 5660 object = Handle<JSObject>::cast(proto); | 5677 object = Handle<JSObject>::cast(proto); |
| 5661 } | 5678 } |
| 5662 | 5679 |
| 5663 bool threw = false; | 5680 bool threw = false; |
| (...skipping 8354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14018 // Handle last resort GC and make sure to allow future allocations | 14035 // Handle last resort GC and make sure to allow future allocations |
| 14019 // to grow the heap without causing GCs (if possible). | 14036 // to grow the heap without causing GCs (if possible). |
| 14020 isolate->counters()->gc_last_resort_from_js()->Increment(); | 14037 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 14021 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 14038 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 14022 "Runtime::PerformGC"); | 14039 "Runtime::PerformGC"); |
| 14023 } | 14040 } |
| 14024 } | 14041 } |
| 14025 | 14042 |
| 14026 | 14043 |
| 14027 } } // namespace v8::internal | 14044 } } // namespace v8::internal |
| OLD | NEW |