Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 23bcd150a801325191373928bf7076cce97ec28c..2c0dc6a598b9b21dc7d817405d3115ac86f348fc 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -2002,8 +2002,24 @@ Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate, |
namespace { |
-MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> target, |
- Handle<Object> source, bool use_set) { |
+bool HasElementInJSArray(Isolate* isolate, Handle<JSArray> array, |
+ Handle<Object> search_element) { |
+ uint32_t len = 0; |
+ bool success = array->length()->ToArrayLength(&len); |
+ DCHECK(success); |
+ |
+ if (len == 0) return false; |
+ |
+ int32_t start = 0; |
+ ElementsAccessor* elements = array->GetElementsAccessor(); |
+ Maybe<bool> result = |
+ elements->IncludesValue(isolate, array, search_element, start, len); |
+ return result.FromJust(); |
+} |
+ |
+MUST_USE_RESULT Maybe<bool> FastAssign( |
+ Handle<JSReceiver> target, Handle<Object> source, |
+ MaybeHandle<JSArray> maybe_excluded_properties, bool use_set) { |
// Non-empty strings are the only non-JSReceivers that need to be handled |
// explicitly by Object.assign. |
if (!source->IsJSReceiver()) { |
@@ -2033,6 +2049,10 @@ MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> target, |
int length = map->NumberOfOwnDescriptors(); |
bool stable = true; |
+ Handle<JSArray> excluded_properties; |
+ if (!maybe_excluded_properties.is_null()) { |
+ excluded_properties = maybe_excluded_properties.ToHandleChecked(); |
adamk
2017/01/10 23:22:56
Pattern for this is:
const bool has_excluded_prop
|
+ } |
for (int i = 0; i < length; i++) { |
Handle<Name> next_key(descriptors->GetKey(i), isolate); |
@@ -2076,6 +2096,11 @@ MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> target, |
if (result.IsNothing()) return result; |
if (stable && call_to_js) stable = from->map() == *map; |
} else { |
+ if (!maybe_excluded_properties.is_null() && |
adamk
2017/01/10 23:22:56
and then this would be
if (has_excluded_propertie
|
+ HasElementInJSArray(isolate, excluded_properties, next_key)) { |
+ continue; |
+ } |
+ |
// 4a ii 2. Perform ? CreateDataProperty(target, nextKey, propValue). |
bool success; |
LookupIterator it = LookupIterator::PropertyOrElement( |
@@ -2089,15 +2114,14 @@ MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> target, |
return Just(true); |
} |
- |
} // namespace |
// static |
-Maybe<bool> JSReceiver::SetOrCopyDataProperties(Isolate* isolate, |
- Handle<JSReceiver> target, |
- Handle<Object> source, |
- bool use_set) { |
- Maybe<bool> fast_assign = FastAssign(target, source, use_set); |
+Maybe<bool> JSReceiver::SetOrCopyDataProperties( |
+ Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source, |
+ MaybeHandle<JSArray> maybe_excluded_properties, bool use_set) { |
+ Maybe<bool> fast_assign = |
+ FastAssign(target, source, maybe_excluded_properties, use_set); |
if (fast_assign.IsNothing()) return Nothing<bool>(); |
if (fast_assign.FromJust()) return Just(true); |
@@ -2110,6 +2134,11 @@ Maybe<bool> JSReceiver::SetOrCopyDataProperties(Isolate* isolate, |
GetKeysConversion::kKeepNumbers), |
Nothing<bool>()); |
+ Handle<JSArray> excluded_properties; |
+ if (!maybe_excluded_properties.is_null()) { |
+ excluded_properties = maybe_excluded_properties.ToHandleChecked(); |
adamk
2017/01/10 23:22:56
Same here as above
|
+ } |
+ |
// 4. Repeat for each element nextKey of keys in List order, |
for (int j = 0; j < keys->length(); ++j) { |
Handle<Object> next_key(keys->get(j), isolate); |
@@ -2134,6 +2163,11 @@ Maybe<bool> JSReceiver::SetOrCopyDataProperties(Isolate* isolate, |
isolate, target, next_key, prop_value, STRICT), |
Nothing<bool>()); |
} else { |
+ if (!maybe_excluded_properties.is_null() && |
adamk
2017/01/10 23:22:55
And here.
|
+ HasElementInJSArray(isolate, excluded_properties, next_key)) { |
+ continue; |
+ } |
+ |
// 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue). |
bool success; |
LookupIterator it = LookupIterator::PropertyOrElement( |