Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 40e06c24ce43d5bffff4aa56429cdd5fc5e95ce6..18d6d44733959e08ca06cde2a413e47d284845a7 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -6060,6 +6060,17 @@ bool JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate, |
LookupIterator it = LookupIterator::PropertyOrElement( |
isolate, object, key, &success, LookupIterator::HIDDEN); |
DCHECK(success); // ...so creating a LookupIterator can't fail. |
+ |
+ // Deal with access checks first. |
+ if (it.state() == LookupIterator::ACCESS_CHECK) { |
+ if (!it.HasAccess()) { |
+ isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>()); |
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false); |
+ return false; |
+ } |
+ it.Next(); |
+ } |
+ |
return OrdinaryDefineOwnProperty(&it, desc, should_throw); |
} |
@@ -6078,9 +6089,14 @@ bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, |
isolate->has_pending_exception()) { |
return false; |
} |
+ // TODO(jkummerow/verwaest): It would be nice if we didn't have to reset |
+ // the iterator every time. Currently, the reasons why we need it are: |
+ // - handle interceptors correctly |
+ // - handle accessors correctly (which might change the holder's map) |
+ it->Restart(); |
// 3. Let extensible be the value of the [[Extensible]] internal slot of O. |
- Handle<JSObject> o = Handle<JSObject>::cast(it->GetReceiver()); |
- bool extensible = JSObject::IsExtensible(o); |
+ Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); |
+ bool extensible = JSObject::IsExtensible(object); |
bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc); |
bool desc_is_accessor_descriptor = |
@@ -6109,7 +6125,7 @@ bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, |
// [[Configurable]] attribute values are described by Desc. If the value |
// of an attribute field of Desc is absent, the attribute of the newly |
// created property is set to its default value. |
- if (!o->IsUndefined()) { |
+ if (!object->IsUndefined()) { |
if (!desc->has_writable()) desc->set_writable(false); |
if (!desc->has_enumerable()) desc->set_enumerable(false); |
if (!desc->has_configurable()) desc->set_configurable(false); |
@@ -6118,8 +6134,8 @@ bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, |
? desc->value() |
: Handle<Object>::cast(isolate->factory()->undefined_value())); |
MaybeHandle<Object> result = |
- JSObject::DefineOwnPropertyIgnoreAttributes(it, value, |
- desc->ToAttributes()); |
+ JSObject::DefineOwnPropertyIgnoreAttributes( |
+ it, value, desc->ToAttributes(), JSObject::DONT_FORCE_FIELD); |
if (result.is_null()) return false; |
} |
} else { |
@@ -6130,7 +6146,7 @@ bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, |
// [[Configurable]] attribute values are described by Desc. If the value |
// of an attribute field of Desc is absent, the attribute of the newly |
// created property is set to its default value. |
- if (!o->IsUndefined()) { |
+ if (!object->IsUndefined()) { |
if (!desc->has_enumerable()) desc->set_enumerable(false); |
if (!desc->has_configurable()) desc->set_configurable(false); |
Handle<Object> getter( |
@@ -6230,10 +6246,11 @@ bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, |
// [Strong mode] Disallow changing writable -> readonly for |
// non-configurable properties. |
if (current.writable() && desc->has_writable() && !desc->writable() && |
- o->map()->is_strong()) { |
+ object->map()->is_strong()) { |
if (should_throw == THROW_ON_ERROR) { |
isolate->Throw(*isolate->factory()->NewTypeError( |
- MessageTemplate::kStrongRedefineDisallowed, o, it->GetName())); |
+ MessageTemplate::kStrongRedefineDisallowed, object, |
+ it->GetName())); |
} |
return false; |
} |
@@ -6288,7 +6305,7 @@ bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, |
} |
// 10. If O is not undefined, then: |
- if (!o->IsUndefined()) { |
+ if (!object->IsUndefined()) { |
// 10a. For each field of Desc that is present, set the corresponding |
// attribute of the property named P of object O to the value of the field. |
PropertyAttributes attrs = NONE; |
@@ -6551,7 +6568,7 @@ bool JSArray::ArraySetLength(Isolate* isolate, Handle<JSArray> a, |
if (!success && should_throw == THROW_ON_ERROR) { |
isolate->Throw(*isolate->factory()->NewTypeError( |
MessageTemplate::kStrictDeleteProperty, |
- isolate->factory()->NewNumberFromUint(actual_new_len - 1))); |
+ isolate->factory()->NewNumberFromUint(actual_new_len - 1), a)); |
} |
return success; |
} |
@@ -6600,7 +6617,11 @@ bool JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it, |
it->GetAccessors()->IsAccessorPair(); |
if (!is_accessor_pair) { |
// 5a. Set D.[[Value]] to the value of X's [[Value]] attribute. |
- Handle<Object> value = JSObject::GetProperty(it).ToHandleChecked(); |
+ Handle<Object> value; |
+ if (!JSObject::GetProperty(it).ToHandle(&value)) { |
+ DCHECK(isolate->has_pending_exception()); |
+ return false; |
+ } |
desc->set_value(value); |
// 5b. Set D.[[Writable]] to the value of X's [[Writable]] attribute |
desc->set_writable((attrs & READ_ONLY) == 0); |
@@ -7819,7 +7840,10 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
DCHECK(filter == INCLUDE_SYMBOLS); |
PropertyAttributes attr_filter = |
static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL); |
- JSObject::CollectOwnElementKeys(current, &accumulator, attr_filter); |
+ Handle<FixedArray> property_keys = isolate->factory()->NewFixedArray( |
+ current->NumberOfOwnProperties(attr_filter)); |
+ current->GetOwnPropertyNames(*property_keys, 0, attr_filter); |
+ accumulator.AddKeys(property_keys); |
} |
// Add the property keys from the interceptor. |