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 |