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

Side by Side Diff: src/runtime.cc

Issue 18298012: Check for scheduled exceptions after a failed-access-check callback. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comment Created 7 years, 5 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.cc ('k') | test/cctest/test-api.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 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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698