Fix spec violation in Function.prototype.bind.

'9. Let targetName be ? Get(Target, "name").' didn't produce required
side effects.

Bug: v8:6712
Change-Id: Iebf007b4e93ebbf9c6c85c9729d972a8c1a7b129
Reviewed-on: https://chromium-review.googlesource.com/616727
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47393}
This commit is contained in:
Igor Sheludko 2017-08-16 13:53:05 +02:00 committed by Commit Bot
parent 31a3710c01
commit d5a398e8c9
4 changed files with 27 additions and 4 deletions

View File

@ -252,14 +252,14 @@ Object* DoFunctionBind(Isolate* isolate, BuiltinArguments args) {
}
// Setup the "name" property based on the "name" of the {target}.
// If the targets name is the default JSFunction accessor, we can keep the
// If the target's name is the default JSFunction accessor, we can keep the
// accessor that's installed by default on the JSBoundFunction. It lazily
// computes the value from the underlying internal name.
LookupIterator name_lookup(target, isolate->factory()->name_string(), target,
LookupIterator::OWN);
LookupIterator name_lookup(target, isolate->factory()->name_string(), target);
if (!target->IsJSFunction() ||
name_lookup.state() != LookupIterator::ACCESSOR ||
!name_lookup.GetAccessors()->IsAccessorInfo()) {
!name_lookup.GetAccessors()->IsAccessorInfo() ||
(name_lookup.IsFound() && !name_lookup.HolderIsReceiver())) {
Handle<Object> target_name;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target_name,
Object::GetProperty(&name_lookup));

View File

@ -629,6 +629,12 @@ void LookupIterator::TransitionToAccessorPair(Handle<Object> pair,
}
}
bool LookupIterator::HolderIsReceiver() const {
DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
// Optimization that only works if configuration_ is not mutable.
if (!check_prototype_chain()) return true;
return *receiver_ == *holder_;
}
bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);

View File

@ -197,6 +197,7 @@ class V8_EXPORT_PRIVATE LookupIterator final BASE_EMBEDDED {
return Handle<T>::cast(holder_);
}
bool HolderIsReceiver() const;
bool HolderIsReceiverOrHiddenPrototype() const;
bool check_prototype_chain() const {

View File

@ -0,0 +1,16 @@
// Copyright 2017 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.
var log = [];
function f() {}
Object.defineProperty(Function.prototype, "name", {
get() { log.push("getter"); return "ok"; }
});
delete f.name;
var b = f.bind();
assertEquals("bound ok", b.name);
assertEquals("bound ok", b.name);
assertEquals("bound ok", b.name);
assertEquals(["getter"], log);