Commit 57e8acbb authored by adamk's avatar adamk Committed by Commit bot

Align __lookupGetter__/__lookupSetter__ behavior with the spec

These methods now return undefined upon finding a data property in the
prototype chain which shadows an accessor property, and when hitting
a Proxy, call the appropriate proxy traps.

R=cbruni@chromium.org, littledan@chromium.org
BUG=v8:5130

Review-Url: https://codereview.chromium.org/2592013003
Cr-Commit-Position: refs/heads/master@{#41929}
parent 207214b6
......@@ -645,13 +645,33 @@ Object* ObjectLookupAccessor(Isolate* isolate, Handle<Object> object,
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
case LookupIterator::JSPROXY:
return isolate->heap()->undefined_value();
case LookupIterator::JSPROXY: {
PropertyDescriptor desc;
Maybe<bool> found = JSProxy::GetOwnPropertyDescriptor(
isolate, it.GetHolder<JSProxy>(), it.GetName(), &desc);
MAYBE_RETURN(found, isolate->heap()->exception());
if (found.FromJust()) {
if (component == ACCESSOR_GETTER && desc.has_get()) {
return *desc.get();
}
if (component == ACCESSOR_SETTER && desc.has_set()) {
return *desc.set();
}
return isolate->heap()->undefined_value();
}
Handle<Object> prototype;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, prototype, JSProxy::GetPrototype(it.GetHolder<JSProxy>()));
if (prototype->IsNull(isolate)) {
return isolate->heap()->undefined_value();
}
return ObjectLookupAccessor(isolate, prototype, key, component);
}
case LookupIterator::INTEGER_INDEXED_EXOTIC:
return isolate->heap()->undefined_value();
case LookupIterator::DATA:
continue;
return isolate->heap()->undefined_value();
case LookupIterator::ACCESSOR: {
Handle<Object> maybe_pair = it.GetAccessors();
if (maybe_pair->IsAccessorPair()) {
......
// Copyright 2016 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.
let get = () => {};
let set = () => {};
let target = {};
let handler = {
getOwnPropertyDescriptor(target, prop) {
let configurable = true;
if (prop == "both") {
return { get, set, configurable };
} else if (prop == "get") {
return { get, configurable };
} else if (prop == "set") {
return { set, configurable };
} else if (prop == "data") {
return { value: 42, configurable };
} else {
return Reflect.getOwnPropertyDescriptor(target, prop);
}
}
};
// Test behavior on own properties.
let proxy = new Proxy(target, handler);
assertSame(get, proxy.__lookupGetter__("both"));
assertSame(get, proxy.__lookupGetter__("get"));
assertSame(undefined, proxy.__lookupGetter__("set"));
assertSame(undefined, proxy.__lookupGetter__("data"));
assertSame(set, proxy.__lookupSetter__("both"));
assertSame(undefined, proxy.__lookupSetter__("get"));
assertSame(set, proxy.__lookupSetter__("set"));
assertSame(undefined, proxy.__lookupSetter__("data"));
// Test behavior on the prototype chain.
let object = { __proto__: proxy };
assertSame(get, object.__lookupGetter__("both"));
assertSame(get, object.__lookupGetter__("get"));
assertSame(undefined, object.__lookupGetter__("set"));
assertSame(undefined, object.__lookupGetter__("data"));
assertSame(set, object.__lookupSetter__("both"));
assertSame(undefined, object.__lookupSetter__("get"));
assertSame(set, object.__lookupSetter__("set"));
assertSame(undefined, object.__lookupSetter__("data"));
// Test being shadowed while on prototype chain.
let shadower = { __proto__: proxy, both: 1, get: 2, set: 3, data: 4 };
assertSame(undefined, shadower.__lookupGetter__("both"));
assertSame(undefined, shadower.__lookupGetter__("get"));
assertSame(undefined, shadower.__lookupGetter__("set"));
assertSame(undefined, shadower.__lookupGetter__("data"));
assertSame(undefined, shadower.__lookupSetter__("both"));
assertSame(undefined, shadower.__lookupSetter__("get"));
assertSame(undefined, shadower.__lookupSetter__("set"));
assertSame(undefined, shadower.__lookupSetter__("data"));
// Test getPrototypeOf trap.
let getFoo = () => {};
let setFoo = () => {};
let proto = {};
Reflect.defineProperty(proto, "foo", { get: getFoo, set: setFoo });
Reflect.setPrototypeOf(target, proto);
assertSame(getFoo, proxy.__lookupGetter__("foo"));
assertSame(setFoo, proxy.__lookupSetter__("foo"));
handler.getPrototypeOf = () => null;
assertSame(undefined, proxy.__lookupGetter__("foo"));
assertSame(undefined, proxy.__lookupSetter__("foo"));
handler.getPrototypeOf = () => proto;
assertSame(getFoo, proxy.__lookupGetter__("foo"));
assertSame(setFoo, proxy.__lookupSetter__("foo"));
// Test shadowing the prototype.
Reflect.defineProperty(proto, "data", { get: getFoo, set: setFoo });
assertSame(undefined, proxy.__lookupGetter__("data"));
assertSame(undefined, proxy.__lookupSetter__("data"));
......@@ -318,20 +318,6 @@
'annexB/built-ins/Object/prototype/__lookupGetter__/this-non-obj': [FAIL],
'annexB/built-ins/Object/prototype/__lookupSetter__/this-non-obj': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=5130
'annexB/built-ins/Object/prototype/__lookupGetter__/lookup-own-data': [FAIL],
'annexB/built-ins/Object/prototype/__lookupGetter__/lookup-own-get-err': [FAIL],
'annexB/built-ins/Object/prototype/__lookupGetter__/lookup-own-proto-err': [FAIL],
'annexB/built-ins/Object/prototype/__lookupGetter__/lookup-proto-data': [FAIL],
'annexB/built-ins/Object/prototype/__lookupGetter__/lookup-proto-get-err': [FAIL],
'annexB/built-ins/Object/prototype/__lookupGetter__/lookup-proto-proto-err': [FAIL],
'annexB/built-ins/Object/prototype/__lookupSetter__/lookup-own-data': [FAIL],
'annexB/built-ins/Object/prototype/__lookupSetter__/lookup-own-get-err': [FAIL],
'annexB/built-ins/Object/prototype/__lookupSetter__/lookup-own-proto-err': [FAIL],
'annexB/built-ins/Object/prototype/__lookupSetter__/lookup-proto-data': [FAIL],
'annexB/built-ins/Object/prototype/__lookupSetter__/lookup-proto-get-err': [FAIL],
'annexB/built-ins/Object/prototype/__lookupSetter__/lookup-proto-proto-err': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=4451
'annexB/language/eval-code/direct/global-block-decl-eval-global-exsting-global-init': [FAIL],
'annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-exsting-global-init': [FAIL],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment