summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/scripts/CodeGeneratorJS.pm
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/scripts/CodeGeneratorJS.pm')
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorJS.pm96
1 files changed, 62 insertions, 34 deletions
diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm
index 247430f..200a95d 100644
--- a/WebCore/bindings/scripts/CodeGeneratorJS.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm
@@ -299,7 +299,7 @@ sub AddIncludesForSVGAnimatedType
sub IsScriptProfileType
{
my $type = shift;
- return 1 if ($type eq "ScriptProfile" or $type eq "ScriptProfileNode");
+ return 1 if ($type eq "ScriptProfileNode");
return 0;
}
@@ -1853,12 +1853,20 @@ sub GenerateImplementation
my $requiresAllArguments = $function->signature->extendedAttributes->{"RequiresAllArguments"};
if ($requiresAllArguments) {
- push(@implContent, " if (exec->argumentCount() < $numParameters)\n");
- if ($requiresAllArguments eq "Raise") {
- push(@implContent, " return throwVMError(exec, createSyntaxError(exec, \"Not enough arguments\"));\n");
+ my $numMandatoryParams = @{$function->parameters};
+ foreach my $param (reverse(@{$function->parameters})) {
+ if ($param->extendedAttributes->{"Optional"}) {
+ $numMandatoryParams--;
} else {
- push(@implContent, " return JSValue::encode(jsUndefined());\n");
+ last;
}
+ }
+ push(@implContent, " if (exec->argumentCount() < $numMandatoryParams)\n");
+ if ($requiresAllArguments eq "Raise") {
+ push(@implContent, " return throwVMError(exec, createSyntaxError(exec, \"Not enough arguments\"));\n");
+ } else {
+ push(@implContent, " return JSValue::encode(jsUndefined());\n");
+ }
}
if (@{$function->raisesExceptions}) {
@@ -1908,14 +1916,18 @@ sub GenerateImplementation
$paramIndex++;
}
+ $implIncludes{"ExceptionCode.h"} = 1;
+ $implIncludes{"JSDOMBinding.h"} = 1;
foreach my $parameter (@{$function->parameters}) {
- if ($parameter->extendedAttributes->{"Optional"}) {
+ # Optional callbacks should be treated differently, because they always have a default value (0),
+ # and we can reduce the number of overloaded functions that take a different number of parameters.
+ if ($parameter->extendedAttributes->{"Optional"} && !$parameter->extendedAttributes->{"Callback"}) {
# Generate early call if there are enough parameters.
if (!$hasOptionalArguments) {
push(@implContent, "\n int argsCount = exec->argumentCount();\n");
$hasOptionalArguments = 1;
}
- push(@implContent, " if (argsCount < " . ($argsIndex + 1) . ") {\n");
+ push(@implContent, " if (argsCount <= $argsIndex) {\n");
GenerateImplementationFunctionCall($function, $functionString, $paramIndex, " " x 2, $podType, $implClassName);
push(@implContent, " }\n\n");
}
@@ -1934,12 +1946,22 @@ sub GenerateImplementation
} elsif ($parameter->extendedAttributes->{"Callback"}) {
my $callbackClassName = GetCallbackClassName($parameter->type);
$implIncludes{"$callbackClassName.h"} = 1;
- $implIncludes{"ExceptionCode.h"} = 1;
- push(@implContent, " if (exec->argumentCount() <= $argsIndex || !exec->argument($argsIndex).isObject()) {\n");
- push(@implContent, " setDOMException(exec, TYPE_MISMATCH_ERR);\n");
- push(@implContent, " return jsUndefined();\n");
- push(@implContent, " }\n");
- push(@implContent, " RefPtr<" . $parameter->type . "> $name = " . $callbackClassName . "::create(asObject(exec->argument($argsIndex)), castedThis->globalObject());\n");
+ if ($parameter->extendedAttributes->{"Optional"}) {
+ push(@implContent, " RefPtr<" . $parameter->type. "> $name;\n");
+ push(@implContent, " if (exec->argumentCount() > $argsIndex && !exec->argument($argsIndex).isNull() && !exec->argument($argsIndex).isUndefined()) {\n");
+ push(@implContent, " if (!exec->argument($argsIndex).isObject()) {\n");
+ push(@implContent, " setDOMException(exec, TYPE_MISMATCH_ERR);\n");
+ push(@implContent, " return JSValue::encode(jsUndefined());\n");
+ push(@implContent, " }\n");
+ push(@implContent, " $name = ${callbackClassName}::create(asObject(exec->argument($argsIndex)), castedThis->globalObject());\n");
+ push(@implContent, " }\n");
+ } else {
+ push(@implContent, " if (exec->argumentCount() <= $argsIndex || !exec->argument($argsIndex).isObject()) {\n");
+ push(@implContent, " setDOMException(exec, TYPE_MISMATCH_ERR);\n");
+ push(@implContent, " return JSValue::encode(jsUndefined());\n");
+ push(@implContent, " }\n");
+ push(@implContent, " RefPtr<" . $parameter->type . "> $name = ${callbackClassName}::create(asObject(exec->argument($argsIndex)), castedThis->globalObject());\n");
+ }
} else {
push(@implContent, " " . GetNativeTypeFromSignature($parameter) . " $name = " . JSValueToNative($parameter, "exec->argument($argsIndex)") . ";\n");
@@ -1947,12 +1969,15 @@ sub GenerateImplementation
# But this needs to be done in the bindings, because the type is unsigned and the fact that it
# was negative will be lost by the time we're inside the DOM.
if ($parameter->extendedAttributes->{"IsIndex"}) {
- $implIncludes{"ExceptionCode.h"} = 1;
push(@implContent, " if ($name < 0) {\n");
push(@implContent, " setDOMException(exec, INDEX_SIZE_ERR);\n");
push(@implContent, " return JSValue::encode(jsUndefined());\n");
push(@implContent, " }\n");
}
+
+ # Check if the type conversion succeeded.
+ push(@implContent, " if (exec->hadException())\n");
+ push(@implContent, " return JSValue::encode(jsUndefined());\n");
}
$functionString .= ", " if $paramIndex;
@@ -2084,12 +2109,13 @@ sub GenerateCallbackHeader
# - Add default header template and header protection
push(@headerContentHeader, GenerateHeaderContentHeader($dataNode));
+ $headerIncludes{"ActiveDOMCallback.h"} = 1;
$headerIncludes{"$interfaceName.h"} = 1;
$headerIncludes{"JSCallbackData.h"} = 1;
$headerIncludes{"<wtf/Forward.h>"} = 1;
push(@headerContent, "\nnamespace WebCore {\n\n");
- push(@headerContent, "class $className : public $interfaceName {\n");
+ push(@headerContent, "class $className : public $interfaceName, public ActiveDOMCallback {\n");
push(@headerContent, "public:\n");
# The static create() method.
@@ -2112,10 +2138,13 @@ sub GenerateCallbackHeader
push(@headerContent, " COMPILE_ASSERT(false)");
}
- push(@headerContent, " virtual " . GetNativeType($function->signature->type) . " " . $function->signature->name . "(ScriptExecutionContext*");
+ push(@headerContent, " virtual " . GetNativeType($function->signature->type) . " " . $function->signature->name . "(");
+
+ my @args = ();
foreach my $param (@params) {
- push(@headerContent, ", " . GetNativeType($param->type) . " " . $param->name);
+ push(@args, GetNativeType($param->type) . " " . $param->name);
}
+ push(@headerContent, join(", ", @args));
push(@headerContent, ");\n");
}
@@ -2128,8 +2157,6 @@ sub GenerateCallbackHeader
# Private members
push(@headerContent, " JSCallbackData* m_data;\n");
- push(@headerContent, " RefPtr<DOMWrapperWorld> m_isolatedWorld;\n");
- push(@headerContent, " ScriptExecutionContext* m_scriptExecutionContext;\n");
push(@headerContent, "};\n\n");
push(@headerContent, "} // namespace WebCore\n\n");
@@ -2159,19 +2186,21 @@ sub GenerateCallbackImplementation
# Constructor
push(@implContent, "${className}::${className}(JSObject* callback, JSDOMGlobalObject* globalObject)\n");
- push(@implContent, " : m_data(new JSCallbackData(callback, globalObject))\n");
- push(@implContent, " , m_isolatedWorld(globalObject->world())\n");
- push(@implContent, " , m_scriptExecutionContext(globalObject->scriptExecutionContext())\n");
+ push(@implContent, " : ActiveDOMCallback(globalObject->scriptExecutionContext())\n");
+ push(@implContent, " , m_data(new JSCallbackData(callback, globalObject))\n");
push(@implContent, "{\n");
push(@implContent, "}\n\n");
# Destructor
push(@implContent, "${className}::~${className}()\n");
push(@implContent, "{\n");
- push(@implContent, " if (m_scriptExecutionContext->isContextThread())\n");
+ push(@implContent, " ScriptExecutionContext* context = scriptExecutionContext();\n");
+ push(@implContent, " // When the context is destroyed, all tasks with a reference to a callback\n");
+ push(@implContent, " // should be deleted. So if the context is 0, we are on the context thread.\n");
+ push(@implContent, " if (!context || context->isContextThread())\n");
push(@implContent, " delete m_data;\n");
push(@implContent, " else\n");
- push(@implContent, " m_scriptExecutionContext->postTask(DeleteCallbackDataTask::create(m_data));\n");
+ push(@implContent, " context->postTask(DeleteCallbackDataTask::create(m_data));\n");
push(@implContent, "#ifndef NDEBUG\n");
push(@implContent, " m_data = 0;\n");
push(@implContent, "#endif\n");
@@ -2189,24 +2218,22 @@ sub GenerateCallbackImplementation
}
AddIncludesForType($function->signature->type);
- push(@implContent, "\n" . GetNativeType($function->signature->type) . " ${className}::" . $function->signature->name . "(ScriptExecutionContext* context");
+ push(@implContent, "\n" . GetNativeType($function->signature->type) . " ${className}::" . $function->signature->name . "(");
+ my @args = ();
foreach my $param (@params) {
AddIncludesForType($param->type, 1);
- push(@implContent, ", " . GetNativeType($param->type) . " " . $param->name);
+ push(@args, GetNativeType($param->type) . " " . $param->name);
}
-
+ push(@implContent, join(", ", @args));
push(@implContent, ")\n");
push(@implContent, "{\n");
- push(@implContent, " ASSERT(m_data);\n");
- push(@implContent, " ASSERT(context);\n\n");
+ push(@implContent, " if (!canInvokeCallback())\n");
+ push(@implContent, " return true;\n\n");
push(@implContent, " RefPtr<$className> protect(this);\n\n");
push(@implContent, " JSLock lock(SilenceAssertionsOnly);\n\n");
- push(@implContent, " JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, m_isolatedWorld.get());\n");
- push(@implContent, " if (!globalObject)\n");
- push(@implContent, " return true;\n\n");
- push(@implContent, " ExecState* exec = globalObject->globalExec();\n");
+ push(@implContent, " ExecState* exec = m_data->globalObject()->globalExec();\n");
push(@implContent, " MarkedArgumentBuffer args;\n");
foreach my $param (@params) {
@@ -2341,7 +2368,8 @@ sub JSValueToNative
return "$value.toBoolean(exec)" if $type eq "boolean";
return "$value.toNumber(exec)" if $type eq "double";
return "$value.toFloat(exec)" if $type eq "float" or $type eq "SVGNumber";
- return "$value.toInt32(exec)" if $type eq "unsigned long" or $type eq "long" or $type eq "unsigned short";
+ return "$value.toInt32(exec)" if $type eq "long";
+ return "$value.toUInt32(exec)" if $type eq "unsigned long" or $type eq "unsigned short";
return "static_cast<$type>($value.toInteger(exec))" if $type eq "long long" or $type eq "unsigned long long";
return "valueToDate(exec, $value)" if $type eq "Date";