| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 static bool FindAllCanReadHolder(LookupIterator* it) { | 568 static bool FindAllCanReadHolder(LookupIterator* it) { |
| 569 it->skip_interceptor(); | 569 it->skip_interceptor(); |
| 570 it->skip_access_check(); | 570 it->skip_access_check(); |
| 571 for (; it->IsFound(); it->Next()) { | 571 for (; it->IsFound(); it->Next()) { |
| 572 if (it->state() == LookupIterator::PROPERTY && | 572 if (it->state() == LookupIterator::PROPERTY && |
| 573 it->HasProperty() && | 573 it->HasProperty() && |
| 574 it->property_kind() == LookupIterator::ACCESSOR) { | 574 it->property_kind() == LookupIterator::ACCESSOR) { |
| 575 Handle<Object> accessors = it->GetAccessors(); | 575 Handle<Object> accessors = it->GetAccessors(); |
| 576 if (accessors->IsAccessorInfo()) { | 576 if (accessors->IsAccessorInfo()) { |
| 577 if (AccessorInfo::cast(*accessors)->all_can_read()) return true; | 577 if (AccessorInfo::cast(*accessors)->all_can_read()) return true; |
| 578 } else if (accessors->IsAccessorPair()) { | |
| 579 if (AccessorPair::cast(*accessors)->all_can_read()) return true; | |
| 580 } | 578 } |
| 581 } | 579 } |
| 582 } | 580 } |
| 583 return false; | 581 return false; |
| 584 } | 582 } |
| 585 | 583 |
| 586 | 584 |
| 587 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( | 585 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( |
| 588 LookupIterator* it) { | 586 LookupIterator* it) { |
| 589 Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder()); | 587 Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 612 bool check_prototype) { | 610 bool check_prototype) { |
| 613 if (result->IsInterceptor()) { | 611 if (result->IsInterceptor()) { |
| 614 result->holder()->LookupOwnRealNamedProperty(name, result); | 612 result->holder()->LookupOwnRealNamedProperty(name, result); |
| 615 } | 613 } |
| 616 | 614 |
| 617 while (result->IsProperty()) { | 615 while (result->IsProperty()) { |
| 618 if (result->type() == CALLBACKS) { | 616 if (result->type() == CALLBACKS) { |
| 619 Object* callback_obj = result->GetCallbackObject(); | 617 Object* callback_obj = result->GetCallbackObject(); |
| 620 if (callback_obj->IsAccessorInfo()) { | 618 if (callback_obj->IsAccessorInfo()) { |
| 621 if (AccessorInfo::cast(callback_obj)->all_can_write()) return true; | 619 if (AccessorInfo::cast(callback_obj)->all_can_write()) return true; |
| 622 } else if (callback_obj->IsAccessorPair()) { | |
| 623 if (AccessorPair::cast(callback_obj)->all_can_write()) return true; | |
| 624 } | 620 } |
| 625 } | 621 } |
| 626 if (!check_prototype) break; | 622 if (!check_prototype) break; |
| 627 result->holder()->LookupRealNamedPropertyInPrototypes(name, result); | 623 result->holder()->LookupRealNamedPropertyInPrototypes(name, result); |
| 628 } | 624 } |
| 629 return false; | 625 return false; |
| 630 } | 626 } |
| 631 | 627 |
| 632 | 628 |
| 633 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck( | 629 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck( |
| (...skipping 5784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6418 } | 6414 } |
| 6419 } | 6415 } |
| 6420 return false; | 6416 return false; |
| 6421 } | 6417 } |
| 6422 | 6418 |
| 6423 | 6419 |
| 6424 void JSObject::DefineElementAccessor(Handle<JSObject> object, | 6420 void JSObject::DefineElementAccessor(Handle<JSObject> object, |
| 6425 uint32_t index, | 6421 uint32_t index, |
| 6426 Handle<Object> getter, | 6422 Handle<Object> getter, |
| 6427 Handle<Object> setter, | 6423 Handle<Object> setter, |
| 6428 PropertyAttributes attributes, | 6424 PropertyAttributes attributes) { |
| 6429 v8::AccessControl access_control) { | |
| 6430 switch (object->GetElementsKind()) { | 6425 switch (object->GetElementsKind()) { |
| 6431 case FAST_SMI_ELEMENTS: | 6426 case FAST_SMI_ELEMENTS: |
| 6432 case FAST_ELEMENTS: | 6427 case FAST_ELEMENTS: |
| 6433 case FAST_DOUBLE_ELEMENTS: | 6428 case FAST_DOUBLE_ELEMENTS: |
| 6434 case FAST_HOLEY_SMI_ELEMENTS: | 6429 case FAST_HOLEY_SMI_ELEMENTS: |
| 6435 case FAST_HOLEY_ELEMENTS: | 6430 case FAST_HOLEY_ELEMENTS: |
| 6436 case FAST_HOLEY_DOUBLE_ELEMENTS: | 6431 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 6437 break; | 6432 break; |
| 6438 | 6433 |
| 6439 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 6434 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6476 } | 6471 } |
| 6477 } | 6472 } |
| 6478 } | 6473 } |
| 6479 break; | 6474 break; |
| 6480 } | 6475 } |
| 6481 } | 6476 } |
| 6482 | 6477 |
| 6483 Isolate* isolate = object->GetIsolate(); | 6478 Isolate* isolate = object->GetIsolate(); |
| 6484 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair(); | 6479 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair(); |
| 6485 accessors->SetComponents(*getter, *setter); | 6480 accessors->SetComponents(*getter, *setter); |
| 6486 accessors->set_access_flags(access_control); | |
| 6487 | 6481 |
| 6488 SetElementCallback(object, index, accessors, attributes); | 6482 SetElementCallback(object, index, accessors, attributes); |
| 6489 } | 6483 } |
| 6490 | 6484 |
| 6491 | 6485 |
| 6492 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object, | 6486 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object, |
| 6493 Handle<Name> name) { | 6487 Handle<Name> name) { |
| 6494 Isolate* isolate = object->GetIsolate(); | 6488 Isolate* isolate = object->GetIsolate(); |
| 6495 LookupResult result(isolate); | 6489 LookupResult result(isolate); |
| 6496 object->LookupOwnRealNamedProperty(name, &result); | 6490 object->LookupOwnRealNamedProperty(name, &result); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 6507 } | 6501 } |
| 6508 } | 6502 } |
| 6509 return isolate->factory()->NewAccessorPair(); | 6503 return isolate->factory()->NewAccessorPair(); |
| 6510 } | 6504 } |
| 6511 | 6505 |
| 6512 | 6506 |
| 6513 void JSObject::DefinePropertyAccessor(Handle<JSObject> object, | 6507 void JSObject::DefinePropertyAccessor(Handle<JSObject> object, |
| 6514 Handle<Name> name, | 6508 Handle<Name> name, |
| 6515 Handle<Object> getter, | 6509 Handle<Object> getter, |
| 6516 Handle<Object> setter, | 6510 Handle<Object> setter, |
| 6517 PropertyAttributes attributes, | 6511 PropertyAttributes attributes) { |
| 6518 v8::AccessControl access_control) { | |
| 6519 // We could assert that the property is configurable here, but we would need | 6512 // We could assert that the property is configurable here, but we would need |
| 6520 // to do a lookup, which seems to be a bit of overkill. | 6513 // to do a lookup, which seems to be a bit of overkill. |
| 6521 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); | 6514 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); |
| 6522 if (object->HasFastProperties() && !only_attribute_changes && | 6515 if (object->HasFastProperties() && !only_attribute_changes && |
| 6523 access_control == v8::DEFAULT && | |
| 6524 (object->map()->NumberOfOwnDescriptors() <= kMaxNumberOfDescriptors)) { | 6516 (object->map()->NumberOfOwnDescriptors() <= kMaxNumberOfDescriptors)) { |
| 6525 bool getterOk = getter->IsNull() || | 6517 bool getterOk = getter->IsNull() || |
| 6526 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); | 6518 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); |
| 6527 bool setterOk = !getterOk || setter->IsNull() || | 6519 bool setterOk = !getterOk || setter->IsNull() || |
| 6528 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); | 6520 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); |
| 6529 if (getterOk && setterOk) return; | 6521 if (getterOk && setterOk) return; |
| 6530 } | 6522 } |
| 6531 | 6523 |
| 6532 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); | 6524 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); |
| 6533 accessors->SetComponents(*getter, *setter); | 6525 accessors->SetComponents(*getter, *setter); |
| 6534 accessors->set_access_flags(access_control); | |
| 6535 | 6526 |
| 6536 SetPropertyCallback(object, name, accessors, attributes); | 6527 SetPropertyCallback(object, name, accessors, attributes); |
| 6537 } | 6528 } |
| 6538 | 6529 |
| 6539 | 6530 |
| 6540 bool Map::DictionaryElementsInPrototypeChainOnly() { | 6531 bool Map::DictionaryElementsInPrototypeChainOnly() { |
| 6541 Heap* heap = GetHeap(); | 6532 Heap* heap = GetHeap(); |
| 6542 | 6533 |
| 6543 if (IsDictionaryElementsKind(elements_kind())) { | 6534 if (IsDictionaryElementsKind(elements_kind())) { |
| 6544 return false; | 6535 return false; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6625 // Update the dictionary with the new CALLBACKS property. | 6616 // Update the dictionary with the new CALLBACKS property. |
| 6626 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6617 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
| 6627 SetNormalizedProperty(object, name, structure, details); | 6618 SetNormalizedProperty(object, name, structure, details); |
| 6628 } | 6619 } |
| 6629 | 6620 |
| 6630 | 6621 |
| 6631 void JSObject::DefineAccessor(Handle<JSObject> object, | 6622 void JSObject::DefineAccessor(Handle<JSObject> object, |
| 6632 Handle<Name> name, | 6623 Handle<Name> name, |
| 6633 Handle<Object> getter, | 6624 Handle<Object> getter, |
| 6634 Handle<Object> setter, | 6625 Handle<Object> setter, |
| 6635 PropertyAttributes attributes, | 6626 PropertyAttributes attributes) { |
| 6636 v8::AccessControl access_control) { | |
| 6637 Isolate* isolate = object->GetIsolate(); | 6627 Isolate* isolate = object->GetIsolate(); |
| 6638 // Check access rights if needed. | 6628 // Check access rights if needed. |
| 6639 if (object->IsAccessCheckNeeded() && | 6629 if (object->IsAccessCheckNeeded() && |
| 6640 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 6630 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 6641 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); | 6631 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); |
| 6642 // TODO(yangguo): Issue 3269, check for scheduled exception missing? | 6632 // TODO(yangguo): Issue 3269, check for scheduled exception missing? |
| 6643 return; | 6633 return; |
| 6644 } | 6634 } |
| 6645 | 6635 |
| 6646 if (object->IsJSGlobalProxy()) { | 6636 if (object->IsJSGlobalProxy()) { |
| 6647 Handle<Object> proto(object->GetPrototype(), isolate); | 6637 Handle<Object> proto(object->GetPrototype(), isolate); |
| 6648 if (proto->IsNull()) return; | 6638 if (proto->IsNull()) return; |
| 6649 ASSERT(proto->IsJSGlobalObject()); | 6639 ASSERT(proto->IsJSGlobalObject()); |
| 6650 DefineAccessor(Handle<JSObject>::cast(proto), | 6640 DefineAccessor(Handle<JSObject>::cast(proto), |
| 6651 name, | 6641 name, |
| 6652 getter, | 6642 getter, |
| 6653 setter, | 6643 setter, |
| 6654 attributes, | 6644 attributes); |
| 6655 access_control); | |
| 6656 return; | 6645 return; |
| 6657 } | 6646 } |
| 6658 | 6647 |
| 6659 // Make sure that the top context does not change when doing callbacks or | 6648 // Make sure that the top context does not change when doing callbacks or |
| 6660 // interceptor calls. | 6649 // interceptor calls. |
| 6661 AssertNoContextChange ncc(isolate); | 6650 AssertNoContextChange ncc(isolate); |
| 6662 | 6651 |
| 6663 // Try to flatten before operating on the string. | 6652 // Try to flatten before operating on the string. |
| 6664 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 6653 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
| 6665 | 6654 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 6682 object->LookupOwn(name, &lookup, true); | 6671 object->LookupOwn(name, &lookup, true); |
| 6683 preexists = lookup.IsProperty(); | 6672 preexists = lookup.IsProperty(); |
| 6684 if (preexists && lookup.IsDataProperty()) { | 6673 if (preexists && lookup.IsDataProperty()) { |
| 6685 old_value = | 6674 old_value = |
| 6686 Object::GetPropertyOrElement(object, name).ToHandleChecked(); | 6675 Object::GetPropertyOrElement(object, name).ToHandleChecked(); |
| 6687 } | 6676 } |
| 6688 } | 6677 } |
| 6689 } | 6678 } |
| 6690 | 6679 |
| 6691 if (is_element) { | 6680 if (is_element) { |
| 6692 DefineElementAccessor( | 6681 DefineElementAccessor(object, index, getter, setter, attributes); |
| 6693 object, index, getter, setter, attributes, access_control); | |
| 6694 } else { | 6682 } else { |
| 6695 DefinePropertyAccessor( | 6683 DefinePropertyAccessor(object, name, getter, setter, attributes); |
| 6696 object, name, getter, setter, attributes, access_control); | |
| 6697 } | 6684 } |
| 6698 | 6685 |
| 6699 if (is_observed) { | 6686 if (is_observed) { |
| 6700 const char* type = preexists ? "reconfigure" : "add"; | 6687 const char* type = preexists ? "reconfigure" : "add"; |
| 6701 EnqueueChangeRecord(object, type, name, old_value); | 6688 EnqueueChangeRecord(object, type, name, old_value); |
| 6702 } | 6689 } |
| 6703 } | 6690 } |
| 6704 | 6691 |
| 6705 | 6692 |
| 6706 static bool TryAccessorTransition(Handle<JSObject> self, | 6693 static bool TryAccessorTransition(Handle<JSObject> self, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6762 | 6749 |
| 6763 int descriptor_number = result.GetDescriptorIndex(); | 6750 int descriptor_number = result.GetDescriptorIndex(); |
| 6764 | 6751 |
| 6765 object->map()->LookupTransition(*object, *name, &result); | 6752 object->map()->LookupTransition(*object, *name, &result); |
| 6766 | 6753 |
| 6767 if (result.IsFound()) { | 6754 if (result.IsFound()) { |
| 6768 Handle<Map> target(result.GetTransitionTarget()); | 6755 Handle<Map> target(result.GetTransitionTarget()); |
| 6769 ASSERT(target->NumberOfOwnDescriptors() == | 6756 ASSERT(target->NumberOfOwnDescriptors() == |
| 6770 object->map()->NumberOfOwnDescriptors()); | 6757 object->map()->NumberOfOwnDescriptors()); |
| 6771 // This works since descriptors are sorted in order of addition. | 6758 // This works since descriptors are sorted in order of addition. |
| 6772 ASSERT(object->map()->instance_descriptors()-> | 6759 ASSERT(Name::Equals( |
| 6773 GetKey(descriptor_number) == *name); | 6760 handle(object->map()->instance_descriptors()->GetKey( |
| 6761 descriptor_number)), |
| 6762 name)); |
| 6774 return TryAccessorTransition(object, target, descriptor_number, | 6763 return TryAccessorTransition(object, target, descriptor_number, |
| 6775 component, accessor, attributes); | 6764 component, accessor, attributes); |
| 6776 } | 6765 } |
| 6777 } else { | 6766 } else { |
| 6778 // If not, lookup a transition. | 6767 // If not, lookup a transition. |
| 6779 object->map()->LookupTransition(*object, *name, &result); | 6768 object->map()->LookupTransition(*object, *name, &result); |
| 6780 | 6769 |
| 6781 // If there is a transition, try to follow it. | 6770 // If there is a transition, try to follow it. |
| 6782 if (result.IsFound()) { | 6771 if (result.IsFound()) { |
| 6783 Handle<Map> target(result.GetTransitionTarget()); | 6772 Handle<Map> target(result.GetTransitionTarget()); |
| (...skipping 10170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16954 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16943 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16955 static const char* error_messages_[] = { | 16944 static const char* error_messages_[] = { |
| 16956 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16945 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16957 }; | 16946 }; |
| 16958 #undef ERROR_MESSAGES_TEXTS | 16947 #undef ERROR_MESSAGES_TEXTS |
| 16959 return error_messages_[reason]; | 16948 return error_messages_[reason]; |
| 16960 } | 16949 } |
| 16961 | 16950 |
| 16962 | 16951 |
| 16963 } } // namespace v8::internal | 16952 } } // namespace v8::internal |
| OLD | NEW |