Commit 641cdd30 authored by neis's avatar neis Committed by Commit bot

[proxies] Fix Object.prototype.hasOwnProperty

It must call the 'getOwnPropertyDescriptor' trap, not the 'has' trap.

R=cbruni@chromium.org, jkummerow@chromium.org
BUG=v8:1543
LOG=n

Review URL: https://codereview.chromium.org/1532723005

Cr-Commit-Position: refs/heads/master@{#32944}
parent 7cf5f8c5
......@@ -7183,9 +7183,16 @@ Maybe<bool> JSReceiver::HasProperty(Handle<JSReceiver> object,
Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object,
Handle<Name> name) {
LookupIterator it = LookupIterator::PropertyOrElement(
object->GetIsolate(), object, name, LookupIterator::HIDDEN);
return HasProperty(&it);
if (object->IsJSObject()) { // Shortcut
LookupIterator it = LookupIterator::PropertyOrElement(
object->GetIsolate(), object, name, LookupIterator::HIDDEN);
return HasProperty(&it);
}
Maybe<PropertyAttributes> attributes =
JSReceiver::GetOwnPropertyAttributes(object, name);
MAYBE_RETURN(attributes, Nothing<bool>());
return Just(attributes.FromJust() != ABSENT);
}
......@@ -7211,14 +7218,6 @@ Maybe<bool> JSReceiver::HasElement(Handle<JSReceiver> object, uint32_t index) {
}
Maybe<bool> JSReceiver::HasOwnElement(Handle<JSReceiver> object,
uint32_t index) {
LookupIterator it(object->GetIsolate(), object, index,
LookupIterator::HIDDEN);
return HasProperty(&it);
}
Maybe<PropertyAttributes> JSReceiver::GetElementAttributes(
Handle<JSReceiver> object, uint32_t index) {
Isolate* isolate = object->GetIsolate();
......
......@@ -1806,12 +1806,11 @@ class JSReceiver: public HeapObject {
MUST_USE_RESULT static Maybe<bool> HasProperty(LookupIterator* it);
MUST_USE_RESULT static inline Maybe<bool> HasProperty(
Handle<JSReceiver> object, Handle<Name> name);
MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(Handle<JSReceiver>,
Handle<Name> name);
MUST_USE_RESULT static inline Maybe<bool> HasElement(
Handle<JSReceiver> object, uint32_t index);
MUST_USE_RESULT static inline Maybe<bool> HasOwnElement(
Handle<JSReceiver> object, uint32_t index);
MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(
Handle<JSReceiver> object, Handle<Name> name);
// Implementation of ES6 [[Delete]]
MUST_USE_RESULT static Maybe<bool> DeletePropertyOrElement(
......
......@@ -705,7 +705,9 @@ RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
// handle all cases directly (without this custom fast path).
Maybe<bool> maybe = Nothing<bool>();
if (key_is_array_index) {
maybe = JSObject::HasOwnElement(js_obj, index);
LookupIterator it(js_obj->GetIsolate(), js_obj, index,
LookupIterator::HIDDEN);
maybe = JSReceiver::HasProperty(&it);
} else {
maybe = JSObject::HasRealNamedProperty(js_obj, key);
}
......
......@@ -14,25 +14,25 @@ assertFalse(target.hasOwnProperty('b'));
assertFalse(proxy.hasOwnProperty('b'));
handler.has = function() {
return false;
}
handler.has = function() { assertUnreachable() }
handler.getOwnPropertyDescriptor = function () {}
assertTrue(target.hasOwnProperty('a'));
assertFalse(proxy.hasOwnProperty('a'));
assertFalse(target.hasOwnProperty('b'));
assertFalse(proxy.hasOwnProperty('b'));
handler.has = function() {
return true;
}
handler.getOwnPropertyDescriptor = function() { return {configurable: true} }
assertTrue(target.hasOwnProperty('a'));
assertTrue(proxy.hasOwnProperty('a'));
assertFalse(target.hasOwnProperty('b'));
assertTrue(proxy.hasOwnProperty('b'));
handler.has = function() {
throw Error();
}
handler.getOwnPropertyDescriptor = function() { throw Error(); }
assertTrue(target.hasOwnProperty('a'));
assertThrows(function(){ proxy.hasOwnProperty('a') }, Error);
assertFalse(target.hasOwnProperty('b'));
......
......@@ -971,19 +971,19 @@ function TestHasOwn2(create, handler) {
}
TestHasOwn({
has(t, k) { key = k; return k < "z" }
getOwnPropertyDescriptor(t, k) {
key = k; if (k < "z") return {configurable: true}
},
has() { assertUnreachable() }
})
TestHasOwn({
has(t, k) { return this.hasOwn2(k) },
hasOwn2(k) { key = k; return k < "z" }
getOwnPropertyDescriptor(t, k) { return this.getOwnPropertyDescriptor2(k) },
getOwnPropertyDescriptor2(k) {
key = k; if (k < "z") return {configurable: true}
}
})
TestHasOwn(new Proxy({}, {
get(pt, pk, pr) {
return (t, k) => { key = k; return k < "z" }
}
}))
// ---------------------------------------------------------------------------
......@@ -1000,24 +1000,13 @@ function TestHasOwnThrow2(create, handler) {
}
TestHasOwnThrow({
has(t, k) { throw "myexn" }
getOwnPropertyDescriptor(t, k) { throw "myexn" }
})
TestHasOwnThrow({
has(t, k) { return this.hasOwn2(k) },
hasOwn2(k) { throw "myexn" }
})
TestHasOwnThrow(new Proxy({}, {
get(pt, pk, pr) { throw "myexn" }
}))
TestHasOwnThrow(new Proxy({}, {
get(pt, pk, pr) {
return (t, k) => { throw "myexn" }
}
}));
getOwnPropertyDescriptor(t, k) { return this.getOwnPropertyDescriptor2(k) },
getOwnPropertyDescriptor2(k) { throw "myexn" }
});
// ---------------------------------------------------------------------------
......
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