Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 498479d8114a935846192e30d27c06a8c73fa307..b57b221afed86ff5a4baa26e41b08026b79f33ca 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -3080,6 +3080,24 @@ MaybeHandle<Object> JSObject::SetPropertyViaPrototypes( |
*done = true; |
if (!result.IsReadOnly()) { |
Handle<Object> callback_object(result.GetCallbackObject(), isolate); |
+ // Only store via executable access info setters if the holder is the |
+ // receiver or on its hidden prototype chain. |
+ if (callback_object->IsExecutableAccessorInfo()) { |
+ Handle<JSObject> current = object; |
+ while (*current != result.holder()) { |
+ // There is a callbacks holder, so we are guaranteed that all |
+ // objects in between are JSObjects. |
+ Handle<JSObject> prototype( |
+ JSObject::cast(current->GetPrototype())); |
+ if (!current->IsJSGlobalProxy() && |
+ !prototype->map()->is_hidden_prototype()) { |
+ *done = result.IsReadOnly(); |
mvstanton
2014/07/03 09:33:08
How about *done = false, because result.IsReadOnly
|
+ break; |
+ } |
+ current = prototype; |
+ } |
+ if (*current != result.holder()) break; |
mvstanton
2014/07/03 09:33:08
comment to explain this break.
|
+ } |
return SetPropertyWithCallback(object, name, value, |
handle(result.holder()), |
callback_object, strict_mode); |