The JSC code generator doesn't generate correct code for Constructors
authortommyw@google.com <tommyw@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Mar 2012 13:27:52 +0000 (13:27 +0000)
committertommyw@google.com <tommyw@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Mar 2012 13:27:52 +0000 (13:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=82046

Reviewed by Kentaro Hara.

The main bulk of generated code for constructors uses the name jsConstructor
for the created object, and then calls GenerateParametersCheck which generates
code that uses the name castedThis.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateConstructorDefinition):
* bindings/scripts/test/JS/JSTestInterface.cpp:
(WebCore::JSTestInterfaceConstructor::constructJSTestInterface):
* bindings/scripts/test/JS/JSTestNamedConstructor.cpp:
(WebCore::JSTestNamedConstructorNamedConstructor::constructJSTestNamedConstructor):
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::JSTestObjConstructor::finishCreation):
(WebCore::JSTestObjConstructor::constructJSTestObj):
* bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp:
(WebCore::JSTestSerializedScriptValueInterfaceConstructor::constructJSTestSerializedScriptValueInterface):
* bindings/scripts/test/TestObj.idl:
* bindings/scripts/test/V8/V8TestObj.cpp:
(WebCore::V8TestObj::constructorCallback):

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

Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestNamedConstructor.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp
Source/WebCore/bindings/scripts/test/TestObj.idl
Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp

index e0c3e21..ff9446c 100644 (file)
@@ -1,5 +1,31 @@
 2012-03-23  Tommy Widenflycht  <tommyw@google.com>
 
+        The JSC code generator doesn't generate correct code for Constructors
+        https://bugs.webkit.org/show_bug.cgi?id=82046
+
+        Reviewed by Kentaro Hara.
+
+        The main bulk of generated code for constructors uses the name jsConstructor
+        for the created object, and then calls GenerateParametersCheck which generates
+        code that uses the name castedThis.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateConstructorDefinition):
+        * bindings/scripts/test/JS/JSTestInterface.cpp:
+        (WebCore::JSTestInterfaceConstructor::constructJSTestInterface):
+        * bindings/scripts/test/JS/JSTestNamedConstructor.cpp:
+        (WebCore::JSTestNamedConstructorNamedConstructor::constructJSTestNamedConstructor):
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        (WebCore::JSTestObjConstructor::finishCreation):
+        (WebCore::JSTestObjConstructor::constructJSTestObj):
+        * bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp:
+        (WebCore::JSTestSerializedScriptValueInterfaceConstructor::constructJSTestSerializedScriptValueInterface):
+        * bindings/scripts/test/TestObj.idl:
+        * bindings/scripts/test/V8/V8TestObj.cpp:
+        (WebCore::V8TestObj::constructorCallback):
+
+2012-03-23  Tommy Widenflycht  <tommyw@google.com>
+
         The JSC code generator can't handle boolean arguments for Callbacks
         https://bugs.webkit.org/show_bug.cgi?id=82045
 
index 465915b..f6e486c 100644 (file)
@@ -3569,7 +3569,7 @@ END
             push(@$outputArray, "EncodedJSValue JSC_HOST_CALL ${constructorClassName}::construct${className}(ExecState* exec)\n");
             push(@$outputArray, "{\n");
 
-            push(@$outputArray, "    ${constructorClassName}* jsConstructor = static_cast<${constructorClassName}*>(exec->callee());\n");
+            push(@$outputArray, "    ${constructorClassName}* castedThis = static_cast<${constructorClassName}*>(exec->callee());\n");
 
             my $function = $dataNode->constructor;
             my @constructorArgList;
@@ -3591,12 +3591,12 @@ END
 
             if ($codeGenerator->ExtendedAttributeContains($dataNode->extendedAttributes->{"CallWith"}, "ScriptExecutionContext")) {
                 push(@constructorArgList, "context");
-                push(@$outputArray, "    ScriptExecutionContext* context = jsConstructor->scriptExecutionContext();\n");
+                push(@$outputArray, "    ScriptExecutionContext* context = castedThis->scriptExecutionContext();\n");
                 push(@$outputArray, "    if (!context)\n");
                 push(@$outputArray, "        return throwVMError(exec, createReferenceError(exec, \"${interfaceName} constructor associated document is unavailable\"));\n");
             }
             if ($generatingNamedConstructor) {
-                push(@constructorArgList, "jsConstructor->document()");
+                push(@constructorArgList, "castedThis->document()");
             }
 
             my $index = 0;
@@ -3623,7 +3623,7 @@ END
                 push(@$outputArray, "    }\n");
             }
 
-            push(@$outputArray, "    return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), object.get())));\n");
+            push(@$outputArray, "    return JSValue::encode(asObject(toJS(exec, castedThis->globalObject(), object.get())));\n");
             push(@$outputArray, "}\n\n");
         }
 
index c3888e8..c464d4a 100644 (file)
@@ -122,7 +122,7 @@ bool JSTestInterfaceConstructor::getOwnPropertyDescriptor(JSObject* object, Exec
 
 EncodedJSValue JSC_HOST_CALL JSTestInterfaceConstructor::constructJSTestInterface(ExecState* exec)
 {
-    JSTestInterfaceConstructor* jsConstructor = static_cast<JSTestInterfaceConstructor*>(exec->callee());
+    JSTestInterfaceConstructor* castedThis = static_cast<JSTestInterfaceConstructor*>(exec->callee());
     if (exec->argumentCount() < 1)
         return throwVMError(exec, createTypeError(exec, "Not enough arguments"));
     ExceptionCode ec = 0;
@@ -132,7 +132,7 @@ EncodedJSValue JSC_HOST_CALL JSTestInterfaceConstructor::constructJSTestInterfac
     const String& str2(ustringToString(MAYBE_MISSING_PARAMETER(exec, 1, DefaultIsUndefined).isEmpty() ? UString() : MAYBE_MISSING_PARAMETER(exec, 1, DefaultIsUndefined).toString(exec)->value(exec)));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
-    ScriptExecutionContext* context = jsConstructor->scriptExecutionContext();
+    ScriptExecutionContext* context = castedThis->scriptExecutionContext();
     if (!context)
         return throwVMError(exec, createReferenceError(exec, "TestInterface constructor associated document is unavailable"));
     RefPtr<TestInterface> object = TestInterface::create(context, str1, str2, ec);
@@ -140,7 +140,7 @@ EncodedJSValue JSC_HOST_CALL JSTestInterfaceConstructor::constructJSTestInterfac
         setDOMException(exec, ec);
         return JSValue::encode(JSValue());
     }
-    return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), object.get())));
+    return JSValue::encode(asObject(toJS(exec, castedThis->globalObject(), object.get())));
 }
 
 ConstructType JSTestInterfaceConstructor::getConstructData(JSCell*, ConstructData& constructData)
index 225208d..2125604 100644 (file)
@@ -89,7 +89,7 @@ void JSTestNamedConstructorNamedConstructor::finishCreation(ExecState* exec, JSD
 
 EncodedJSValue JSC_HOST_CALL JSTestNamedConstructorNamedConstructor::constructJSTestNamedConstructor(ExecState* exec)
 {
-    JSTestNamedConstructorNamedConstructor* jsConstructor = static_cast<JSTestNamedConstructorNamedConstructor*>(exec->callee());
+    JSTestNamedConstructorNamedConstructor* castedThis = static_cast<JSTestNamedConstructorNamedConstructor*>(exec->callee());
     if (exec->argumentCount() < 1)
         return throwVMError(exec, createTypeError(exec, "Not enough arguments"));
     ExceptionCode ec = 0;
@@ -102,12 +102,12 @@ EncodedJSValue JSC_HOST_CALL JSTestNamedConstructorNamedConstructor::constructJS
     const String& str3(ustringToString(MAYBE_MISSING_PARAMETER(exec, 2, DefaultIsNullString).isEmpty() ? UString() : MAYBE_MISSING_PARAMETER(exec, 2, DefaultIsNullString).toString(exec)->value(exec)));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
-    RefPtr<TestNamedConstructor> object = TestNamedConstructor::createForJSConstructor(jsConstructor->document(), str1, str2, str3, ec);
+    RefPtr<TestNamedConstructor> object = TestNamedConstructor::createForJSConstructor(castedThis->document(), str1, str2, str3, ec);
     if (ec) {
         setDOMException(exec, ec);
         return JSValue::encode(JSValue());
     }
-    return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), object.get())));
+    return JSValue::encode(asObject(toJS(exec, castedThis->globalObject(), object.get())));
 }
 
 ConstructType JSTestNamedConstructorNamedConstructor::getConstructData(JSCell*, ConstructData& constructData)
index 569392d..a5d1fab 100644 (file)
@@ -205,7 +205,7 @@ void JSTestObjConstructor::finishCreation(ExecState* exec, JSDOMGlobalObject* gl
     Base::finishCreation(exec->globalData());
     ASSERT(inherits(&s_info));
     putDirect(exec->globalData(), exec->propertyNames().prototype, JSTestObjPrototype::self(exec, globalObject), DontDelete | ReadOnly);
-    putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(0), ReadOnly | DontDelete | DontEnum);
+    putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
 }
 
 bool JSTestObjConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
@@ -220,9 +220,16 @@ bool JSTestObjConstructor::getOwnPropertyDescriptor(JSObject* object, ExecState*
 
 EncodedJSValue JSC_HOST_CALL JSTestObjConstructor::constructJSTestObj(ExecState* exec)
 {
-    JSTestObjConstructor* jsConstructor = static_cast<JSTestObjConstructor*>(exec->callee());
-    RefPtr<TestObj> object = TestObj::create();
-    return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), object.get())));
+    JSTestObjConstructor* castedThis = static_cast<JSTestObjConstructor*>(exec->callee());
+    if (exec->argumentCount() < 1)
+        return throwVMError(exec, createTypeError(exec, "Not enough arguments"));
+    if (exec->argumentCount() <= 0 || !exec->argument(0).isFunction()) {
+        setDOMException(exec, TYPE_MISMATCH_ERR);
+        return JSValue::encode(jsUndefined());
+    }
+    RefPtr<TestCallback> testCallback = JSTestCallback::create(asObject(exec->argument(0)), castedThis->globalObject());
+    RefPtr<TestObj> object = TestObj::create(testCallback);
+    return JSValue::encode(asObject(toJS(exec, castedThis->globalObject(), object.get())));
 }
 
 ConstructType JSTestObjConstructor::getConstructData(JSCell*, ConstructData& constructData)
index 32e44d5..9db6ea6 100644 (file)
@@ -85,7 +85,7 @@ bool JSTestSerializedScriptValueInterfaceConstructor::getOwnPropertyDescriptor(J
 
 EncodedJSValue JSC_HOST_CALL JSTestSerializedScriptValueInterfaceConstructor::constructJSTestSerializedScriptValueInterface(ExecState* exec)
 {
-    JSTestSerializedScriptValueInterfaceConstructor* jsConstructor = static_cast<JSTestSerializedScriptValueInterfaceConstructor*>(exec->callee());
+    JSTestSerializedScriptValueInterfaceConstructor* castedThis = static_cast<JSTestSerializedScriptValueInterfaceConstructor*>(exec->callee());
     if (exec->argumentCount() < 2)
         return throwVMError(exec, createTypeError(exec, "Not enough arguments"));
     const String& hello(ustringToString(MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined).isEmpty() ? UString() : MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined).toString(exec)->value(exec)));
@@ -98,7 +98,7 @@ EncodedJSValue JSC_HOST_CALL JSTestSerializedScriptValueInterfaceConstructor::co
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     RefPtr<TestSerializedScriptValueInterface> object = TestSerializedScriptValueInterface::create(hello, data, transferList);
-    return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), object.get())));
+    return JSValue::encode(asObject(toJS(exec, castedThis->globalObject(), object.get())));
 }
 
 ConstructType JSTestSerializedScriptValueInterfaceConstructor::getConstructData(JSCell*, ConstructData& constructData)
index a403b5a..625fc1d 100644 (file)
@@ -31,7 +31,7 @@
 // changes in its ouput.
 module test {
     interface [
-        Constructor,
+        Constructor(in [Callback] TestCallback testCallback),
         InterfaceName=TestObject
     ] TestObj {
         // Attributes
index 2a82828..98c6eeb 100644 (file)
@@ -1991,8 +1991,13 @@ v8::Handle<v8::Value> V8TestObj::constructorCallback(const v8::Arguments& args)
 
     if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
         return args.Holder();
+    if (args.Length() < 1)
+        return throwError("Not enough arguments", V8Proxy::TypeError);
+    if (args.Length() <= 0 || !args[0]->IsFunction())
+        return throwError(TYPE_MISMATCH_ERR);
+    RefPtr<TestCallback> testCallback = V8TestCallback::create(args[0], getScriptExecutionContext());
 
-    RefPtr<TestObj> impl = TestObj::create();
+    RefPtr<TestObj> impl = TestObj::create(testCallback);
     v8::Handle<v8::Object> wrapper = args.Holder();
 
     V8DOMWrapper::setDOMWrapper(wrapper, &info, impl.get());