Make JavaScript binding get and set legacy event listener attributes directly
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Mar 2015 17:30:32 +0000 (17:30 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Mar 2015 17:30:32 +0000 (17:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=142282

Reviewed by Sam Weinig.

Test: fast/dom/legacy-event-handler-attributes.html

This patch changes the JavaScript getters and setters for these attributes
to work directly without requiring any functions in the C++ DOM implementation.
A subsequent patch will remove the now-unused C++ DOM implementation.

* bindings/js/JSEventListener.cpp:
(WebCore::legacyEventListenerAttribute): Added.
(WebCore::createEventListenerForLegacyAttribute): Added.
(WebCore::setLegacyEventListenerAttribute): Added.
(WebCore::legacyWindowEventListenerAttribute): Added.
(WebCore::setLegacyWindowEventListenerAttribute): Added.

* bindings/js/JSEventListener.h:
(WebCore::createJSEventListenerForAttribute): Deleted.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateAttributeEventListenerCall): Deleted.
(LegacyEventListenerAttributeEventName): Added.
(LegacyEventListenerAttributePrefix): Added.
(GenerateImplementation): Use "auto" in lots of places to simplify the code
generation. Replaced the old inlined code to deal with legacy event listener
attributes with code that simply calls the new functions from JSEventLister.h.
(GenerateCallWith): Use "auto".
(GenerateConstructorDefinition): Ditto.

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

Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSEventListener.cpp
Source/WebCore/bindings/js/JSEventListener.h
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

index 4d444cc3036e3748eb3b8bc39ec82d52fcc05b70..5173a5ef71bac2ee440dfed263a57f96f79c1e01 100644 (file)
@@ -1,3 +1,36 @@
+2015-03-04  Darin Adler  <darin@apple.com>
+
+        Make JavaScript binding get and set legacy event listener attributes directly
+        https://bugs.webkit.org/show_bug.cgi?id=142282
+
+        Reviewed by Sam Weinig.
+
+        Test: fast/dom/legacy-event-handler-attributes.html
+
+        This patch changes the JavaScript getters and setters for these attributes
+        to work directly without requiring any functions in the C++ DOM implementation.
+        A subsequent patch will remove the now-unused C++ DOM implementation.
+
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::legacyEventListenerAttribute): Added.
+        (WebCore::createEventListenerForLegacyAttribute): Added.
+        (WebCore::setLegacyEventListenerAttribute): Added.
+        (WebCore::legacyWindowEventListenerAttribute): Added.
+        (WebCore::setLegacyWindowEventListenerAttribute): Added.
+
+        * bindings/js/JSEventListener.h:
+        (WebCore::createJSEventListenerForAttribute): Deleted.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateAttributeEventListenerCall): Deleted.
+        (LegacyEventListenerAttributeEventName): Added.
+        (LegacyEventListenerAttributePrefix): Added.
+        (GenerateImplementation): Use "auto" in lots of places to simplify the code
+        generation. Replaced the old inlined code to deal with legacy event listener
+        attributes with code that simply calls the new functions from JSEventLister.h.
+        (GenerateCallWith): Use "auto".
+        (GenerateConstructorDefinition): Ditto.
+
 2015-03-03  Sam Weinig  <sam@webkit.org>
 
         [Content Extensions] Split parsing and compiling of content extensions into their own files
index a2cf268dd664f66ab8fc6a7d064bd2c0d07c1f88..959b2366743d79f63b0aac1bac812bd1bfd548cb 100644 (file)
@@ -23,6 +23,7 @@
 #include "BeforeUnloadEvent.h"
 #include "Event.h"
 #include "Frame.h"
+#include "HTMLElement.h"
 #include "JSEvent.h"
 #include "JSEventTarget.h"
 #include "JSMainThreadExecState.h"
@@ -170,4 +171,49 @@ Ref<JSEventListener> createJSEventListenerForAdd(JSC::ExecState& state, JSC::JSO
     return JSEventListener::create(&listener, &wrapper, false, currentWorld(&state));
 }
 
+static inline JSC::JSValue eventHandlerAttribute(EventListener* abstractListener, ScriptExecutionContext& context)
+{
+    if (!abstractListener)
+        return jsNull();
+
+    auto* listener = JSEventListener::cast(abstractListener);
+    if (!listener)
+        return jsNull();
+
+    auto* function = listener->jsFunction(&context);
+    if (!function)
+        return jsNull();
+
+    return function;
+}
+
+static inline RefPtr<JSEventListener> createEventListenerForEventHandlerAttribute(JSC::ExecState& state, JSC::JSValue listener, JSC::JSObject& wrapper)
+{
+    if (!listener.isObject())
+        return nullptr;
+    return JSEventListener::create(asObject(listener), &wrapper, true, currentWorld(&state));
+}
+
+JSC::JSValue eventHandlerAttribute(EventTarget& target, const AtomicString& eventType)
+{
+    return eventHandlerAttribute(target.getAttributeEventListener(eventType), *target.scriptExecutionContext());
+}
+
+void setEventHandlerAttribute(JSC::ExecState& state, JSC::JSObject& wrapper, EventTarget& target, const AtomicString& eventType, JSC::JSValue value)
+{
+    target.setAttributeEventListener(eventType, createEventListenerForEventHandlerAttribute(state, value, wrapper));
+}
+
+JSC::JSValue windowForwardedEventHandlerAttribute(HTMLElement& element, const AtomicString& eventType)
+{
+    auto& document = element.document();
+    return eventHandlerAttribute(document.getWindowAttributeEventListener(eventType), document);
+}
+
+void setWindowForwardedEventHandlerAttribute(JSC::ExecState& state, JSC::JSObject& wrapper, HTMLElement& element, const AtomicString& eventType, JSC::JSValue value)
+{
+    ASSERT(wrapper.globalObject());
+    element.document().setWindowAttributeEventListener(eventType, createEventListenerForEventHandlerAttribute(state, value, *wrapper.globalObject()));
+}
+
 } // namespace WebCore
index 1bcb96eef1fa001186cd8cd60743651f6e9d8fcc..ce3f923d7826a4e3be5179746c875c736e9a438c 100644 (file)
@@ -29,6 +29,8 @@
 
 namespace WebCore {
 
+    class EventTarget;
+    class HTMLElement;
     class JSDOMGlobalObject;
 
     class JSEventListener : public EventListener {
@@ -75,8 +77,13 @@ namespace WebCore {
         RefPtr<DOMWrapperWorld> m_isolatedWorld;
     };
 
-    // For "onXXX" event attributes.
-    RefPtr<JSEventListener> createJSEventListenerForAttribute(JSC::ExecState&, JSC::JSValue listener, JSC::JSObject& wrapper);
+    // For "onxxx" attributes that automatically set up JavaScript event listeners.
+    JSC::JSValue eventHandlerAttribute(EventTarget&, const AtomicString& eventType);
+    void setEventHandlerAttribute(JSC::ExecState&, JSC::JSObject&, EventTarget&, const AtomicString& eventType, JSC::JSValue);
+
+    // Like the functions above, but for attributes that forward event handlers to the window object rather than setting them on the target.
+    JSC::JSValue windowForwardedEventHandlerAttribute(HTMLElement&, const AtomicString& eventType);
+    void setWindowForwardedEventHandlerAttribute(JSC::ExecState&, JSC::JSObject&, HTMLElement&, const AtomicString& eventType, JSC::JSValue);
 
     Ref<JSEventListener> createJSEventListenerForAdd(JSC::ExecState&, JSC::JSObject& listener, JSC::JSObject& wrapper);
     Ref<JSEventListener> createJSEventListenerForRemove(JSC::ExecState&, JSC::JSObject& listener, JSC::JSObject& wrapper);
@@ -112,13 +119,6 @@ namespace WebCore {
         return m_jsFunction.get();
     }
 
-    inline RefPtr<JSEventListener> createJSEventListenerForAttribute(JSC::ExecState& state, JSC::JSValue listener, JSC::JSObject& wrapper)
-    {
-        if (!listener.isObject())
-            return nullptr;
-        return JSEventListener::create(asObject(listener), &wrapper, true, currentWorld(&state));
-    }
-
     inline Ref<JSEventListener> createJSEventListenerForRemove(JSC::ExecState& state, JSC::JSObject& listener, JSC::JSObject& wrapper)
     {
         return createJSEventListenerForAdd(state, listener, wrapper);
index ffcfd967b1ad5f9e0959a1d1463001e3deca9aa6..a0c8a68c4fa8ef49053f572ebcf8b7977a9abaa6 100644 (file)
@@ -140,16 +140,21 @@ sub GenerateInterface
     }
 }
 
-sub GenerateAttributeEventListenerCall
+sub EventHandlerAttributeEventName
 {
-    my $implSetterFunctionName = shift;
-    my $windowEventListener = shift;
+    my $attribute = shift;
 
-    my $wrapperObject = $windowEventListener ? "globalObject" : "castedThis";
-    my @GenerateEventListenerImpl = ();
+    # Remove the "on" prefix.
+    my $eventType = substr($attribute->signature->name, 2);
 
-    push(@GenerateEventListenerImpl, "    impl.set$implSetterFunctionName(createJSEventListenerForAttribute(*exec, value, *$wrapperObject));\n");
-    return @GenerateEventListenerImpl;
+    # FIXME: Consider adding a property in the IDL file instead of hard coding these four event names.
+    # Note: This same hard coded list of property names exists in HTMLElement.cpp.
+    $eventType = "webkitAnimationEnd" if $eventType eq "webkitanimationend";
+    $eventType = "webkitAnimationIteration" if $eventType eq "webkitanimationiteration";
+    $eventType = "webkitAnimationStart" if $eventType eq "webkitanimationstart";
+    $eventType = "webkitTransitionEnd" if $eventType eq "webkittransitionend";
+
+    return "eventNames().${eventType}Event";
 }
 
 sub GenerateEventListenerCall
@@ -1969,7 +1974,7 @@ sub GenerateImplementation
             push(@implContent, "{\n");
             push(@implContent, "    VM& vm = exec->vm();\n");
             push(@implContent, "    UNUSED_PARAM(vm);\n");
-            push(@implContent, "    ${className}Prototype* thisObject = jsCast<${className}Prototype*>(object);\n");
+            push(@implContent, "    auto* thisObject = jsCast<${className}Prototype*>(object);\n");
 
             if ($numConstants eq 0 && $numFunctions eq 0 && $numPrototypeAttributes eq 0) {
                 push(@implContent, "    return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);\n");        
@@ -2012,7 +2017,7 @@ sub GenerateImplementation
     if ($interface->extendedAttributes->{"JSCustomNamedGetterOnPrototype"}) {
         push(@implContent, "void ${className}Prototype::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)\n");
         push(@implContent, "{\n");
-        push(@implContent, "    ${className}Prototype* thisObject = jsCast<${className}Prototype*>(cell);\n");
+        push(@implContent, "    auto* thisObject = jsCast<${className}Prototype*>(cell);\n");
         push(@implContent, "    if (thisObject->putDelegate(exec, propertyName, value, slot))\n");
         push(@implContent, "        return;\n");
         push(@implContent, "    Base::put(thisObject, exec, propertyName, value, slot);\n");
@@ -2106,7 +2111,7 @@ sub GenerateImplementation
         if (!$interface->extendedAttributes->{"CustomGetOwnPropertySlot"}) {
             push(@implContent, "bool ${className}::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)\n");
             push(@implContent, "{\n");
-            push(@implContent, "    ${className}* thisObject = jsCast<${className}*>(object);\n");
+            push(@implContent, "    auto* thisObject = jsCast<${className}*>(object);\n");
             push(@implContent, "    ASSERT_GC_OBJECT_INHERITS(thisObject, info());\n");
             push(@implContent, GenerateGetOwnPropertySlotBody($interface, $interfaceName, $className, $numInstanceAttributes > 0, 0));
             push(@implContent, "}\n\n");
@@ -2117,7 +2122,7 @@ sub GenerateImplementation
                 || $interface->extendedAttributes->{"JSCustomGetOwnPropertySlotAndDescriptor"}) {
             push(@implContent, "bool ${className}::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned index, PropertySlot& slot)\n");
             push(@implContent, "{\n");
-            push(@implContent, "    ${className}* thisObject = jsCast<${className}*>(object);\n");
+            push(@implContent, "    auto* thisObject = jsCast<${className}*>(object);\n");
             push(@implContent, "    ASSERT_GC_OBJECT_INHERITS(thisObject, info());\n");
 
             # Sink the int-to-string conversion that happens when we create a PropertyName
@@ -2190,9 +2195,9 @@ sub GenerateImplementation
             push(@implContent, "    UNUSED_PARAM(thisValue);\n");
             if (!$attribute->isStatic || $attribute->signature->type =~ /Constructor$/) {
                 if ($interface->extendedAttributes->{"CustomProxyToJSObject"}) {
-                    push(@implContent, "    ${className}* castedThis = to${className}(JSValue::decode(thisValue));\n");
+                    push(@implContent, "    auto* castedThis = to${className}(JSValue::decode(thisValue));\n");
                 } elsif (AttributeShouldBeOnInstance($interface, $attribute)) {
-                    push(@implContent, "    ${className}* castedThis = jsCast<JS${interfaceName}*>(slotBase);\n");
+                    push(@implContent, "    auto* castedThis = jsCast<JS${interfaceName}*>(slotBase);\n");
                     if (InterfaceRequiresAttributesOnInstanceForCompatibility($interface)) {
                         push(@implContent, "    ${className}* castedThisObject = " . GetCastingHelperForThisObject($interface) . "(JSValue::decode(thisValue));\n");
                         push(@implContent, "    if (UNLIKELY(!castedThisObject))\n");
@@ -2283,23 +2288,13 @@ sub GenerateImplementation
                 push(@implContent, "    return JSValue::encode(castedThis->$implGetterFunctionName(exec));\n");
             } elsif ($attribute->signature->extendedAttributes->{"CheckSecurityForNode"}) {
                 $implIncludes{"JSDOMBinding.h"} = 1;
-                push(@implContent, "    $implType& impl = castedThis->impl();\n");
+                push(@implContent, "    auto& impl = castedThis->impl();\n");
                 push(@implContent, "    return JSValue::encode(shouldAllowAccessToNode(exec, impl." . $attribute->signature->name . "()) ? " . NativeToJSValue($attribute->signature, 0, $interfaceName, "impl.$implGetterFunctionName()", "castedThis") . " : jsNull());\n");
             } elsif ($type eq "EventListener") {
-                $implIncludes{"EventListener.h"} = 1;
+                my $getter = $attribute->signature->extendedAttributes->{"JSWindowEventListener"} ? "windowForwardedEventHandlerAttribute" : "eventHandlerAttribute";
+                my $eventName = EventHandlerAttributeEventName($attribute);
                 push(@implContent, "    UNUSED_PARAM(exec);\n");
-                push(@implContent, "    $implType& impl = castedThis->impl();\n");
-                push(@implContent, "    if (EventListener* listener = impl.$implGetterFunctionName()) {\n");
-                push(@implContent, "        if (const JSEventListener* jsListener = JSEventListener::cast(listener)) {\n");
-                if ($interfaceName eq "Document" || $codeGenerator->InheritsInterface($interface, "WorkerGlobalScope")) {
-                    push(@implContent, "            if (JSObject* jsFunction = jsListener->jsFunction(&impl))\n");
-                } else {
-                    push(@implContent, "            if (JSObject* jsFunction = jsListener->jsFunction(impl.scriptExecutionContext()))\n");
-                }
-                push(@implContent, "                return JSValue::encode(jsFunction);\n");
-                push(@implContent, "        }\n");
-                push(@implContent, "    }\n");
-                push(@implContent, "    return JSValue::encode(jsNull());\n");
+                push(@implContent, "    return JSValue::encode($getter(castedThis->impl(), $eventName));\n");
             } elsif ($attribute->signature->type =~ /Constructor$/) {
                 my $constructorType = $attribute->signature->type;
                 $constructorType =~ s/Constructor$//;
@@ -2352,7 +2347,7 @@ sub GenerateImplementation
 
                     unshift(@arguments, @callWithArgs);
                     my $jsType = NativeToJSValue($attribute->signature, 0, $interfaceName, "${functionName}(" . join(", ", @arguments) . ")", "castedThis");
-                    push(@implContent, "    $implType& impl = castedThis->impl();\n") if !$attribute->isStatic;
+                    push(@implContent, "    auto& impl = castedThis->impl();\n") if !$attribute->isStatic;
                     if ($codeGenerator->IsSVGAnimatedType($type)) {
                         push(@implContent, "    RefPtr<$type> obj = $jsType;\n");
                         push(@implContent, "    JSValue result = toJS(exec, castedThis->globalObject(), obj.get());\n");
@@ -2381,7 +2376,7 @@ sub GenerateImplementation
                     push(@implContent, "    $svgPropertyOrListPropertyType impl(*castedThis->impl());\n");
                     push(@implContent, "    JSValue result = " . NativeToJSValue($attribute->signature, 0, $interfaceName, "impl.$implGetterFunctionName(" . join(", ", @arguments) . ")", "castedThis") . ";\n");
                 } else {
-                    push(@implContent, "    $implType& impl = castedThis->impl();\n");
+                    push(@implContent, "    auto& impl = castedThis->impl();\n");
                     push(@implContent, "    JSValue result = " . NativeToJSValue($attribute->signature, 0, $interfaceName, "impl.$implGetterFunctionName(" . join(", ", @arguments) . ")", "castedThis") . ";\n");
                 }
 
@@ -2472,7 +2467,7 @@ sub GenerateImplementation
         if (!$interface->extendedAttributes->{"CustomPutFunction"}) {
             push(@implContent, "void ${className}::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)\n");
             push(@implContent, "{\n");
-            push(@implContent, "    ${className}* thisObject = jsCast<${className}*>(cell);\n");
+            push(@implContent, "    auto* thisObject = jsCast<${className}*>(cell);\n");
             push(@implContent, "    ASSERT_GC_OBJECT_INHERITS(thisObject, info());\n");
             if ($interface->extendedAttributes->{"CustomIndexedSetter"}) {
                 push(@implContent, "    unsigned index = propertyName.asIndex();\n");
@@ -2492,7 +2487,7 @@ sub GenerateImplementation
             if ($interface->extendedAttributes->{"CustomIndexedSetter"} || $interface->extendedAttributes->{"CustomNamedSetter"}) {
                 push(@implContent, "void ${className}::putByIndex(JSCell* cell, ExecState* exec, unsigned index, JSValue value, bool shouldThrow)\n");
                 push(@implContent, "{\n");
-                push(@implContent, "    ${className}* thisObject = jsCast<${className}*>(cell);\n");
+                push(@implContent, "    auto* thisObject = jsCast<${className}*>(cell);\n");
                 push(@implContent, "    ASSERT_GC_OBJECT_INHERITS(thisObject, info());\n");
 
                 if ($interface->extendedAttributes->{"CustomIndexedSetter"}) {
@@ -2548,7 +2543,7 @@ sub GenerateImplementation
                         push(@implContent, "    ${className}* castedThis = to${className}(JSValue::decode(thisValue));\n");
                     } elsif (AttributeShouldBeOnInstance($interface, $attribute)) {
                         push(@implContent, "    UNUSED_PARAM(thisValue);\n");
-                        push(@implContent, "    ${className}* castedThis = jsCast<JS${interfaceName}*>(baseObject);\n");
+                        push(@implContent, "    auto* castedThis = jsCast<JS${interfaceName}*>(baseObject);\n");
                         if (InterfaceRequiresAttributesOnInstanceForCompatibility($interface)) {
                             push(@implContent, "    ${className}* castedThisObject = " . GetCastingHelperForThisObject($interface) . "(JSValue::decode(thisValue));\n");
                             push(@implContent, "    if (UNLIKELY(!castedThisObject))\n");
@@ -2580,18 +2575,15 @@ sub GenerateImplementation
                 if (HasCustomSetter($attribute->signature->extendedAttributes)) {
                     push(@implContent, "    castedThis->set$implSetterFunctionName(exec, value);\n");
                 } elsif ($type eq "EventListener") {
-                    $implIncludes{"JSEventListener.h"} = 1;
-                    push(@implContent, "    UNUSED_PARAM(exec);\n");
-                    my $windowEventListener = $attribute->signature->extendedAttributes->{"JSWindowEventListener"};
-                    if ($windowEventListener) {
-                        push(@implContent, "    JSDOMGlobalObject* globalObject = castedThis->globalObject();\n");
-                    }
-                    push(@implContent, "    $implType& impl = castedThis->impl();\n");
+                    my $eventName = EventHandlerAttributeEventName($attribute);
+                    # FIXME: Find a way to do this special case without hardcoding the class and attribute names here.
                     if ((($interfaceName eq "DOMWindow") or ($interfaceName eq "WorkerGlobalScope")) and $name eq "onerror") {
                         $implIncludes{"JSErrorHandler.h"} = 1;
-                        push(@implContent, "    impl.set$implSetterFunctionName(createJSErrorHandler(exec, value, castedThis));\n");
+                        push(@implContent, "    castedThis->impl().setAttributeEventListener($eventName, createJSErrorHandler(exec, value, castedThis));\n");
                     } else {
-                        push(@implContent, GenerateAttributeEventListenerCall($implSetterFunctionName, $windowEventListener));
+                        $implIncludes{"JSEventListener.h"} = 1;
+                        my $setter = $attribute->signature->extendedAttributes->{"JSWindowEventListener"} ? "setWindowForwardedEventHandlerAttribute" : "setEventHandlerAttribute";
+                        push(@implContent, "    $setter(*exec, *castedThis, castedThis->impl(), $eventName, value);\n");
                     }
                 } elsif ($attribute->signature->type =~ /Constructor$/) {
                     my $constructorType = $attribute->signature->type;
@@ -2602,14 +2594,14 @@ sub GenerateImplementation
                     if ($constructorType ne "any" and $constructorType !~ /Named$/) {
                         AddToImplIncludes("JS" . $constructorType . ".h", $attribute->signature->extendedAttributes->{"Conditional"});
                     }
-                    push(@implContent, "    // Shadowing a built-in constructor\n");
+                    push(@implContent, "    // Shadowing a built-in constructor.\n");
                     push(@implContent, "    castedThis->putDirect(exec->vm(), Identifier(exec, \"$name\"), value);\n");
                 } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
-                    push(@implContent, "    // Shadowing a built-in object\n");
+                    push(@implContent, "    // Shadowing a built-in object.\n");
                     push(@implContent, "    castedThis->putDirect(exec->vm(), Identifier(exec, \"$name\"), value);\n");
                 } else {
                     if (!$attribute->isStatic) {
-                        push(@implContent, "    $implType& impl = castedThis->impl();\n");
+                        push(@implContent, "    auto& impl = castedThis->impl();\n");
                     }
                     push(@implContent, "    ExceptionCode ec = 0;\n") if $setterRaisesException;
 
@@ -2712,7 +2704,7 @@ sub GenerateImplementation
     if ($indexedGetterFunction && !$interface->extendedAttributes->{"CustomEnumerateProperty"}) {
         push(@implContent, "void ${className}::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)\n");
         push(@implContent, "{\n");
-        push(@implContent, "    ${className}* thisObject = jsCast<${className}*>(object);\n");
+        push(@implContent, "    auto* thisObject = jsCast<${className}*>(object);\n");
         push(@implContent, "    ASSERT_GC_OBJECT_INHERITS(thisObject, info());\n");
         push(@implContent, "    for (unsigned i = 0, count = thisObject->impl().length(); i < count; ++i)\n");
         push(@implContent, "        propertyNames.add(Identifier::from(exec, i));\n");
@@ -2819,7 +2811,7 @@ sub GenerateImplementation
                 if ($isCustom) {
                     push(@implContent, "    return JSValue::encode(castedThis->" . $functionImplementationName . "(exec));\n");
                 } else {
-                    push(@implContent, "    $implType& impl = castedThis->impl();\n");
+                    push(@implContent, "    auto& impl = castedThis->impl();\n");
                     if ($svgPropertyType) {
                         push(@implContent, "    if (impl.isReadOnly()) {\n");
                         push(@implContent, "        setDOMException(exec, NO_MODIFICATION_ALLOWED_ERR);\n");
@@ -2869,7 +2861,7 @@ sub GenerateImplementation
     if ($needsVisitChildren) {
         push(@implContent, "void ${className}::visitChildren(JSCell* cell, SlotVisitor& visitor)\n");
         push(@implContent, "{\n");
-        push(@implContent, "    ${className}* thisObject = jsCast<${className}*>(cell);\n");
+        push(@implContent, "    auto* thisObject = jsCast<${className}*>(cell);\n");
         push(@implContent, "    ASSERT_GC_OBJECT_INHERITS(thisObject, info());\n");
         push(@implContent, "    Base::visitChildren(thisObject, visitor);\n");
         if ($interface->extendedAttributes->{"EventTarget"} || $interface->name eq "EventTarget") {
@@ -2913,8 +2905,8 @@ sub GenerateImplementation
             push(@implContent, "}\n\n");
             push(@implContent, "EncodedJSValue ${className}::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)\n");
             push(@implContent, "{\n");
-            push(@implContent, "    ${className}* thisObj = jsCast<$className*>(slotBase);\n");
-            push(@implContent, "    return JSValue::encode(toJS(exec, thisObj->globalObject(), thisObj->impl().namedItem(propertyNameToAtomicString(propertyName))));\n");
+            push(@implContent, "    auto* thisObject = jsCast<$className*>(slotBase);\n");
+            push(@implContent, "    return JSValue::encode(toJS(exec, thisObject->globalObject(), thisObject->impl().namedItem(propertyNameToAtomicString(propertyName))));\n");
             push(@implContent, "}\n\n");
         }
     }
@@ -2944,14 +2936,14 @@ sub GenerateImplementation
         # check below the isObservable check.
         my $emittedJSCast = 0;
         if ($codeGenerator->InheritsExtendedAttribute($interface, "ActiveDOMObject")) {
-            push(@implContent, "    JS${interfaceName}* js${interfaceName} = jsCast<JS${interfaceName}*>(handle.slot()->asCell());\n");
+            push(@implContent, "    auto* js${interfaceName} = jsCast<JS${interfaceName}*>(handle.slot()->asCell());\n");
             $emittedJSCast = 1;
             push(@implContent, "    if (js${interfaceName}->impl().hasPendingActivity())\n");
             push(@implContent, "        return true;\n");
         }
         if ($codeGenerator->InheritsExtendedAttribute($interface, "EventTarget")) {
             if (!$emittedJSCast) {
-                push(@implContent, "    JS${interfaceName}* js${interfaceName} = jsCast<JS${interfaceName}*>(handle.slot()->asCell());\n");
+                push(@implContent, "    auto* js${interfaceName} = jsCast<JS${interfaceName}*>(handle.slot()->asCell());\n");
                 $emittedJSCast = 1;
             }
             push(@implContent, "    if (js${interfaceName}->impl().isFiringEventListeners())\n");
@@ -2959,7 +2951,7 @@ sub GenerateImplementation
         }
         if ($codeGenerator->InheritsInterface($interface, "Node")) {
             if (!$emittedJSCast) {
-                push(@implContent, "    JS${interfaceName}* js${interfaceName} = jsCast<JS${interfaceName}*>(handle.slot()->asCell());\n");
+                push(@implContent, "    auto* js${interfaceName} = jsCast<JS${interfaceName}*>(handle.slot()->asCell());\n");
                 $emittedJSCast = 1;
             }
             push(@implContent, "    if (JSNodeOwner::isReachableFromOpaqueRoots(handle, 0, visitor))\n");
@@ -2967,7 +2959,7 @@ sub GenerateImplementation
         }
         if (GetGenerateIsReachable($interface)) {
             if (!$emittedJSCast) {
-                push(@implContent, "    JS${interfaceName}* js${interfaceName} = jsCast<JS${interfaceName}*>(handle.slot()->asCell());\n");
+                push(@implContent, "    auto* js${interfaceName} = jsCast<JS${interfaceName}*>(handle.slot()->asCell());\n");
                 $emittedJSCast = 1;
             }
             push(@implContent, "    if (!isObservable(js${interfaceName}))\n");
@@ -3024,8 +3016,8 @@ sub GenerateImplementation
          $codeGenerator->InheritsExtendedAttribute($interface, "ActiveDOMObject"))) {
         push(@implContent, "void JS${interfaceName}Owner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)\n");
         push(@implContent, "{\n");
-        push(@implContent, "    JS${interfaceName}* js${interfaceName} = jsCast<JS${interfaceName}*>(handle.slot()->asCell());\n");
-        push(@implContent, "    DOMWrapperWorld& world = *static_cast<DOMWrapperWorld*>(context);\n");
+        push(@implContent, "    auto* js${interfaceName} = jsCast<JS${interfaceName}*>(handle.slot()->asCell());\n");
+        push(@implContent, "    auto& world = *static_cast<DOMWrapperWorld*>(context);\n");
         push(@implContent, "    uncacheWrapper(world, &js${interfaceName}->impl(), js${interfaceName});\n");
         push(@implContent, "    js${interfaceName}->releaseImpl();\n");
         push(@implContent, "}\n\n");
@@ -3132,7 +3124,7 @@ sub GenerateCallWith
         push(@callWithArgs, "exec");
     }
     if ($codeGenerator->ExtendedAttributeContains($callWith, "ScriptExecutionContext")) {
-        push(@$outputArray, "    ScriptExecutionContext* scriptContext = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext();\n");
+        push(@$outputArray, "    auto* scriptContext = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext();\n");
         push(@$outputArray, "    if (!scriptContext)\n");
         push(@$outputArray, "        return" . ($returnValue ? " " . $returnValue : "") . ";\n");
         push(@callWithArgs, "scriptContext");
@@ -4509,7 +4501,7 @@ sub GenerateConstructorDefinition
             push(@$outputArray, <<END);
 EncodedJSValue JSC_HOST_CALL ${constructorClassName}::construct${className}(ExecState* exec)
 {
-    ${constructorClassName}* jsConstructor = jsCast<${constructorClassName}*>(exec->callee());
+    auto* jsConstructor = jsCast<${constructorClassName}*>(exec->callee());
 
     ScriptExecutionContext* executionContext = jsConstructor->scriptExecutionContext();
     if (!executionContext)
@@ -4576,7 +4568,7 @@ END
 
             push(@$outputArray, "EncodedJSValue JSC_HOST_CALL ${constructorClassName}::construct${className}${overloadedIndexString}(ExecState* exec)\n");
             push(@$outputArray, "{\n");
-            push(@$outputArray, "    ${constructorClassName}* castedThis = jsCast<${constructorClassName}*>(exec->callee());\n");
+            push(@$outputArray, "    auto* castedThis = jsCast<${constructorClassName}*>(exec->callee());\n");
 
             my @constructorArgList;
 
@@ -4606,7 +4598,7 @@ END
                 push(@$outputArray, "    ScriptExecutionContext* context = castedThis->scriptExecutionContext();\n");
                 push(@$outputArray, "    if (!context)\n");
                 push(@$outputArray, "        return throwConstructorDocumentUnavailableError(*exec, \"${interfaceName}\");\n");
-                push(@$outputArray, "    Document& document = downcast<Document>(*context);\n");
+                push(@$outputArray, "    auto& document = downcast<Document>(*context);\n");
             }
             if ($generatingNamedConstructor) {
                 push(@constructorArgList, "*castedThis->document()");