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 e0c3e21383dd71559c304165e21e0bccadcab966..ff9446cd3ea89dcf7258ca6d7dab5e40adbc5178 100644 (file)
@@ -1,3 +1,29 @@
+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
index 465915bd60f1526111720c27fee09d3eb49fde8d..f6e486ccf697be47f2b88750fdc7bf62a6b94830 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 c3888e8e8f020a21c934b16891d623cb8f4dedc7..c464d4a127ae5bc2c6e7ac55891468b5d17cd6c6 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 225208dc2865eb3a2785ef32340a771030ed55b3..2125604a0367675d0cce14765d9c55b8e23bbf86 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 569392d05f3eceb92def181790309e73cb995913..a5d1fabf309b547693059320c0422dd529218f7d 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 32e44d5f0f367df6d54a7c5002297861d203f83a..9db6ea61e49d5cffe4a1675ee8c089357dc04295 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 a403b5a9c0acd78e1aca5cc879d91b9ec9bca0b6..625fc1dbea77b75c15158a4c84fb89d8a1aad122 100644 (file)
@@ -31,7 +31,7 @@
 // changes in its ouput.
 module test {
     interface [
-        Constructor,
+        Constructor(in [Callback] TestCallback testCallback),
         InterfaceName=TestObject
     ] TestObj {
         // Attributes
index 2a828283db5837014c0ca9161bc209f7476cd37e..98c6eebfab72fc9887ccda68b7aaf01904108f35 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());