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

Side by Side Diff: src/objects.cc

Issue 1412103007: Version 4.8.135.3 (cherry-pick) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@4.8.135
Patch Set: Created 5 years, 2 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
« no previous file with comments | « src/lookup.cc ('k') | src/property-descriptor.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 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/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 6006 matching lines...) Expand 10 before | Expand all | Expand 10 after
6017 bool JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate, 6017 bool JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate,
6018 Handle<JSObject> object, 6018 Handle<JSObject> object,
6019 Handle<Object> key, 6019 Handle<Object> key,
6020 PropertyDescriptor* desc, 6020 PropertyDescriptor* desc,
6021 ShouldThrow should_throw) { 6021 ShouldThrow should_throw) {
6022 bool success = false; 6022 bool success = false;
6023 DCHECK(key->IsName() || key->IsNumber()); // |key| is a PropertyKey... 6023 DCHECK(key->IsName() || key->IsNumber()); // |key| is a PropertyKey...
6024 LookupIterator it = LookupIterator::PropertyOrElement( 6024 LookupIterator it = LookupIterator::PropertyOrElement(
6025 isolate, object, key, &success, LookupIterator::HIDDEN); 6025 isolate, object, key, &success, LookupIterator::HIDDEN);
6026 DCHECK(success); // ...so creating a LookupIterator can't fail. 6026 DCHECK(success); // ...so creating a LookupIterator can't fail.
6027
6028 // Deal with access checks first.
6029 if (it.state() == LookupIterator::ACCESS_CHECK) {
6030 if (!it.HasAccess()) {
6031 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
6032 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false);
6033 return false;
6034 }
6035 it.Next();
6036 }
6037
6038 return OrdinaryDefineOwnProperty(&it, desc, should_throw); 6027 return OrdinaryDefineOwnProperty(&it, desc, should_throw);
6039 } 6028 }
6040 6029
6041 6030
6042 // ES6 9.1.6.1 6031 // ES6 9.1.6.1
6043 // static 6032 // static
6044 bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, 6033 bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it,
6045 PropertyDescriptor* desc, 6034 PropertyDescriptor* desc,
6046 ShouldThrow should_throw) { 6035 ShouldThrow should_throw) {
6047 Isolate* isolate = it->isolate(); 6036 Isolate* isolate = it->isolate();
6048 // == OrdinaryDefineOwnProperty (O, P, Desc) == 6037 // == OrdinaryDefineOwnProperty (O, P, Desc) ==
6049 // 1. Let current be O.[[GetOwnProperty]](P). 6038 // 1. Let current be O.[[GetOwnProperty]](P).
6050 // 2. ReturnIfAbrupt(current). 6039 // 2. ReturnIfAbrupt(current).
6051 PropertyDescriptor current; 6040 PropertyDescriptor current;
6052 if (!GetOwnPropertyDescriptor(it, &current) && 6041 if (!GetOwnPropertyDescriptor(it, &current) &&
6053 isolate->has_pending_exception()) { 6042 isolate->has_pending_exception()) {
6054 return false; 6043 return false;
6055 } 6044 }
6056 // TODO(jkummerow/verwaest): It would be nice if we didn't have to reset
6057 // the iterator every time. Currently, the reasons why we need it are:
6058 // - handle interceptors correctly
6059 // - handle accessors correctly (which might change the holder's map)
6060 it->Restart();
6061 // 3. Let extensible be the value of the [[Extensible]] internal slot of O. 6045 // 3. Let extensible be the value of the [[Extensible]] internal slot of O.
6062 Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); 6046 Handle<JSObject> o = Handle<JSObject>::cast(it->GetReceiver());
6063 bool extensible = JSObject::IsExtensible(object); 6047 bool extensible = JSObject::IsExtensible(o);
6064 6048
6065 bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc); 6049 bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc);
6066 bool desc_is_accessor_descriptor = 6050 bool desc_is_accessor_descriptor =
6067 PropertyDescriptor::IsAccessorDescriptor(desc); 6051 PropertyDescriptor::IsAccessorDescriptor(desc);
6068 bool desc_is_generic_descriptor = 6052 bool desc_is_generic_descriptor =
6069 PropertyDescriptor::IsGenericDescriptor(desc); 6053 PropertyDescriptor::IsGenericDescriptor(desc);
6070 6054
6071 // == ValidateAndApplyPropertyDescriptor (O, P, extensible, Desc, current) == 6055 // == ValidateAndApplyPropertyDescriptor (O, P, extensible, Desc, current) ==
6072 // 2. If current is undefined, then 6056 // 2. If current is undefined, then
6073 if (current.is_empty()) { 6057 if (current.is_empty()) {
6074 // 2a. If extensible is false, return false. 6058 // 2a. If extensible is false, return false.
6075 if (!extensible) { 6059 if (!extensible) {
6076 if (should_throw == THROW_ON_ERROR) { 6060 if (should_throw == THROW_ON_ERROR) {
6077 isolate->Throw(*isolate->factory()->NewTypeError( 6061 isolate->Throw(*isolate->factory()->NewTypeError(
6078 MessageTemplate::kDefineDisallowed, it->GetName())); 6062 MessageTemplate::kDefineDisallowed, it->GetName()));
6079 } 6063 }
6080 return false; 6064 return false;
6081 } 6065 }
6082 // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then: 6066 // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then:
6083 // (This is equivalent to !IsAccessorDescriptor(desc).) 6067 // (This is equivalent to !IsAccessorDescriptor(desc).)
6084 DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) == 6068 DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) ==
6085 !desc_is_accessor_descriptor); 6069 !desc_is_accessor_descriptor);
6086 if (!desc_is_accessor_descriptor) { 6070 if (!desc_is_accessor_descriptor) {
6087 // 2c i. If O is not undefined, create an own data property named P of 6071 // 2c i. If O is not undefined, create an own data property named P of
6088 // object O whose [[Value]], [[Writable]], [[Enumerable]] and 6072 // object O whose [[Value]], [[Writable]], [[Enumerable]] and
6089 // [[Configurable]] attribute values are described by Desc. If the value 6073 // [[Configurable]] attribute values are described by Desc. If the value
6090 // of an attribute field of Desc is absent, the attribute of the newly 6074 // of an attribute field of Desc is absent, the attribute of the newly
6091 // created property is set to its default value. 6075 // created property is set to its default value.
6092 if (!object->IsUndefined()) { 6076 if (!o->IsUndefined()) {
6093 if (!desc->has_writable()) desc->set_writable(false); 6077 if (!desc->has_writable()) desc->set_writable(false);
6094 if (!desc->has_enumerable()) desc->set_enumerable(false); 6078 if (!desc->has_enumerable()) desc->set_enumerable(false);
6095 if (!desc->has_configurable()) desc->set_configurable(false); 6079 if (!desc->has_configurable()) desc->set_configurable(false);
6096 Handle<Object> value( 6080 Handle<Object> value(
6097 desc->has_value() 6081 desc->has_value()
6098 ? desc->value() 6082 ? desc->value()
6099 : Handle<Object>::cast(isolate->factory()->undefined_value())); 6083 : Handle<Object>::cast(isolate->factory()->undefined_value()));
6100 MaybeHandle<Object> result = 6084 MaybeHandle<Object> result =
6101 JSObject::DefineOwnPropertyIgnoreAttributes( 6085 JSObject::DefineOwnPropertyIgnoreAttributes(it, value,
6102 it, value, desc->ToAttributes(), JSObject::DONT_FORCE_FIELD); 6086 desc->ToAttributes());
6103 if (result.is_null()) return false; 6087 if (result.is_null()) return false;
6104 } 6088 }
6105 } else { 6089 } else {
6106 // 2d. Else Desc must be an accessor Property Descriptor, 6090 // 2d. Else Desc must be an accessor Property Descriptor,
6107 DCHECK(desc_is_accessor_descriptor); 6091 DCHECK(desc_is_accessor_descriptor);
6108 // 2d i. If O is not undefined, create an own accessor property named P 6092 // 2d i. If O is not undefined, create an own accessor property named P
6109 // of object O whose [[Get]], [[Set]], [[Enumerable]] and 6093 // of object O whose [[Get]], [[Set]], [[Enumerable]] and
6110 // [[Configurable]] attribute values are described by Desc. If the value 6094 // [[Configurable]] attribute values are described by Desc. If the value
6111 // of an attribute field of Desc is absent, the attribute of the newly 6095 // of an attribute field of Desc is absent, the attribute of the newly
6112 // created property is set to its default value. 6096 // created property is set to its default value.
6113 if (!object->IsUndefined()) { 6097 if (!o->IsUndefined()) {
6114 if (!desc->has_enumerable()) desc->set_enumerable(false); 6098 if (!desc->has_enumerable()) desc->set_enumerable(false);
6115 if (!desc->has_configurable()) desc->set_configurable(false); 6099 if (!desc->has_configurable()) desc->set_configurable(false);
6116 Handle<Object> getter( 6100 Handle<Object> getter(
6117 desc->has_get() 6101 desc->has_get()
6118 ? desc->get() 6102 ? desc->get()
6119 : Handle<Object>::cast(isolate->factory()->undefined_value())); 6103 : Handle<Object>::cast(isolate->factory()->undefined_value()));
6120 Handle<Object> setter( 6104 Handle<Object> setter(
6121 desc->has_set() 6105 desc->has_set()
6122 ? desc->set() 6106 ? desc->set()
6123 : Handle<Object>::cast(isolate->factory()->undefined_value())); 6107 : Handle<Object>::cast(isolate->factory()->undefined_value()));
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
6203 } 6187 }
6204 6188
6205 // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both 6189 // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both
6206 // true, then: 6190 // true, then:
6207 } else if (current_is_data_descriptor && desc_is_data_descriptor) { 6191 } else if (current_is_data_descriptor && desc_is_data_descriptor) {
6208 // 8a. If the [[Configurable]] field of current is false, then: 6192 // 8a. If the [[Configurable]] field of current is false, then:
6209 if (!current.configurable()) { 6193 if (!current.configurable()) {
6210 // [Strong mode] Disallow changing writable -> readonly for 6194 // [Strong mode] Disallow changing writable -> readonly for
6211 // non-configurable properties. 6195 // non-configurable properties.
6212 if (current.writable() && desc->has_writable() && !desc->writable() && 6196 if (current.writable() && desc->has_writable() && !desc->writable() &&
6213 object->map()->is_strong()) { 6197 o->map()->is_strong()) {
6214 if (should_throw == THROW_ON_ERROR) { 6198 if (should_throw == THROW_ON_ERROR) {
6215 isolate->Throw(*isolate->factory()->NewTypeError( 6199 isolate->Throw(*isolate->factory()->NewTypeError(
6216 MessageTemplate::kStrongRedefineDisallowed, object, 6200 MessageTemplate::kStrongRedefineDisallowed, o, it->GetName()));
6217 it->GetName()));
6218 } 6201 }
6219 return false; 6202 return false;
6220 } 6203 }
6221 // 8a i. Return false, if the [[Writable]] field of current is false and 6204 // 8a i. Return false, if the [[Writable]] field of current is false and
6222 // the [[Writable]] field of Desc is true. 6205 // the [[Writable]] field of Desc is true.
6223 if (!current.writable() && desc->has_writable() && desc->writable()) { 6206 if (!current.writable() && desc->has_writable() && desc->writable()) {
6224 if (should_throw == THROW_ON_ERROR) { 6207 if (should_throw == THROW_ON_ERROR) {
6225 isolate->Throw(*isolate->factory()->NewTypeError( 6208 isolate->Throw(*isolate->factory()->NewTypeError(
6226 MessageTemplate::kRedefineDisallowed, it->GetName())); 6209 MessageTemplate::kRedefineDisallowed, it->GetName()));
6227 } 6210 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
6262 if (should_throw == THROW_ON_ERROR) { 6245 if (should_throw == THROW_ON_ERROR) {
6263 isolate->Throw(*isolate->factory()->NewTypeError( 6246 isolate->Throw(*isolate->factory()->NewTypeError(
6264 MessageTemplate::kRedefineDisallowed, it->GetName())); 6247 MessageTemplate::kRedefineDisallowed, it->GetName()));
6265 } 6248 }
6266 return false; 6249 return false;
6267 } 6250 }
6268 } 6251 }
6269 } 6252 }
6270 6253
6271 // 10. If O is not undefined, then: 6254 // 10. If O is not undefined, then:
6272 if (!object->IsUndefined()) { 6255 if (!o->IsUndefined()) {
6273 // 10a. For each field of Desc that is present, set the corresponding 6256 // 10a. For each field of Desc that is present, set the corresponding
6274 // attribute of the property named P of object O to the value of the field. 6257 // attribute of the property named P of object O to the value of the field.
6275 PropertyAttributes attrs = NONE; 6258 PropertyAttributes attrs = NONE;
6276 6259
6277 if (desc->has_enumerable()) { 6260 if (desc->has_enumerable()) {
6278 attrs = static_cast<PropertyAttributes>( 6261 attrs = static_cast<PropertyAttributes>(
6279 attrs | (desc->enumerable() ? NONE : DONT_ENUM)); 6262 attrs | (desc->enumerable() ? NONE : DONT_ENUM));
6280 } else { 6263 } else {
6281 attrs = static_cast<PropertyAttributes>( 6264 attrs = static_cast<PropertyAttributes>(
6282 attrs | (current.enumerable() ? NONE : DONT_ENUM)); 6265 attrs | (current.enumerable() ? NONE : DONT_ENUM));
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
6525 OrdinaryDefineOwnProperty(isolate, a, isolate->factory()->length_string(), 6508 OrdinaryDefineOwnProperty(isolate, a, isolate->factory()->length_string(),
6526 &readonly, should_throw); 6509 &readonly, should_throw);
6527 } 6510 }
6528 uint32_t actual_new_len = 0; 6511 uint32_t actual_new_len = 0;
6529 CHECK(a->length()->ToArrayLength(&actual_new_len)); 6512 CHECK(a->length()->ToArrayLength(&actual_new_len));
6530 // Steps 19d-v, 21. Return false if there were non-deletable elements. 6513 // Steps 19d-v, 21. Return false if there were non-deletable elements.
6531 success = actual_new_len == new_len; 6514 success = actual_new_len == new_len;
6532 if (!success && should_throw == THROW_ON_ERROR) { 6515 if (!success && should_throw == THROW_ON_ERROR) {
6533 isolate->Throw(*isolate->factory()->NewTypeError( 6516 isolate->Throw(*isolate->factory()->NewTypeError(
6534 MessageTemplate::kStrictDeleteProperty, 6517 MessageTemplate::kStrictDeleteProperty,
6535 isolate->factory()->NewNumberFromUint(actual_new_len - 1), a)); 6518 isolate->factory()->NewNumberFromUint(actual_new_len - 1)));
6536 } 6519 }
6537 return success; 6520 return success;
6538 } 6521 }
6539 6522
6540 6523
6541 // static 6524 // static
6542 bool JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate, 6525 bool JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate,
6543 Handle<JSObject> object, 6526 Handle<JSObject> object,
6544 Handle<Object> key, 6527 Handle<Object> key,
6545 PropertyDescriptor* desc) { 6528 PropertyDescriptor* desc) {
(...skipping 28 matching lines...) Expand all
6574 DCHECK(!isolate->has_pending_exception()); 6557 DCHECK(!isolate->has_pending_exception());
6575 6558
6576 // 3. Let D be a newly created Property Descriptor with no fields. 6559 // 3. Let D be a newly created Property Descriptor with no fields.
6577 DCHECK(desc->is_empty()); 6560 DCHECK(desc->is_empty());
6578 // 4. Let X be O's own property whose key is P. 6561 // 4. Let X be O's own property whose key is P.
6579 // 5. If X is a data property, then 6562 // 5. If X is a data property, then
6580 bool is_accessor_pair = it->state() == LookupIterator::ACCESSOR && 6563 bool is_accessor_pair = it->state() == LookupIterator::ACCESSOR &&
6581 it->GetAccessors()->IsAccessorPair(); 6564 it->GetAccessors()->IsAccessorPair();
6582 if (!is_accessor_pair) { 6565 if (!is_accessor_pair) {
6583 // 5a. Set D.[[Value]] to the value of X's [[Value]] attribute. 6566 // 5a. Set D.[[Value]] to the value of X's [[Value]] attribute.
6584 Handle<Object> value; 6567 Handle<Object> value = JSObject::GetProperty(it).ToHandleChecked();
6585 if (!JSObject::GetProperty(it).ToHandle(&value)) {
6586 DCHECK(isolate->has_pending_exception());
6587 return false;
6588 }
6589 desc->set_value(value); 6568 desc->set_value(value);
6590 // 5b. Set D.[[Writable]] to the value of X's [[Writable]] attribute 6569 // 5b. Set D.[[Writable]] to the value of X's [[Writable]] attribute
6591 desc->set_writable((attrs & READ_ONLY) == 0); 6570 desc->set_writable((attrs & READ_ONLY) == 0);
6592 } else { 6571 } else {
6593 // 6. Else X is an accessor property, so 6572 // 6. Else X is an accessor property, so
6594 Handle<AccessorPair> accessors = 6573 Handle<AccessorPair> accessors =
6595 Handle<AccessorPair>::cast(it->GetAccessors()); 6574 Handle<AccessorPair>::cast(it->GetAccessors());
6596 // 6a. Set D.[[Get]] to the value of X's [[Get]] attribute. 6575 // 6a. Set D.[[Get]] to the value of X's [[Get]] attribute.
6597 desc->set_get(handle(accessors->GetComponent(ACCESSOR_GETTER), isolate)); 6576 desc->set_get(handle(accessors->GetComponent(ACCESSOR_GETTER), isolate));
6598 // 6b. Set D.[[Set]] to the value of X's [[Set]] attribute. 6577 // 6b. Set D.[[Set]] to the value of X's [[Set]] attribute.
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after
7798 !current->HasNamedInterceptor() && 7777 !current->HasNamedInterceptor() &&
7799 !current->HasIndexedInterceptor()); 7778 !current->HasIndexedInterceptor());
7800 // Compute the property keys and cache them if possible. 7779 // Compute the property keys and cache them if possible.
7801 Handle<FixedArray> enum_keys = 7780 Handle<FixedArray> enum_keys =
7802 JSObject::GetEnumPropertyKeys(current, cache_enum_length); 7781 JSObject::GetEnumPropertyKeys(current, cache_enum_length);
7803 accumulator.AddKeys(enum_keys); 7782 accumulator.AddKeys(enum_keys);
7804 } else { 7783 } else {
7805 DCHECK(filter == INCLUDE_SYMBOLS); 7784 DCHECK(filter == INCLUDE_SYMBOLS);
7806 PropertyAttributes attr_filter = 7785 PropertyAttributes attr_filter =
7807 static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL); 7786 static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL);
7808 Handle<FixedArray> property_keys = isolate->factory()->NewFixedArray( 7787 JSObject::CollectOwnElementKeys(current, &accumulator, attr_filter);
7809 current->NumberOfOwnProperties(attr_filter));
7810 current->GetOwnPropertyNames(*property_keys, 0, attr_filter);
7811 accumulator.AddKeys(property_keys);
7812 } 7788 }
7813 7789
7814 // Add the property keys from the interceptor. 7790 // Add the property keys from the interceptor.
7815 if (current->HasNamedInterceptor()) { 7791 if (current->HasNamedInterceptor()) {
7816 Handle<JSObject> result; 7792 Handle<JSObject> result;
7817 if (JSObject::GetKeysForNamedInterceptor(current, object) 7793 if (JSObject::GetKeysForNamedInterceptor(current, object)
7818 .ToHandle(&result)) { 7794 .ToHandle(&result)) {
7819 accumulator.AddKeys(result); 7795 accumulator.AddKeys(result);
7820 } 7796 }
7821 } 7797 }
(...skipping 10012 matching lines...) Expand 10 before | Expand all | Expand 10 after
17834 if (cell->value() != *new_value) { 17810 if (cell->value() != *new_value) {
17835 cell->set_value(*new_value); 17811 cell->set_value(*new_value);
17836 Isolate* isolate = cell->GetIsolate(); 17812 Isolate* isolate = cell->GetIsolate();
17837 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17813 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17838 isolate, DependentCode::kPropertyCellChangedGroup); 17814 isolate, DependentCode::kPropertyCellChangedGroup);
17839 } 17815 }
17840 } 17816 }
17841 17817
17842 } // namespace internal 17818 } // namespace internal
17843 } // namespace v8 17819 } // namespace v8
OLDNEW
« no previous file with comments | « src/lookup.cc ('k') | src/property-descriptor.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698