From 30b771a662d7056190205de7667d2b4a4897af2e Mon Sep 17 00:00:00 2001 From: dslomov Date: Tue, 12 May 2015 10:13:12 -0700 Subject: [PATCH] Fix the behavior of 'super.foo' assignment when receiver is not an object. R=arv@chromium.org,verwaest@chromium.org BUG=v8:4097 LOG=N Review URL: https://codereview.chromium.org/1132203005 Cr-Commit-Position: refs/heads/master@{#28377} --- src/objects.cc | 5 ++++ test/mjsunit/es6/regress/regress-4097.js | 37 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/mjsunit/es6/regress/regress-4097.js diff --git a/src/objects.cc b/src/objects.cc index 92f7b0fbcf..1224ab1c6d 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -3279,6 +3279,11 @@ MaybeHandle Object::SetSuperProperty(LookupIterator* it, SetPropertyInternal(it, value, language_mode, store_mode, &found); if (found) return result; + if (!it->GetReceiver()->IsJSReceiver()) { + return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(), it->name(), + value, language_mode); + } + LookupIterator own_lookup(it->GetReceiver(), it->name(), LookupIterator::OWN); switch (own_lookup.state()) { diff --git a/test/mjsunit/es6/regress/regress-4097.js b/test/mjsunit/es6/regress/regress-4097.js new file mode 100644 index 0000000000..ffaaa1033a --- /dev/null +++ b/test/mjsunit/es6/regress/regress-4097.js @@ -0,0 +1,37 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(function StoreToSuper () { + "use strict"; + class A { + s() { + super.bla = 10; + } + }; + + let a = new A(); + (new A).s.call(a); + assertEquals(10, a.bla); + assertThrows(function() { (new A).s.call(undefined); }, TypeError); + assertThrows(function() { (new A).s.call(42); }, TypeError); + assertThrows(function() { (new A).s.call(null); }, TypeError); + assertThrows(function() { (new A).s.call("abc"); }, TypeError); +})(); + + +(function LoadFromSuper () { + "use strict"; + class A { + s() { + return super.bla; + } + }; + + let a = new A(); + assertSame(undefined, (new A).s.call(a)); + assertSame(undefined, (new A).s.call(undefined)); + assertSame(undefined, (new A).s.call(42)); + assertSame(undefined, (new A).s.call(null)); + assertSame(undefined, (new A).s.call("abc")); +})();