Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (101507 => 101508)
--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2011-11-30 14:47:07 UTC (rev 101507)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2011-11-30 14:55:50 UTC (rev 101508)
@@ -1099,7 +1099,7 @@
push(@headerContent, "};\n\n");
- if ($dataNode->extendedAttributes->{"JSCustomConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"} || !$dataNode->extendedAttributes->{"OmitConstructor"}) {
+ if (!$dataNode->extendedAttributes->{"OmitConstructor"}) {
$headerIncludes{"JSDOMBinding.h"} = 1;
GenerateConstructorDeclaration(\@headerContent, $className, $dataNode, $interfaceName);
}
@@ -1436,6 +1436,9 @@
my $protoClassName = "${className}Prototype";
GenerateConstructorDefinition(\@implContent, $className, $protoClassName, $interfaceName, $visibleClassName, $dataNode);
+ if ($dataNode->extendedAttributes->{"NamedConstructor"}) {
+ GenerateConstructorDefinition(\@implContent, $className, $protoClassName, $interfaceName, $visibleClassName, $dataNode, "GeneratingNamedConstructor");
+ }
}
# - Add functions and constants to a hashtable definition
@@ -3335,7 +3338,7 @@
push(@$outputArray, "protected:\n");
push(@$outputArray, " static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::ImplementsHasInstance | DOMConstructorObject::StructureFlags;\n");
- if (IsConstructable($dataNode)) {
+ if (IsConstructable($dataNode) && !$dataNode->extendedAttributes->{"NamedConstructor"}) {
push(@$outputArray, " static JSC::EncodedJSValue JSC_HOST_CALL construct${className}(JSC::ExecState*);\n");
push(@$outputArray, " static JSC::ConstructType getConstructData(JSC::JSCell*, JSC::ConstructData&);\n");
}
@@ -3344,6 +3347,36 @@
if (IsConstructorTemplate($dataNode, "Event")) {
push(@$outputArray, "bool fill${interfaceName}Init(${interfaceName}Init&, JSDictionary&);\n\n");
}
+
+ if ($dataNode->extendedAttributes->{"NamedConstructor"}) {
+ push(@$outputArray, <<END);
+class JS${interfaceName}NamedConstructor : public DOMConstructorWithDocument {
+public:
+ typedef DOMConstructorWithDocument Base;
+
+ static JS${interfaceName}NamedConstructor* create(JSC::ExecState* exec, JSC::Structure* structure, JSDOMGlobalObject* globalObject)
+ {
+ JS${interfaceName}NamedConstructor* constructor = new (JSC::allocateCell<JS${interfaceName}NamedConstructor>(*exec->heap())) JS${interfaceName}NamedConstructor(structure, globalObject);
+ constructor->finishCreation(exec, globalObject);
+ return constructor;
+ }
+
+ static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
+ }
+
+ static const JSC::ClassInfo s_info;
+
+private:
+ JS${interfaceName}NamedConstructor(JSC::Structure*, JSDOMGlobalObject*);
+ static JSC::EncodedJSValue JSC_HOST_CALL constructJS${interfaceName}(JSC::ExecState*);
+ static JSC::ConstructType getConstructData(JSC::JSCell*, JSC::ConstructData&);
+ void finishCreation(JSC::ExecState*, JSDOMGlobalObject*);
+};
+
+END
+ }
}
sub GenerateConstructorDefinition
@@ -3355,48 +3388,64 @@
my $interfaceName = shift;
my $visibleClassName = shift;
my $dataNode = shift;
+ my $generatingNamedConstructor = shift;
- my $constructorClassName = "${className}Constructor";
+ my $constructorClassName = $generatingNamedConstructor ? "${className}NamedConstructor" : "${className}Constructor";
my $numberOfconstructParameters = $dataNode->extendedAttributes->{"ConstructorParameters"};
- push(@$outputArray, "const ClassInfo ${constructorClassName}::s_info = { \"${visibleClassName}Constructor\", &DOMConstructorObject::s_info, &${constructorClassName}Table, 0, CREATE_METHOD_TABLE($constructorClassName) };\n\n");
+ if ($generatingNamedConstructor) {
+ push(@$outputArray, "const ClassInfo ${constructorClassName}::s_info = { \"${visibleClassName}Constructor\", &DOMConstructorObject::s_info, 0, 0, CREATE_METHOD_TABLE($constructorClassName) };\n\n");
+ push(@$outputArray, "${constructorClassName}::${constructorClassName}(Structure* structure, JSDOMGlobalObject* globalObject)\n");
+ push(@$outputArray, " : DOMConstructorWithDocument(structure, globalObject)\n");
+ push(@$outputArray, "{\n");
+ push(@$outputArray, "}\n\n");
+ } else {
+ push(@$outputArray, "const ClassInfo ${constructorClassName}::s_info = { \"${visibleClassName}Constructor\", &DOMConstructorObject::s_info, &${constructorClassName}Table, 0, CREATE_METHOD_TABLE($constructorClassName) };\n\n");
+ push(@$outputArray, "${constructorClassName}::${constructorClassName}(Structure* structure, JSDOMGlobalObject* globalObject)\n");
+ push(@$outputArray, " : DOMConstructorObject(structure, globalObject)\n");
+ push(@$outputArray, "{\n");
+ push(@$outputArray, "}\n\n");
+ }
- push(@$outputArray, "${constructorClassName}::${constructorClassName}(Structure* structure, JSDOMGlobalObject* globalObject)\n");
- push(@$outputArray, " : DOMConstructorObject(structure, globalObject)\n");
- push(@$outputArray, "{\n");
- push(@$outputArray, "}\n\n");
-
push(@$outputArray, "void ${constructorClassName}::finishCreation(ExecState* exec, JSDOMGlobalObject* globalObject)\n");
push(@$outputArray, "{\n");
- push(@$outputArray, " Base::finishCreation(exec->globalData());\n");
- push(@$outputArray, " ASSERT(inherits(&s_info));\n");
if ($interfaceName eq "DOMWindow") {
+ push(@$outputArray, " Base::finishCreation(exec->globalData());\n");
+ push(@$outputArray, " ASSERT(inherits(&s_info));\n");
push(@$outputArray, " putDirect(exec->globalData(), exec->propertyNames().prototype, globalObject->prototype(), DontDelete | ReadOnly);\n");
+ } elsif ($generatingNamedConstructor) {
+ push(@$outputArray, " Base::finishCreation(globalObject);\n");
+ push(@$outputArray, " ASSERT(inherits(&s_info));\n");
+ push(@$outputArray, " putDirect(exec->globalData(), exec->propertyNames().prototype, ${className}Prototype::self(exec, globalObject), None);\n");
} else {
+ push(@$outputArray, " Base::finishCreation(exec->globalData());\n");
+ push(@$outputArray, " ASSERT(inherits(&s_info));\n");
push(@$outputArray, " putDirect(exec->globalData(), exec->propertyNames().prototype, ${protoClassName}::self(exec, globalObject), DontDelete | ReadOnly);\n");
}
push(@$outputArray, " putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(${numberOfconstructParameters}), ReadOnly | DontDelete | DontEnum);\n") if $numberOfconstructParameters;
push(@$outputArray, "}\n\n");
- my $hasStaticFunctions = 0;
- foreach my $function (@{$dataNode->functions}) {
- if ($function->isStatic) {
- $hasStaticFunctions = 1;
- last;
+ if (!$generatingNamedConstructor) {
+ my $hasStaticFunctions = 0;
+ foreach my $function (@{$dataNode->functions}) {
+ if ($function->isStatic) {
+ $hasStaticFunctions = 1;
+ last;
+ }
}
- }
- my $kind = $hasStaticFunctions ? "Property" : "Value";
+ my $kind = $hasStaticFunctions ? "Property" : "Value";
- push(@$outputArray, "bool ${constructorClassName}::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)\n");
- push(@$outputArray, "{\n");
- push(@$outputArray, " return getStatic${kind}Slot<${constructorClassName}, JSDOMWrapper>(exec, &${constructorClassName}Table, static_cast<${constructorClassName}*>(cell), propertyName, slot);\n");
- push(@$outputArray, "}\n\n");
+ push(@$outputArray, "bool ${constructorClassName}::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)\n");
+ push(@$outputArray, "{\n");
+ push(@$outputArray, " return getStatic${kind}Slot<${constructorClassName}, JSDOMWrapper>(exec, &${constructorClassName}Table, static_cast<${constructorClassName}*>(cell), propertyName, slot);\n");
+ push(@$outputArray, "}\n\n");
- push(@$outputArray, "bool ${constructorClassName}::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)\n");
- push(@$outputArray, "{\n");
- push(@$outputArray, " return getStatic${kind}Descriptor<${constructorClassName}, JSDOMWrapper>(exec, &${constructorClassName}Table, static_cast<${constructorClassName}*>(object), propertyName, descriptor);\n");
- push(@$outputArray, "}\n\n");
+ push(@$outputArray, "bool ${constructorClassName}::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)\n");
+ push(@$outputArray, "{\n");
+ push(@$outputArray, " return getStatic${kind}Descriptor<${constructorClassName}, JSDOMWrapper>(exec, &${constructorClassName}Table, static_cast<${constructorClassName}*>(object), propertyName, descriptor);\n");
+ push(@$outputArray, "}\n\n");
+ }
if (IsConstructable($dataNode)) {
if (IsConstructorTemplate($dataNode, "Event")) {
@@ -3463,7 +3512,7 @@
}
END
- } elsif (!($dataNode->extendedAttributes->{"JSCustomConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})) {
+ } elsif (!($dataNode->extendedAttributes->{"JSCustomConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"}) && (!$dataNode->extendedAttributes->{"NamedConstructor"} || $generatingNamedConstructor)) {
push(@$outputArray, "EncodedJSValue JSC_HOST_CALL ${constructorClassName}::construct${className}(ExecState* exec)\n");
push(@$outputArray, "{\n");
@@ -3493,6 +3542,9 @@
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()");
+ }
my $index = 0;
foreach my $parameter (@{$function->parameters}) {
@@ -3505,7 +3557,12 @@
push(@constructorArgList, "ec");
}
my $constructorArg = join(", ", @constructorArgList);
- push(@$outputArray, " RefPtr<${interfaceName}> object = ${interfaceName}::create(${constructorArg});\n");
+ if ($generatingNamedConstructor) {
+ push(@$outputArray, " RefPtr<${interfaceName}> object = ${interfaceName}::createForJSConstructor(${constructorArg});\n");
+ } else {
+ push(@$outputArray, " RefPtr<${interfaceName}> object = ${interfaceName}::create(${constructorArg});\n");
+ }
+
if ($dataNode->extendedAttributes->{"ConstructorRaisesException"}) {
push(@$outputArray, " if (ec) {\n");
push(@$outputArray, " setDOMException(exec, ec);\n");
@@ -3517,11 +3574,13 @@
push(@$outputArray, "}\n\n");
}
- push(@$outputArray, "ConstructType ${constructorClassName}::getConstructData(JSCell*, ConstructData& constructData)\n");
- push(@$outputArray, "{\n");
- push(@$outputArray, " constructData.native.function = construct${className};\n");
- push(@$outputArray, " return ConstructTypeHost;\n");
- push(@$outputArray, "}\n\n");
+ if (!$dataNode->extendedAttributes->{"NamedConstructor"} || $generatingNamedConstructor) {
+ push(@$outputArray, "ConstructType ${constructorClassName}::getConstructData(JSCell*, ConstructData& constructData)\n");
+ push(@$outputArray, "{\n");
+ push(@$outputArray, " constructData.native.function = construct${className};\n");
+ push(@$outputArray, " return ConstructTypeHost;\n");
+ push(@$outputArray, "}\n\n");
+ }
}
}
@@ -3529,7 +3588,7 @@
{
my $dataNode = shift;
- return $dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"JSCustomConstructor"} || $dataNode->extendedAttributes->{"Constructor"} || $dataNode->extendedAttributes->{"JSConstructorTemplate"} || $dataNode->extendedAttributes->{"ConstructorTemplate"};
+ return $dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"JSCustomConstructor"} || $dataNode->extendedAttributes->{"Constructor"} || $dataNode->extendedAttributes->{"NamedConstructor"} || $dataNode->extendedAttributes->{"JSConstructorTemplate"} || $dataNode->extendedAttributes->{"ConstructorTemplate"};
}
sub IsConstructorTemplate
Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedConstructor.cpp (101507 => 101508)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedConstructor.cpp 2011-11-30 14:47:07 UTC (rev 101507)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedConstructor.cpp 2011-11-30 14:55:50 UTC (rev 101508)
@@ -21,7 +21,10 @@
#include "config.h"
#include "JSTestNamedConstructor.h"
+#include "ExceptionCode.h"
+#include "JSDOMBinding.h"
#include "TestNamedConstructor.h"
+#include <runtime/Error.h>
#include <wtf/GetPtr.h>
using namespace JSC;
@@ -93,6 +96,49 @@
return getStaticValueDescriptor<JSTestNamedConstructorConstructor, JSDOMWrapper>(exec, &JSTestNamedConstructorConstructorTable, static_cast<JSTestNamedConstructorConstructor*>(object), propertyName, descriptor);
}
+const ClassInfo JSTestNamedConstructorNamedConstructor::s_info = { "TestNamedConstructorConstructor", &DOMConstructorObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSTestNamedConstructorNamedConstructor) };
+
+JSTestNamedConstructorNamedConstructor::JSTestNamedConstructorNamedConstructor(Structure* structure, JSDOMGlobalObject* globalObject)
+ : DOMConstructorWithDocument(structure, globalObject)
+{
+}
+
+void JSTestNamedConstructorNamedConstructor::finishCreation(ExecState* exec, JSDOMGlobalObject* globalObject)
+{
+ Base::finishCreation(globalObject);
+ ASSERT(inherits(&s_info));
+ putDirect(exec->globalData(), exec->propertyNames().prototype, JSTestNamedConstructorPrototype::self(exec, globalObject), None);
+}
+
+EncodedJSValue JSC_HOST_CALL JSTestNamedConstructorNamedConstructor::constructJSTestNamedConstructor(ExecState* exec)
+{
+ JSTestNamedConstructorNamedConstructor* jsConstructor = static_cast<JSTestNamedConstructorNamedConstructor*>(exec->callee());
+ if (exec->argumentCount() < 1)
+ return throwVMError(exec, createTypeError(exec, "Not enough arguments"));
+ ExceptionCode ec = 0;
+ const String& str1(ustringToString(MAYBE_MISSING_PARAMETER(exec, 0, MissingIsUndefined).isEmpty() ? UString() : MAYBE_MISSING_PARAMETER(exec, 0, MissingIsUndefined).toString(exec)));
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ const String& str2(ustringToString(MAYBE_MISSING_PARAMETER(exec, 1, MissingIsUndefined).isEmpty() ? UString() : MAYBE_MISSING_PARAMETER(exec, 1, MissingIsUndefined).toString(exec)));
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ const String& str3(ustringToString(MAYBE_MISSING_PARAMETER(exec, 2, MissingIsEmpty).isEmpty() ? UString() : MAYBE_MISSING_PARAMETER(exec, 2, MissingIsEmpty).toString(exec)));
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ RefPtr<TestNamedConstructor> object = TestNamedConstructor::createForJSConstructor(jsConstructor->document(), str1, str2, str3, ec);
+ if (ec) {
+ setDOMException(exec, ec);
+ return JSValue::encode(JSValue());
+ }
+ return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), object.get())));
+}
+
+ConstructType JSTestNamedConstructorNamedConstructor::getConstructData(JSCell*, ConstructData& constructData)
+{
+ constructData.native.function = constructJSTestNamedConstructor;
+ return ConstructTypeHost;
+}
+
/* Hash table for prototype */
#if ENABLE(JIT)
#define THUNK_GENERATOR(generator) , generator