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