Index: src/builtins.cc |
diff --git a/src/builtins.cc b/src/builtins.cc |
index 5436569027fb5aba1b52b9e73659ad0393a7c48a..f906b50aa8b037b9ec6215487fbc290938417209 100644 |
--- a/src/builtins.cc |
+++ b/src/builtins.cc |
@@ -1609,11 +1609,13 @@ MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> to, |
Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate); |
int length = map->NumberOfOwnDescriptors(); |
+ bool stable = true; |
+ |
for (int i = 0; i < length; i++) { |
Handle<Name> next_key(descriptors->GetKey(i), isolate); |
Handle<Object> prop_value; |
// Directly decode from the descriptor array if |from| did not change shape. |
- if (from->map() == *map) { |
+ if (stable) { |
PropertyDetails details = descriptors->GetDetails(i); |
if (!details.IsEnumerable()) continue; |
if (details.kind() == kData) { |
@@ -1628,6 +1630,7 @@ MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> to, |
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, prop_value, |
Object::GetProperty(from, next_key), |
Nothing<bool>()); |
+ stable = from->map() == *map; |
} |
} else { |
// If the map did change, do a slower lookup. We are still guaranteed that |
@@ -1640,12 +1643,12 @@ MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> to, |
ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
isolate, prop_value, Object::GetProperty(&it), Nothing<bool>()); |
} |
- Handle<Object> status; |
- ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
- isolate, status, |
- Object::SetProperty(to, next_key, prop_value, STRICT, |
- Object::CERTAINLY_NOT_STORE_FROM_KEYED), |
- Nothing<bool>()); |
+ LookupIterator it(to, next_key); |
+ bool call_to_js = it.IsFound() && it.state() != LookupIterator::DATA; |
+ Maybe<bool> result = Object::SetProperty( |
+ &it, prop_value, STRICT, Object::CERTAINLY_NOT_STORE_FROM_KEYED); |
+ if (result.IsNothing()) return result; |
+ if (stable && call_to_js) stable = from->map() == *map; |
} |
return Just(true); |