Bindings generator emits incorrect code when using VoidCallback as an IDL dictionary...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Jan 2019 21:46:30 +0000 (21:46 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Jan 2019 21:46:30 +0000 (21:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193328

Reviewed by Chris Dumez.

Currently, when generating the function body of `convertDictionary`, our bindings generator does not pass in an
argument to use as the `$globalObjectReference` in `JSValueToNative`, when generating code to convert a wrapped
attribute value to the native value. As a result, if the generated IDL type returns `true` from
`JSValueToNativeDOMConvertNeedsGlobalObject` (i.e. for callback function types), we will end up using the empty
string as the generated expression for the global object. This emits syntactically incorrect code:

    `convert<IDLCallbackFunction<JSVoidCallback>>(state, someValue, );`

To fix this, we pass in a string to use as the global object, which uses the given ExecState to grab the global
object. Tested by augmenting TestStandaloneDictionary.idl and its generated expectation.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateDictionaryImplementationContent):
* bindings/scripts/test/JS/JSTestStandaloneDictionary.cpp:
(WebCore::convertDictionary<DictionaryImplName>):
* bindings/scripts/test/TestStandaloneDictionary.idl:

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

Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSTestStandaloneDictionary.cpp
Source/WebCore/bindings/scripts/test/TestStandaloneDictionary.idl

index 0c390df..93be2a8 100644 (file)
@@ -1,3 +1,27 @@
+2019-01-10  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Bindings generator emits incorrect code when using VoidCallback as an IDL dictionary attribute
+        https://bugs.webkit.org/show_bug.cgi?id=193328
+
+        Reviewed by Chris Dumez.
+
+        Currently, when generating the function body of `convertDictionary`, our bindings generator does not pass in an
+        argument to use as the `$globalObjectReference` in `JSValueToNative`, when generating code to convert a wrapped
+        attribute value to the native value. As a result, if the generated IDL type returns `true` from
+        `JSValueToNativeDOMConvertNeedsGlobalObject` (i.e. for callback function types), we will end up using the empty
+        string as the generated expression for the global object. This emits syntactically incorrect code:
+
+            `convert<IDLCallbackFunction<JSVoidCallback>>(state, someValue, );`
+
+        To fix this, we pass in a string to use as the global object, which uses the given ExecState to grab the global
+        object. Tested by augmenting TestStandaloneDictionary.idl and its generated expectation.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateDictionaryImplementationContent):
+        * bindings/scripts/test/JS/JSTestStandaloneDictionary.cpp:
+        (WebCore::convertDictionary<DictionaryImplName>):
+        * bindings/scripts/test/TestStandaloneDictionary.idl:
+
 2019-01-10  Eric Carlson  <eric.carlson@apple.com>
 
         Define page media state flags for display capture.
index a98264b..f92ed2d 100644 (file)
@@ -2348,7 +2348,7 @@ sub GenerateDictionaryImplementationContent
             # 4.3. If value is not undefined, then:
             $result .= "    if (!${key}Value.isUndefined()) {\n";
 
-            my $nativeValue = JSValueToNative($typeScope, $member, "${key}Value", $member->extendedAttributes->{Conditional}, "&state", "state");
+            my $nativeValue = JSValueToNative($typeScope, $member, "${key}Value", $member->extendedAttributes->{Conditional}, "&state", "state", "", "*jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject())");
             $result .= "        result.$implementedAsKey = $nativeValue;\n";
             $result .= "        RETURN_IF_EXCEPTION(throwScope, { });\n";
 
index abc7c41..e21259e 100644 (file)
 #include "JSTestStandaloneDictionary.h"
 
 #include "JSDOMConvertBoolean.h"
+#include "JSDOMConvertCallbacks.h"
 #include "JSDOMConvertStrings.h"
+#include "JSDOMGlobalObject.h"
+#include "JSVoidCallback.h"
 #include <JavaScriptCore/JSCInlines.h>
 #include <JavaScriptCore/JSString.h>
 #include <wtf/NeverDestroyed.h>
@@ -58,6 +61,17 @@ template<> DictionaryImplName convertDictionary<DictionaryImplName>(ExecState& s
         result.boolMember = convert<IDLBoolean>(state, boolMemberValue);
         RETURN_IF_EXCEPTION(throwScope, { });
     }
+    JSValue callbackMemberValue;
+    if (isNullOrUndefined)
+        callbackMemberValue = jsUndefined();
+    else {
+        callbackMemberValue = object->get(&state, Identifier::fromString(&state, "callbackMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!callbackMemberValue.isUndefined()) {
+        result.callbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, callbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
     JSValue enumMemberValue;
     if (isNullOrUndefined)
         enumMemberValue = jsUndefined();
index 77a5894..5727bac 100644 (file)
@@ -36,4 +36,5 @@ enum TestEnumInStandaloneDictionaryFile { "enumValue1", "enumValue2" };
     boolean boolMember;
     DOMString stringMember;
     TestEnumInStandaloneDictionaryFile enumMember;
+    VoidCallback callbackMember;
 };