object.__lookupGetter__() / object.__lookupSetter__() does not work for native bindings
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Feb 2016 06:35:09 +0000 (06:35 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Feb 2016 06:35:09 +0000 (06:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153765
<rdar://problem/24439699>

Reviewed by Oliver Hunt.

Source/JavaScriptCore:

Add support for CustomAccessor slots to objectProtoFuncLookupGetter() and
objectProtoFuncLookupSetter() by return getOwnPropertyDescriptor().get / set.
getOwnPropertyDescriptor() now correctly deals with CustomAccessors since
r196001.

* runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncLookupGetter):
(JSC::objectProtoFuncLookupSetter):

LayoutTests:

Add layout tests to test that object.__lookupGetter__() / object.__lookupSetter__()
works for native bindings.

* js/lookupGetterGetter-native-bindings-expected.txt: Added.
* js/lookupGetterGetter-native-bindings.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196004 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/js/lookupGetterGetter-native-bindings-expected.txt [new file with mode: 0644]
LayoutTests/js/lookupGetterGetter-native-bindings.html [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/ObjectPrototype.cpp

index e1fa460..6855e14 100644 (file)
@@ -1,5 +1,19 @@
 2016-02-01  Chris Dumez  <cdumez@apple.com>
 
+        object.__lookupGetter__() / object.__lookupSetter__() does not work for native bindings
+        https://bugs.webkit.org/show_bug.cgi?id=153765
+        <rdar://problem/24439699>
+
+        Reviewed by Oliver Hunt.
+
+        Add layout tests to test that object.__lookupGetter__() / object.__lookupSetter__()
+        works for native bindings.
+
+        * js/lookupGetterGetter-native-bindings-expected.txt: Added.
+        * js/lookupGetterGetter-native-bindings.html: Added.
+
+2016-02-01  Chris Dumez  <cdumez@apple.com>
+
         Unreviewed, fix http/tests/security/cross-origin-window-property-access.html
 
         Update http/tests/security/cross-origin-window-property-access.html that was
diff --git a/LayoutTests/js/lookupGetterGetter-native-bindings-expected.txt b/LayoutTests/js/lookupGetterGetter-native-bindings-expected.txt
new file mode 100644 (file)
index 0000000..2a0b817
--- /dev/null
@@ -0,0 +1,41 @@
+Checks that __lookupGetter__ / __lookupSetter__() works for native bindings.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Element.prototype.__lookupGetter__('tagName') is an instance of Function
+PASS Element.prototype.__lookupSetter__('tagName') is undefined.
+PASS Element.prototype.__lookupGetter__('tagName') is Object.getOwnPropertyDescriptor(Element.prototype, 'tagName').get
+PASS Element.prototype.__lookupSetter__('tagName') is Object.getOwnPropertyDescriptor(Element.prototype, 'tagName').set
+PASS testDiv.tagName is "DIV"
+PASS Element.prototype.__lookupGetter__('tagName').call(testDiv) is "DIV"
+
+PASS Element.prototype.__lookupGetter__('nodeName') is an instance of Function
+PASS Element.prototype.__lookupSetter__('nodeName') is undefined.
+PASS Element.prototype.__lookupGetter__('nodeName') is Object.getOwnPropertyDescriptor(Node.prototype, 'nodeName').get
+PASS Element.prototype.__lookupSetter__('nodeName') is Object.getOwnPropertyDescriptor(Node.prototype, 'nodeName').set
+PASS testDiv.nodeName is "DIV"
+PASS Element.prototype.__lookupGetter__('nodeName').call(testDiv) is "DIV"
+
+PASS HTMLElement.prototype.__lookupGetter__('innerText') is an instance of Function
+PASS HTMLElement.prototype.__lookupSetter__('innerText') is an instance of Function
+PASS HTMLDivElement.prototype.__lookupGetter__('innerText') is an instance of Function
+PASS HTMLDivElement.prototype.__lookupSetter__('innerText') is an instance of Function
+PASS testDiv.__proto__.__lookupGetter__('innerText') is an instance of Function
+PASS testDiv.__proto__.__lookupSetter__('innerText') is an instance of Function
+PASS testDiv.__proto__.__proto__.__lookupGetter__('innerText') is an instance of Function
+PASS testDiv.__proto__.__proto__.__lookupSetter__('innerText') is an instance of Function
+PASS HTMLElement.prototype.__lookupGetter__('innerText') is Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'innerText').get
+PASS HTMLElement.prototype.__lookupSetter__('innerText') is Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'innerText').set
+PASS testDiv.innerText is ""
+PASS HTMLElement.prototype.__lookupGetter__('innerText').call(testDiv) is ""
+testDiv.innerText = 'TEST1'
+PASS testDiv.innerText is "TEST1"
+PASS HTMLElement.prototype.__lookupGetter__('innerText').call(testDiv) is "TEST1"
+HTMLElement.prototype.__lookupSetter__('innerText').call(testDiv, '')
+PASS testDiv.innerText is ""
+PASS HTMLElement.prototype.__lookupGetter__('innerText').call(testDiv) is ""
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/lookupGetterGetter-native-bindings.html b/LayoutTests/js/lookupGetterGetter-native-bindings.html
new file mode 100644 (file)
index 0000000..d9e3a23
--- /dev/null
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="testDiv"></div>
+<script>
+description("Checks that __lookupGetter__ / __lookupSetter__() works for native bindings.");
+
+var testDiv = document.getElementById("testDiv");
+
+shouldBeType("Element.prototype.__lookupGetter__('tagName')", "Function");
+shouldBeUndefined("Element.prototype.__lookupSetter__('tagName')");
+shouldBe("Element.prototype.__lookupGetter__('tagName')", "Object.getOwnPropertyDescriptor(Element.prototype, 'tagName').get");
+shouldBe("Element.prototype.__lookupSetter__('tagName')", "Object.getOwnPropertyDescriptor(Element.prototype, 'tagName').set");
+shouldBeEqualToString("testDiv.tagName", "DIV");
+shouldBeEqualToString("Element.prototype.__lookupGetter__('tagName').call(testDiv)", "DIV");
+
+debug("");
+shouldBeType("Element.prototype.__lookupGetter__('nodeName')", "Function");
+shouldBeUndefined("Element.prototype.__lookupSetter__('nodeName')");
+shouldBe("Element.prototype.__lookupGetter__('nodeName')", "Object.getOwnPropertyDescriptor(Node.prototype, 'nodeName').get");
+shouldBe("Element.prototype.__lookupSetter__('nodeName')", "Object.getOwnPropertyDescriptor(Node.prototype, 'nodeName').set");
+shouldBeEqualToString("testDiv.nodeName", "DIV");
+shouldBeEqualToString("Element.prototype.__lookupGetter__('nodeName').call(testDiv)", "DIV");
+
+debug("");
+shouldBeType("HTMLElement.prototype.__lookupGetter__('innerText')", "Function");
+shouldBeType("HTMLElement.prototype.__lookupSetter__('innerText')", "Function");
+shouldBeType("HTMLDivElement.prototype.__lookupGetter__('innerText')", "Function");
+shouldBeType("HTMLDivElement.prototype.__lookupSetter__('innerText')", "Function");
+shouldBeType("testDiv.__proto__.__lookupGetter__('innerText')", "Function");
+shouldBeType("testDiv.__proto__.__lookupSetter__('innerText')", "Function");
+shouldBeType("testDiv.__proto__.__proto__.__lookupGetter__('innerText')", "Function");
+shouldBeType("testDiv.__proto__.__proto__.__lookupSetter__('innerText')", "Function");
+shouldBe("HTMLElement.prototype.__lookupGetter__('innerText')", "Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'innerText').get");
+shouldBe("HTMLElement.prototype.__lookupSetter__('innerText')", "Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'innerText').set");
+shouldBeEqualToString("testDiv.innerText", "");
+shouldBeEqualToString("HTMLElement.prototype.__lookupGetter__('innerText').call(testDiv)", "");
+evalAndLog("testDiv.innerText = 'TEST1'");
+shouldBeEqualToString("testDiv.innerText", "TEST1");
+shouldBeEqualToString("HTMLElement.prototype.__lookupGetter__('innerText').call(testDiv)", "TEST1");
+evalAndLog("HTMLElement.prototype.__lookupSetter__('innerText').call(testDiv, '')");
+shouldBeEqualToString("testDiv.innerText", "");
+shouldBeEqualToString("HTMLElement.prototype.__lookupGetter__('innerText').call(testDiv)", "");
+</script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
index c88e695..9f42c4b 100644 (file)
@@ -1,5 +1,22 @@
 2016-02-01  Chris Dumez  <cdumez@apple.com>
 
+        object.__lookupGetter__() / object.__lookupSetter__() does not work for native bindings
+        https://bugs.webkit.org/show_bug.cgi?id=153765
+        <rdar://problem/24439699>
+
+        Reviewed by Oliver Hunt.
+
+        Add support for CustomAccessor slots to objectProtoFuncLookupGetter() and
+        objectProtoFuncLookupSetter() by return getOwnPropertyDescriptor().get / set.
+        getOwnPropertyDescriptor() now correctly deals with CustomAccessors since
+        r196001.
+
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncLookupGetter):
+        (JSC::objectProtoFuncLookupSetter):
+
+2016-02-01  Chris Dumez  <cdumez@apple.com>
+
         Native Bindings Descriptors are Incomplete
         https://bugs.webkit.org/show_bug.cgi?id=140575
         <rdar://problem/19506502>
index c525436..fdaba1a 100644 (file)
@@ -175,9 +175,17 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState* exec)
         return JSValue::encode(jsUndefined());
 
     PropertySlot slot(thisObject);
-    if (thisObject->getPropertySlot(exec, propertyName, slot) && slot.isAccessor()) {
-        GetterSetter* getterSetter = slot.getterSetter();
-        return getterSetter->isGetterNull() ? JSValue::encode(jsUndefined()) : JSValue::encode(getterSetter->getter());
+    if (thisObject->getPropertySlot(exec, propertyName, slot)) {
+        if (slot.isAccessor()) {
+            GetterSetter* getterSetter = slot.getterSetter();
+            return getterSetter->isGetterNull() ? JSValue::encode(jsUndefined()) : JSValue::encode(getterSetter->getter());
+        }
+        if (slot.attributes() & CustomAccessor) {
+            PropertyDescriptor descriptor;
+            ASSERT(slot.slotBase());
+            if (slot.slotBase()->getOwnPropertyDescriptor(exec, propertyName, descriptor))
+                return descriptor.getterPresent() ? JSValue::encode(descriptor.getter()) : JSValue::encode(jsUndefined());
+        }
     }
 
     return JSValue::encode(jsUndefined());
@@ -194,9 +202,17 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec)
         return JSValue::encode(jsUndefined());
 
     PropertySlot slot(thisObject);
-    if (thisObject->getPropertySlot(exec, propertyName, slot) && slot.isAccessor()) {
-        GetterSetter* getterSetter = slot.getterSetter();
-        return getterSetter->isSetterNull() ? JSValue::encode(jsUndefined()) : JSValue::encode(getterSetter->setter());
+    if (thisObject->getPropertySlot(exec, propertyName, slot)) {
+        if (slot.isAccessor()) {
+            GetterSetter* getterSetter = slot.getterSetter();
+            return getterSetter->isSetterNull() ? JSValue::encode(jsUndefined()) : JSValue::encode(getterSetter->setter());
+        }
+        if (slot.attributes() & CustomAccessor) {
+            PropertyDescriptor descriptor;
+            ASSERT(slot.slotBase());
+            if (slot.slotBase()->getOwnPropertyDescriptor(exec, propertyName, descriptor))
+                return descriptor.setterPresent() ? JSValue::encode(descriptor.setter()) : JSValue::encode(jsUndefined());
+        }
     }
 
     return JSValue::encode(jsUndefined());