summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/scripts')
-rw-r--r--WebCore/bindings/scripts/CodeGenerator.pm2
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorGObject.pm1086
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorJS.pm128
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorObjC.pm10
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorV8.pm1124
-rw-r--r--WebCore/bindings/scripts/IDLParser.pm11
-rw-r--r--WebCore/bindings/scripts/IDLStructure.pm2
-rwxr-xr-xWebCore/bindings/scripts/generate-bindings.pl2
-rw-r--r--WebCore/bindings/scripts/gobject-generate-headers.pl77
9 files changed, 1914 insertions, 528 deletions
diff --git a/WebCore/bindings/scripts/CodeGenerator.pm b/WebCore/bindings/scripts/CodeGenerator.pm
index 506e8ea..487a4b3 100644
--- a/WebCore/bindings/scripts/CodeGenerator.pm
+++ b/WebCore/bindings/scripts/CodeGenerator.pm
@@ -17,7 +17,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
diff --git a/WebCore/bindings/scripts/CodeGeneratorGObject.pm b/WebCore/bindings/scripts/CodeGeneratorGObject.pm
new file mode 100644
index 0000000..2a38eff
--- /dev/null
+++ b/WebCore/bindings/scripts/CodeGeneratorGObject.pm
@@ -0,0 +1,1086 @@
+# Copyright (C) 2008 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+# Copyright (C) 2008 Martin Soto <soto@freedesktop.org>
+# Copyright (C) 2008 Alp Toker <alp@atoker.com>
+# Copyright (C) 2009 Adam Dingle <adam@yorba.org>
+# Copyright (C) 2009 Jim Nelson <jim@yorba.org>
+# Copyright (C) 2009, 2010 Igalia S.L.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+package CodeGeneratorGObject;
+
+# Global Variables
+my %implIncludes = ();
+my %hdrIncludes = ();
+
+my $className = "";
+
+# Default constructor
+sub new {
+ my $object = shift;
+ my $reference = { };
+
+ $codeGenerator = shift;
+ $outputDir = shift;
+ mkdir $outputDir;
+
+ bless($reference, $object);
+}
+
+sub finish {
+}
+
+my $licenceTemplate = << "EOF";
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+EOF
+
+sub GenerateModule {
+}
+
+sub GetParentClassName {
+ my $dataNode = shift;
+
+ return "WebKitDOMObject" if @{$dataNode->parents} eq 0;
+ return "WebKitDOM" . $codeGenerator->StripModule($dataNode->parents(0));
+}
+
+# From String::CamelCase 0.01
+sub camelize
+{
+ my $s = shift;
+ join('', map{ ucfirst $_ } split(/(?<=[A-Za-z])_(?=[A-Za-z])|\b/, $s));
+}
+
+sub decamelize
+{
+ my $s = shift;
+ $s =~ s{([^a-zA-Z]?)([A-Z]*)([A-Z])([a-z]?)}{
+ my $fc = pos($s)==0;
+ my ($p0,$p1,$p2,$p3) = ($1,lc$2,lc$3,$4);
+ my $t = $p0 || $fc ? $p0 : '_';
+ $t .= $p3 ? $p1 ? "${p1}_$p2$p3" : "$p2$p3" : "$p1$p2";
+ $t;
+ }ge;
+ $s;
+}
+
+sub ClassNameToGObjectType {
+ my $className = shift;
+ my $CLASS_NAME = uc(decamelize($className));
+ # Fixup: with our prefix being 'WebKitDOM' decamelize can't get
+ # WebKitDOMCSS right, so we have to fix it manually (and there
+ # might be more like this in the future)
+ $CLASS_NAME =~ s/DOMCSS/DOM_CSS/;
+ return $CLASS_NAME;
+}
+
+sub GetParentGObjType {
+ my $dataNode = shift;
+
+ return "WEBKIT_TYPE_DOM_OBJECT" if @{$dataNode->parents} eq 0;
+ return "WEBKIT_TYPE_DOM_" . ClassNameToGObjectType($codeGenerator->StripModule($dataNode->parents(0)));
+}
+
+sub GetClassName {
+ my $name = $codeGenerator->StripModule(shift);
+
+ return "WebKitDOM$name";
+}
+
+sub GetCoreObject {
+ my ($interfaceName, $name, $parameter) = @_;
+
+ return "WebCore::${interfaceName}* $name = WebKit::core($parameter);";
+}
+
+sub SkipAttribute {
+ my $attribute = shift;
+
+ if ($attribute->signature->extendedAttributes->{"CustomGetter"} ||
+ $attribute->signature->extendedAttributes->{"CustomSetter"}) {
+ return 1;
+ }
+
+ my $propType = $attribute->signature->type;
+ if ($propType eq "EventListener") {
+ return 1;
+ }
+
+ if ($propType =~ /Constructor$/) {
+ return 1;
+ }
+
+ return 0;
+}
+
+# Name type used in the g_value_{set,get}_* functions
+sub GetGValueTypeName {
+ my $type = shift;
+
+ my %types = ("DOMString", "string",
+ "float", "float",
+ "double", "double",
+ "boolean", "boolean",
+ "char", "char",
+ "long", "long",
+ "short", "int",
+ "uchar", "uchar",
+ "unsigned", "uint",
+ "int", "int",
+ "unsigned int", "uint",
+ "unsigned long long", "uint64",
+ "unsigned long", "ulong",
+ "unsigned short", "ushort");
+
+ return $types{$type} ? $types{$type} : "object";
+}
+
+# Name type used in C declarations
+sub GetGlibTypeName {
+ my $type = shift;
+ my $name = GetClassName($type);
+
+ my %types = ("DOMString", "gchar* ",
+ "float", "gfloat",
+ "double", "gdouble",
+ "boolean", "gboolean",
+ "char", "gchar",
+ "long", "glong",
+ "short", "gshort",
+ "uchar", "guchar",
+ "unsigned", "guint",
+ "int", "gint",
+ "unsigned int", "guint",
+ "unsigned long", "gulong",
+ "unsigned long long", "guint64",
+ "unsigned short", "gushort",
+ "void", "void");
+
+ return $types{$type} ? $types{$type} : "$name* ";
+}
+
+sub IsGDOMClassType {
+ my $type = shift;
+
+ return 0 if $type eq "DOMString";
+ return 0 if $type eq "float";
+ return 0 if $type eq "double";
+ return 0 if $type eq "boolean";
+ return 0 if $type eq "char";
+ return 0 if $type eq "long";
+ return 0 if $type eq "short";
+ return 0 if $type eq "uchar";
+ return 0 if $type eq "unsigned";
+ return 0 if $type eq "int";
+ return 0 if $type eq "unsigned int";
+ return 0 if $type eq "unsigned long";
+ return 0 if $type eq "unsigned long long";
+ return 0 if $type eq "unsigned short";
+ return 0 if $type eq "void";
+
+ return 1;
+}
+
+sub GenerateProperties {
+ my ($object, $interfaceName, $dataNode) = @_;
+
+ my $clsCaps = substr(ClassNameToGObjectType($className), 12);
+ my $lowerCaseIfaceName = "webkit_dom_" . (decamelize($interfaceName));
+
+ # Properties
+ my $implContent = "";
+
+ # Properties
+ $implContent = << "EOF";
+enum {
+ PROP_0,
+EOF
+ push(@cBodyPriv, $implContent);
+
+ my @txtInstallProps = ();
+ my @txtSetProps = ();
+ my @txtGetProps = ();
+
+ my $privFunction = GetCoreObject($interfaceName, "coreSelf", "self");
+
+ my $txtGetProp = << "EOF";
+static void ${lowerCaseIfaceName}_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
+{
+ ${className}* self = WEBKIT_DOM_${clsCaps}(object);
+ $privFunction
+
+ switch (prop_id) {
+EOF
+ push(@txtGetProps, $txtGetProp);
+
+ my $txtSetProps = << "EOF";
+static void ${lowerCaseIfaceName}_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
+{
+ ${className} *self = WEBKIT_DOM_${clsCaps}(object);
+ $privFunction
+
+ switch (prop_id) {
+EOF
+ push(@txtSetProps, $txtSetProps);
+
+ # Iterate over the interface attributes and generate a property for
+ # each one of them.
+ SKIPENUM:
+ foreach my $attribute (@{$dataNode->attributes}) {
+ if (SkipAttribute($attribute)) {
+ next SKIPENUM;
+ }
+
+ my $camelPropName = $attribute->signature->name;
+ my $setPropNameFunction = $codeGenerator->WK_ucfirst($camelPropName);
+ my $getPropNameFunction = $codeGenerator->WK_lcfirst($camelPropName);
+
+ my $propName = decamelize($camelPropName);
+ my $propNameCaps = uc($propName);
+ $propName =~ s/_/-/g;
+ my ${propEnum} = "PROP_${propNameCaps}";
+ push(@cBodyPriv, " ${propEnum},\n");
+
+ my $propType = $attribute->signature->type;
+ my ${propGType} = decamelize($propType);
+ if ($propGType eq "event_target") {
+ $propGType = "event_target_node";
+ }
+ my ${ucPropGType} = uc($propGType);
+
+ my $gtype = GetGValueTypeName($propType);
+ my $gparamflag = "WEBKIT_PARAM_READABLE";
+ my $writeable = $attribute->type !~ /^readonly/;
+ my $const = "read-only ";
+ if ($writeable && $custom) {
+ $const = "read-only (due to custom functions needed in webkitdom)";
+ next SKIPENUM;
+ }
+ if ($writeable && !$custom) {
+ $gparamflag = "WEBKIT_PARAM_READWRITE";
+ $const = "read-write ";
+ }
+
+ my $type = GetGlibTypeName($propType);
+ $nick = decamelize("${interfaceName}_${propName}");
+ $long = "${const} ${type} ${interfaceName}.${propName}";
+
+ my $convertFunction = "";
+
+ if ($writeable && ($gtype eq "boolean" || $gtype eq "float" || $gtype eq "double" ||
+ $gtype eq "uint64" || $gtype eq "ulong" || $gtype eq "long" ||
+ $gtype eq "uint" || $gtype eq "ushort" || $gtype eq "uchar" ||
+ $gtype eq "char" || $gtype eq "string")) {
+
+ push(@txtSetProps, " case ${propEnum}:\n {\n");
+ push(@txtSetProps, " WebCore::ExceptionCode ec = 0;\n") if @{$attribute->setterExceptions};
+
+ if ($gtype eq "string") {
+ $convertFunction = "WebCore::String::fromUTF8";
+ } elsif ($attribute->signature->extendedAttributes->{"ConvertFromString"}) {
+ $convertFunction = "WebCore::String::number";
+ }
+
+ push(@txtSetProps, " coreSelf->set${setPropNameFunction}(${convertFunction}(g_value_get_$gtype(value))");
+ push(@txtSetProps, ", ec") if @{$attribute->setterExceptions};
+ push(@txtSetProps, ");\n");
+
+ push(@txtSetProps, " break;\n }\n");
+ }
+
+ push(@txtGetProps, " case ${propEnum}:\n {\n");
+
+ my $exception = "";
+ if (@{$attribute->getterExceptions}) {
+ $exception = "ec";
+ push(@txtGetProps, " WebCore::ExceptionCode ec = 0;\n");
+ }
+
+ my $postConvertFunction = "";
+ my $done = 0;
+ if ($gtype eq "string") {
+ push(@txtGetProps, " g_value_take_string(value, convertToUTF8String(coreSelf->${getPropNameFunction}(${exception})));\n");
+ $done = 1;
+ } elsif ($gtype eq "object") {
+
+ $txtGetProp = << "EOF";
+ RefPtr<WebCore::${propType}> ptr = coreSelf->${getPropNameFunction}(${exception});
+ g_value_set_object(value, WebKit::kit(ptr.get()));
+EOF
+ push(@txtGetProps, $txtGetProp);
+
+ $done = 1;
+ }
+
+ if($attribute->signature->extendedAttributes->{"ConvertFromString"}) {
+ # TODO: Add other conversion functions for different types. Current
+ # IDLs only list longs.
+ if($gtype eq "long") {
+ $convertFunction = "";
+ $postConvertFunction = ".toInt()";
+ } else {
+ die "Can't convert to type ${gtype}.";
+ }
+ }
+
+ # FIXME: get rid of this glitch?
+ my $_gtype = $gtype;
+ if ($gtype eq "ushort") {
+ $_gtype = "uint";
+ }
+
+ if (!$done) {
+ push(@txtGetProps, " g_value_set_$_gtype(value, ${convertFunction}coreSelf->${getPropNameFunction}(${exception})${postConvertFunction});\n");
+ }
+
+ push(@txtGetProps, " break;\n }\n");
+
+my %param_spec_options = ("int", "G_MININT, /* min */\nG_MAXINT, /* max */\n0, /* default */",
+ "boolean", "FALSE, /* default */",
+ "float", "G_MINFLOAT, /* min */\nG_MAXFLOAT, /* max */\n0.0, /* default */",
+ "double", "G_MINDOUBLE, /* min */\nG_MAXDOUBLE, /* max */\n0.0, /* default */",
+ "uint64", "0, /* min */\nG_MAXUINT64, /* min */\n0, /* default */",
+ "long", "G_MINLONG, /* min */\nG_MAXLONG, /* max */\n0, /* default */",
+ "ulong", "0, /* min */\nG_MAXULONG, /* max */\n0, /* default */",
+ "uint", "0, /* min */\nG_MAXUINT, /* max */\n0, /* default */",
+ "ushort", "0, /* min */\nG_MAXUINT16, /* max */\n0, /* default */",
+ "uchar", "G_MININT8, /* min */\nG_MAXINT8, /* max */\n0, /* default */",
+ "char", "0, /* min */\nG_MAXUINT8, /* max */\n0, /* default */",
+ "string", "\"\", /* default */",
+ "object", "WEBKIT_TYPE_DOM_${ucPropGType}, /* gobject type */");
+
+ my $txtInstallProp = << "EOF";
+ g_object_class_install_property(gobjectClass,
+ ${propEnum},
+ g_param_spec_${_gtype}("${propName}", /* name */
+ "$nick", /* short description */
+ "$long", /* longer - could do with some extra doc stuff here */
+ $param_spec_options{$gtype}
+ ${gparamflag}));
+EOF
+ push(@txtInstallProps, $txtInstallProp);
+ $txtInstallProp = "/* TODO! $gtype */\n";
+ }
+
+ push(@cBodyPriv, "};\n\n");
+
+ $txtGetProp = << "EOF";
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+EOF
+ push(@txtGetProps, $txtGetProp);
+
+ $txtSetProps = << "EOF";
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+EOF
+ push(@txtSetProps, $txtSetProps);
+
+ # TODO: work out if it's appropriate to split this into many different
+ # signals e.g. "click" etc.
+ my $txtInstallSignals = "";
+
+ $implContent = << "EOF";
+
+static void ${lowerCaseIfaceName}_finalize(GObject* object)
+{
+ WebKitDOMObject* dom_object = WEBKIT_DOM_OBJECT(object);
+
+ if (dom_object->coreObject != NULL) {
+ WebCore::${interfaceName}* coreObject = static_cast<WebCore::${interfaceName} *>(dom_object->coreObject);
+
+ WebKit::DOMObjectCache::forget(coreObject);
+ coreObject->deref();
+
+ dom_object->coreObject = NULL;
+ }
+
+ G_OBJECT_CLASS(${lowerCaseIfaceName}_parent_class)->finalize(object);
+}
+
+@txtSetProps
+
+@txtGetProps
+
+static void ${lowerCaseIfaceName}_class_init(${className}Class* requestClass)
+{
+ GObjectClass *gobjectClass = G_OBJECT_CLASS(requestClass);
+ gobjectClass->finalize = ${lowerCaseIfaceName}_finalize;
+ gobjectClass->set_property = ${lowerCaseIfaceName}_set_property;
+ gobjectClass->get_property = ${lowerCaseIfaceName}_get_property;
+
+@txtInstallProps
+
+$txtInstallSignals
+}
+
+static void ${lowerCaseIfaceName}_init(${className}* request)
+{
+}
+
+EOF
+ push(@cBodyPriv, $implContent);
+}
+
+sub GenerateHeader {
+ my ($object, $interfaceName, $parentClassName) = @_;
+
+ my $implContent = "";
+
+ # Add the default header template
+ @hPrefix = split("\r", $licenceTemplate);
+ push(@hPrefix, "\n");
+
+ #Header guard
+ my $guard = $className . "_h";
+
+ @hPrefixGuard = << "EOF";
+#ifndef $guard
+#define $guard
+
+EOF
+
+ $implContent = << "EOF";
+G_BEGIN_DECLS
+EOF
+
+ push(@hBodyPre, $implContent);
+
+ my $clsCaps = uc(decamelize($interfaceName));
+ my $lowerCaseIfaceName = "webkit_dom_" . (decamelize($interfaceName));
+
+ $implContent = << "EOF";
+
+#define WEBKIT_TYPE_DOM_${clsCaps} (${lowerCaseIfaceName}_get_type())
+#define WEBKIT_DOM_${clsCaps}(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_DOM_${clsCaps}, ${className}))
+#define WEBKIT_DOM_${clsCaps}_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_DOM_${clsCaps}, ${className}Class)
+#define WEBKIT_DOM_IS_${clsCaps}(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_DOM_${clsCaps}))
+#define WEBKIT_DOM_IS_${clsCaps}_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_DOM_${clsCaps}))
+#define WEBKIT_DOM_${clsCaps}_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_DOM_${clsCaps}, ${className}Class))
+
+struct _${className} {
+ ${parentClassName} parent_instance;
+};
+
+struct _${className}Class {
+ ${parentClassName}Class parent_class;
+};
+
+WEBKIT_API GType
+${lowerCaseIfaceName}_get_type (void);
+
+EOF
+
+ push(@hBody, $implContent);
+}
+
+sub getIncludeHeader {
+ my $type = shift;
+ my $name = GetClassName($type);
+
+ return "" if $type eq "int";
+ return "" if $type eq "long";
+ return "" if $type eq "short";
+ return "" if $type eq "char";
+ return "" if $type eq "float";
+ return "" if $type eq "double";
+ return "" if $type eq "unsigned";
+ return "" if $type eq "unsigned int";
+ return "" if $type eq "unsigned long";
+ return "" if $type eq "unsigned long long";
+ return "" if $type eq "unsigned short";
+ return "" if $type eq "DOMTimeStamp";
+ return "" if $type eq "EventListener";
+ return "" if $type eq "unsigned char";
+ return "" if $type eq "DOMString";
+ return "" if $type eq "float";
+ return "" if $type eq "boolean";
+ return "" if $type eq "void";
+
+ return "$name.h";
+}
+
+sub addIncludeInBody {
+ my $type = shift;
+
+ my $header = getIncludeHeader($type);
+ if ($header eq "") {
+ return;
+ }
+
+ if (IsGDOMClassType($type)) {
+ $implIncludes{"webkit/$header"} = 1;
+ } else {
+ $implIncludes{$header} = 1
+ }
+}
+
+sub GenerateFunction {
+ my ($object, $interfaceName, $function, $prefix) = @_;
+
+ my $functionSigName = $function->signature->name;
+ my $functionSigType = $function->signature->type;
+ my $functionName = "webkit_dom_" . decamelize($interfaceName) . "_" . $prefix . decamelize($functionSigName);
+ my $returnType = GetGlibTypeName($functionSigType);
+ my $returnValueIsGDOMType = IsGDOMClassType($functionSigType);
+
+ my $functionSig = "$className *self";
+
+ my $callImplParams = "";
+
+ # skip some custom functions for now
+ my $isCustomFunction = $function->signature->extendedAttributes->{"Custom"} ||
+ $function->signature->extendedAttributes->{"CustomArgumentHandling"};
+
+ foreach my $param (@{$function->parameters}) {
+ my $paramIDLType = $param->type;
+ if ($paramIDLType eq "Event") {
+ push(@hBody, "\n/* TODO: event function ${functionName} */\n\n");
+ push(@cBody, "\n/* TODO: event function ${functionName} */\n\n");
+ return;
+ }
+ addIncludeInBody($paramIDLType);
+ my $paramType = GetGlibTypeName($paramIDLType);
+ my $paramName = decamelize($param->name);
+
+ $functionSig .= ", $paramType $paramName";
+
+ my $paramIsGDOMType = IsGDOMClassType($paramIDLType);
+ if ($paramIsGDOMType) {
+ if ($paramIDLType ne "DOMObject") {
+ $implIncludes{"webkit/WebKitDOM${paramIDLType}Private.h"} = 1;
+ }
+ }
+ if ($paramIsGDOMType || ($paramIDLType eq "DOMString")) {
+ $paramName = "_g_" . $paramName;
+ }
+ if ($callImplParams) {
+ $callImplParams .= ", $paramName";
+ } else {
+ $callImplParams = "$paramName";
+ }
+ }
+
+ if ($functionSigType eq "Event") {
+ push(@hBody, "\n/* TODO: event function ${functionName} */\n\n");
+ push(@cBody, "\n/* TODO: event function ${functionName} */\n\n");
+ return;
+ }
+
+ if ($returnType ne "void" && $returnValueIsGDOMType) {
+ if ($functionSigType ne "EventTarget") {
+ $implIncludes{"webkit/WebKitDOM${functionSigType}Private.h"} = 1;
+ $implIncludes{"webkit/WebKitDOM${functionSigType}.h"} = 1;
+ }
+
+ $implIncludes{"${functionSigType}.h"} = 1;
+ }
+
+ # skip custom functions for now
+ # but skip from here to allow some headers to be created
+ # for a successful compile.
+ if ($isCustomFunction &&
+ $functionName ne "webkit_dom_node_remove_child" &&
+ $functionName ne "webkit_dom_node_insert_before" &&
+ $functionName ne "webkit_dom_node_replace_child" &&
+ $functionName ne "webkit_dom_node_append_child") {
+ push(@hBody, "\n/* TODO: custom function ${functionName} */\n\n");
+ push(@cBody, "\n/* TODO: custom function ${functionName} */\n\n");
+ return;
+ }
+
+ if(@{$function->raisesExceptions}) {
+ $functionSig .= ", GError **error";
+ }
+
+ push(@hBody, "WEBKIT_API $returnType\n$functionName ($functionSig);\n\n");
+ push(@cBody, "$returnType\n$functionName ($functionSig)\n{\n");
+
+ if ($returnType ne "void") {
+ # TODO: return proper default result
+ push(@cBody, " g_return_val_if_fail (self, 0);\n");
+ } else {
+ push(@cBody, " g_return_if_fail (self);\n");
+ }
+
+ # The WebKit::core implementations check for NULL already; no need to
+ # duplicate effort.
+ push(@cBody, " WebCore::${interfaceName} * item = WebKit::core(self);\n");
+
+ foreach my $param (@{$function->parameters}) {
+ my $paramName = decamelize($param->name);
+ my $paramIDLType = $param->type;
+ my $paramTypeIsPrimitive = $codeGenerator->IsPrimitiveType($paramIDLType);
+ my $paramIsGDOMType = IsGDOMClassType($paramIDLType);
+ if (!$paramTypeIsPrimitive) {
+ if ($returnType ne "void") {
+ # TODO: return proper default result
+ push(@cBody, " g_return_val_if_fail ($paramName, 0);\n");
+ } else {
+ push(@cBody, " g_return_if_fail ($paramName);\n");
+ }
+ }
+ }
+
+ $returnParamName = "";
+ foreach my $param (@{$function->parameters}) {
+ my $paramIDLType = $param->type;
+ my $paramName = decamelize($param->name);
+
+ my $paramIsGDOMType = IsGDOMClassType($paramIDLType);
+ if ($paramIDLType eq "DOMString") {
+ push(@cBody, " WebCore::String _g_${paramName} = WebCore::String::fromUTF8($paramName);\n");
+ }
+ if ($paramIsGDOMType) {
+ push(@cBody, " WebCore::${paramIDLType} * _g_${paramName} = WebKit::core($paramName);\n");
+ if ($returnType ne "void") {
+ # TODO: return proper default result
+ push(@cBody, " g_return_val_if_fail (_g_${paramName}, 0);\n");
+ } else {
+ push(@cBody, " g_return_if_fail (_g_${paramName});\n");
+ }
+ }
+ $returnParamName = "_g_".$paramName if $param->extendedAttributes->{"Return"};
+ }
+
+ my $assign = "";
+ my $assignPre = "";
+ my $assignPost = "";
+
+ if ($returnType ne "void" && !$isCustomFunction) {
+ if ($returnValueIsGDOMType) {
+ $assign = "PassRefPtr<WebCore::${functionSigType}> g_res = ";
+ $assignPre = "WTF::getPtr(";
+ $assignPost = ")";
+ } else {
+ $assign = "${returnType} res = ";
+ }
+ }
+ my $exceptions = "";
+ if (@{$function->raisesExceptions}) {
+ push(@cBody, " WebCore::ExceptionCode ec = 0;\n");
+ if (${callImplParams} ne "") {
+ $exceptions = ", ec";
+ } else {
+ $exceptions = "ec";
+ }
+ }
+
+ # We need to special-case these Node methods because their C++ signature is different
+ # from what we'd expect given their IDL description; see Node.h.
+ if ($functionName eq "webkit_dom_node_append_child" ||
+ $functionName eq "webkit_dom_node_insert_before" ||
+ $functionName eq "webkit_dom_node_replace_child" ||
+ $functionName eq "webkit_dom_node_remove_child") {
+ my $customNodeAppendChild = << "EOF";
+ bool ok = item->${functionSigName}(${callImplParams}${exceptions});
+ if (ok)
+ {
+ ${returnType} res = static_cast<${returnType}>(WebKit::kit($returnParamName));
+ return res;
+ }
+EOF
+ push(@cBody, $customNodeAppendChild);
+
+ if(@{$function->raisesExceptions}) {
+ my $exceptionHandling = << "EOF";
+
+ WebCore::ExceptionCodeDescription ecdesc;
+ WebCore::getExceptionCodeDescription(ec, ecdesc);
+ g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name);
+EOF
+ push(@cBody, $exceptionHandling);
+ }
+ push(@cBody, "return NULL;");
+ push(@cBody, "}\n\n");
+ return;
+ } elsif ($functionSigType eq "DOMString") {
+ push(@cBody, " ${assign}convertToUTF8String(item->${functionSigName}(${callImplParams}${exceptions}));\n" );
+ } else {
+ push(@cBody, " ${assign}${assignPre}item->${functionSigName}(${callImplParams}${exceptions}${assignPost});\n" );
+
+ if(@{$function->raisesExceptions}) {
+ my $exceptionHandling = << "EOF";
+ if(ec) {
+ WebCore::ExceptionCodeDescription ecdesc;
+ WebCore::getExceptionCodeDescription(ec, ecdesc);
+ g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name);
+ }
+EOF
+ push(@cBody, $exceptionHandling);
+ }
+ }
+
+ if ($returnType ne "void" && !$isCustomFunction) {
+ if ($functionSigType ne "DOMObject") {
+ if ($returnValueIsGDOMType) {
+ push(@cBody, " ${returnType} res = static_cast<${returnType}>(WebKit::kit(g_res.get()));\n");
+ }
+ }
+ if ($functionSigType eq "DOMObject") {
+ push(@cBody, " return NULL; /* TODO: return canvas object */\n");
+ } else {
+ push(@cBody, " return res;\n");
+ }
+ }
+ push(@cBody, "\n}\n\n");
+}
+
+sub ClassHasFunction {
+ my ($class, $name) = @_;
+
+ foreach my $function (@{$class->functions}) {
+ if ($function->signature->name eq $name) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+sub GenerateFunctions {
+ my ($object, $interfaceName, $dataNode) = @_;
+
+ foreach my $function (@{$dataNode->functions}) {
+ $object->GenerateFunction($interfaceName, $function, "");
+ }
+
+ TOP:
+ foreach my $attribute (@{$dataNode->attributes}) {
+ if (SkipAttribute($attribute)) {
+ next TOP;
+ }
+
+ if ($attribute->signature->name eq "type"
+ # This will conflict with the get_type() function we define to return a GType
+ # according to GObject conventions. Skip this for now.
+ || $attribute->signature->name eq "URL" # TODO: handle this
+ || $attribute->signature->extendedAttributes->{"ConvertFromString"} # TODO: handle this
+ ) {
+ next TOP;
+ }
+
+ my $attrNameUpper = $codeGenerator->WK_ucfirst($attribute->signature->name);
+ my $getname = "get${attrNameUpper}";
+ my $setname = "set${attrNameUpper}";
+ if (ClassHasFunction($dataNode, $getname) || ClassHasFunction($dataNode, $setname)) {
+ # Very occasionally an IDL file defines getter/setter functions for one of its
+ # attributes; in this case we don't need to autogenerate the getter/setter.
+ next TOP;
+ }
+
+ # Generate an attribute getter. For an attribute "foo", this is a function named
+ # "get_foo" which calls a DOM class method named foo().
+ my $function = new domFunction();
+ $function->signature($attribute->signature);
+ $function->raisesExceptions($attribute->getterExceptions);
+ $object->GenerateFunction($interfaceName, $function, "get_");
+
+ if ($attribute->type =~ /^readonly/ ||
+ $attribute->signature->extendedAttributes->{"Replaceable"} # can't handle this yet
+ ) {
+ next TOP;
+ }
+
+ # Generate an attribute setter. For an attribute, "foo", this is a function named
+ # "set_foo" which calls a DOM class method named setFoo().
+ $function = new domFunction();
+
+ $function->signature(new domSignature());
+ $function->signature->name($setname);
+ $function->signature->type("void");
+ $function->signature->extendedAttributes($attribute->signature->extendedAttributes);
+
+ my $param = new domSignature();
+ $param->name("value");
+ $param->type($attribute->signature->type);
+ my %attributes = ();
+ $param->extendedAttributes(attributes);
+ my $arrayRef = $function->parameters;
+ push(@$arrayRef, $param);
+
+ $function->raisesExceptions($attribute->setterExceptions);
+
+ $object->GenerateFunction($interfaceName, $function, "");
+ }
+}
+
+sub GenerateCFile {
+ my ($object, $interfaceName, $parentClassName, $parentGObjType, $dataNode) = @_;
+ my $implContent = "";
+
+ my $clsCaps = uc(decamelize($interfaceName));
+ my $lowerCaseIfaceName = "webkit_dom_" . decamelize($interfaceName);
+
+ $implContent = << "EOF";
+G_DEFINE_TYPE(${className}, ${lowerCaseIfaceName}, ${parentGObjType})
+
+namespace WebKit {
+
+${className}* wrap${interfaceName}(WebCore::${interfaceName}* coreObject)
+{
+ g_return_val_if_fail(coreObject != 0, 0);
+
+ ${className}* wrapper = WEBKIT_DOM_${clsCaps}(g_object_new(WEBKIT_TYPE_DOM_${clsCaps}, NULL));
+ g_return_val_if_fail(wrapper != 0, 0);
+
+ /* We call ref() rather than using a C++ smart pointer because we can't store a C++ object
+ * in a C-allocated GObject structure. See the finalize() code for the
+ * matching deref().
+ */
+
+ coreObject->ref();
+ WEBKIT_DOM_OBJECT(wrapper)->coreObject = coreObject;
+
+ return wrapper;
+}
+
+WebCore::${interfaceName}* core(${className}* request)
+{
+ g_return_val_if_fail(request != 0, 0);
+
+ WebCore::${interfaceName}* coreObject = static_cast<WebCore::${interfaceName}*>(WEBKIT_DOM_OBJECT(request)->coreObject);
+ g_return_val_if_fail(coreObject != 0, 0);
+
+ return coreObject;
+}
+
+} // namespace WebKit
+EOF
+
+ push(@cBodyPriv, $implContent);
+ $object->GenerateProperties($interfaceName, $dataNode);
+ $object->GenerateFunctions($interfaceName, $dataNode);
+}
+
+sub GenerateEndHeader {
+ my ($object) = @_;
+
+ #Header guard
+ my $guard = $className . "_h";
+
+ push(@hBody, "G_END_DECLS\n\n");
+ push(@hBody, "#endif /* $guard */\n");
+}
+
+sub GeneratePrivateHeader {
+ my $object = shift;
+ my $dataNode = shift;
+
+ my $interfaceName = $dataNode->name;
+ my $filename = "$outputDir/" . $className . "Private.h";
+ my $guard = uc(decamelize($className)) . "_PRIVATE_H";
+ my $parentClassName = GetParentClassName($dataNode);
+ my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
+ my $hasRealParent = @{$dataNode->parents} > 0;
+ my $hasParent = $hasLegacyParent || $hasRealParent;
+
+ open(PRIVHEADER, ">$filename") or die "Couldn't open file $filename for writing";
+
+ print PRIVHEADER split("\r", $licenceTemplate);
+ print PRIVHEADER "\n";
+
+ my $text = << "EOF";
+#ifndef $guard
+#define $guard
+
+#include <glib-object.h>
+#include <webkit/${parentClassName}.h>
+#include "${interfaceName}.h"
+EOF
+
+ print PRIVHEADER $text;
+
+ print PRIVHEADER map { "#include \"$_\"\n" } sort keys(%hdrPropIncludes);
+ print PRIVHEADER "\n" if keys(%hdrPropIncludes);
+
+ $text = << "EOF";
+namespace WebKit {
+ ${className} *
+ wrap${interfaceName}(WebCore::${interfaceName} *coreObject);
+
+ WebCore::${interfaceName} *
+ core(${className} *request);
+
+EOF
+
+ print PRIVHEADER $text;
+
+ if ($className ne "WebKitDOMNode") {
+ $text = << "EOF";
+ gpointer
+ kit(WebCore::${interfaceName}* node);
+
+EOF
+ print PRIVHEADER $text;
+ }
+
+ $text = << "EOF";
+} // namespace WebKit
+
+#endif /* ${guard} */
+EOF
+ print PRIVHEADER $text;
+
+ close(PRIVHEADER);
+}
+
+sub UsesManualToJSImplementation {
+ my $type = shift;
+
+ return 1 if $type eq "Node" or $type eq "Document" or $type eq "HTMLCollection" or
+ $type eq "SVGPathSeg" or $type eq "StyleSheet" or $type eq "CSSRule" or $type eq "CSSValue" or
+ $type eq "Event" or $type eq "Element" or $type eq "Text";
+ return 0;
+}
+
+sub Generate {
+ my ($object, $dataNode) = @_;
+
+ my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
+ my $hasRealParent = @{$dataNode->parents} > 0;
+ my $hasParent = $hasLegacyParent || $hasRealParent;
+ my $parentClassName = GetParentClassName($dataNode);
+ my $parentGObjType = GetParentGObjType($dataNode);
+ my $interfaceName = $dataNode->name;
+
+ # Add the default impl header template
+ @cPrefix = split("\r", $licenceTemplate);
+ push(@cPrefix, "\n");
+
+ $implIncludes{"webkitmarshal.h"} = 1;
+ $implIncludes{"webkitprivate.h"} = 1;
+ $implIncludes{"WebKitDOMBinding.h"} = 1;
+ $implIncludes{"gobject/ConvertToUTF8String.h"} = 1;
+ $implIncludes{"webkit/$className.h"} = 1;
+ $implIncludes{"webkit/${className}Private.h"} = 1;
+ $implIncludes{"${interfaceName}.h"} = 1;
+ $implIncludes{"ExceptionCode.h"} = 1;
+
+ $hdrIncludes{"webkit/${parentClassName}.h"} = 1;
+
+ if ($className ne "WebKitDOMNode") {
+ my $converter = << "EOF";
+namespace WebKit {
+
+gpointer kit(WebCore::$interfaceName* obj)
+{
+ g_return_val_if_fail(obj != 0, 0);
+
+ if (gpointer ret = DOMObjectCache::get(obj))
+ return ret;
+
+ return DOMObjectCache::put(obj, WebKit::wrap${interfaceName}(obj));
+}
+
+} // namespace WebKit //
+
+EOF
+ push(@cBody, $converter);
+ }
+
+ $object->GenerateHeader($interfaceName, $parentClassName);
+ $object->GenerateCFile($interfaceName, $parentClassName, $parentGObjType, $dataNode);
+ $object->GenerateEndHeader();
+ $object->GeneratePrivateHeader($dataNode);
+}
+
+# Internal helper
+sub WriteData {
+ my ($object, $name) = @_;
+
+ # Write public header.
+ my $hdrFName = "$outputDir/" . $name . ".h";
+ open(HEADER, ">$hdrFName") or die "Couldn't open file $hdrFName";
+
+ print HEADER @hPrefix;
+ print HEADER @hPrefixGuard;
+ print HEADER "#include \"webkit/webkitdomdefines.h\"\n";
+ print HEADER "#include <glib-object.h>\n";
+ print HEADER "#include <webkit/webkitdefines.h>\n";
+ print HEADER map { "#include \"$_\"\n" } sort keys(%hdrIncludes);
+ print HEADER "\n" if keys(%hdrIncludes);
+ print HEADER "\n";
+ print HEADER @hBodyPre;
+ print HEADER @hBody;
+
+ close(HEADER);
+
+ # Write the implementation sources
+ my $implFileName = "$outputDir/" . $name . ".cpp";
+ open(IMPL, ">$implFileName") or die "Couldn't open file $implFileName";
+
+ print IMPL @cPrefix;
+ print IMPL "#include <glib-object.h>\n";
+ print IMPL "#include \"config.h\"\n\n";
+ print IMPL "#include <wtf/GetPtr.h>\n";
+ print IMPL "#include <wtf/RefPtr.h>\n";
+ print IMPL map { "#include \"$_\"\n" } sort keys(%implIncludes);
+ print IMPL "\n" if keys(%implIncludes);
+ print IMPL @cBody;
+
+ print IMPL "\n";
+ print IMPL @cBodyPriv;
+
+ close(IMPL);
+
+ %implIncludes = ();
+ %hdrIncludes = ();
+ @hPrefix = ();
+ @hBody = ();
+
+ @cPrefix = ();
+ @cBody = ();
+ @cBodyPriv = ();
+}
+
+sub GenerateInterface {
+ my ($object, $dataNode, $defines) = @_;
+ my $name = $dataNode->name;
+
+ # Set up some global variables
+ $className = GetClassName($dataNode->name);
+ $object->Generate($dataNode);
+
+ # Write changes
+ my $fname = "WebKitDOM_" . $name;
+ $fname =~ s/_//g;
+ $object->WriteData($fname);
+}
diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm
index 94fc2b8..919e321 100644
--- a/WebCore/bindings/scripts/CodeGeneratorJS.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm
@@ -17,7 +17,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
@@ -32,6 +32,7 @@ my $writeDependencies = 0;
my @headerContentHeader = ();
my @headerContent = ();
my %headerIncludes = ();
+my %headerTrailingIncludes = ();
my @implContentHeader = ();
my @implContent = ();
@@ -143,6 +144,7 @@ sub GetVisibleClassName
my $className = shift;
return "DOMException" if $className eq "DOMCoreException";
+ return "FormData" if $className eq "DOMFormData";
return $className;
}
@@ -212,12 +214,32 @@ sub AddIncludesForSVGAnimatedType
}
}
+sub IsScriptProfileType
+{
+ my $type = shift;
+ return 1 if ($type eq "ScriptProfile" or $type eq "ScriptProfileNode");
+ return 0;
+}
+
+sub AddTypedefForScriptProfileType
+{
+ my $type = shift;
+ (my $jscType = $type) =~ s/Script//;
+
+ push(@headerContent, "typedef JSC::$jscType $type;\n\n");
+}
+
sub AddClassForwardIfNeeded
{
my $implClassName = shift;
# SVGAnimatedLength/Number/etc. are typedefs to SVGAnimatedTemplate, so don't use class forwards for them!
- push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName);
+ unless ($codeGenerator->IsSVGAnimatedType($implClassName) or IsScriptProfileType($implClassName)) {
+ push(@headerContent, "class $implClassName;\n\n");
+ # ScriptProfile and ScriptProfileNode are typedefs to JSC::Profile and JSC::ProfileNode.
+ } elsif (IsScriptProfileType($implClassName)) {
+ AddTypedefForScriptProfileType($implClassName);
+ }
}
sub IsSVGTypeNeedingContextParameter
@@ -517,6 +539,7 @@ sub GenerateHeader
# Get correct pass/store types respecting PODType flag
my $podType = $dataNode->extendedAttributes->{"PODType"};
my $implType = $podType ? "JSSVGPODTypeWrapper<$podType> " : $implClassName;
+
$headerIncludes{"$podType.h"} = 1 if $podType and $podType ne "float";
$headerIncludes{"JSSVGPODTypeWrapper.h"} = 1 if $podType;
@@ -551,7 +574,9 @@ sub GenerateHeader
# Prototype
push(@headerContent, " static JSC::JSObject* createPrototype(JSC::ExecState*, JSC::JSGlobalObject*);\n") unless ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"});
- $implIncludes{"${className}Custom.h"} = 1 if $dataNode->extendedAttributes->{"CustomHeader"} || $dataNode->extendedAttributes->{"CustomPutFunction"} || $dataNode->extendedAttributes->{"DelegatingPutFunction"};
+ $headerTrailingIncludes{"${className}Custom.h"} = 1 if $dataNode->extendedAttributes->{"CustomHeader"};
+
+ $implIncludes{"${className}Custom.h"} = 1 if !$dataNode->extendedAttributes->{"CustomHeader"} && ($dataNode->extendedAttributes->{"CustomPutFunction"} || $dataNode->extendedAttributes->{"DelegatingPutFunction"});
my $hasGetter = $numAttributes > 0
|| !($dataNode->extendedAttributes->{"OmitConstructor"}
@@ -743,7 +768,7 @@ sub GenerateHeader
# Index getter
if ($dataNode->extendedAttributes->{"HasIndexGetter"}) {
- push(@headerContent, " static JSC::JSValue indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n");
+ push(@headerContent, " static JSC::JSValue indexGetter(JSC::ExecState*, JSC::JSValue, unsigned);\n");
}
if ($dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) {
push(@headerContent, " JSC::JSValue getByIndex(JSC::ExecState*, unsigned index);\n");
@@ -758,7 +783,7 @@ sub GenerateHeader
if ($dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"}) {
push(@headerContent, "private:\n");
push(@headerContent, " static bool canGetItemsForName(JSC::ExecState*, $implClassName*, const JSC::Identifier&);\n");
- push(@headerContent, " static JSC::JSValue nameGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n");
+ push(@headerContent, " static JSC::JSValue nameGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n");
}
push(@headerContent, "};\n\n");
@@ -859,7 +884,7 @@ sub GenerateHeader
push(@headerContent,"// Attributes\n\n");
foreach my $attribute (@{$dataNode->attributes}) {
my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : "");
- push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n");
+ push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n");
unless ($attribute->type =~ /readonly/) {
my $setter = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : "");
push(@headerContent, "void ${setter}(JSC::ExecState*, JSC::JSObject*, JSC::JSValue);\n");
@@ -868,7 +893,7 @@ sub GenerateHeader
if (!($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})) {
my $getter = "js" . $interfaceName . "Constructor";
- push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n");
+ push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n");
}
}
@@ -876,7 +901,7 @@ sub GenerateHeader
push(@headerContent,"// Constants\n\n");
foreach my $constant (@{$dataNode->constants}) {
my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($constant->name);
- push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n");
+ push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n");
}
}
@@ -1286,9 +1311,9 @@ sub GenerateImplementation
push(@implContent, "#if ${conditionalString}\n");
}
- push(@implContent, "JSValue ${getFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n");
+ push(@implContent, "JSValue ${getFunctionName}(ExecState* exec, JSValue slotBase, const Identifier&)\n");
push(@implContent, "{\n");
- push(@implContent, " ${className}* castedThis = static_cast<$className*>(asObject(slot.slotBase()));\n");
+ push(@implContent, " ${className}* castedThis = static_cast<$className*>(asObject(slotBase));\n");
my $implClassNameForValueConversion = "";
if (!$podType and ($codeGenerator->IsSVGAnimatedType($implClassName) or $attribute->type !~ /^readonly/)) {
@@ -1402,9 +1427,9 @@ sub GenerateImplementation
if (!($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})) {
my $constructorFunctionName = "js" . $interfaceName . "Constructor";
- push(@implContent, "JSValue ${constructorFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n");
+ push(@implContent, "JSValue ${constructorFunctionName}(ExecState* exec, JSValue slotBase, const Identifier&)\n");
push(@implContent, "{\n");
- push(@implContent, " ${className}* domObject = static_cast<$className*>(asObject(slot.slotBase()));\n");
+ push(@implContent, " ${className}* domObject = static_cast<$className*>(asObject(slotBase));\n");
push(@implContent, " return ${className}::getConstructor(exec, domObject->globalObject());\n");
push(@implContent, "}\n");
}
@@ -1461,6 +1486,12 @@ sub GenerateImplementation
my $putFunctionName = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : "");
my $implSetterFunctionName = $codeGenerator->WK_ucfirst($name);
+ my $conditional = $attribute->signature->extendedAttributes->{"Conditional"};
+ if ($conditional) {
+ $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
+ push(@implContent, "#if ${conditionalString}\n");
+ }
+
push(@implContent, "void ${putFunctionName}(ExecState* exec, JSObject* thisObject, JSValue value)\n");
push(@implContent, "{\n");
@@ -1478,12 +1509,28 @@ sub GenerateImplementation
} elsif ($type eq "EventListener") {
$implIncludes{"JSEventListener.h"} = 1;
push(@implContent, " UNUSED_PARAM(exec);\n");
+ my $windowEventListener = $attribute->signature->extendedAttributes->{"WindowEventListener"};
+ if ($windowEventListener) {
+ push(@implContent, " ${className}* castedThis = static_cast<${className}*>(thisObject);\n");
+ push(@implContent, " JSDOMGlobalObject* globalObject = castedThis->globalObject();\n");
+ }
push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(thisObject)->impl());\n");
- push(@implContent, " imp->set$implSetterFunctionName(createJSAttributeEventListener(exec, value, thisObject));\n");
+ if ($interfaceName eq "WorkerContext" and $name eq "onerror") {
+ $implIncludes{"JSWorkerContextErrorHandler.h"} = 1;
+ push(@implContent, " imp->set$implSetterFunctionName(createJSWorkerContextErrorHandler(exec, value, thisObject));\n");
+ } else {
+ if ($windowEventListener) {
+ push(@implContent, " imp->set$implSetterFunctionName(createJSAttributeEventListener(exec, value, globalObject));\n");
+ } else {
+ push(@implContent, " imp->set$implSetterFunctionName(createJSAttributeEventListener(exec, value, thisObject));\n");
+ }
+ }
} elsif ($attribute->signature->type =~ /Constructor$/) {
my $constructorType = $attribute->signature->type;
$constructorType =~ s/Constructor$//;
- $implIncludes{"JS" . $constructorType . ".h"} = 1;
+ if ($constructorType ne "DOMObject") {
+ $implIncludes{"JS" . $constructorType . ".h"} = 1;
+ }
push(@implContent, " // Shadowing a built-in constructor\n");
push(@implContent, " static_cast<$className*>(thisObject)->putDirect(Identifier(exec, \"$name\"), value);\n");
} elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
@@ -1522,7 +1569,13 @@ sub GenerateImplementation
}
}
- push(@implContent, "}\n\n");
+ push(@implContent, "}\n");
+
+ if ($conditional) {
+ push(@implContent, "#endif\n");
+ }
+
+ push(@implContent, "\n");
}
}
}
@@ -1701,7 +1754,7 @@ sub GenerateImplementation
my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($constant->name);
# FIXME: this casts into int to match our previous behavior which turned 0xFFFFFFFF in -1 for NodeFilter.SHOW_ALL
- push(@implContent, "JSValue ${getter}(ExecState* exec, const Identifier&, const PropertySlot&)\n");
+ push(@implContent, "JSValue ${getter}(ExecState* exec, JSValue, const Identifier&)\n");
push(@implContent, "{\n");
push(@implContent, " return jsNumber(exec, static_cast<int>(" . $constant->value . "));\n");
push(@implContent, "}\n\n");
@@ -1709,14 +1762,14 @@ sub GenerateImplementation
}
if ($dataNode->extendedAttributes->{"HasIndexGetter"}) {
- push(@implContent, "\nJSValue ${className}::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)\n");
+ push(@implContent, "\nJSValue ${className}::indexGetter(ExecState* exec, JSValue slotBase, unsigned index)\n");
push(@implContent, "{\n");
- push(@implContent, " ${className}* thisObj = static_cast<$className*>(asObject(slot.slotBase()));\n");
+ push(@implContent, " ${className}* thisObj = static_cast<$className*>(asObject(slotBase));\n");
if (IndexGetterReturnsStrings($implClassName)) {
$implIncludes{"KURL.h"} = 1;
- push(@implContent, " return jsStringOrNull(exec, thisObj->impl()->item(slot.index()));\n");
+ push(@implContent, " return jsStringOrNull(exec, thisObj->impl()->item(index));\n");
} else {
- push(@implContent, " return toJS(exec, thisObj->globalObject(), static_cast<$implClassName*>(thisObj->impl())->item(slot.index()));\n");
+ push(@implContent, " return toJS(exec, thisObj->globalObject(), static_cast<$implClassName*>(thisObj->impl())->item(index));\n");
}
push(@implContent, "}\n");
if ($interfaceName eq "HTMLCollection" or $interfaceName eq "HTMLAllCollection") {
@@ -1832,7 +1885,8 @@ sub GetNativeTypeFromSignature
my %nativeType = (
"CompareHow" => "Range::CompareHow",
- "DOMString" => "const UString&",
+ "DOMString" => "const String&",
+ "DOMObject" => "ScriptValue",
"NodeFilter" => "RefPtr<NodeFilter>",
"SVGAngle" => "SVGAngle",
"SVGLength" => "SVGLength",
@@ -1883,7 +1937,11 @@ sub JSValueToNative
if ($type eq "DOMString") {
return "valueToStringWithNullCheck(exec, $value)" if $signature->extendedAttributes->{"ConvertNullToNullString"};
return "valueToStringWithUndefinedOrNullCheck(exec, $value)" if $signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"};
- return "$value.toString(exec)";
+ return "ustringToString($value.toString(exec))";
+ }
+
+ if ($type eq "DOMObject") {
+ return "$value";
}
if ($type eq "SerializedScriptValue" or $type eq "any") {
@@ -1985,7 +2043,11 @@ sub NativeToJSValue
}
if ($type eq "DOMObject") {
- $implIncludes{"JSCanvasRenderingContext2D.h"} = 1;
+ if ($implClassName eq "Document") {
+ $implIncludes{"JSCanvasRenderingContext2D.h"} = 1;
+ } else {
+ return "$value.jsValue();";
+ }
} elsif ($type =~ /SVGPathSeg/) {
$implIncludes{"JS$type.h"} = 1;
$joinedName = $type;
@@ -2123,6 +2185,7 @@ tableSizeLoop:
$i = 0;
foreach my $key (@{$keys}) {
my $conditional;
+ my $targetType;
if ($conditionals) {
$conditional = $conditionals->{$key};
@@ -2131,7 +2194,13 @@ tableSizeLoop:
my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
push(@implContent, "#if ${conditionalString}\n");
}
- push(@implContent, " { \"$key\", @$specials[$i], (intptr_t)@$value1[$i], (intptr_t)@$value2[$i] },\n");
+
+ if ("@$specials[$i]" =~ m/Function/) {
+ $targetType = "static_cast<NativeFunction>";
+ } else {
+ $targetType = "static_cast<PropertySlot::GetValueFunc>";
+ }
+ push(@implContent, " { \"$key\", @$specials[$i], (intptr_t)" . $targetType . "(@$value1[$i]), (intptr_t)@$value2[$i] },\n");
if ($conditional) {
push(@implContent, "#endif\n");
}
@@ -2246,12 +2315,23 @@ sub WriteData
}
print $HEADER @headerContent;
+
+ @includes = ();
+ foreach my $include (keys %headerTrailingIncludes) {
+ $include = "\"$include\"" unless $include =~ /^["<]/; # "
+ push @includes, $include;
+ }
+ foreach my $include (sort @includes) {
+ print $HEADER "#include $include\n";
+ }
+
close($HEADER);
undef($HEADER);
@headerContentHeader = ();
@headerContent = ();
%headerIncludes = ();
+ %headerTrailingIncludes = ();
}
if (defined($DEPS)) {
diff --git a/WebCore/bindings/scripts/CodeGeneratorObjC.pm b/WebCore/bindings/scripts/CodeGeneratorObjC.pm
index dcb22a7..3c5fe45 100644
--- a/WebCore/bindings/scripts/CodeGeneratorObjC.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorObjC.pm
@@ -17,7 +17,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
@@ -222,7 +222,13 @@ sub ReadPublicInterfaces
%publicInterfaces = ();
my $fileName = "WebCore/bindings/objc/PublicDOMInterfaces.h";
- open FILE, "-|", "/usr/bin/gcc", "-E", "-P", "-x", "objective-c",
+ my $gccLocation = "";
+ if (($Config::Config{'osname'}) =~ /solaris/i) {
+ $gccLocation = "/usr/sfw/bin/gcc";
+ } else {
+ $gccLocation = "/usr/bin/gcc";
+ }
+ open FILE, "-|", $gccLocation, "-E", "-P", "-x", "objective-c",
(map { "-D$_" } split(/ +/, $defines)), "-DOBJC_CODE_GENERATION", $fileName or die "Could not open $fileName";
my @documentContent = <FILE>;
close FILE;
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
index ee51ec3..1c5f398 100644
--- a/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -18,7 +18,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
@@ -84,11 +84,6 @@ sub finish
$object->WriteData();
}
-sub leftShift($$) {
- my ($value, $distance) = @_;
- return (($value << $distance) & 0xFFFFFFFF);
-}
-
# Workaround for V8 bindings difference where RGBColor is not a POD type.
sub IsPodType
{
@@ -126,13 +121,6 @@ sub GenerateModule
$module = $dataNode->module;
}
-sub GetLegacyHeaderIncludes
-{
- my $legacyParent = shift;
-
- die "Don't know what headers to include for module $module";
-}
-
sub AvoidInclusionOfType
{
my $type = shift;
@@ -142,14 +130,6 @@ sub AvoidInclusionOfType
return 0;
}
-sub UsesManualToJSImplementation
-{
- my $type = shift;
-
- return 1 if $type eq "SVGPathSeg";
- return 0;
-}
-
sub AddIncludesForType
{
my $type = $codeGenerator->StripModule(shift);
@@ -203,14 +183,6 @@ sub AddIncludesForSVGAnimatedType
$implIncludes{"SVGAnimatedTemplate.h"} = 1;
}
-sub AddClassForwardIfNeeded
-{
- my $implClassName = shift;
-
- # SVGAnimatedLength/Number/etc.. are typedefs to SVGAnimtatedTemplate, so don't use class forwards for them!
- push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName);
-}
-
# If the node has a [Conditional=XXX] attribute, returns an "ENABLE(XXX)" string for use in an #if.
sub GenerateConditionalString
{
@@ -223,6 +195,23 @@ sub GenerateConditionalString
}
}
+sub LinkOverloadedFunctions
+{
+ my $dataNode = shift;
+
+ # Identifies overloaded functions and for each function adds an array with
+ # links to its respective overloads (including itself).
+ my %nameToFunctionsMap = ();
+ foreach my $function (@{$dataNode->functions}) {
+ my $name = $function->signature->name;
+ $nameToFunctionsMap{$name} = [] if !exists $nameToFunctionsMap{$name};
+ push(@{$nameToFunctionsMap{$name}}, $function);
+ $function->{overloads} = $nameToFunctionsMap{$name};
+ $function->{overloadIndex} = @{$nameToFunctionsMap{$name}};
+ }
+
+}
+
sub GenerateHeader
{
my $object = shift;
@@ -243,19 +232,26 @@ sub GenerateHeader
@headerContent = split("\r", $headerTemplate);
push(@headerContent, "\n#if ${conditionalString}\n\n") if $conditionalString;
- push(@headerContent, "\n#ifndef $className" . "_H");
- push(@headerContent, "\n#define $className" . "_H\n\n");
+ push(@headerContent, "\n#ifndef $className" . "_h");
+ push(@headerContent, "\n#define $className" . "_h\n\n");
# Get correct pass/store types respecting PODType flag
my $podType = $dataNode->extendedAttributes->{"PODType"};
- push(@headerContent, "#include \"$podType.h\"\n") if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
+ my %headerInclues = ();
+ $headerIncludes{"$podType.h"} = 1 if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
+ $headerIncludes{"StringHash.h"} = 1;
+ $headerIncludes{"WrapperTypeInfo.h"} = 1;
+ my $headerClassInclude = GetHeaderClassInclude($implClassName);
+ $headerIncludes{$headerClassInclude} = 1 if $headerClassInclude ne "";
+
+ foreach my $headerInclude (sort keys(%headerIncludes)) {
+ push(@headerContent, "#include \"${headerInclude}\"\n");
+ }
push(@headerContent, "#include <v8.h>\n");
push(@headerContent, "#include <wtf/HashMap.h>\n");
- push(@headerContent, "#include \"StringHash.h\"\n");
- push(@headerContent, "#include \"V8Index.h\"\n");
- push(@headerContent, GetHeaderClassInclude($implClassName));
+
push(@headerContent, "\nnamespace WebCore {\n");
if ($podType) {
push(@headerContent, "\ntemplate<typename PODType> class V8SVGPODTypeWrapper;\n");
@@ -269,17 +265,22 @@ sub GenerateHeader
my $forceNewObjectParameter = IsDOMNodeType($interfaceName) ? ", bool forceNewObject = false" : "";
push(@headerContent, <<END);
- public:
- static bool HasInstance(v8::Handle<v8::Value> value);
- static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
- static v8::Persistent<v8::FunctionTemplate> GetTemplate();
- static ${nativeType}* toNative(v8::Handle<v8::Object>);
- static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
+public:
+ static bool HasInstance(v8::Handle<v8::Value> value);
+ static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
+ static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ static ${nativeType}* toNative(v8::Handle<v8::Object>);
+ static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
+ static void derefObject(void*);
+ static WrapperTypeInfo info;
END
+ if (IsActiveDomType($implClassName)) {
+ push(@headerContent, " static ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object>);\n");
+ }
if ($implClassName eq "DOMWindow") {
- push(@headerContent, <<END);
- static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
+ push(@headerContent, <<END);
+ static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
END
}
@@ -288,11 +289,12 @@ END
my $name = $function->signature->name;
my $attrExt = $function->signature->extendedAttributes;
- # FIXME: We should only be generating callback declarations for functions labeled [Custom] or [V8Custom],
- # but we can't do that due to some mislabeled functions in the idl's (https://bugs.webkit.org/show_bug.cgi?id=33066).
- push(@headerContent, <<END);
- static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments&);
+ if ($attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments&);
END
+ }
+
if ($attrExt->{"EnabledAtRuntime"}) {
push(@enabledAtRuntime, $function);
}
@@ -300,7 +302,7 @@ END
if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> constructorCallback(const v8::Arguments& args);
+ static v8::Handle<v8::Value> constructorCallback(const v8::Arguments& args);
END
}
@@ -310,13 +312,13 @@ END
if ($attrExt->{"V8CustomGetter"} || $attrExt->{"CustomGetter"}
|| $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> ${name}AccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> ${name}AccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
END
}
if ($attrExt->{"V8CustomSetter"} || $attrExt->{"CustomSetter"}
|| $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) {
push(@headerContent, <<END);
- static void ${name}AccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+ static void ${name}AccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
END
}
if ($attrExt->{"EnabledAtRuntime"}) {
@@ -330,24 +332,24 @@ END
if ($dataNode->extendedAttributes->{"CheckDomainSecurity"}) {
push(@headerContent, <<END);
- static bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType, v8::Local<v8::Value> data);
- static bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType, v8::Local<v8::Value> data);
+ static bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType, v8::Local<v8::Value> data);
+ static bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType, v8::Local<v8::Value> data);
END
}
push(@headerContent, <<END);
};
- v8::Handle<v8::Value> toV8(${nativeType}*${forceNewObjectParameter});
+v8::Handle<v8::Value> toV8(${nativeType}*${forceNewObjectParameter});
END
if (IsRefPtrType($implClassName)) {
push(@headerContent, <<END);
- v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} >${forceNewObjectParameter});
+v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} >${forceNewObjectParameter});
END
}
push(@headerContent, "}\n\n");
- push(@headerContent, "#endif // $className" . "_H\n");
+ push(@headerContent, "#endif // $className" . "_h\n");
push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditionalString;
}
@@ -356,33 +358,25 @@ sub GetInternalFields
{
my $dataNode = shift;
my $name = $dataNode->name;
-
- # FIXME: I am hideous and hard-coded. Make me beautiful.
- return ("cacheIndex", "implementationIndex") if ($name eq "Document") || ($name eq "SVGDocument");
- return ("cacheIndex", "implementationIndex", "markerIndex", "shadowIndex") if $name eq "HTMLDocument";
- return ("cacheIndex") if IsNodeSubType($dataNode);
- return ("cacheIndex") if $name eq "EventSource";
- return ("cacheIndex") if $name eq "XMLHttpRequest";
- return ("cacheIndex") if $name eq "XMLHttpRequestUpload";
- return ("cacheIndex") if $name eq "MessagePort";
- return ("port1Index", "port2Index") if ($name eq "MessageChannel");
- return ("cacheIndex") if $name eq "AbstractWorker";
- return ("abstractWorkerCacheIndex", "cacheIndex") if $name eq "Worker";
- return ("abstractWorkerCacheIndex", "cacheIndex") if $name eq "WorkerContext";
- return ("abstractWorkerCacheIndex", "workerContextCacheIndex", "cacheIndex") if $name eq "DedicatedWorkerContext";
- return ("abstractWorkerCacheIndex", "cacheIndex") if $name eq "SharedWorker";
- return ("abstractWorkerCacheIndex", "workerContextCacheIndex", "cacheIndex") if $name eq "SharedWorkerContext";
- return ("cacheIndex") if $name eq "Notification";
- return ("cacheIndex") if $name eq "IDBRequest";
- return ("cacheIndex") if $name eq "SVGElementInstance";
- return ("consoleIndex", "historyIndex", "locationbarIndex", "menubarIndex", "navigatorIndex", "personalbarIndex",
- "screenIndex", "scrollbarsIndex", "selectionIndex", "statusbarIndex", "toolbarIndex", "locationIndex",
- "domSelectionIndex", "cacheIndex", "enteredIsolatedWorldIndex") if $name eq "DOMWindow";
- return ("cacheIndex") if $name eq "DOMApplicationCache";
- return ("cacheIndex") if $name eq "WebSocket";
- return ("ownerNodeIndex") if ($name eq "StyleSheet") || ($name eq "CSSStyleSheet");
- return ("ownerNodeIndex") if ($name eq "NamedNodeMap");
- return ();
+
+ my @customInternalFields = ();
+
+ # We can't ask whether a parent type has a given extendedAttribute, so special-case Node, AbstractWorker and WorkerContext to include all sub-types.
+ # FIXME: SVGElementInstance should probably have the EventTarget extended attribute, but doesn't.
+ if ($dataNode->extendedAttributes->{"EventTarget"} || IsNodeSubType($dataNode) || IsSubType($dataNode, "AbstractWorker") || IsSubType($dataNode, "WorkerContext")
+ || $name eq "SVGElementInstance") {
+ push(@customInternalFields, "eventListenerCacheIndex");
+ }
+
+ if (IsSubType($dataNode, "Document")) {
+ push(@customInternalFields, "implementationIndex");
+ if ($name eq "HTMLDocument") {
+ push(@customInternalFields, ("markerIndex", "shadowIndex"));
+ }
+ } elsif ($name eq "DOMWindow") {
+ push(@customInternalFields, "enteredIsolatedWorldIndex");
+ }
+ return @customInternalFields;
}
sub GetHeaderClassInclude
@@ -392,8 +386,8 @@ sub GetHeaderClassInclude
$className =~ s/Abs|Rel//;
}
return "" if (AvoidInclusionOfType($className));
- return "#include \"SVGAnimatedTemplate.h\"\n" if ($codeGenerator->IsSVGAnimatedType($className));
- return "#include \"${className}.h\"\n";
+ return "SVGAnimatedTemplate.h" if ($codeGenerator->IsSVGAnimatedType($className));
+ return "${className}.h";
}
sub GenerateHeaderCustomInternalFieldIndices
@@ -403,12 +397,12 @@ sub GenerateHeaderCustomInternalFieldIndices
my $customFieldCounter = 0;
foreach my $customInternalField (@customInternalFields) {
push(@headerContent, <<END);
- static const int ${customInternalField} = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
+ static const int ${customInternalField} = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
END
$customFieldCounter++;
}
push(@headerContent, <<END);
- static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
+ static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
END
}
@@ -439,45 +433,45 @@ sub GenerateHeaderNamedAndIndexedPropertyAccessors
$hasCustomDeleterr = 0;
$hasEnumerator = 0;
}
- if ($interfaceName eq "HTMLSelectElement") {
+ if ($interfaceName eq "HTMLSelectElement" || $interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
$hasCustomNamedGetter = 1;
}
my $isIndexerSpecialCase = exists $indexerSpecialCases{$interfaceName};
if ($hasCustomIndexedGetter || $isIndexerSpecialCase) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info);
END
}
if ($isIndexerSpecialCase || $hasCustomIndexedSetter) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> indexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> indexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
END
}
if ($hasCustomDeleters) {
push(@headerContent, <<END);
- static v8::Handle<v8::Boolean> indexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Boolean> indexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info);
END
}
if ($hasCustomNamedGetter) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
END
}
if ($hasCustomNamedSetter) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
END
}
if ($hasCustomDeleters || $interfaceName eq "HTMLDocument") {
push(@headerContent, <<END);
- static v8::Handle<v8::Boolean> namedPropertyDeleter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Boolean> namedPropertyDeleter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
END
}
if ($hasCustomEnumerator) {
push(@headerContent, <<END);
- static v8::Handle<v8::Array> namedPropertyEnumerator(const v8::AccessorInfo& info);
+ static v8::Handle<v8::Array> namedPropertyEnumerator(const v8::AccessorInfo& info);
END
}
}
@@ -487,16 +481,16 @@ sub GenerateHeaderCustomCall
my $dataNode = shift;
if ($dataNode->extendedAttributes->{"CustomCall"}) {
- push(@headerContent, " static v8::Handle<v8::Value> callAsFunctionCallback(const v8::Arguments&);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> callAsFunctionCallback(const v8::Arguments&);\n");
}
if ($dataNode->name eq "Event") {
- push(@headerContent, " static v8::Handle<v8::Value> dataTransferAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
- push(@headerContent, " static void valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> dataTransferAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static void valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);\n");
}
if ($dataNode->name eq "Location") {
- push(@headerContent, " static v8::Handle<v8::Value> assignAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
- push(@headerContent, " static v8::Handle<v8::Value> reloadAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
- push(@headerContent, " static v8::Handle<v8::Value> replaceAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> assignAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> reloadAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> replaceAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
}
}
@@ -531,19 +525,12 @@ sub IsNodeSubType
return IsSubType($dataNode, "Node");
}
-sub IsEventSubType
-{
- my $dataNode = shift;
- return IsSubType($dataNode, "Event");
-}
-
sub GenerateDomainSafeFunctionGetter
{
my $function = shift;
- my $dataNode = shift;
my $implClassName = shift;
- my $className = "V8" . $dataNode->name;
+ my $className = "V8" . $implClassName;
my $funcName = $function->signature->name;
my $signature = "v8::Signature::New(" . $className . "::GetRawTemplate())";
@@ -551,29 +538,26 @@ sub GenerateDomainSafeFunctionGetter
$signature = "v8::Local<v8::Signature>()";
}
- my $newTemplateString = GenerateNewFunctionTemplate($function, $dataNode, $signature);
+ my $newTemplateString = GenerateNewFunctionTemplate($function, $implClassName, $signature);
push(@implContentDecls, <<END);
- static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
INC_STATS(\"DOM.$implClassName.$funcName._get\");
- static v8::Persistent<v8::FunctionTemplate> private_template =
- v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
+ static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(${className}::GetTemplate(), info.This());
if (holder.IsEmpty()) {
- // can only reach here by 'object.__proto__.func', and it should passed
- // domain security check already
- return private_template->GetFunction();
+ // can only reach here by 'object.__proto__.func', and it should passed
+ // domain security check already
+ return privateTemplate->GetFunction();
}
${implClassName}* imp = ${className}::toNative(holder);
if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false)) {
- static v8::Persistent<v8::FunctionTemplate> shared_template =
- v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
- return shared_template->GetFunction();
-
- } else {
- return private_template->GetFunction();
+ static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
+ return sharedTemplate->GetFunction();
}
- }
+ return privateTemplate->GetFunction();
+}
END
}
@@ -581,24 +565,24 @@ END
sub GenerateConstructorGetter
{
my $implClassName = shift;
- my $classIndex = shift;
push(@implContentDecls, <<END);
- static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
INC_STATS(\"DOM.$implClassName.constructors._get\");
v8::Handle<v8::Value> data = info.Data();
- ASSERT(data->IsNumber());
- V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(data->Int32Value());
+ ASSERT(data->IsExternal() || data->IsNumber());
+ WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data);
END
- if ($classIndex eq "DOMWINDOW") {
+ if ($implClassName eq "DOMWindow") {
push(@implContentDecls, <<END);
// Get the proxy corresponding to the DOMWindow if possible to
// make sure that the constructor function is constructed in the
// context of the DOMWindow and not in the context of the caller.
return V8DOMWrapper::getConstructor(type, V8DOMWindow::toNative(info.Holder()));
END
- } elsif ($classIndex eq "DEDICATEDWORKERCONTEXT" or $classIndex eq "WORKERCONTEXT" or $classIndex eq "SHAREDWORKERCONTEXT") {
+ } elsif ($implClassName eq "DedicatedWorkerContext" or $implClassName eq "WorkerContext" or $implClassName eq "SharedWorkerContext") {
push(@implContentDecls, <<END);
return V8DOMWrapper::getConstructor(type, V8WorkerContext::toNative(info.Holder()));
END
@@ -607,8 +591,7 @@ END
}
push(@implContentDecls, <<END);
-
- }
+}
END
}
@@ -631,7 +614,6 @@ sub GenerateNormalAttrGetter
my $isPodType = IsPodType($implClassName);
my $skipContext = 0;
-
if ($isPodType) {
$implClassName = GetNativeType($implClassName);
$implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
@@ -658,34 +640,36 @@ sub GenerateNormalAttrGetter
# Getter
push(@implContentDecls, <<END);
- static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
INC_STATS(\"DOM.$implClassName.$attrName._get\");
END
if ($isPodType) {
push(@implContentDecls, <<END);
- V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder());
- $implClassName imp_instance = *imp_wrapper;
+ V8SVGPODTypeWrapper<$implClassName>* impWrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder());
+ $implClassName impInstance = *impWrapper;
END
if ($getterStringUsesImp) {
push(@implContentDecls, <<END);
- $implClassName* imp = &imp_instance;
+ $implClassName* imp = &impInstance;
END
}
} elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) {
- if ($interfaceName eq "DOMWindow") {
- push(@implContentDecls, <<END);
+ if ($interfaceName eq "DOMWindow") {
+ push(@implContentDecls, <<END);
v8::Handle<v8::Object> holder = info.Holder();
END
- } else {
- # perform lookup first
- push(@implContentDecls, <<END);
+ } else {
+ # perform lookup first
+ push(@implContentDecls, <<END);
v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8${interfaceName}::GetTemplate(), info.This());
- if (holder.IsEmpty()) return v8::Handle<v8::Value>();
+ if (holder.IsEmpty())
+ return v8::Handle<v8::Value>();
END
- }
- push(@implContentDecls, <<END);
+ }
+ push(@implContentDecls, <<END);
${implClassName}* imp = V8${implClassName}::toNative(holder);
END
} else {
@@ -696,7 +680,7 @@ END
my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
$implIncludes{"${namespace}.h"} = 1;
push(@implContentDecls, " return getElementStringAttr(info, ${namespace}::${contentAttributeName}Attr);\n");
- push(@implContentDecls, " }\n\n");
+ push(@implContentDecls, "}\n\n");
return;
# Skip the rest of the function!
}
@@ -707,9 +691,9 @@ END
# Generate security checks if necessary
if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
- push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->$attrName())) return v8::Handle<v8::Value>();\n\n");
+ push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->$attrName()))\n return v8::Handle<v8::Value>();\n\n");
} elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
- push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->contentDocument())) return v8::Handle<v8::Value>();\n\n");
+ push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->contentDocument()))\n return v8::Handle<v8::Value>();\n\n");
}
my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType);
@@ -751,7 +735,7 @@ END
$getterString .= ".toInt()";
}
} else {
- $getterString = "imp_instance";
+ $getterString = "impInstance";
}
my $result;
@@ -768,7 +752,7 @@ END
my $implClassIsAnimatedType = $codeGenerator->IsSVGAnimatedType($implClassName);
if (not $implClassIsAnimatedType and $codeGenerator->IsPodTypeWithWriteableProperties($attrType) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
if (IsPodType($implClassName)) {
- my $wrapper = "V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>::create($getterString, imp_wrapper)";
+ my $wrapper = "V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>::create($getterString, impWrapper)";
push(@implContentDecls, " RefPtr<V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName> > wrapper = $wrapper;\n");
} else {
my $wrapper = "V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName>::create(imp, &${implClassName}::$getter, &${implClassName}::$setter)";
@@ -790,7 +774,7 @@ END
} else {
if ($attribute->signature->type eq "EventListener" && $dataNode->name eq "DOMWindow") {
push(@implContentDecls, " if (!imp->document())\n");
- push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
+ push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
}
if ($useExceptions) {
@@ -803,6 +787,32 @@ END
# Can inline the function call into the return statement to avoid overhead of using a Ref<> temporary
$result = $getterString;
}
+
+ # Special case for readonly or Replaceable attributes (with a few exceptions). This attempts to ensure that JS wrappers don't get
+ # garbage-collected prematurely when their lifetime is strongly tied to their owner. We accomplish this by inserting a reference to
+ # the newly created wrapper into an internal field of the holder object.
+ if (!IsNodeSubType($dataNode) && $attrName ne "self" && (IsWrapperType($returnType) && ($attribute->type =~ /^readonly/ || $attribute->signature->extendedAttributes->{"Replaceable"})
+ && $returnType ne "EventTarget" && $returnType ne "SerializedScriptValue" && $returnType ne "DOMWindow"
+ && $returnType !~ /SVG/ && $returnType !~ /HTML/ && !IsDOMNodeType($returnType))) {
+ AddIncludesForType($returnType);
+ my $domMapFunction = GetDomMapFunction(0, $returnType);
+ # Check for a wrapper in the wrapper cache. If there is one, we know that a hidden reference has already
+ # been created. If we don't find a wrapper, we create both a wrapper and a hidden reference.
+ push(@implContentDecls, " RefPtr<$returnType> result = ${getterString};\n");
+ push(@implContentDecls, " v8::Handle<v8::Value> wrapper = result.get() ? ${domMapFunction}.get(result.get()) : v8::Handle<v8::Value>();\n");
+ push(@implContentDecls, " if (wrapper.IsEmpty()) {\n");
+ push(@implContentDecls, " wrapper = toV8(result.get());\n");
+ push(@implContentDecls, " if (!wrapper.IsEmpty())\n");
+ if ($dataNode->name eq "DOMWindow") {
+ push(@implContentDecls, " V8DOMWrapper::setHiddenWindowReference(imp->frame(), wrapper);\n");
+ } else {
+ push(@implContentDecls, " V8DOMWrapper::setHiddenReference(info.Holder(), wrapper);\n");
+ }
+ push(@implContentDecls, " }\n");
+ push(@implContentDecls, " return wrapper;\n");
+ push(@implContentDecls, "}\n\n");
+ return;
+ }
}
if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) {
@@ -824,27 +834,9 @@ END
push(@implContentDecls, " " . ReturnNativeToJSValue($attribute->signature, $result, " ").";\n");
}
- push(@implContentDecls, " }\n\n"); # end of getter
-}
-
-
-sub GenerateReplaceableAttrSetter
-{
- my $implClassName = shift;
-
- push(@implContentDecls,
- " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
- " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
-
- push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
-
- push(@implContentDecls, " v8::Local<v8::String> ${attrName}_string = v8::String::New(\"${attrName}\");\n");
- push(@implContentDecls, " info.Holder()->Delete(${attrName}_string);\n");
- push(@implContentDecls, " info.This()->Set(${attrName}_string, value);\n");
- push(@implContentDecls, " }\n\n");
+ push(@implContentDecls, "}\n\n"); # end of getter
}
-
sub GenerateNormalAttrSetter
{
my $attribute = shift;
@@ -854,10 +846,7 @@ sub GenerateNormalAttrSetter
my $attrExt = $attribute->signature->extendedAttributes;
- push(@implContentDecls,
- " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
- " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
-
+ push(@implContentDecls, "static void ${attrName}AttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)\n{\n");
push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
my $isPodType = IsPodType($implClassName);
@@ -866,8 +855,8 @@ sub GenerateNormalAttrSetter
$implClassName = GetNativeType($implClassName);
$implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder());\n");
- push(@implContentDecls, " $implClassName imp_instance = *wrapper;\n");
- push(@implContentDecls, " $implClassName* imp = &imp_instance;\n");
+ push(@implContentDecls, " $implClassName impInstance = *wrapper;\n");
+ push(@implContentDecls, " $implClassName* imp = &impInstance;\n");
} elsif ($attrExt->{"v8OnProto"}) {
if ($interfaceName eq "DOMWindow") {
@@ -878,7 +867,8 @@ END
# perform lookup first
push(@implContentDecls, <<END);
v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8${interfaceName}::GetTemplate(), info.This());
- if (holder.IsEmpty()) return;
+ if (holder.IsEmpty())
+ return;
END
}
push(@implContentDecls, <<END);
@@ -894,7 +884,7 @@ END
my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
$implIncludes{"${namespace}.h"} = 1;
push(@implContentDecls, " setElementStringAttr(info, ${namespace}::${contentAttributeName}Attr, value);\n");
- push(@implContentDecls, " }\n\n");
+ push(@implContentDecls, "}\n\n");
return;
# Skip the rest of the function!
}
@@ -908,7 +898,7 @@ END
if ($attribute->signature->type eq "EventListener") {
if ($dataNode->name eq "DOMWindow") {
push(@implContentDecls, " if (!imp->document())\n");
- push(@implContentDecls, " return;\n");
+ push(@implContentDecls, " return;\n");
}
} else {
push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n");
@@ -947,8 +937,14 @@ END
push(@implContentDecls, " imp->setAttribute(${namespace}::${contentAttributeName}Attr, $result");
} elsif ($attribute->signature->type eq "EventListener") {
$implIncludes{"V8AbstractEventListener.h"} = 1;
- push(@implContentDecls, " transferHiddenDependency(info.Holder(), imp->$attrName(), value, V8${interfaceName}::cacheIndex);\n");
- push(@implContentDecls, " imp->set$implSetterFunctionName(V8DOMWrapper::getEventListener(imp, value, true, ListenerFindOrCreate)");
+ push(@implContentDecls, " transferHiddenDependency(info.Holder(), imp->$attrName(), value, V8${interfaceName}::eventListenerCacheIndex);\n");
+ if ($interfaceName eq "WorkerContext" and $attribute->signature->name eq "onerror") {
+ $implIncludes{"V8EventListenerList.h"} = 1;
+ $implIncludes{"V8WorkerContextErrorHandler.h"} = 1;
+ push(@implContentDecls, " imp->set$implSetterFunctionName(V8EventListenerList::findOrCreateWrapper<V8WorkerContextErrorHandler>(value, true)");
+ } else {
+ push(@implContentDecls, " imp->set$implSetterFunctionName(V8DOMWrapper::getEventListener(value, true, ListenerFindOrCreate)");
+ }
} else {
push(@implContentDecls, " imp->set$implSetterFunctionName($result");
}
@@ -971,21 +967,19 @@ END
$currentObject = "wrapper";
}
- push(@implContentDecls, " if (SVGElement* context = V8Proxy::svgContext($currentObject)) {\n");
+ push(@implContentDecls, " if (SVGElement* context = V8Proxy::svgContext($currentObject))\n");
push(@implContentDecls, " context->svgAttributeChanged(imp->associatedAttributeName());\n");
- push(@implContentDecls, " }\n");
}
push(@implContentDecls, " return;\n");
- push(@implContentDecls, " }\n\n"); # end of setter
+ push(@implContentDecls, "}\n\n"); # end of setter
}
sub GetFunctionTemplateCallbackName
{
$function = shift;
- $dataNode = shift;
+ $interfaceName = shift;
- my $interfaceName = $dataNode->name;
my $name = $function->signature->name;
if ($function->signature->extendedAttributes->{"Custom"} ||
@@ -1003,54 +997,167 @@ sub GetFunctionTemplateCallbackName
sub GenerateNewFunctionTemplate
{
$function = shift;
- $dataNode = shift;
+ $interfaceName = shift;
$signature = shift;
- my $callback = GetFunctionTemplateCallbackName($function, $dataNode);
+ my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
return "v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), $signature)";
}
+sub GenerateEventListenerCallback
+{
+ my $implClassName = shift;
+ my $functionName = shift;
+ my $lookupType = ($functionName eq "add") ? "OrCreate" : "Only";
+ my $passRefPtrHandling = ($functionName eq "add") ? "" : ".get()";
+ my $hiddenDependencyAction = ($functionName eq "add") ? "create" : "remove";
+
+ push(@implContentDecls, <<END);
+static v8::Handle<v8::Value> ${functionName}EventListenerCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.${implClassName}.${functionName}EventListener()");
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(args[1], false, ListenerFind${lookupType});
+ if (listener) {
+ V8${implClassName}::toNative(args.Holder())->${functionName}EventListener(v8ValueToAtomicWebCoreString(args[0]), listener${passRefPtrHandling}, args[2]->BooleanValue());
+ ${hiddenDependencyAction}HiddenDependency(args.Holder(), args[1], V8${implClassName}::eventListenerCacheIndex);
+ }
+ return v8::Undefined();
+}
+
+END
+}
+
+sub GenerateParametersCheckExpression
+{
+ my $numParameters = shift;
+ my $function = shift;
+
+ my @andExpression = ();
+ push(@andExpression, "args.Length() == $numParameters");
+ my $parameterIndex = 0;
+ foreach $parameter (@{$function->parameters}) {
+ last if $parameterIndex >= $numParameters;
+ my $value = "args[$parameterIndex]";
+ my $type = GetTypeFromSignature($parameter);
+
+ # Only DOMString or wrapper types are checked.
+ # For DOMString, Null, Undefined and any Object are accepted too, as
+ # these are acceptable values for a DOMString argument (any Object can
+ # be converted to a string via .toString).
+ push(@andExpression, "(${value}->IsNull() || ${value}->IsUndefined() || ${value}->IsString() || ${value}->IsObject())") if $codeGenerator->IsStringType($type);
+ push(@andExpression, "(${value}->IsNull() || V8${type}::HasInstance($value))") if IsWrapperType($type);
+
+ $parameterIndex++;
+ }
+ my $res = join(" && ", @andExpression);
+ $res = "($res)" if @andExpression > 1;
+ return $res;
+}
+
+sub GenerateFunctionParametersCheck
+{
+ my $function = shift;
+
+ my @orExpression = ();
+ my $numParameters = 0;
+ foreach $parameter (@{$function->parameters}) {
+ if ($parameter->extendedAttributes->{"Optional"}) {
+ push(@orExpression, GenerateParametersCheckExpression($numParameters, $function));
+ }
+ $numParameters++;
+ }
+ push(@orExpression, GenerateParametersCheckExpression($numParameters, $function));
+ return join(" || ", @orExpression);
+}
+
+sub GenerateOverloadedFunctionCallback
+{
+ my $function = shift;
+ my $dataNode = shift;
+ my $implClassName = shift;
+
+ # Generate code for choosing the correct overload to call. Overloads are
+ # chosen based on the total number of arguments passed and the type of
+ # values passed in non-primitive argument slots. When more than a single
+ # overload is applicable, precedence is given according to the order of
+ # declaration in the IDL.
+
+ my $name = $function->signature->name;
+ push(@implContentDecls, <<END);
+static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args)
+{
+ INC_STATS(\"DOM.$implClassName.$name\");
+END
+
+ foreach my $overload (@{$function->{overloads}}) {
+ my $parametersCheck = GenerateFunctionParametersCheck($overload);
+ push(@implContentDecls, " if ($parametersCheck)\n");
+ push(@implContentDecls, " return ${name}$overload->{overloadIndex}Callback(args);\n");
+ }
+ push(@implContentDecls, <<END);
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+END
+ push(@implContentDecls, "}\n\n");
+}
+
sub GenerateFunctionCallback
{
my $function = shift;
my $dataNode = shift;
- my $classIndex = shift;
my $implClassName = shift;
my $interfaceName = $dataNode->name;
my $name = $function->signature->name;
- push(@implContentDecls,
-" static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {\n" .
-" INC_STATS(\"DOM.$implClassName.$name\");\n");
+ if (@{$function->{overloads}} > 1) {
+ # Append a number to an overloaded method's name to make it unique:
+ $name = $name . $function->{overloadIndex};
+ }
+
+ # Adding and removing event listeners are not standard callback behavior,
+ # but they are extremely consistent across the various classes that take event listeners,
+ # so we can generate them as a "special case".
+ if ($name eq "addEventListener") {
+ GenerateEventListenerCallback($implClassName, "add");
+ return;
+ } elsif ($name eq "removeEventListener") {
+ GenerateEventListenerCallback($implClassName, "remove");
+ return;
+ }
+
+ push(@implContentDecls, <<END);
+static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args)
+{
+ INC_STATS(\"DOM.$implClassName.$name\");
+END
my $numParameters = @{$function->parameters};
if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) {
- push(@implContentDecls,
- " if (args.Length() < $numParameters) return v8::Handle<v8::Value>();\n");
+ push(@implContentDecls, " if (args.Length() < $numParameters)\n return v8::Handle<v8::Value>();\n");
}
if (IsPodType($implClassName)) {
my $nativeClassName = GetNativeType($implClassName);
- push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = V8SVGPODTypeWrapper<$nativeClassName>::toNative(args.Holder());\n");
- push(@implContentDecls, " $nativeClassName imp_instance = *imp_wrapper;\n");
- push(@implContentDecls, " $nativeClassName* imp = &imp_instance;\n");
+ push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* impWrapper = V8SVGPODTypeWrapper<$nativeClassName>::toNative(args.Holder());\n");
+ push(@implContentDecls, " $nativeClassName impInstance = *impWrapper;\n");
+ push(@implContentDecls, " $nativeClassName* imp = &impInstance;\n");
} else {
push(@implContentDecls, <<END);
${implClassName}* imp = V8${implClassName}::toNative(args.Holder());
END
}
- # Check domain security if needed
+ # Check domain security if needed
if (($dataNode->extendedAttributes->{"CheckDomainSecurity"}
|| $interfaceName eq "DOMWindow")
&& !$function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
# We have not find real use cases yet.
- push(@implContentDecls,
-" if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) {\n".
-" return v8::Handle<v8::Value>();\n" .
-" }\n");
+ push(@implContentDecls, <<END);
+ if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true))
+ return v8::Handle<v8::Value>();
+END
}
my $raisesExceptions = @{$function->raisesExceptions};
@@ -1072,16 +1179,18 @@ END
}
if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
- push(@implContentDecls,
-" OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, $numParameters));\n".
-" if (!callStack)\n".
-" return v8::Undefined();\n");
+ push(@implContentDecls, <<END);
+ OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, $numParameters));
+ if (!callStack)
+ return v8::Undefined();
+END
$implIncludes{"ScriptCallStack.h"} = 1;
}
if ($function->signature->extendedAttributes->{"SVGCheckSecurityDocument"}) {
- push(@implContentDecls,
-" if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->getSVGDocument(ec)))\n" .
-" return v8::Handle<v8::Value>();\n");
+ push(@implContentDecls, <<END);
+ if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->getSVGDocument(ec)))
+ return v8::Handle<v8::Value>();
+END
}
my $paramIndex = 0;
@@ -1098,20 +1207,29 @@ END
push(@implContentDecls, " }\n");
}
- if (BasicTypeCanFailConversion($parameter)) {
+ if ($parameter->type eq "SerializedScriptValue") {
+ $implIncludes{"SerializedScriptValue.h"} = 1;
+ push(@implContentDecls, " bool ${parameterName}DidThrow = false;\n");
+ } elsif (BasicTypeCanFailConversion($parameter)) {
push(@implContentDecls, " bool ${parameterName}Ok;\n");
}
push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, $paramIndex) . " $parameterName = ");
- push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]",
- BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n");
+
+ if ($parameter->type eq "SerializedScriptValue") {
+ push(@implContentDecls, "SerializedScriptValue::create(args[$paramIndex], ${parameterName}DidThrow);\n");
+ push(@implContentDecls, " if (${parameterName}DidThrow)\n return v8::Undefined();\n");
+ } else {
+ push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]",
+ BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n");
+ }
if (TypeCanFailConversion($parameter)) {
$implIncludes{"ExceptionCode.h"} = 1;
push(@implContentDecls,
" if (UNLIKELY(!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "") . ")) {\n" .
-" ec = TYPE_MISMATCH_ERR;\n" .
-" goto fail;\n" .
+" ec = TYPE_MISMATCH_ERR;\n" .
+" goto fail;\n" .
" }\n");
}
@@ -1119,8 +1237,8 @@ END
$implIncludes{"ExceptionCode.h"} = 1;
push(@implContentDecls,
" if (UNLIKELY($parameterName < 0)) {\n" .
-" ec = INDEX_SIZE_ERR;\n" .
-" goto fail;\n" .
+" ec = INDEX_SIZE_ERR;\n" .
+" goto fail;\n" .
" }\n");
}
@@ -1133,12 +1251,12 @@ END
if ($raisesExceptions) {
push(@implContentDecls, " }\n");
- push(@implContentDecls, " fail:\n");
+ push(@implContentDecls, " fail:\n");
push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
}
- push(@implContentDecls, " }\n\n");
+ push(@implContentDecls, "}\n\n");
}
sub GenerateBatchedAttributeData
@@ -1164,6 +1282,10 @@ sub GenerateSingleBatchedAttribute
my $attrName = $attribute->signature->name;
my $attrExt = $attribute->signature->extendedAttributes;
+ # Attributes of type SerializedScriptValue are set in the
+ # constructor and don't require callbacks.
+ return if ($attribute->signature->type eq "SerializedScriptValue");
+
my $accessControl = "v8::DEFAULT";
if ($attrExt->{"DoNotCheckDomainSecurityOnGet"}) {
$accessControl = "v8::ALL_CAN_READ";
@@ -1172,11 +1294,11 @@ sub GenerateSingleBatchedAttribute
} elsif ($attrExt->{"DoNotCheckDomainSecurity"}) {
$accessControl = "v8::ALL_CAN_READ";
if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) {
- $accessControl .= "|v8::ALL_CAN_WRITE";
+ $accessControl .= " | v8::ALL_CAN_WRITE";
}
}
if ($attrExt->{"V8DisallowShadowing"}) {
- $accessControl .= "|v8::PROHIBITS_OVERWRITING";
+ $accessControl .= " | v8::PROHIBITS_OVERWRITING";
}
$accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";
@@ -1200,24 +1322,24 @@ sub GenerateSingleBatchedAttribute
# Check attributes.
if ($attrExt->{"DontEnum"}) {
- $propAttr .= "|v8::DontEnum";
+ $propAttr .= " | v8::DontEnum";
}
if ($attrExt->{"V8DisallowShadowing"}) {
- $propAttr .= "|v8::DontDelete";
+ $propAttr .= " | v8::DontDelete";
}
my $on_proto = "0 /* on instance */";
- my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";
+ my $data = "0 /* no data */";
# Constructor
if ($attribute->signature->type =~ /Constructor$/) {
my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
$constructorType =~ s/Constructor$//;
- my $constructorIndex = uc($constructorType);
+ $implIncludes{"V8${constructorType}.h"} = 1;
if ($customAccessor) {
$getter = "V8${customAccessor}AccessorGetter";
} else {
- $data = "V8ClassIndex::${constructorIndex}";
+ $data = "&V8${constructorType}::info";
$getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
}
$setter = "0";
@@ -1247,7 +1369,7 @@ sub GenerateSingleBatchedAttribute
# FIXME: Investigate whether we could treat window.top as replaceable
# and allow shadowing without it being a security hole.
if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) {
- $propAttr .= "|v8::ReadOnly";
+ $propAttr .= " | v8::ReadOnly";
}
}
@@ -1264,17 +1386,8 @@ sub GenerateSingleBatchedAttribute
my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
"' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
- push(@implContent, $indent . " {\n");
- push(@implContent, $indent . " \/\/ $commentInfo\n");
- push(@implContent, $indent . " \"$attrName\",\n");
- push(@implContent, $indent . " $getter,\n");
- push(@implContent, $indent . " $setter,\n");
- push(@implContent, $indent . " $data,\n");
- push(@implContent, $indent . " $accessControl,\n");
- push(@implContent, $indent . " static_cast<v8::PropertyAttribute>($propAttr),\n");
- push(@implContent, $indent . " $on_proto\n");
- push(@implContent, $indent . " }" . $delimiter . "\n");
-END
+ push(@implContent, $indent . " \/\/ $commentInfo\n");
+ push(@implContent, $indent . " {\"$attrName\", $getter, $setter, $data, $accessControl, static_cast<v8::PropertyAttribute>($propAttr), $on_proto}" . $delimiter . "\n");
}
sub GenerateImplementationIndexer
@@ -1326,17 +1439,16 @@ sub GenerateImplementationIndexer
my $conversion = $indexer->extendedAttributes->{"ConvertNullStringTo"};
if ($conversion && $conversion eq "Null") {
push(@implContent, <<END);
- setCollectionStringOrNullIndexedGetter<${interfaceName}>(desc);
+ setCollectionStringOrNullIndexedGetter<${interfaceName}>(desc);
END
} else {
push(@implContent, <<END);
- setCollectionStringIndexedGetter<${interfaceName}>(desc);
+ setCollectionStringIndexedGetter<${interfaceName}>(desc);
END
}
} else {
- my $indexerClassIndex = uc($indexerType);
push(@implContent, <<END);
- setCollectionIndexedGetter<${interfaceName}, ${indexerType}>(desc, V8ClassIndex::${indexerClassIndex});
+ setCollectionIndexedGetter<${interfaceName}, ${indexerType}>(desc);
END
# Include the header for this indexer type, because setCollectionIndexedGetter() requires toV8() for this type.
$implIncludes{"V8${indexerType}.h"} = 1;
@@ -1358,11 +1470,11 @@ END
$hasDeleter = 0;
}
- push(@implContent, " desc->${setOn}Template()->SetIndexedPropertyHandler(V8${interfaceName}::indexedPropertyGetter");
+ push(@implContent, " desc->${setOn}Template()->SetIndexedPropertyHandler(V8${interfaceName}::indexedPropertyGetter");
push(@implContent, $hasCustomSetter ? ", V8${interfaceName}::indexedPropertySetter" : ", 0");
push(@implContent, ", 0"); # IndexedPropertyQuery -- not being used at the moment.
push(@implContent, $hasDeleter ? ", V8${interfaceName}::indexedPropertyDeleter" : ", 0");
- push(@implContent, ", nodeCollectionIndexedPropertyEnumerator<${interfaceName}>, v8::Integer::New(V8ClassIndex::NODE)") if $hasEnumerator;
+ push(@implContent, ", nodeCollectionIndexedPropertyEnumerator<${interfaceName}>") if $hasEnumerator;
push(@implContent, ");\n");
}
@@ -1380,6 +1492,10 @@ sub GenerateImplementationNamedPropertyGetter
$hasCustomGetter = 1;
}
+ if ($interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
+ $hasCustomGetter = 1;
+ }
+
my $hasGetter = $dataNode->extendedAttributes->{"HasNameGetter"} || $hasCustomGetter || $namedPropertyGetter;
if (!$hasGetter) {
return;
@@ -1388,9 +1504,8 @@ sub GenerateImplementationNamedPropertyGetter
if ($namedPropertyGetter && $namedPropertyGetter->type ne "Node" && !$namedPropertyGetter->extendedAttributes->{"Custom"} && !$hasCustomGetter) {
$implIncludes{"V8Collection.h"} = 1;
my $type = $namedPropertyGetter->type;
- my $classIndex = uc($type);
push(@implContent, <<END);
- setCollectionNamedGetter<${interfaceName}, ${type}>(desc, V8ClassIndex::${classIndex});
+ setCollectionNamedGetter<${interfaceName}, ${type}>(desc);
END
return;
}
@@ -1411,7 +1526,7 @@ END
$hasEnumerator = 0;
}
- push(@implContent, " desc->${setOn}Template()->SetNamedPropertyHandler(V8${interfaceName}::namedPropertyGetter, ");
+ push(@implContent, " desc->${setOn}Template()->SetNamedPropertyHandler(V8${interfaceName}::namedPropertyGetter, ");
push(@implContent, $hasSetter ? "V8${interfaceName}::namedPropertySetter, " : "0, ");
push(@implContent, "0, "); # NamedPropertyQuery -- not being used at the moment.
push(@implContent, $hasDeleter ? "V8${interfaceName}::namedPropertyDeleter, " : "0, ");
@@ -1432,7 +1547,7 @@ sub GenerateImplementationCustomCall
}
if ($hasCustomCall) {
- push(@implContent, " desc->InstanceTemplate()->SetCallAsFunctionHandler(V8${interfaceName}::callAsFunctionCallback);\n");
+ push(@implContent, " desc->InstanceTemplate()->SetCallAsFunctionHandler(V8${interfaceName}::callAsFunctionCallback);\n");
}
}
@@ -1441,7 +1556,7 @@ sub GenerateImplementationMasqueradesAsUndefined
my $dataNode = shift;
if ($dataNode->extendedAttributes->{"MasqueradesAsUndefined"})
{
- push(@implContent, " desc->InstanceTemplate()->MarkAsUndetectable();\n");
+ push(@implContent, " desc->InstanceTemplate()->MarkAsUndetectable();\n");
}
}
@@ -1450,9 +1565,9 @@ sub GenerateImplementation
my $object = shift;
my $dataNode = shift;
my $interfaceName = $dataNode->name;
+ my $visibleInterfaceName = GetVisibleInterfaceName($interfaceName);
my $className = "V8$interfaceName";
my $implClassName = $interfaceName;
- my $classIndex = uc($codeGenerator->StripModule($interfaceName));
my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
my $conditionalString = GenerateConditionalString($dataNode);
@@ -1461,30 +1576,33 @@ sub GenerateImplementation
@implContentHeader = split("\r", $headerTemplate);
push(@implFixedHeader,
- "#include \"config.h\"\n" .
- "#include \"RuntimeEnabledFeatures.h\"\n" .
- "#include \"V8Proxy.h\"\n" .
- "#include \"V8Binding.h\"\n" .
- "#include \"V8BindingState.h\"\n" .
- "#include \"V8DOMWrapper.h\"\n" .
- "#include \"V8IsolatedContext.h\"\n\n" .
- "#undef LOG\n\n");
+ "\n#include \"config.h\"\n" .
+ "#include \"${className}.h\"\n\n");
push(@implFixedHeader, "\n#if ${conditionalString}\n\n") if $conditionalString;
+
+ $implIncludes{"RuntimeEnabledFeatures.h"} = 1;
+ $implIncludes{"V8Proxy.h"} = 1;
+ $implIncludes{"V8Binding.h"} = 1;
+ $implIncludes{"V8BindingState.h"} = 1;
+ $implIncludes{"V8DOMWrapper.h"} = 1;
+ $implIncludes{"V8IsolatedContext.h"} = 1;
if ($className =~ /^V8SVGAnimated/) {
AddIncludesForSVGAnimatedType($interfaceName);
}
- $implIncludes{"${className}.h"} = 1;
-
AddIncludesForType($interfaceName);
- push(@implContentDecls, "namespace WebCore {\n");
+ my $toActive = IsActiveDomType($interfaceName) ? "${className}::toActiveDOMObject" : "0";
+
+ push(@implContentDecls, "namespace WebCore {\n\n");
+ push(@implContentDecls, "WrapperTypeInfo ${className}::info = { ${className}::GetTemplate, ${className}::derefObject, ${toActive} };\n\n");
push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n");
push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n");
my $hasConstructors = 0;
+ my $serializedAttribute;
# Generate property accessors for attributes.
for ($index = 0; $index < @{$dataNode->attributes}; $index++) {
$attribute = @{$dataNode->attributes}[$index];
@@ -1504,6 +1622,15 @@ sub GenerateImplementation
$attribute->signature->extendedAttributes->{"v8OnProto"} = 1;
}
+ # Attributes of type SerializedScriptValue are set in the
+ # constructor and don't require callbacks.
+ if ($attrType eq "SerializedScriptValue") {
+ die "Only one attribute of type SerializedScriptValue supported" if $serializedAttribute;
+ $implIncludes{"SerializedScriptValue.h"} = 1;
+ $serializedAttribute = $attribute;
+ next;
+ }
+
# Do not generate accessor if this is a custom attribute. The
# call will be forwarded to a hand-written accessor
# implementation.
@@ -1517,29 +1644,30 @@ sub GenerateImplementation
$attribute->signature->extendedAttributes->{"V8CustomGetter"})) {
GenerateNormalAttrGetter($attribute, $dataNode, $implClassName, $interfaceName);
}
- if (!($attribute->signature->extendedAttributes->{"CustomSetter"} ||
- $attribute->signature->extendedAttributes->{"V8CustomSetter"})) {
- if ($attribute->signature->extendedAttributes->{"Replaceable"}) {
- $dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"} || die "Replaceable attribute can only be used in interface that defines ExtendsDOMGlobalObject attribute!";
- # GenerateReplaceableAttrSetter($implClassName);
- } elsif ($attribute->type !~ /^readonly/ && !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
- GenerateNormalAttrSetter($attribute, $dataNode, $implClassName, $interfaceName);
- }
+ if (!$attribute->signature->extendedAttributes->{"CustomSetter"} &&
+ !$attribute->signature->extendedAttributes->{"V8CustomSetter"} &&
+ !$attribute->signature->extendedAttributes->{"Replaceable"} &&
+ $attribute->type !~ /^readonly/ &&
+ !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
+ GenerateNormalAttrSetter($attribute, $dataNode, $implClassName, $interfaceName);
}
}
if ($hasConstructors) {
- GenerateConstructorGetter($implClassName, $classIndex);
+ GenerateConstructorGetter($implClassName);
}
+ LinkOverloadedFunctions($dataNode);
+
my $indexer;
my $namedPropertyGetter;
# Generate methods for functions.
foreach my $function (@{$dataNode->functions}) {
- # hack for addEventListener/RemoveEventListener
- # FIXME: avoid naming conflict
if (!($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"})) {
- GenerateFunctionCallback($function, $dataNode, $classIndex, $implClassName);
+ GenerateFunctionCallback($function, $dataNode, $implClassName);
+ if ($function->{overloadIndex} > 1 && $function->{overloadIndex} == @{$function->{overloads}}) {
+ GenerateOverloadedFunctionCallback($function, $dataNode, $implClassName);
+ }
}
if ($function->signature->name eq "item") {
@@ -1554,7 +1682,7 @@ sub GenerateImplementation
# generate an access getter that returns different function objects
# for different calling context.
if (($dataNode->extendedAttributes->{"CheckDomainSecurity"} || ($interfaceName eq "DOMWindow")) && $function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
- GenerateDomainSafeFunctionGetter($function, $dataNode, $implClassName);
+ GenerateDomainSafeFunctionGetter($function, $implClassName);
}
}
@@ -1580,7 +1708,7 @@ sub GenerateImplementation
$attributes = \@normal;
# Put the attributes that disallow shadowing on the shadow object.
if (@disallowsShadowing) {
- push(@implContent, "static const BatchedAttribute shadow_attrs[] = {\n");
+ push(@implContent, "static const BatchedAttribute shadowAttrs[] = {\n");
GenerateBatchedAttributeData($dataNode, \@disallowsShadowing);
push(@implContent, "};\n");
}
@@ -1588,7 +1716,7 @@ sub GenerateImplementation
my $has_attributes = 0;
if (@$attributes) {
$has_attributes = 1;
- push(@implContent, "static const BatchedAttribute ${interfaceName}_attrs[] = {\n");
+ push(@implContent, "static const BatchedAttribute ${interfaceName}Attrs[] = {\n");
GenerateBatchedAttributeData($dataNode, $attributes);
push(@implContent, "};\n");
}
@@ -1597,6 +1725,9 @@ sub GenerateImplementation
$num_callbacks = 0;
$has_callbacks = 0;
foreach my $function (@{$dataNode->functions}) {
+ # Only one table entry is needed for overloaded methods:
+ next if $function->{overloadIndex} > 1;
+
my $attrExt = $function->signature->extendedAttributes;
# Don't put any nonstandard functions into this table:
if ($attrExt->{"V8OnInstance"}) {
@@ -1614,12 +1745,12 @@ sub GenerateImplementation
}
if (!$has_callbacks) {
$has_callbacks = 1;
- push(@implContent, "static const BatchedCallback ${interfaceName}_callbacks[] = {\n");
+ push(@implContent, "static const BatchedCallback ${interfaceName}Callbacks[] = {\n");
}
my $name = $function->signature->name;
- my $callback = GetFunctionTemplateCallbackName($function, $dataNode);
+ my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
push(@implContent, <<END);
- {"$name", $callback},
+ {"$name", $callback},
END
$num_callbacks++;
}
@@ -1629,7 +1760,7 @@ END
my $has_constants = 0;
if (@{$dataNode->constants}) {
$has_constants = 1;
- push(@implContent, "static const BatchedConstant ${interfaceName}_consts[] = {\n");
+ push(@implContent, "static const BatchedConstant ${interfaceName}Consts[] = {\n");
}
foreach my $constant (@{$dataNode->constants}) {
my $name = $constant->name;
@@ -1638,7 +1769,7 @@ END
# defines "const unsigned long SHOW_ALL = 0xFFFFFFFF". It would be better if we
# handled this here, and converted it to a -1 constant in the c++ output.
push(@implContent, <<END);
- { "${name}", static_cast<signed int>($value) },
+ {"${name}", static_cast<signed int>($value)},
END
}
if ($has_constants) {
@@ -1650,33 +1781,31 @@ END
# In namespace WebCore, add generated implementation for 'CanBeConstructed'.
if ($dataNode->extendedAttributes->{"CanBeConstructed"} && !$dataNode->extendedAttributes->{"CustomConstructor"}) {
push(@implContent, <<END);
- v8::Handle<v8::Value> ${className}::constructorCallback(const v8::Arguments& args)
- {
+v8::Handle<v8::Value> ${className}::constructorCallback(const v8::Arguments& args)
+{
INC_STATS("DOM.${interfaceName}.Contructor");
- return V8Proxy::constructDOMObject<V8ClassIndex::${classIndex}, $interfaceName>(args);
- }
+ return V8Proxy::constructDOMObject<$interfaceName>(args, &info);
+}
END
}
my $access_check = "";
if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !($interfaceName eq "DOMWindow")) {
- $access_check = "instance->SetAccessCheckCallbacks(V8${interfaceName}::namedSecurityCheck, V8${interfaceName}::indexedSecurityCheck, v8::Integer::New(V8ClassIndex::ToInt(V8ClassIndex::${classIndex})));";
+ $access_check = "instance->SetAccessCheckCallbacks(V8${interfaceName}::namedSecurityCheck, V8${interfaceName}::indexedSecurityCheck, v8::External::Wrap(&V8${interfaceName}::info));";
}
# For the DOMWindow interface, generate the shadow object template
# configuration method.
if ($implClassName eq "DOMWindow") {
push(@implContent, <<END);
-static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ) {
- batchConfigureAttributes(templ,
- v8::Handle<v8::ObjectTemplate>(),
- shadow_attrs,
- sizeof(shadow_attrs)/sizeof(*shadow_attrs));
+static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ)
+{
+ batchConfigureAttributes(templ, v8::Handle<v8::ObjectTemplate>(), shadowAttrs, sizeof(shadowAttrs) / sizeof(*shadowAttrs));
- // Install a security handler with V8.
- templ->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::Integer::New(V8ClassIndex::DOMWINDOW));
- templ->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
- return templ;
+ // Install a security handler with V8.
+ templ->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::External::Wrap(&V8DOMWindow::info));
+ templ->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
+ return templ;
}
END
}
@@ -1696,45 +1825,45 @@ END
# Generate the template configuration method
push(@implContent, <<END);
-static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) {
- v8::Local<v8::Signature> default_signature = configureTemplate(desc, \"${interfaceName}\",
- $parentClassTemplate, V8${interfaceName}::internalFieldCount,
+static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc)
+{
+ v8::Local<v8::Signature> defaultSignature = configureTemplate(desc, \"${visibleInterfaceName}\", $parentClassTemplate, V8${interfaceName}::internalFieldCount,
END
# Set up our attributes if we have them
if ($has_attributes) {
push(@implContent, <<END);
- ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs),
+ ${interfaceName}Attrs, sizeof(${interfaceName}Attrs) / sizeof(*${interfaceName}Attrs),
END
} else {
push(@implContent, <<END);
- NULL, 0,
+ 0, 0,
END
}
if ($has_callbacks) {
push(@implContent, <<END);
- ${interfaceName}_callbacks, sizeof(${interfaceName}_callbacks)/sizeof(*${interfaceName}_callbacks));
+ ${interfaceName}Callbacks, sizeof(${interfaceName}Callbacks) / sizeof(*${interfaceName}Callbacks));
END
} else {
push(@implContent, <<END);
- NULL, 0);
+ 0, 0);
END
}
if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) {
push(@implContent, <<END);
- desc->SetCallHandler(V8${interfaceName}::constructorCallback);
+ desc->SetCallHandler(V8${interfaceName}::constructorCallback);
END
}
if ($access_check or @enabledAtRuntime or @{$dataNode->functions} or $has_constants) {
push(@implContent, <<END);
- v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
- v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
+ v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
+ v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
END
}
- push(@implContent, " $access_check\n");
+ push(@implContent, " $access_check\n");
# Setup the enable-at-runtime attrs if we have them
foreach my $runtime_attr (@enabledAtRuntime) {
@@ -1760,16 +1889,19 @@ END
# Define our functions with Set() or SetAccessor()
$total_functions = 0;
foreach my $function (@{$dataNode->functions}) {
+ # Only one accessor is needed for overloaded methods:
+ next if $function->{overloadIndex} > 1;
+
$total_functions++;
my $attrExt = $function->signature->extendedAttributes;
my $name = $function->signature->name;
my $property_attributes = "v8::DontDelete";
if ($attrExt->{"DontEnum"}) {
- $property_attributes .= "|v8::DontEnum";
+ $property_attributes .= " | v8::DontEnum";
}
if ($attrExt->{"V8ReadOnly"}) {
- $property_attributes .= "|v8::ReadOnly";
+ $property_attributes .= " | v8::ReadOnly";
}
my $commentInfo = "Function '$name' (ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
@@ -1783,7 +1915,7 @@ END
if ($attrExt->{"EnabledAtRuntime"}) {
# Only call Set()/SetAccessor() if this method should be enabled
$enable_function = "RuntimeEnabledFeatures::" . $codeGenerator->WK_lcfirst($function->signature->name) . "Enabled";
- $conditional = "if (${enable_function}())\n";
+ $conditional = "if (${enable_function}())\n ";
}
if ($attrExt->{"DoNotCheckDomainSecurity"} &&
@@ -1802,34 +1934,28 @@ END
#
# The solution is very hacky and fragile, it really needs to be replaced
# by a better solution.
- $property_attributes .= "|v8::ReadOnly";
+ $property_attributes .= " | v8::ReadOnly";
push(@implContent, <<END);
- // $commentInfo
- $conditional $template->SetAccessor(
- v8::String::New("$name"),
- ${interfaceName}Internal::${name}AttrGetter,
- 0,
- v8::Handle<v8::Value>(),
- v8::ALL_CAN_READ,
- static_cast<v8::PropertyAttribute>($property_attributes));
+ // $commentInfo
+ ${conditional}$template->SetAccessor(v8::String::New("$name"), ${interfaceName}Internal::${name}AttrGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>($property_attributes));
END
$num_callbacks++;
next;
}
- my $signature = "default_signature";
- if ($attrExt->{"V8DoNotCheckSignature"}){
+ my $signature = "defaultSignature";
+ if ($attrExt->{"V8DoNotCheckSignature"}) {
$signature = "v8::Local<v8::Signature>()";
}
if (RequiresCustomSignature($function)) {
- $signature = "${name}_signature";
- push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function));
+ $signature = "${name}Signature";
+ push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function));
}
# Normal function call is a template
- my $callback = GetFunctionTemplateCallbackName($function, $dataNode);
+ my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
if ($property_attributes eq "v8::DontDelete") {
$property_attributes = "";
@@ -1837,13 +1963,13 @@ END
$property_attributes = ", static_cast<v8::PropertyAttribute>($property_attributes)";
}
- if ($template eq "proto" && $conditional eq "" && $signature eq "default_signature" && $property_attributes eq "") {
+ if ($template eq "proto" && $conditional eq "" && $signature eq "defaultSignature" && $property_attributes eq "") {
# Standard type of callback, already created in the batch, so skip it here.
next;
}
push(@implContent, <<END);
- ${conditional}$template->Set(v8::String::New("$name"), v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), ${signature})$property_attributes);
+ ${conditional}$template->Set(v8::String::New("$name"), v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), ${signature})$property_attributes);
END
$num_callbacks++;
}
@@ -1852,7 +1978,7 @@ END
if ($has_constants) {
push(@implContent, <<END);
- batchConfigureConstants(desc, proto, ${interfaceName}_consts, sizeof(${interfaceName}_consts)/sizeof(*${interfaceName}_consts));
+ batchConfigureConstants(desc, proto, ${interfaceName}Consts, sizeof(${interfaceName}Consts) / sizeof(*${interfaceName}Consts));
END
}
@@ -1860,23 +1986,23 @@ END
if ($interfaceName eq "DOMWindow") {
push(@implContent, <<END);
- proto->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
- desc->SetHiddenPrototype(true);
- instance->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
- // Set access check callbacks, but turned off initially.
- // When a context is detached from a frame, turn on the access check.
- // Turning on checks also invalidates inline caches of the object.
- instance->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::Integer::New(V8ClassIndex::DOMWINDOW), false);
+ proto->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
+ desc->SetHiddenPrototype(true);
+ instance->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
+ // Set access check callbacks, but turned off initially.
+ // When a context is detached from a frame, turn on the access check.
+ // Turning on checks also invalidates inline caches of the object.
+ instance->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::External::Wrap(&V8DOMWindow::info), false);
END
}
if ($interfaceName eq "Location") {
push(@implContent, <<END);
- // For security reasons, these functions are on the instance instead
- // of on the prototype object to insure that they cannot be overwritten.
- instance->SetAccessor(v8::String::New("reload"), V8Location::reloadAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
- instance->SetAccessor(v8::String::New("replace"), V8Location::replaceAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
- instance->SetAccessor(v8::String::New("assign"), V8Location::assignAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
+ // For security reasons, these functions are on the instance instead
+ // of on the prototype object to ensure that they cannot be overwritten.
+ instance->SetAccessor(v8::String::New("reload"), V8Location::reloadAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
+ instance->SetAccessor(v8::String::New("replace"), V8Location::replaceAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
+ instance->SetAccessor(v8::String::New("assign"), V8Location::assignAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
END
}
@@ -1886,51 +2012,86 @@ END
}
push(@implContent, <<END);
- // Custom toString template
- desc->Set(getToStringName(), getToStringTemplate());
- return desc;
+ // Custom toString template
+ desc->Set(getToStringName(), getToStringTemplate());
+ return desc;
}
-v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() {
- static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_ = createRawTemplate();
- return ${className}_raw_cache_;
+v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate()
+{
+ static v8::Persistent<v8::FunctionTemplate> ${className}RawCache = createRawTemplate();
+ return ${className}RawCache;
}
-v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() {
- static v8::Persistent<v8::FunctionTemplate> ${className}_cache_ = Configure${className}Template(GetRawTemplate());
- return ${className}_cache_;
+v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate()\
+{
+ static v8::Persistent<v8::FunctionTemplate> ${className}Cache = Configure${className}Template(GetRawTemplate());
+ return ${className}Cache;
}
-${nativeType}* ${className}::toNative(v8::Handle<v8::Object> object) {
- return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
+${nativeType}* ${className}::toNative(v8::Handle<v8::Object> object)
+{
+ return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
}
-bool ${className}::HasInstance(v8::Handle<v8::Value> value) {
- return GetRawTemplate()->HasInstance(value);
+bool ${className}::HasInstance(v8::Handle<v8::Value> value)
+{
+ return GetRawTemplate()->HasInstance(value);
}
END
+ if (IsActiveDomType($interfaceName)) {
+ # MessagePort is handled like an active dom object even though it doesn't inherit
+ # from ActiveDOMObject, so don't try to cast it to ActiveDOMObject.
+ my $returnValue = $interfaceName eq "MessagePort" ? "0" : "toNative(object)";
+ push(@implContent, <<END);
+ActiveDOMObject* ${className}::toActiveDOMObject(v8::Handle<v8::Object> object)
+{
+ return ${returnValue};
+}
+END
+ }
+
if ($implClassName eq "DOMWindow") {
push(@implContent, <<END);
-v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate() {
- static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_;
- if (V8DOMWindowShadowObject_cache_.IsEmpty()) {
- V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
- ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_);
- }
- return V8DOMWindowShadowObject_cache_;
+v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate()
+{
+ static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObjectCache;
+ if (V8DOMWindowShadowObjectCache.IsEmpty()) {
+ V8DOMWindowShadowObjectCache = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
+ ConfigureShadowObjectTemplate(V8DOMWindowShadowObjectCache);
+ }
+ return V8DOMWindowShadowObjectCache;
}
END
}
- GenerateToV8Converters($dataNode, $interfaceName, $className, $nativeType);
+ GenerateToV8Converters($dataNode, $interfaceName, $className, $nativeType, $serializedAttribute);
+
+ push(@implContent, <<END);
+
+void ${className}::derefObject(void* object)
+{
+END
+
+ if (IsRefPtrType($interfaceName)) {
+ push(@implContent, <<END);
+ static_cast<${nativeType}*>(object)->deref();
+END
+ }
push(@implContent, <<END);
+}
+
} // namespace WebCore
END
push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
+
+ # We've already added the header for this file in implFixedHeader, so remove
+ # it from implIncludes to ensure we don't #include it twice.
+ delete $implIncludes{"${className}.h"};
}
sub GenerateToV8Converters
@@ -1939,90 +2100,107 @@ sub GenerateToV8Converters
my $interfaceName = shift;
my $className = shift;
my $nativeType = shift;
+ my $serializedAttribute = shift;
- my $wrapperType = "V8ClassIndex::" . uc($interfaceName);
my $domMapFunction = GetDomMapFunction($dataNode, $interfaceName);
my $forceNewObjectInput = IsDOMNodeType($interfaceName) ? ", bool forceNewObject" : "";
my $forceNewObjectCall = IsDOMNodeType($interfaceName) ? ", forceNewObject" : "";
push(@implContent, <<END);
-v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput}) {
- v8::Handle<v8::Object> wrapper;
- V8Proxy* proxy = 0;
+v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput})
+{
+ v8::Handle<v8::Object> wrapper;
+ V8Proxy* proxy = 0;
END
if (IsNodeSubType($dataNode)) {
push(@implContent, <<END);
- if (impl->document()) {
- proxy = V8Proxy::retrieve(impl->document()->frame());
- if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl))
- proxy->windowShell()->initContextIfNeeded();
- }
+ if (impl->document()) {
+ proxy = V8Proxy::retrieve(impl->document()->frame());
+ if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl))
+ proxy->windowShell()->initContextIfNeeded();
+ }
END
}
if ($domMapFunction) {
- push(@implContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
+ push(@implContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
if (IsNodeSubType($dataNode)) {
- push(@implContent, " wrapper = V8DOMWrapper::getWrapper(impl);\n");
+ push(@implContent, " wrapper = V8DOMWrapper::getWrapper(impl);\n");
} else {
- push(@implContent, " wrapper = ${domMapFunction}.get(impl);\n");
+ push(@implContent, " wrapper = ${domMapFunction}.get(impl);\n");
}
push(@implContent, <<END);
- if (!wrapper.IsEmpty())
- return wrapper;
+ if (!wrapper.IsEmpty())
+ return wrapper;
END
- push(@implContent, " }\n") if IsDOMNodeType($interfaceName);
+ push(@implContent, " }\n") if IsDOMNodeType($interfaceName);
}
if (IsNodeSubType($dataNode)) {
push(@implContent, <<END);
- v8::Handle<v8::Context> context;
- if (proxy)
- context = proxy->context();
+ v8::Handle<v8::Context> context;
+ if (proxy)
+ context = proxy->context();
- // Enter the node's context and create the wrapper in that context.
- if (!context.IsEmpty())
- context->Enter();
+ // Enter the node's context and create the wrapper in that context.
+ if (!context.IsEmpty())
+ context->Enter();
END
}
push(@implContent, <<END);
- wrapper = V8DOMWrapper::instantiateV8Object(proxy, ${wrapperType}, impl);
+ wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl);
END
-
if (IsNodeSubType($dataNode)) {
push(@implContent, <<END);
- // Exit the node's context if it was entered.
- if (!context.IsEmpty())
- context->Exit();
+ // Exit the node's context if it was entered.
+ if (!context.IsEmpty())
+ context->Exit();
END
}
push(@implContent, <<END);
- if (wrapper.IsEmpty())
- return wrapper;
+ if (wrapper.IsEmpty())
+ return wrapper;
+END
+ push(@implContent, "\n impl->ref();\n") if IsRefPtrType($interfaceName);
+
+ # Eagerly deserialize attributes of type SerializedScriptValue
+ # while we're in the right context.
+ if ($serializedAttribute) {
+ die "Attribute of type SerializedScriptValue expected" if $serializedAttribute->signature->type ne "SerializedScriptValue";
+ my $attrName = $serializedAttribute->signature->name;
+ my $attrAttr = "v8::DontDelete";
+ if ($serializedAttribute->type =~ /^readonly/) {
+ $attrAttr .= " | v8::ReadOnly";
+ }
+ $attrAttr = "static_cast<v8::PropertyAttribute>($attrAttr)";
+ my $getterFunc = $codeGenerator->WK_lcfirst($attrName);
+ push(@implContent, <<END);
+ SerializedScriptValue::deserializeAndSetProperty(wrapper, "${attrName}", ${attrAttr}, impl->${getterFunc}());
END
- push(@implContent, "\n impl->ref();\n") if IsRefPtrType($interfaceName);
+ }
if ($domMapFunction) {
push(@implContent, <<END);
- ${domMapFunction}.set(impl, v8::Persistent<v8::Object>::New(wrapper));
+ ${domMapFunction}.set(impl, v8::Persistent<v8::Object>::New(wrapper));
END
}
push(@implContent, <<END);
- return wrapper;
+ return wrapper;
}
END
if (IsRefPtrType($interfaceName)) {
push(@implContent, <<END);
-v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl${forceNewObjectInput}) {
- return toV8(impl.get()${forceNewObjectCall});
+v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl${forceNewObjectInput})
+{
+ return toV8(impl.get()${forceNewObjectCall});
}
END
}
@@ -2030,10 +2208,11 @@ END
if (!HasCustomToV8Implementation($dataNode, $interfaceName)) {
push(@implContent, <<END);
-v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectInput}) {
- if (!impl)
- return v8::Null();
- return ${className}::wrap(impl${forceNewObjectCall});
+v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectInput})
+{
+ if (!impl)
+ return v8::Null();
+ return ${className}::wrap(impl${forceNewObjectCall});
}
END
}
@@ -2045,21 +2224,18 @@ sub HasCustomToV8Implementation {
$interfaceName = shift;
# We generate a custom converter (but JSC doesn't) for the following:
- return 1 if $interfaceName eq "BarInfo";
return 1 if $interfaceName eq "CSSStyleSheet";
return 1 if $interfaceName eq "CanvasPixelArray";
- return 1 if $interfaceName eq "DOMSelection";
return 1 if $interfaceName eq "DOMWindow";
return 1 if $interfaceName eq "Element";
- return 1 if $interfaceName eq "Location";
return 1 if $interfaceName eq "HTMLDocument";
return 1 if $interfaceName eq "HTMLElement";
- return 1 if $interfaceName eq "History";
+ return 1 if $interfaceName eq "Location";
return 1 if $interfaceName eq "NamedNodeMap";
- return 1 if $interfaceName eq "Navigator";
return 1 if $interfaceName eq "SVGDocument";
return 1 if $interfaceName eq "SVGElement";
- return 1 if $interfaceName eq "Screen";
+ return 1 if $interfaceName eq "ScriptProfile";
+ return 1 if $interfaceName eq "ScriptProfileNode";
return 1 if $interfaceName eq "WorkerContext";
# We don't generate a custom converter (but JSC does) for the following:
return 0 if $interfaceName eq "AbstractWorker";
@@ -2076,7 +2252,7 @@ sub GetDomMapFunction
my $dataNode = shift;
my $type = shift;
return "getDOMSVGElementInstanceMap()" if $type eq "SVGElementInstance";
- return "getDOMNodeMap()" if IsNodeSubType($dataNode);
+ return "getDOMNodeMap()" if ($dataNode && IsNodeSubType($dataNode));
# Only use getDOMSVGObjectWithContextMap() for non-node svg objects
return "getDOMSVGObjectWithContextMap()" if $type =~ /SVG/;
return "" if $type eq "DOMImplementation";
@@ -2088,6 +2264,7 @@ sub IsActiveDomType
{
# FIXME: Consider making this an .idl attribute.
my $type = shift;
+ return 1 if $type eq "EventSource";
return 1 if $type eq "MessagePort";
return 1 if $type eq "XMLHttpRequest";
return 1 if $type eq "WebSocket";
@@ -2201,9 +2378,7 @@ sub GenerateFunctionCallString()
if ($returnType eq "void") {
$result .= $indent . "$functionString;\n";
} elsif ($copyFirst) {
- $result .=
- $indent . GetNativeType($returnType, 0) . " result = *imp;\n" .
- $indent . "$functionString;\n";
+ $result .= $indent . GetNativeType($returnType, 0) . " result = *imp;\n" . $indent . "$functionString;\n";
} elsif ($returnsListItemPodType) {
$result .= $indent . "RefPtr<SVGPODListItem<$nativeReturnType> > result = $functionString;\n";
} elsif (@{$function->raisesExceptions} or $returnsPodType or $isPodType or IsSVGTypeNeedingContextParameter($returnType)) {
@@ -2215,7 +2390,7 @@ sub GenerateFunctionCallString()
}
if (@{$function->raisesExceptions}) {
- $result .= $indent . "if (UNLIKELY(ec)) goto fail;\n";
+ $result .= $indent . "if (UNLIKELY(ec))\n" . $indent . " goto fail;\n";
}
# If the return type is a POD type, separate out the wrapper generation
@@ -2253,7 +2428,7 @@ sub GenerateFunctionCallString()
$generatedSVGContextRetrieval = 1;
}
- $result .= $indent . "imp_wrapper->commitChange(imp_instance, context);\n";
+ $result .= $indent . "impWrapper->commitChange(impInstance, context);\n";
}
if ($returnsPodType) {
@@ -2355,6 +2530,7 @@ sub GetNativeType
return "unsigned" if $type eq "unsigned int";
return "Node*" if $type eq "EventTarget" and $isParameter;
return "double" if $type eq "Date";
+ return "ScriptValue" if $type eq "DOMObject";
return "String" if $type eq "DOMUserData"; # FIXME: Temporary hack?
@@ -2370,75 +2546,6 @@ sub GetNativeType
return "${type}*";
}
-
-my %typeCanFailConversion = (
- "Attr" => 1,
- "WebGLArray" => 0,
- "WebGLBuffer" => 0,
- "WebGLByteArray" => 0,
- "WebGLUnsignedByteArray" => 0,
- "WebGLContextAttributes" => 0,
- "WebGLFloatArray" => 0,
- "WebGLFramebuffer" => 0,
- "CanvasGradient" => 0,
- "WebGLIntArray" => 0,
- "CanvasPixelArray" => 0,
- "WebGLProgram" => 0,
- "WebGLRenderbuffer" => 0,
- "WebGLShader" => 0,
- "WebGLShortArray" => 0,
- "WebGLTexture" => 0,
- "WebGLUniformLocation" => 0,
- "CompareHow" => 0,
- "DataGridColumn" => 0,
- "DOMString" => 0,
- "DOMWindow" => 0,
- "DocumentType" => 0,
- "Element" => 0,
- "Event" => 0,
- "EventListener" => 0,
- "EventTarget" => 0,
- "HTMLCanvasElement" => 0,
- "HTMLElement" => 0,
- "HTMLImageElement" => 0,
- "HTMLOptionElement" => 0,
- "HTMLVideoElement" => 0,
- "Node" => 0,
- "NodeFilter" => 0,
- "MessagePort" => 0,
- "NSResolver" => 0,
- "Range" => 0,
- "SQLResultSet" => 0,
- "Storage" => 0,
- "SVGAngle" => 1,
- "SVGElement" => 0,
- "SVGLength" => 1,
- "SVGMatrix" => 1,
- "SVGNumber" => 0,
- "SVGPaintType" => 0,
- "SVGPathSeg" => 0,
- "SVGPoint" => 1,
- "SVGPreserveAspectRatio" => 1,
- "SVGRect" => 1,
- "SVGTransform" => 1,
- "TouchList" => 0,
- "VoidCallback" => 1,
- "WebKitCSSMatrix" => 0,
- "WebKitPoint" => 0,
- "XPathEvaluator" => 0,
- "XPathNSResolver" => 0,
- "XPathResult" => 0,
- "boolean" => 0,
- "double" => 0,
- "float" => 0,
- "long" => 0,
- "unsigned long" => 0,
- "unsigned short" => 0,
- "long long" => 0,
- "unsigned long long" => 0
-);
-
-
sub TranslateParameter
{
my $signature = shift;
@@ -2471,10 +2578,9 @@ sub TypeCanFailConversion
my $type = GetTypeFromSignature($signature);
$implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr";
-
- return $typeCanFailConversion{$type} if exists $typeCanFailConversion{$type};
-
- die "Don't know whether a JS value can fail conversion to type $type.";
+ return 1 if $type eq "Attr";
+ return 1 if $type eq "VoidCallback";
+ return BasicTypeCanFailConversion($signature);
}
sub JSValueToNative
@@ -2501,9 +2607,11 @@ sub JSValueToNative
return $value;
}
- if ($type eq "SerializedScriptValue") {
- $implIncludes{"SerializedScriptValue.h"} = 1;
- return "SerializedScriptValue::create($value)";
+ die "Unexpected SerializedScriptValue" if $type eq "SerializedScriptValue";
+
+ if ($type eq "DOMObject") {
+ $implIncludes{"ScriptValue.h"} = 1;
+ return "ScriptValue($value)";
}
if ($type eq "NodeFilter") {
@@ -2539,17 +2647,13 @@ sub JSValueToNative
# return NULL.
return "V8${type}::HasInstance($value) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
} else {
- # TODO: Temporary to avoid Window name conflict.
- my $classIndex = uc($type);
- my $implClassName = ${type};
-
$implIncludes{"V8$type.h"} = 1;
if (IsPodType($type)) {
my $nativeType = GetNativeType($type);
$implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
- return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(V8ClassIndex::${classIndex}, $value${maybeOkParam})"
+ return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(&V8${type}::info, $value${maybeOkParam})"
}
$implIncludes{"V8${type}.h"} = 1;
@@ -2560,7 +2664,6 @@ sub JSValueToNative
}
}
-
sub GetV8HeaderName
{
my $type = shift;
@@ -2568,17 +2671,17 @@ sub GetV8HeaderName
return "EventListener.h" if $type eq "EventListener";
return "EventTarget.h" if $type eq "EventTarget";
return "SerializedScriptValue.h" if $type eq "SerializedScriptValue";
+ return "ScriptValue.h" if $type eq "DOMObject";
return "V8${type}.h";
}
-
sub CreateCustomSignature
{
my $function = shift;
my $count = @{$function->parameters};
my $name = $function->signature->name;
- my $result = " const int ${name}_argc = ${count};\n" .
- " v8::Handle<v8::FunctionTemplate> ${name}_argv[${name}_argc] = { ";
+ my $result = " const int ${name}Argc = ${count};\n" .
+ " v8::Handle<v8::FunctionTemplate> ${name}Argv[${name}Argc] = { ";
my $first = 1;
foreach my $parameter (@{$function->parameters}) {
if ($first) { $first = 0; }
@@ -2599,7 +2702,7 @@ sub CreateCustomSignature
}
}
$result .= " };\n";
- $result .= " v8::Handle<v8::Signature> ${name}_signature = v8::Signature::New(desc, ${name}_argc, ${name}_argv);\n";
+ $result .= " v8::Handle<v8::Signature> ${name}Signature = v8::Signature::New(desc, ${name}Argc, ${name}Argv);\n";
return $result;
}
@@ -2612,11 +2715,21 @@ sub RequiresCustomSignature
$function->signature->extendedAttributes->{"V8Custom"}) {
return 0;
}
+ # No signature needed for overloaded function
+ if (@{$function->{overloads}} > 1) {
+ return 0;
+ }
foreach my $parameter (@{$function->parameters}) {
- if (IsWrapperType($parameter->type)) {
- return 1;
- }
+ if ($parameter->extendedAttributes->{"Optional"}) {
+ return 0;
+ }
+ }
+
+ foreach my $parameter (@{$function->parameters}) {
+ if (IsWrapperType($parameter->type)) {
+ return 1;
+ }
}
return 0;
}
@@ -2625,6 +2738,8 @@ sub RequiresCustomSignature
my %non_wrapper_types = (
'float' => 1,
'double' => 1,
+ 'int' => 1,
+ 'unsigned int' => 1,
'short' => 1,
'unsigned short' => 1,
'long' => 1,
@@ -2645,6 +2760,7 @@ my %non_wrapper_types = (
'SVGPaintType' => 1,
'DOMTimeStamp' => 1,
'JSObject' => 1,
+ 'DOMObject' => 1,
'EventTarget' => 1,
'NodeFilter' => 1,
'EventListener' => 1
@@ -2704,8 +2820,9 @@ sub ReturnNativeToJSValue
return "return v8::Integer::New($value)" if $nativeType eq "int";
return "return v8::Integer::NewFromUnsigned($value)" if $nativeType eq "unsigned";
- return "return v8DateOrNull($value);" if $type eq "Date";
+ return "return v8DateOrNull($value)" if $type eq "Date";
return "return v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType";
+ return "return $value.v8Value()" if $nativeType eq "ScriptValue";
if ($codeGenerator->IsStringType($type)) {
my $conv = $signature->extendedAttributes->{"ConvertNullStringTo"};
@@ -2775,7 +2892,11 @@ sub WriteData
my $checkType = $implInclude;
$checkType =~ s/\.h//;
- print $IMPL "#include \"$implInclude\"\n" unless $codeGenerator->IsSVGAnimatedType($checkType);
+ if ($implInclude =~ /wtf/) {
+ print $IMPL "#include \<$implInclude\>\n";
+ } else {
+ print $IMPL "#include \"$implInclude\"\n" unless $codeGenerator->IsSVGAnimatedType($checkType);
+ }
}
print $IMPL "\n";
@@ -2833,7 +2954,7 @@ sub GenerateSVGContextRetrieval
my $srcObject = "imp";
if ($srcIsPodType) {
- $srcObject = "imp_wrapper";
+ $srcObject = "impWrapper";
}
my $contextDecl;
@@ -2882,6 +3003,15 @@ sub IsSVGListTypeNeedingSpecialHandling
return 0;
}
+sub GetVisibleInterfaceName
+{
+ my $interfaceName = shift;
+
+ return "DOMException" if $interfaceName eq "DOMCoreException";
+ return "FormData" if $interfaceName eq "DOMFormData";
+ return $interfaceName;
+}
+
sub DebugPrint
{
my $output = shift;
diff --git a/WebCore/bindings/scripts/IDLParser.pm b/WebCore/bindings/scripts/IDLParser.pm
index b2577d2..7db7747 100644
--- a/WebCore/bindings/scripts/IDLParser.pm
+++ b/WebCore/bindings/scripts/IDLParser.pm
@@ -14,7 +14,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
@@ -64,7 +64,14 @@ sub Parse
$parentsOnly = shift;
if (!$preprocessor) {
- $preprocessor = "/usr/bin/gcc -E -P -x c++";
+ require Config;
+ my $gccLocation = "";
+ if (($Config::Config{'osname'}) =~ /solaris/i) {
+ $gccLocation = "/usr/sfw/bin/gcc";
+ } else {
+ $gccLocation = "/usr/bin/gcc";
+ }
+ $preprocessor = $gccLocation . " -E -P -x c++";
}
if (!$defines) {
diff --git a/WebCore/bindings/scripts/IDLStructure.pm b/WebCore/bindings/scripts/IDLStructure.pm
index f5970b4..6224e54 100644
--- a/WebCore/bindings/scripts/IDLStructure.pm
+++ b/WebCore/bindings/scripts/IDLStructure.pm
@@ -14,7 +14,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
diff --git a/WebCore/bindings/scripts/generate-bindings.pl b/WebCore/bindings/scripts/generate-bindings.pl
index ad29dc5..44ed4d3 100755
--- a/WebCore/bindings/scripts/generate-bindings.pl
+++ b/WebCore/bindings/scripts/generate-bindings.pl
@@ -16,7 +16,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
diff --git a/WebCore/bindings/scripts/gobject-generate-headers.pl b/WebCore/bindings/scripts/gobject-generate-headers.pl
new file mode 100644
index 0000000..1017406
--- /dev/null
+++ b/WebCore/bindings/scripts/gobject-generate-headers.pl
@@ -0,0 +1,77 @@
+#!/usr/bin/perl -w
+#
+# Copyright (C) 2009 Adam Dingle <adam@yorba.org>
+#
+# This file is part of WebKit
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# aint with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+
+my $classlist = <STDIN>;
+chomp($classlist);
+my @classes = split / /, $classlist;
+@classes = sort @classes;
+
+print <<EOF;
+/* This file is part of the WebKit open source project.
+ This file has been generated by gobject-generate-headers.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+EOF
+
+my $outType = $ARGV[0];
+my $header;
+if ($outType eq "defines") {
+ $header = "webkitdomdefines_h";
+} elsif ($outType eq "gdom") {
+ $header = "webkitdom_h";
+} else {
+ die "unknown output type";
+}
+
+print "#ifndef ${header}\n";
+print "#define ${header}\n";
+print "\n";
+
+if ($outType eq "defines") {
+ foreach my $class (@classes) {
+ print "typedef struct _WebKitDOM${class} WebKitDOM${class};\n";
+ print "typedef struct _WebKitDOM${class}Class WebKitDOM${class}Class;\n";
+ print "\n";
+ }
+} elsif ($outType eq "gdom") {
+ foreach my $class (@classes) {
+ print "#include <webkit/WebKitDOM${class}.h>\n";
+ }
+}
+
+print "\n";
+print "#endif\n";