Title: [201128] trunk/Source/WebCore
Revision
201128
Author
youenn.fab...@crf.canon.fr
Date
2016-05-19 00:14:45 -0700 (Thu, 19 May 2016)

Log Message

Make binding DOM constructor use toJSNewlyCreated instead of toJS
https://bugs.webkit.org/show_bug.cgi?id=157832

Reviewed by Chris Dumez.

Using toJSNewlyCreated in generated constructors instead of toJS.
Enabling generation of toJS and toJSNewlyCreated for constructable DOM objects.
This ensures that toJSNewlyCreated call in constructor will compile properly.

Updating some custom code to implement toJSNewlyCreated.

Covered by existing tests.

* bindings/js/JSImageDataCustom.cpp:
(WebCore::toJSNewlyCreated):
(WebCore::toJS):
* bindings/js/JSTextTrackCueCustom.cpp:
(WebCore::toJSNewlyCreated):
(WebCore::toJS):
* bindings/scripts/CodeGeneratorJS.pm:
(ShouldGenerateToJSDeclaration):
(GenerateConstructorDefinition):
* bindings/scripts/test/JS/JSTestInterface.cpp:
(WebCore::JSTestInterfaceConstructor::construct):
* bindings/scripts/test/JS/JSTestNamedConstructor.cpp:
(WebCore::JSTestNamedConstructorNamedConstructor::construct):
* bindings/scripts/test/JS/JSTestNode.cpp:
(WebCore::JSTestNodeConstructor::construct):
(WebCore::toJSNewlyCreated):
(WebCore::toJS):
* bindings/scripts/test/JS/JSTestNode.h:
(WebCore::toJS):
(WebCore::toJSNewlyCreated):
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::JSTestObjConstructor::construct):
* bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp:
(WebCore::constructJSTestOverloadedConstructors1):
(WebCore::constructJSTestOverloadedConstructors2):
(WebCore::constructJSTestOverloadedConstructors3):
(WebCore::constructJSTestOverloadedConstructors4):
(WebCore::constructJSTestOverloadedConstructors5):
* bindings/scripts/test/JS/JSTestTypedefs.cpp:
(WebCore::JSTestTypedefsConstructor::construct):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (201127 => 201128)


--- trunk/Source/WebCore/ChangeLog	2016-05-19 05:20:03 UTC (rev 201127)
+++ trunk/Source/WebCore/ChangeLog	2016-05-19 07:14:45 UTC (rev 201128)
@@ -1,3 +1,49 @@
+2016-05-19  Youenn Fablet  <youenn.fab...@crf.canon.fr>
+
+        Make binding DOM constructor use toJSNewlyCreated instead of toJS
+        https://bugs.webkit.org/show_bug.cgi?id=157832
+
+        Reviewed by Chris Dumez.
+
+        Using toJSNewlyCreated in generated constructors instead of toJS.
+        Enabling generation of toJS and toJSNewlyCreated for constructable DOM objects.
+        This ensures that toJSNewlyCreated call in constructor will compile properly.
+
+        Updating some custom code to implement toJSNewlyCreated.
+
+        Covered by existing tests.
+
+        * bindings/js/JSImageDataCustom.cpp:
+        (WebCore::toJSNewlyCreated):
+        (WebCore::toJS):
+        * bindings/js/JSTextTrackCueCustom.cpp:
+        (WebCore::toJSNewlyCreated):
+        (WebCore::toJS):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (ShouldGenerateToJSDeclaration):
+        (GenerateConstructorDefinition):
+        * bindings/scripts/test/JS/JSTestInterface.cpp:
+        (WebCore::JSTestInterfaceConstructor::construct):
+        * bindings/scripts/test/JS/JSTestNamedConstructor.cpp:
+        (WebCore::JSTestNamedConstructorNamedConstructor::construct):
+        * bindings/scripts/test/JS/JSTestNode.cpp:
+        (WebCore::JSTestNodeConstructor::construct):
+        (WebCore::toJSNewlyCreated):
+        (WebCore::toJS):
+        * bindings/scripts/test/JS/JSTestNode.h:
+        (WebCore::toJS):
+        (WebCore::toJSNewlyCreated):
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        (WebCore::JSTestObjConstructor::construct):
+        * bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp:
+        (WebCore::constructJSTestOverloadedConstructors1):
+        (WebCore::constructJSTestOverloadedConstructors2):
+        (WebCore::constructJSTestOverloadedConstructors3):
+        (WebCore::constructJSTestOverloadedConstructors4):
+        (WebCore::constructJSTestOverloadedConstructors5):
+        * bindings/scripts/test/JS/JSTestTypedefs.cpp:
+        (WebCore::JSTestTypedefsConstructor::construct):
+
 2016-05-18  Zalan Bujtas  <za...@apple.com>
 
         Make LayoutUnit::operator bool() explicit.

Modified: trunk/Source/WebCore/bindings/js/JSImageDataCustom.cpp (201127 => 201128)


--- trunk/Source/WebCore/bindings/js/JSImageDataCustom.cpp	2016-05-19 05:20:03 UTC (rev 201127)
+++ trunk/Source/WebCore/bindings/js/JSImageDataCustom.cpp	2016-05-19 07:14:45 UTC (rev 201128)
@@ -35,19 +35,24 @@
 
 namespace WebCore {
 
-JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, ImageData& imageData)
+JSValue toJSNewlyCreated(ExecState* state, JSDOMGlobalObject* globalObject, Ref<ImageData>&& imageData)
 {
-    if (auto* wrapper = getCachedWrapper(globalObject->world(), imageData))
-        return wrapper;
-    
-    auto* wrapper = CREATE_DOM_WRAPPER(globalObject, ImageData, imageData);
-    Identifier dataName = Identifier::fromString(exec, "data");
-    wrapper->putDirect(exec->vm(), dataName, toJS(exec, globalObject, imageData.data()), DontDelete | ReadOnly);
+    auto* data = ""
+    auto* wrapper = CREATE_DOM_WRAPPER(globalObject, ImageData, WTFMove(imageData));
+    Identifier dataName = Identifier::fromString(state, "data");
+    wrapper->putDirect(state->vm(), dataName, toJS(state, globalObject, data), DontDelete | ReadOnly);
     // FIXME: Adopt reportExtraMemoryVisited, and switch to reportExtraMemoryAllocated.
     // https://bugs.webkit.org/show_bug.cgi?id=142595
-    exec->heap()->deprecatedReportExtraMemory(imageData.data()->length());
+    state->heap()->deprecatedReportExtraMemory(data->length());
     
     return wrapper;
 }
 
+JSValue toJS(ExecState* state, JSDOMGlobalObject* globalObject, ImageData& imageData)
+{
+    if (auto* wrapper = getCachedWrapper(globalObject->world(), imageData))
+        return wrapper;
+    return toJSNewlyCreated(state, globalObject, Ref<ImageData>(imageData));
 }
+
+}

Modified: trunk/Source/WebCore/bindings/js/JSTextTrackCueCustom.cpp (201127 => 201128)


--- trunk/Source/WebCore/bindings/js/JSTextTrackCueCustom.cpp	2016-05-19 05:20:03 UTC (rev 201127)
+++ trunk/Source/WebCore/bindings/js/JSTextTrackCueCustom.cpp	2016-05-19 07:14:45 UTC (rev 201128)
@@ -59,24 +59,29 @@
     return visitor.containsOpaqueRoot(root(textTrackCue.track()));
 }
 
-JSValue toJS(ExecState*, JSDOMGlobalObject* globalObject, TextTrackCue& cue)
+JSValue toJSNewlyCreated(ExecState*, JSDOMGlobalObject* globalObject, Ref<TextTrackCue>&& cue)
 {
-    if (auto* wrapper = getCachedWrapper(globalObject->world(), cue))
-        return wrapper;
-
     // This switch will make more sense once we support DataCue
-    switch (cue.cueType()) {
+    switch (cue->cueType()) {
     case TextTrackCue::Data:
-        return CREATE_DOM_WRAPPER(globalObject, DataCue, cue);
+        return CREATE_DOM_WRAPPER(globalObject, DataCue, WTFMove(cue));
     case TextTrackCue::WebVTT:
     case TextTrackCue::Generic:
-        return CREATE_DOM_WRAPPER(globalObject, VTTCue, cue);
+        return CREATE_DOM_WRAPPER(globalObject, VTTCue, WTFMove(cue));
     default:
         ASSERT_NOT_REACHED();
         return jsNull();
     }
 }
 
+JSValue toJS(ExecState* state, JSDOMGlobalObject* globalObject, TextTrackCue& cue)
+{
+    if (auto* wrapper = getCachedWrapper(globalObject->world(), cue))
+        return wrapper;
+
+    return toJSNewlyCreated(state, globalObject, Ref<TextTrackCue>(cue));
+}
+
 void JSTextTrackCue::visitAdditionalChildren(SlotVisitor& visitor)
 {
     if (TextTrack* textTrack = wrapped().track())

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (201127 => 201128)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-05-19 05:20:03 UTC (rev 201127)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-05-19 07:14:45 UTC (rev 201128)
@@ -474,6 +474,7 @@
     return 0 if $interface->extendedAttributes->{"CustomProxyToJSObject"};
     return 1 if (!$hasParent or $interface->extendedAttributes->{"JSGenerateToJSObject"} or $interface->extendedAttributes->{"CustomToJSObject"});
     return 1 if $interface->parent && $interface->parent eq "EventTarget";
+    return 1 if $interface->extendedAttributes->{"Constructor"} or $interface->extendedAttributes->{"NamedConstructor"};
     return 0;
 }
 
@@ -5154,7 +5155,7 @@
                  push(@$outputArray, "        return JSValue::encode(jsUndefined());\n");
             }
 
-            push(@$outputArray, "    return JSValue::encode(asObject(toJS(state, castedThis->globalObject(), WTFMove(object))));\n");
+            push(@$outputArray, "    return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object))));\n");
             push(@$outputArray, "}\n\n");
         }
     }

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp (201127 => 201128)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp	2016-05-19 05:20:03 UTC (rev 201127)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp	2016-05-19 07:14:45 UTC (rev 201128)
@@ -240,7 +240,7 @@
         setDOMException(state, ec);
         return JSValue::encode(JSValue());
     }
-    return JSValue::encode(asObject(toJS(state, castedThis->globalObject(), WTFMove(object))));
+    return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object))));
 }
 
 template<> JSValue JSTestInterfaceConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedConstructor.cpp (201127 => 201128)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedConstructor.cpp	2016-05-19 05:20:03 UTC (rev 201127)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedConstructor.cpp	2016-05-19 07:14:45 UTC (rev 201128)
@@ -100,7 +100,7 @@
         setDOMException(state, ec);
         return JSValue::encode(JSValue());
     }
-    return JSValue::encode(asObject(toJS(state, castedThis->globalObject(), WTFMove(object))));
+    return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object))));
 }
 
 template<> JSValue JSTestNamedConstructorNamedConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp (201127 => 201128)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp	2016-05-19 05:20:03 UTC (rev 201127)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp	2016-05-19 07:14:45 UTC (rev 201128)
@@ -80,7 +80,7 @@
 {
     auto* castedThis = jsCast<JSTestNodeConstructor*>(state->callee());
     auto object = TestNode::create();
-    return JSValue::encode(asObject(toJS(state, castedThis->globalObject(), WTFMove(object))));
+    return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object))));
 }
 
 template<> JSValue JSTestNodeConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
@@ -234,5 +234,45 @@
     thisObject->wrapped().visitJSEventListeners(visitor);
 }
 
+#if ENABLE(BINDING_INTEGRITY)
+#if PLATFORM(WIN)
+#pragma warning(disable: 4483)
+extern "C" { extern void (*const __identifier("??_7TestNode@WebCore@@6B@")[])(); }
+#else
+extern "C" { extern void* _ZTVN7WebCore8TestNodeE[]; }
+#endif
+#endif
 
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<TestNode>&& impl)
+{
+    return createNewWrapper<JSTestNode>(globalObject, WTFMove(impl));
 }
+
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject* globalObject, TestNode& impl)
+{
+    if (JSValue result = getExistingWrapper<JSTestNode>(globalObject, impl))
+        return result;
+
+#if ENABLE(BINDING_INTEGRITY)
+    void* actualVTablePointer = *(reinterpret_cast<void**>(&impl));
+#if PLATFORM(WIN)
+    void* expectedVTablePointer = reinterpret_cast<void*>(__identifier("??_7TestNode@WebCore@@6B@"));
+#else
+    void* expectedVTablePointer = &_ZTVN7WebCore8TestNodeE[2];
+#if COMPILER(CLANG)
+    // If this fails TestNode does not have a vtable, so you need to add the
+    // ImplementationLacksVTable attribute to the interface definition
+    static_assert(__is_polymorphic(TestNode), "TestNode is not polymorphic");
+#endif
+#endif
+    // If you hit this assertion you either have a use after free bug, or
+    // TestNode has subclasses. If TestNode has subclasses that get passed
+    // to toJS() we currently require TestNode you to opt out of binding hardening
+    // by adding the SkipVTableValidation attribute to the interface IDL definition
+    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
+#endif
+    return createNewWrapper<JSTestNode, TestNode>(globalObject, impl);
+}
+
+
+}

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.h (201127 => 201128)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.h	2016-05-19 05:20:03 UTC (rev 201127)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.h	2016-05-19 07:14:45 UTC (rev 201128)
@@ -65,6 +65,10 @@
 
 };
 
+WEBCORE_TESTSUPPORT_EXPORT JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestNode&);
+inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestNode* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject*, Ref<TestNode>&&);
+inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* state, JSDOMGlobalObject* globalObject, RefPtr<TestNode>&& impl) { return impl ? toJSNewlyCreated(state, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
 
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (201127 => 201128)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-05-19 05:20:03 UTC (rev 201127)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-05-19 07:14:45 UTC (rev 201128)
@@ -1024,7 +1024,7 @@
         return throwArgumentMustBeFunctionError(*state, 1, "testCallbackFunction", "TestObj", nullptr);
     RefPtr<TestCallbackFunction> testCallbackFunction = JSTestCallbackFunction::create(asObject(state->uncheckedArgument(1)), castedThis->globalObject());
     auto object = TestObj::create(*testCallback, *testCallbackFunction);
-    return JSValue::encode(asObject(toJS(state, castedThis->globalObject(), WTFMove(object))));
+    return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object))));
 }
 
 template<> JSValue JSTestObjConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp (201127 => 201128)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp	2016-05-19 05:20:03 UTC (rev 201127)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp	2016-05-19 07:14:45 UTC (rev 201128)
@@ -76,7 +76,7 @@
     if (UNLIKELY(!arrayBuffer))
         return throwArgumentTypeError(*state, 0, "arrayBuffer", "TestOverloadedConstructors", nullptr, "ArrayBuffer");
     auto object = TestOverloadedConstructors::create(*arrayBuffer);
-    return JSValue::encode(asObject(toJS(state, castedThis->globalObject(), WTFMove(object))));
+    return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object))));
 }
 
 static inline EncodedJSValue constructJSTestOverloadedConstructors2(ExecState* state)
@@ -90,7 +90,7 @@
     if (UNLIKELY(!arrayBufferView))
         return throwArgumentTypeError(*state, 0, "arrayBufferView", "TestOverloadedConstructors", nullptr, "ArrayBufferView");
     auto object = TestOverloadedConstructors::create(*arrayBufferView);
-    return JSValue::encode(asObject(toJS(state, castedThis->globalObject(), WTFMove(object))));
+    return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object))));
 }
 
 static inline EncodedJSValue constructJSTestOverloadedConstructors3(ExecState* state)
@@ -102,7 +102,7 @@
     if (UNLIKELY(!blob))
         return throwArgumentTypeError(*state, 0, "blob", "TestOverloadedConstructors", nullptr, "Blob");
     auto object = TestOverloadedConstructors::create(*blob);
-    return JSValue::encode(asObject(toJS(state, castedThis->globalObject(), WTFMove(object))));
+    return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object))));
 }
 
 static inline EncodedJSValue constructJSTestOverloadedConstructors4(ExecState* state)
@@ -114,7 +114,7 @@
     if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
     auto object = TestOverloadedConstructors::create(string);
-    return JSValue::encode(asObject(toJS(state, castedThis->globalObject(), WTFMove(object))));
+    return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object))));
 }
 
 static inline EncodedJSValue constructJSTestOverloadedConstructors5(ExecState* state)
@@ -124,7 +124,7 @@
     if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
     auto object = TestOverloadedConstructors::create(longArgs);
-    return JSValue::encode(asObject(toJS(state, castedThis->globalObject(), WTFMove(object))));
+    return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object))));
 }
 
 template<> EncodedJSValue JSC_HOST_CALL JSTestOverloadedConstructorsConstructor::construct(ExecState* state)

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestTypedefs.cpp (201127 => 201128)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestTypedefs.cpp	2016-05-19 05:20:03 UTC (rev 201127)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestTypedefs.cpp	2016-05-19 07:14:45 UTC (rev 201128)
@@ -136,7 +136,7 @@
         return throwArgumentMustBeFunctionError(*state, 1, "testCallback", "TestTypedefs", nullptr);
     RefPtr<TestCallback> testCallback = JSTestCallback::create(asObject(state->uncheckedArgument(1)), castedThis->globalObject());
     auto object = TestTypedefs::create(hello, *testCallback);
-    return JSValue::encode(asObject(toJS(state, castedThis->globalObject(), WTFMove(object))));
+    return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object))));
 }
 
 template<> JSValue JSTestTypedefsConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to