diff options
Diffstat (limited to 'WebCore/bindings/scripts/CodeGeneratorJS.pm')
-rw-r--r-- | WebCore/bindings/scripts/CodeGeneratorJS.pm | 96 |
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"; |