summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/scripts/CodeGeneratorV8.pm
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/scripts/CodeGeneratorV8.pm')
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorV8.pm3251
1 files changed, 0 insertions, 3251 deletions
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
deleted file mode 100644
index f50e74a..0000000
--- a/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ /dev/null
@@ -1,3251 +0,0 @@
-# Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
-# Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
-# Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
-# Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
-# Copyright (C) 2006 Apple Computer, Inc.
-# Copyright (C) 2007, 2008, 2009 Google Inc.
-# Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
-# Copyright (C) Research In Motion Limited 2010. All rights reserved.
-# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
-#
-# 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 CodeGeneratorV8;
-
-use Digest::MD5;
-
-my $module = "";
-my $outputDir = "";
-my $outputHeadersDir = "";
-
-my @headerContent = ();
-my @implContentHeader = ();
-my @implFixedHeader = ();
-my @implContent = ();
-my @implContentDecls = ();
-my %implIncludes = ();
-my %headerIncludes = ();
-
-my @allParents = ();
-
-# Default .h template
-my $headerTemplate = << "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., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-EOF
-
-# Default constructor
-sub new
-{
- my $object = shift;
- my $reference = { };
-
- $codeGenerator = shift;
- $outputDir = shift;
- $outputHeadersDir = shift;
-
- bless($reference, $object);
- return $reference;
-}
-
-sub finish
-{
- my $object = shift;
-
- # Commit changes!
- $object->WriteData();
-}
-
-# Params: 'domClass' struct
-sub GenerateInterface
-{
- my $object = shift;
- my $dataNode = shift;
- my $defines = shift;
-
- # Start actual generation
- if ($dataNode->extendedAttributes->{"Callback"}) {
- $object->GenerateCallbackHeader($dataNode);
- $object->GenerateCallbackImplementation($dataNode);
- } else {
- $object->GenerateHeader($dataNode);
- $object->GenerateImplementation($dataNode);
- }
-
- my $name = $dataNode->name;
-
- # Open files for writing
- my $headerFileName = "$outputHeadersDir/V8$name.h";
- my $implFileName = "$outputDir/V8$name.cpp";
-
- open($IMPL, ">$implFileName") || die "Couldn't open file $implFileName";
- open($HEADER, ">$headerFileName") || die "Couldn't open file $headerFileName";
-}
-
-# Params: 'idlDocument' struct
-sub GenerateModule
-{
- my $object = shift;
- my $dataNode = shift;
-
- $module = $dataNode->module;
-}
-
-sub AddIncludesForType
-{
- my $type = $codeGenerator->StripModule(shift);
-
- # When we're finished with the one-file-per-class
- # reorganization, we won't need these special cases.
- if (!$codeGenerator->IsPrimitiveType($type) and !$codeGenerator->AvoidInclusionOfType($type) and $type ne "Date") {
- # default, include the same named file
- $implIncludes{GetV8HeaderName(${type})} = 1;
-
- if ($type =~ /SVGPathSeg/) {
- $joinedName = $type;
- $joinedName =~ s/Abs|Rel//;
- $implIncludes{"${joinedName}.h"} = 1;
- }
- }
-
- # additional includes (things needed to compile the bindings but not the header)
-
- if ($type eq "CanvasRenderingContext2D") {
- $implIncludes{"CanvasGradient.h"} = 1;
- $implIncludes{"CanvasPattern.h"} = 1;
- $implIncludes{"CanvasStyle.h"} = 1;
- }
-
- if ($type eq "CanvasGradient" or $type eq "XPathNSResolver") {
- $implIncludes{"PlatformString.h"} = 1;
- }
-
- if ($type eq "CSSStyleDeclaration") {
- $implIncludes{"CSSMutableStyleDeclaration.h"} = 1;
- }
-
- if ($type eq "Plugin" or $type eq "PluginArray" or $type eq "MimeTypeArray") {
- # So we can get String -> AtomicString conversion for namedItem().
- $implIncludes{"wtf/text/AtomicString.h"} = 1;
- }
-}
-
-# If the node has a [Conditional=XXX] attribute, returns an "ENABLE(XXX)" string for use in an #if.
-sub GenerateConditionalString
-{
- my $node = shift;
- my $conditional = $node->extendedAttributes->{"Conditional"};
- if ($conditional) {
- if ($conditional =~ /&/) {
- return "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
- } elsif ($conditional =~ /\|/) {
- return "ENABLE(" . join(") || ENABLE(", split(/\|/, $conditional)) . ")";
- } else {
- return "ENABLE(" . $conditional . ")";
- }
- } else {
- return "";
- }
-}
-
-sub GetSVGPropertyTypes
-{
- my $implType = shift;
-
- my $svgPropertyType;
- my $svgListPropertyType;
- my $svgNativeType;
-
- return ($svgPropertyType, $svgListPropertyType, $svgNativeType) if not $implType =~ /SVG/;
-
- $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($implType);
- return ($svgPropertyType, $svgListPropertyType, $svgNativeType) if not $svgNativeType;
-
- # Append space to avoid compilation errors when using PassRefPtr<$svgNativeType>
- $svgNativeType = "$svgNativeType ";
-
- my $svgWrappedNativeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($implType);
- if ($svgNativeType =~ /SVGPropertyTearOff/) {
- $svgPropertyType = $svgWrappedNativeType;
- $implIncludes{"SVGAnimatedPropertyTearOff.h"} = 1;
- } elsif ($svgNativeType =~ /SVGListPropertyTearOff/ or $svgNativeType =~ /SVGStaticListPropertyTearOff/) {
- $svgListPropertyType = $svgWrappedNativeType;
- $headerIncludes{"SVGAnimatedListPropertyTearOff.h"} = 1;
- $headerIncludes{"SVGStaticListPropertyTearOff.h"} = 1;
- } elsif ($svgNativeType =~ /SVGTransformListPropertyTearOff/) {
- $svgListPropertyType = $svgWrappedNativeType;
- $headerIncludes{"SVGAnimatedListPropertyTearOff.h"} = 1;
- $headerIncludes{"SVGTransformListPropertyTearOff.h"} = 1;
- } elsif ($svgNativeType =~ /SVGPathSegListPropertyTearOff/) {
- $svgListPropertyType = $svgWrappedNativeType;
- $headerIncludes{"SVGPathSegListPropertyTearOff.h"} = 1;
- }
-
- if ($svgPropertyType) {
- $svgPropertyType = "SVGPoint" if $svgPropertyType eq "FloatPoint";
- }
-
- return ($svgPropertyType, $svgListPropertyType, $svgNativeType);
-}
-
-sub GenerateHeader
-{
- my $object = shift;
- my $dataNode = shift;
-
- my $interfaceName = $dataNode->name;
- my $className = "V8$interfaceName";
- my $implClassName = $interfaceName;
-
- # Copy contents of parent classes except the first parent or if it is
- # EventTarget.
- $codeGenerator->AddMethodsConstantsAndAttributesFromParentClasses($dataNode, \@allParents, 1);
-
- my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
-
- # - Add default header template
- push(@headerContent, GenerateHeaderContentHeader($dataNode));
-
- $headerIncludes{"wtf/text/StringHash.h"} = 1;
- $headerIncludes{"WrapperTypeInfo.h"} = 1;
- $headerIncludes{"V8DOMWrapper.h"} = 1;
-
- my $headerClassInclude = GetHeaderClassInclude($implClassName);
- $headerIncludes{$headerClassInclude} = 1 if $headerClassInclude ne "";
-
- my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGPropertyTypes($implClassName);
-
- 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, "\nnamespace WebCore {\n");
- push(@headerContent, "\ntemplate<typename PropertyType> class SVGPropertyTearOff;\n") if $svgPropertyType;
- if ($svgNativeType) {
- if ($svgNativeType =~ /SVGStaticListPropertyTearOff/) {
- push(@headerContent, "\ntemplate<typename PropertyType> class SVGStaticListPropertyTearOff;\n");
- } else {
- push(@headerContent, "\ntemplate<typename PropertyType> class SVGListPropertyTearOff;\n");
- }
- }
- push(@headerContent, "\nclass FloatRect;\n") if $svgPropertyType && $svgPropertyType eq "FloatRect";
- push(@headerContent, "\nclass $className {\n");
-
- my $nativeType = GetNativeTypeForConversions($dataNode, $interfaceName);
- my $domMapFunction = GetDomMapFunction($dataNode, $interfaceName);
- my $forceNewObjectParameter = IsDOMNodeType($interfaceName) ? ", bool forceNewObject = false" : "";
- my $forceNewObjectInput = IsDOMNodeType($interfaceName) ? ", bool forceNewObject" : "";
- my $forceNewObjectCall = IsDOMNodeType($interfaceName) ? ", forceNewObject" : "";
-
- 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> object)
- {
- return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
- }
- inline 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();
-END
- }
-
- if ($implClassName eq "HTMLDocument") {
- push(@headerContent, <<END);
- static v8::Local<v8::Object> WrapInShadowObject(v8::Local<v8::Object> wrapper, Node* impl);
- static v8::Handle<v8::Value> GetNamedProperty(HTMLDocument* htmlDocument, const AtomicString& key);
-END
- }
-
- my @enabledAtRuntime;
- foreach my $function (@{$dataNode->functions}) {
- my $name = $function->signature->name;
- my $attrExt = $function->signature->extendedAttributes;
-
- 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);
- }
- }
-
- if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"V8CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) {
- push(@headerContent, <<END);
- static v8::Handle<v8::Value> constructorCallback(const v8::Arguments& args);
-END
- }
-
- foreach my $attribute (@{$dataNode->attributes}) {
- my $name = $attribute->signature->name;
- my $attrExt = $attribute->signature->extendedAttributes;
- 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);
-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);
-END
- }
- if ($attrExt->{"EnabledAtRuntime"}) {
- push(@enabledAtRuntime, $attribute);
- }
- }
-
- GenerateHeaderNamedAndIndexedPropertyAccessors($dataNode);
- GenerateHeaderCustomCall($dataNode);
- GenerateHeaderCustomInternalFieldIndices($dataNode);
-
- 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);
-END
- }
-
- push(@headerContent, <<END);
-private:
- static v8::Handle<v8::Object> wrapSlow(${nativeType}*);
-};
-
-END
-
- push(@headerContent, <<END);
-
-v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput})
-{
-END
- if ($domMapFunction) {
- push(@headerContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
- my $getWrapper = IsNodeSubType($dataNode) ? "V8DOMWrapper::getWrapper(impl)" : "${domMapFunction}.get(impl)";
- push(@headerContent, <<END);
- v8::Handle<v8::Object> wrapper = ${getWrapper};
- if (!wrapper.IsEmpty())
- return wrapper;
-END
- push(@headerContent, " }\n") if IsDOMNodeType($interfaceName);
- }
- push(@headerContent, <<END);
- return ${className}::wrapSlow(impl);
-}
-END
-
- if (!HasCustomToV8Implementation($dataNode, $interfaceName)) {
- push(@headerContent, <<END);
-
-inline v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectParameter})
-{
- if (!impl)
- return v8::Null();
- return ${className}::wrap(impl${forceNewObjectCall});
-}
-END
- } elsif ($interfaceName ne 'Node') {
- push(@headerContent, <<END);
-
-v8::Handle<v8::Value> toV8(${nativeType}*${forceNewObjectParameter});
-END
- } else {
- push(@headerContent, <<END);
-
-v8::Handle<v8::Value> toV8Slow(Node*, bool);
-
-inline v8::Handle<v8::Value> toV8(Node* impl, bool forceNewObject = false)
-{
- if (!impl)
- return v8::Null();
- if (!forceNewObject) {
- v8::Handle<v8::Value> wrapper = V8DOMWrapper::getWrapper(impl);
- if (!wrapper.IsEmpty())
- return wrapper;
- }
- return toV8Slow(impl, forceNewObject);
-}
-END
- }
-
- if (IsRefPtrType($implClassName)) {
- push(@headerContent, <<END);
-inline v8::Handle<v8::Value> toV8(PassRefPtr< ${nativeType} > impl${forceNewObjectParameter})
-{
- return toV8(impl.get()${forceNewObjectCall});
-}
-END
- }
-
- push(@headerContent, "}\n\n");
- push(@headerContent, "#endif // $className" . "_h\n");
-
- my $conditionalString = GenerateConditionalString($dataNode);
- push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditionalString;
-}
-
-sub GetInternalFields
-{
- my $dataNode = shift;
- my $name = $dataNode->name;
-
- 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");
- } elsif ($name eq "DOMWindow") {
- push(@customInternalFields, "enteredIsolatedWorldIndex");
- }
- return @customInternalFields;
-}
-
-sub GetHeaderClassInclude
-{
- my $className = shift;
- if ($className =~ /SVGPathSeg/) {
- $className =~ s/Abs|Rel//;
- }
- return "" if ($codeGenerator->AvoidInclusionOfType($className));
- return "${className}.h";
-}
-
-sub GenerateHeaderCustomInternalFieldIndices
-{
- my $dataNode = shift;
- my @customInternalFields = GetInternalFields($dataNode);
- my $customFieldCounter = 0;
- foreach my $customInternalField (@customInternalFields) {
- push(@headerContent, <<END);
- static const int ${customInternalField} = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
-END
- $customFieldCounter++;
- }
- push(@headerContent, <<END);
- static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
-END
-}
-
-my %indexerSpecialCases = (
- "Storage" => 1,
- "HTMLAppletElement" => 1,
- "HTMLEmbedElement" => 1,
- "HTMLObjectElement" => 1
-);
-
-sub GenerateHeaderNamedAndIndexedPropertyAccessors
-{
- my $dataNode = shift;
- my $interfaceName = $dataNode->name;
- my $hasCustomIndexedGetter = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
- my $hasCustomIndexedSetter = $dataNode->extendedAttributes->{"HasCustomIndexSetter"} && !$dataNode->extendedAttributes->{"HasNumericIndexGetter"};
- my $hasCustomNamedGetter = $dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
- my $hasCustomNamedSetter = $dataNode->extendedAttributes->{"DelegatingPutFunction"};
- my $hasCustomDeleters = $dataNode->extendedAttributes->{"CustomDeleteProperty"};
- my $hasCustomEnumerator = $dataNode->extendedAttributes->{"CustomGetPropertyNames"};
- if ($interfaceName eq "HTMLOptionsCollection") {
- $interfaceName = "HTMLCollection";
- $hasCustomIndexedGetter = 1;
- $hasCustomNamedGetter = 1;
- }
- if ($interfaceName eq "DOMWindow") {
- $hasCustomDeleterr = 0;
- $hasEnumerator = 0;
- }
- if ($interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
- $hasCustomNamedGetter = 1;
- }
- if ($interfaceName eq "HTMLDocument") {
- $hasCustomNamedGetter = 0;
- $hasCustomIndexedGetter = 0;
- }
- my $isIndexerSpecialCase = exists $indexerSpecialCases{$interfaceName};
-
- if ($hasCustomIndexedGetter || $isIndexerSpecialCase) {
- push(@headerContent, <<END);
- static v8::Handle<v8::Value> indexedPropertyGetter(uint32_t, const v8::AccessorInfo&);
-END
- }
-
- if ($isIndexerSpecialCase || $hasCustomIndexedSetter) {
- push(@headerContent, <<END);
- static v8::Handle<v8::Value> indexedPropertySetter(uint32_t, v8::Local<v8::Value>, const v8::AccessorInfo&);
-END
- }
- if ($hasCustomDeleters) {
- push(@headerContent, <<END);
- static v8::Handle<v8::Boolean> indexedPropertyDeleter(uint32_t, const v8::AccessorInfo&);
-END
- }
- if ($hasCustomNamedGetter) {
- push(@headerContent, <<END);
- static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String>, const v8::AccessorInfo&);
-END
- }
- if ($hasCustomNamedSetter) {
- push(@headerContent, <<END);
- static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo&);
-END
- }
- if ($hasCustomDeleters) {
- push(@headerContent, <<END);
- static v8::Handle<v8::Boolean> namedPropertyDeleter(v8::Local<v8::String>, const v8::AccessorInfo&);
-END
- }
- if ($hasCustomEnumerator) {
- push(@headerContent, <<END);
- static v8::Handle<v8::Array> namedPropertyEnumerator(const v8::AccessorInfo&);
- static v8::Handle<v8::Integer> namedPropertyQuery(v8::Local<v8::String>, const v8::AccessorInfo&);
-END
- }
-}
-
-sub GenerateHeaderCustomCall
-{
- my $dataNode = shift;
-
- if ($dataNode->extendedAttributes->{"CustomCall"}) {
- 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");
- }
- 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");
- }
-}
-
-sub GenerateSetDOMException
-{
- my $indent = shift;
- my $result = "";
-
- $result .= $indent . "if (UNLIKELY(ec)) {\n";
- $result .= $indent . " V8Proxy::setDOMException(ec);\n";
- $result .= $indent . " return v8::Handle<v8::Value>();\n";
- $result .= $indent . "}\n";
-
- return $result;
-}
-
-sub IsSubType
-{
- my $dataNode = shift;
- my $parentType = shift;
- return 1 if ($dataNode->name eq $parentType);
- foreach (@allParents) {
- my $parent = $codeGenerator->StripModule($_);
- return 1 if $parent eq $parentType;
- }
- return 0;
-}
-
-sub IsNodeSubType
-{
- my $dataNode = shift;
- return IsSubType($dataNode, "Node");
-}
-
-sub GenerateDomainSafeFunctionGetter
-{
- my $function = shift;
- my $implClassName = shift;
-
- my $className = "V8" . $implClassName;
- my $funcName = $function->signature->name;
-
- my $signature = "v8::Signature::New(" . $className . "::GetRawTemplate())";
- if ($function->signature->extendedAttributes->{"V8DoNotCheckSignature"}) {
- $signature = "v8::Local<v8::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)
-{
- INC_STATS(\"DOM.$implClassName.$funcName._get\");
- 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 privateTemplate->GetFunction();
- }
- ${implClassName}* imp = ${className}::toNative(holder);
- if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false)) {
- static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
- return sharedTemplate->GetFunction();
- }
- return privateTemplate->GetFunction();
-}
-
-END
-}
-
-sub GenerateConstructorGetter
-{
- my $implClassName = shift;
-
- push(@implContentDecls, <<END);
-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->IsExternal() || data->IsNumber());
- WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data);
-END
-
- 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 ($implClassName eq "DedicatedWorkerContext" or $implClassName eq "WorkerContext" or $implClassName eq "SharedWorkerContext") {
- push(@implContentDecls, <<END);
- return V8DOMWrapper::getConstructor(type, V8WorkerContext::toNative(info.Holder()));
-END
- } else {
- push(@implContentDecls, " return v8::Handle<v8::Value>();");
- }
-
- push(@implContentDecls, <<END);
-}
-
-END
-}
-
-sub GenerateNormalAttrGetter
-{
- my $attribute = shift;
- my $dataNode = shift;
- my $implClassName = shift;
- my $interfaceName = shift;
-
- my $attrExt = $attribute->signature->extendedAttributes;
- my $attrName = $attribute->signature->name;
- my $attrType = GetTypeFromSignature($attribute->signature);
- my $nativeType = GetNativeTypeFromSignature($attribute->signature, -1);
-
- my $getterStringUsesImp = $implClassName ne "SVGNumber";
- my $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($implClassName);
-
- # Getter
- my $conditionalString = GenerateConditionalString($attribute->signature);
- push(@implContentDecls, "#if ${conditionalString}\n\n") if $conditionalString;
-
- push(@implContentDecls, <<END);
-static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
-{
- INC_STATS(\"DOM.$implClassName.$attrName._get\");
-END
-
- if ($svgNativeType) {
- my $svgWrappedNativeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($implClassName);
- if ($svgWrappedNativeType =~ /List/) {
- push(@implContentDecls, <<END);
- $svgNativeType* imp = V8${implClassName}::toNative(info.Holder());
-END
- } else {
- push(@implContentDecls, <<END);
- $svgNativeType* wrapper = V8${implClassName}::toNative(info.Holder());
- $svgWrappedNativeType& impInstance = wrapper->propertyReference();
-END
- if ($getterStringUsesImp) {
- push(@implContentDecls, <<END);
- $svgWrappedNativeType* imp = &impInstance;
-END
- }
- }
- } elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) {
- if ($interfaceName eq "DOMWindow") {
- push(@implContentDecls, <<END);
- v8::Handle<v8::Object> holder = info.Holder();
-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>();
-END
- }
- push(@implContentDecls, <<END);
- ${implClassName}* imp = V8${implClassName}::toNative(holder);
-END
- } else {
- my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
- my $url = $attribute->signature->extendedAttributes->{"URL"};
- if ($getterStringUsesImp && $reflect && !$url && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) {
- # Generate super-compact call for regular attribute getter:
- my $contentAttributeName = $reflect eq "1" ? lc $attrName : $reflect;
- 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, "#endif // ${conditionalString}\n\n") if $conditionalString;
- return;
- # Skip the rest of the function!
- }
- push(@implContentDecls, <<END);
- ${implClassName}* imp = V8${implClassName}::toNative(info.Holder());
-END
- }
-
- # Generate security checks if necessary
- if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
- 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()))\n return v8::Handle<v8::Value>();\n\n");
- }
-
- my $useExceptions = 1 if @{$attribute->getterExceptions};
- if ($useExceptions) {
- $implIncludes{"ExceptionCode.h"} = 1;
- push(@implContentDecls, " ExceptionCode ec = 0;\n");
- }
-
- if ($attribute->signature->extendedAttributes->{"v8referenceattr"}) {
- $attrName = $attribute->signature->extendedAttributes->{"v8referenceattr"};
- }
-
- my $returnType = GetTypeFromSignature($attribute->signature);
-
- my $getterString;
- if ($getterStringUsesImp) {
- $getterString = "imp->" . $codeGenerator->GetterExpressionPrefix(\%implIncludes, $interfaceName, $attribute);
- $getterString .= "ec" if $useExceptions;
- $getterString .= ")";
- } else {
- $getterString = "impInstance";
- }
-
- my $result;
- my $wrapper;
-
- if ($attribute->signature->type eq "EventListener" && $dataNode->name eq "DOMWindow") {
- push(@implContentDecls, " if (!imp->document())\n");
- push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
- }
-
- if ($useExceptions) {
- if ($nativeType =~ /^V8Parameter/) {
- push(@implContentDecls, " " . ConvertToV8Parameter($attribute->signature, $nativeType, "v", $getterString) . ";\n");
- } else {
- push(@implContentDecls, " $nativeType v = $getterString;\n");
- }
- push(@implContentDecls, GenerateSetDOMException(" "));
- $result = "v";
- $result .= ".release()" if (IsRefPtrType($returnType));
- } else {
- # 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");
- push(@implContentDecls, "#endif // ${conditionalString}\n\n") if $conditionalString;
- return;
- }
-
- if ($codeGenerator->IsSVGAnimatedType($implClassName) and $codeGenerator->IsSVGTypeNeedingTearOff($attrType)) {
- $implIncludes{"V8$attrType.h"} = 1;
- my $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($attrType);
- # Convert from abstract SVGProperty to real type, so the right toJS() method can be invoked.
- push(@implContentDecls, " return toV8(static_cast<$svgNativeType*>($result));\n");
- } elsif ($codeGenerator->IsSVGTypeNeedingTearOff($attrType) and not $implClassName =~ /List$/) {
- $implIncludes{"V8$attrType.h"} = 1;
- $implIncludes{"SVGPropertyTearOff.h"} = 1;
- my $tearOffType = $codeGenerator->GetSVGTypeNeedingTearOff($attrType);
- if ($codeGenerator->IsSVGTypeWithWritablePropertiesNeedingTearOff($attrType) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
- my $getter = $result;
- $getter =~ s/imp->//;
- $getter =~ s/\(\)//;
-
- my $updateMethod = "&${implClassName}::update" . $codeGenerator->WK_ucfirst($getter);
-
- my $selfIsTearOffType = $codeGenerator->IsSVGTypeNeedingTearOff($implClassName);
- if ($selfIsTearOffType) {
- $implIncludes{"SVGStaticPropertyWithParentTearOff.h"} = 1;
- $tearOffType =~ s/SVGPropertyTearOff</SVGStaticPropertyWithParentTearOff<$implClassName, /;
-
- if ($result =~ /matrix/ and $implClassName eq "SVGTransform") {
- # SVGTransform offers a matrix() method for internal usage that returns an AffineTransform
- # and a svgMatrix() method returning a SVGMatrix, used for the bindings.
- $result =~ s/matrix/svgMatrix/;
- }
-
- push(@implContentDecls, " return toV8(WTF::getPtr(${tearOffType}::create(wrapper, $result, $updateMethod)));\n");
- } else {
- $implIncludes{"SVGStaticPropertyTearOff.h"} = 1;
- $tearOffType =~ s/SVGPropertyTearOff</SVGStaticPropertyTearOff<$implClassName, /;
-
- push(@implContentDecls, " return toV8(WTF::getPtr(${tearOffType}::create(imp, $result, $updateMethod)));\n");
- }
- } elsif ($tearOffType =~ /SVGStaticListPropertyTearOff/) {
- my $extraImp = "GetOwnerElementForType<$implClassName, IsDerivedFromSVGElement<$implClassName>::value>::ownerElement(imp), ";
- push(@implContentDecls, " return toV8(WTF::getPtr(${tearOffType}::create($extraImp$result)));\n");
- } elsif ($tearOffType =~ /SVG(Point|PathSeg)List/) {
- push(@implContentDecls, " return toV8(WTF::getPtr($result));\n");
- } else {
- push(@implContentDecls, " return toV8(WTF::getPtr(${tearOffType}::create($result)));\n");
- }
- } else {
- push(@implContentDecls, " " . ReturnNativeToJSValue($attribute->signature, $result, " ").";\n");
- }
-
- push(@implContentDecls, "}\n\n"); # end of getter
- push(@implContentDecls, "#endif // ${conditionalString}\n\n") if $conditionalString;
-}
-
-sub GenerateNormalAttrSetter
-{
- my $attribute = shift;
- my $dataNode = shift;
- my $implClassName = shift;
- my $interfaceName = shift;
-
- $implIncludes{"V8BindingMacros.h"} = 1;
-
- my $attrExt = $attribute->signature->extendedAttributes;
-
- my $conditionalString = GenerateConditionalString($attribute->signature);
- push(@implContentDecls, "#if ${conditionalString}\n\n") if $conditionalString;
-
- 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");
-
- # If the "StrictTypeChecking" extended attribute is present, and the attribute's type is an
- # interface type, then if the incoming value does not implement that interface, a TypeError is
- # thrown rather than silently passing NULL to the C++ code.
- # Per the Web IDL and ECMAScript specifications, incoming values can always be converted to both
- # strings and numbers, so do not throw TypeError if the attribute is of these types.
- if ($attribute->signature->extendedAttributes->{"StrictTypeChecking"}) {
- my $argType = GetTypeFromSignature($attribute->signature);
- if (IsWrapperType($argType)) {
- push(@implContentDecls, " if (!isUndefinedOrNull(value) && !V8${argType}::HasInstance(value)) {\n");
- push(@implContentDecls, " V8Proxy::throwTypeError();\n");
- push(@implContentDecls, " return;\n");
- push(@implContentDecls, " }\n");
- }
- }
-
- my $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($implClassName);
- if ($svgNativeType) {
- my $svgWrappedNativeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($implClassName);
- if ($svgWrappedNativeType =~ /List$/) {
- push(@implContentDecls, <<END);
- $svgNativeType* imp = V8${implClassName}::toNative(info.Holder());
-END
- } else {
- push(@implContentDecls, " $svgNativeType* wrapper = V8${implClassName}::toNative(info.Holder());\n");
- push(@implContentDecls, " if (wrapper->role() == AnimValRole) {\n");
- push(@implContentDecls, " V8Proxy::setDOMException(NO_MODIFICATION_ALLOWED_ERR);\n");
- push(@implContentDecls, " return;\n");
- push(@implContentDecls, " }\n");
- push(@implContentDecls, " $svgWrappedNativeType& impInstance = wrapper->propertyReference();\n");
- push(@implContentDecls, " $svgWrappedNativeType* imp = &impInstance;\n");
- }
- } elsif ($attrExt->{"v8OnProto"}) {
- if ($interfaceName eq "DOMWindow") {
- push(@implContentDecls, <<END);
- v8::Handle<v8::Object> holder = info.Holder();
-END
- } else {
- # perform lookup first
- push(@implContentDecls, <<END);
- v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8${interfaceName}::GetTemplate(), info.This());
- if (holder.IsEmpty())
- return;
-END
- }
- push(@implContentDecls, <<END);
- ${implClassName}* imp = V8${implClassName}::toNative(holder);
-END
- } else {
- my $attrType = GetTypeFromSignature($attribute->signature);
- my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
- if ($reflect && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) {
- # Generate super-compact call for regular attribute setter:
- my $contentAttributeName = $reflect eq "1" ? lc $attrName : $reflect;
- 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, "#endif // ${conditionalString}\n\n") if $conditionalString;
- return;
- # Skip the rest of the function!
- }
-
- push(@implContentDecls, <<END);
- ${implClassName}* imp = V8${implClassName}::toNative(info.Holder());
-END
- }
-
- my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
- if ($attribute->signature->type eq "EventListener") {
- if ($dataNode->name eq "DOMWindow") {
- push(@implContentDecls, " if (!imp->document())\n");
- push(@implContentDecls, " return;\n");
- }
- } else {
- my $value = JSValueToNative($attribute->signature, "value");
- if ($nativeType =~ /^V8Parameter/) {
- push(@implContentDecls, " " . ConvertToV8Parameter($attribute->signature, $nativeType, "v", $value, "VOID") . "\n");
- } else {
- push(@implContentDecls, " $nativeType v = $value;\n");
- }
- }
-
- my $result = "v";
- my $returnType = GetTypeFromSignature($attribute->signature);
- if (IsRefPtrType($returnType)) {
- $result = "WTF::getPtr(" . $result . ")";
- }
-
- my $useExceptions = 1 if @{$attribute->setterExceptions};
-
- if ($useExceptions) {
- $implIncludes{"ExceptionCode.h"} = 1;
- push(@implContentDecls, " ExceptionCode ec = 0;\n");
- }
-
- if ($implClassName eq "SVGNumber") {
- push(@implContentDecls, " *imp = $result;\n");
- } else {
- if ($attribute->signature->type eq "EventListener") {
- my $implSetterFunctionName = $codeGenerator->WK_ucfirst($attrName);
- $implIncludes{"V8AbstractEventListener.h"} = 1;
- 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 {
- my $setterExpressionPrefix = $codeGenerator->SetterExpressionPrefix(\%implIncludes, $interfaceName, $attribute);
- push(@implContentDecls, " imp->$setterExpressionPrefix$result");
- }
- push(@implContentDecls, ", ec") if $useExceptions;
- push(@implContentDecls, ");\n");
- }
-
- if ($useExceptions) {
- push(@implContentDecls, " if (UNLIKELY(ec))\n");
- push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
- }
-
- if ($svgNativeType) {
- if ($useExceptions) {
- push(@implContentDecls, " if (!ec)\n");
- push(@implContentDecls, " wrapper->commitChange();\n");
- } else {
- push(@implContentDecls, " wrapper->commitChange();\n");
- }
- }
-
- push(@implContentDecls, " return;\n");
- push(@implContentDecls, "}\n\n"); # end of setter
- push(@implContentDecls, "#endif // ${conditionalString}\n\n") if $conditionalString;
-}
-
-sub GetFunctionTemplateCallbackName
-{
- $function = shift;
- $interfaceName = shift;
-
- my $name = $function->signature->name;
-
- if ($function->signature->extendedAttributes->{"Custom"} ||
- $function->signature->extendedAttributes->{"V8Custom"}) {
- if ($function->signature->extendedAttributes->{"Custom"} &&
- $function->signature->extendedAttributes->{"V8Custom"}) {
- die "Custom and V8Custom should be mutually exclusive!"
- }
- return "V8${interfaceName}::${name}Callback";
- } else {
- return "${interfaceName}Internal::${name}Callback";
- }
-}
-
-sub GenerateNewFunctionTemplate
-{
- $function = shift;
- $interfaceName = shift;
- $signature = shift;
-
- 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).
- if ($codeGenerator->IsStringType($type)) {
- push(@andExpression, "(${value}->IsNull() || ${value}->IsUndefined() || ${value}->IsString() || ${value}->IsObject())");
- } elsif ($parameter->extendedAttributes->{"Callback"}) {
- # For Callbacks only checks if the value is null or object.
- push(@andExpression, "(${value}->IsNull() || ${value}->IsObject())");
- } elsif (IsWrapperType($type)) {
- push(@andExpression, "(${value}->IsNull() || V8${type}::HasInstance($value))");
- }
-
- $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::throwTypeError();
- return notHandledByInterceptor();
-END
- push(@implContentDecls, "}\n\n");
-}
-
-sub GenerateFunctionCallback
-{
- my $function = shift;
- my $dataNode = shift;
- my $implClassName = shift;
-
- my $interfaceName = $dataNode->name;
- my $name = $function->signature->name;
-
- 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};
-
- my $requiresAllArguments = $function->signature->extendedAttributes->{"RequiresAllArguments"};
- if ($requiresAllArguments) {
- my $numMandatoryParams = @{$function->parameters};
- foreach my $param (reverse(@{$function->parameters})) {
- if ($param->extendedAttributes->{"Optional"}) {
- $numMandatoryParams--;
- } else {
- last;
- }
- }
- push(@implContentDecls, " if (args.Length() < $numMandatoryParams)\n");
- if ($requiresAllArguments eq "Raise") {
- push(@implContentDecls, " return throwError(\"Not enough arguments\", V8Proxy::SyntaxError);\n");
- } else {
- push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
- }
- }
-
- my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGPropertyTypes($implClassName);
-
- if ($svgNativeType) {
- my $nativeClassName = GetNativeType($implClassName);
- if ($implClassName =~ /List$/) {
- push(@implContentDecls, " $nativeClassName imp = V8${implClassName}::toNative(args.Holder());\n");
- } else {
- push(@implContentDecls, " $nativeClassName wrapper = V8${implClassName}::toNative(args.Holder());\n");
- push(@implContentDecls, " if (wrapper->role() == AnimValRole) {\n");
- push(@implContentDecls, " V8Proxy::setDOMException(NO_MODIFICATION_ALLOWED_ERR);\n");
- push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
- push(@implContentDecls, " }\n");
- my $svgWrappedNativeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($implClassName);
- push(@implContentDecls, " $svgWrappedNativeType& impInstance = wrapper->propertyReference();\n");
- push(@implContentDecls, " $svgWrappedNativeType* imp = &impInstance;\n");
- }
- } elsif (!$function->signature->extendedAttributes->{"ClassMethod"}) {
- push(@implContentDecls, <<END);
- ${implClassName}* imp = V8${implClassName}::toNative(args.Holder());
-END
- }
-
- # 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, <<END);
- if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true))
- return v8::Handle<v8::Value>();
-END
- }
-
- my $raisesExceptions = @{$function->raisesExceptions};
- if (!$raisesExceptions) {
- foreach my $parameter (@{$function->parameters}) {
- if ((!$parameter->extendedAttributes->{"Callback"} and TypeCanFailConversion($parameter)) or $parameter->extendedAttributes->{"IsIndex"}) {
- $raisesExceptions = 1;
- }
- }
- }
-
- if ($raisesExceptions) {
- $implIncludes{"ExceptionCode.h"} = 1;
- push(@implContentDecls, " ExceptionCode ec = 0;\n");
- push(@implContentDecls, " {\n");
- # The brace here is needed to prevent the ensuing 'goto fail's from jumping past constructors
- # of objects (like Strings) declared later, causing compile errors. The block scope ends
- # right before the label 'fail:'.
- }
-
- if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
- push(@implContentDecls, <<END);
- RefPtr<ScriptArguments> scriptArguments(createScriptArguments(args, $numParameters));
- size_t maxStackSize = imp->shouldCaptureFullStackTrace() ? ScriptCallStack::maxCallStackSizeToCapture : 1;
- RefPtr<ScriptCallStack> callStack(createScriptCallStack(maxStackSize));
- if (!callStack)
- return v8::Undefined();
-END
- $implIncludes{"ScriptArguments.h"} = 1;
- $implIncludes{"ScriptCallStack.h"} = 1;
- $implIncludes{"ScriptCallStackFactory.h"} = 1;
- }
- if ($function->signature->extendedAttributes->{"SVGCheckSecurityDocument"}) {
- push(@implContentDecls, <<END);
- if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->getSVGDocument(ec)))
- return v8::Handle<v8::Value>();
-END
- }
-
- my $paramIndex = 0;
- foreach my $parameter (@{$function->parameters}) {
- TranslateParameter($parameter);
-
- my $parameterName = $parameter->name;
-
- # Optional callbacks should be treated differently, because they always have a default value (0),
- # and we can reduce the number of overloaded functions that take a different number of parameters.
- if ($parameter->extendedAttributes->{"Optional"} && !$parameter->extendedAttributes->{"Callback"}) {
- # Generate early call if there are not enough parameters.
- push(@implContentDecls, " if (args.Length() <= $paramIndex) {\n");
- my $functionCall = GenerateFunctionCallString($function, $paramIndex, " " x 2, $implClassName);
- push(@implContentDecls, $functionCall);
- push(@implContentDecls, " }\n");
- }
-
- $implIncludes{"ExceptionCode.h"} = 1;
- my $nativeType = GetNativeTypeFromSignature($parameter, $paramIndex);
- if ($parameter->extendedAttributes->{"Callback"}) {
- my $className = GetCallbackClassName($parameter->type);
- $implIncludes{"$className.h"} = 1;
- if ($parameter->extendedAttributes->{"Optional"}) {
- push(@implContentDecls, " RefPtr<" . $parameter->type . "> $parameterName;\n");
- push(@implContentDecls, " if (args.Length() > $paramIndex && !args[$paramIndex]->IsNull() && !args[$paramIndex]->IsUndefined()) {\n");
- push(@implContentDecls, " if (!args[$paramIndex]->IsObject())\n");
- push(@implContentDecls, " return throwError(TYPE_MISMATCH_ERR);\n");
- push(@implContentDecls, " $parameterName = ${className}::create(args[$paramIndex], getScriptExecutionContext());\n");
- push(@implContentDecls, " }\n");
- } else {
- push(@implContentDecls, " if (args.Length() <= $paramIndex || !args[$paramIndex]->IsObject())\n");
- push(@implContentDecls, " return throwError(TYPE_MISMATCH_ERR);\n");
- push(@implContentDecls, " RefPtr<" . $parameter->type . "> $parameterName = ${className}::create(args[$paramIndex], getScriptExecutionContext());\n");
- }
- } elsif ($parameter->type eq "SerializedScriptValue") {
- $implIncludes{"SerializedScriptValue.h"} = 1;
- push(@implContentDecls, " bool ${parameterName}DidThrow = false;\n");
- push(@implContentDecls, " $nativeType $parameterName = SerializedScriptValue::create(args[$paramIndex], ${parameterName}DidThrow);\n");
- push(@implContentDecls, " if (${parameterName}DidThrow)\n");
- push(@implContentDecls, " return v8::Undefined();\n");
- } elsif (TypeCanFailConversion($parameter)) {
- push(@implContentDecls, " $nativeType $parameterName = " .
- JSValueToNative($parameter, "args[$paramIndex]") . ";\n");
- push(@implContentDecls, " if (UNLIKELY(!$parameterName)) {\n");
- push(@implContentDecls, " ec = TYPE_MISMATCH_ERR;\n");
- push(@implContentDecls, " goto fail;\n");
- push(@implContentDecls, " }\n");
- } elsif ($nativeType =~ /^V8Parameter/) {
- my $value = JSValueToNative($parameter, "args[$paramIndex]");
- push(@implContentDecls, " " . ConvertToV8Parameter($parameter, $nativeType, $parameterName, $value) . "\n");
- } else {
- $implIncludes{"V8BindingMacros.h"} = 1;
- # If the "StrictTypeChecking" extended attribute is present, and the argument's type is an
- # interface type, then if the incoming value does not implement that interface, a TypeError
- # is thrown rather than silently passing NULL to the C++ code.
- # Per the Web IDL and ECMAScript specifications, incoming values can always be converted
- # to both strings and numbers, so do not throw TypeError if the argument is of these
- # types.
- if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) {
- my $argValue = "args[$paramIndex]";
- my $argType = GetTypeFromSignature($parameter);
- if (IsWrapperType($argType)) {
- push(@implContentDecls, " if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !V8${argType}::HasInstance($argValue)) {\n");
- push(@implContentDecls, " V8Proxy::throwTypeError();\n");
- push(@implContentDecls, " return notHandledByInterceptor();\n");
- push(@implContentDecls, " }\n");
- }
- }
- push(@implContentDecls, " EXCEPTION_BLOCK($nativeType, $parameterName, " .
- JSValueToNative($parameter, "args[$paramIndex]") . ");\n");
- }
-
- if ($parameter->extendedAttributes->{"IsIndex"}) {
- push(@implContentDecls, " if (UNLIKELY($parameterName < 0)) {\n");
- push(@implContentDecls, " ec = INDEX_SIZE_ERR;\n");
- push(@implContentDecls, " goto fail;\n");
- push(@implContentDecls, " }\n");
- }
-
- $paramIndex++;
- }
-
- # Build the function call string.
- my $callString = GenerateFunctionCallString($function, $paramIndex, " ", $implClassName);
- push(@implContentDecls, "$callString");
-
- if ($raisesExceptions) {
- push(@implContentDecls, " }\n");
- push(@implContentDecls, " fail:\n");
- push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
- push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
- }
-
- push(@implContentDecls, "}\n\n");
-}
-
-sub GenerateBatchedAttributeData
-{
- my $dataNode = shift;
- my $interfaceName = $dataNode->name;
- my $attributes = shift;
-
- foreach my $attribute (@$attributes) {
- my $conditionalString = GenerateConditionalString($attribute->signature);
- push(@implContent, "#if ${conditionalString}\n") if $conditionalString;
- GenerateSingleBatchedAttribute($interfaceName, $attribute, ",", "");
- push(@implContent, "#endif // ${conditionalString}\n") if $conditionalString;
- }
-}
-
-sub GenerateSingleBatchedAttribute
-{
- my $interfaceName = shift;
- my $attribute = shift;
- my $delimiter = shift;
- my $indent = shift;
- 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";
- } elsif ($attrExt->{"DoNotCheckDomainSecurityOnSet"}) {
- $accessControl = "v8::ALL_CAN_WRITE";
- } elsif ($attrExt->{"DoNotCheckDomainSecurity"}) {
- $accessControl = "v8::ALL_CAN_READ";
- if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) {
- $accessControl .= " | v8::ALL_CAN_WRITE";
- }
- }
- if ($attrExt->{"V8DisallowShadowing"}) {
- $accessControl .= " | v8::PROHIBITS_OVERWRITING";
- }
- $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";
-
- my $customAccessor =
- $attrExt->{"Custom"} ||
- $attrExt->{"CustomSetter"} ||
- $attrExt->{"CustomGetter"} ||
- $attrExt->{"V8Custom"} ||
- $attrExt->{"V8CustomSetter"} ||
- $attrExt->{"V8CustomGetter"} ||
- "";
- if ($customAccessor eq 1) {
- # use the naming convension, interface + (capitalize) attr name
- $customAccessor = $interfaceName . "::" . $attrName;
- }
-
- my $getter;
- my $setter;
- my $propAttr = "v8::None";
- my $hasCustomSetter = 0;
-
- # Check attributes.
- if ($attrExt->{"DontEnum"}) {
- $propAttr .= " | v8::DontEnum";
- }
- if ($attrExt->{"V8DisallowShadowing"}) {
- $propAttr .= " | v8::DontDelete";
- }
-
- my $on_proto = "0 /* on instance */";
- my $data = "0 /* no data */";
-
- # Constructor
- if ($attribute->signature->type =~ /Constructor$/) {
- my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
- $constructorType =~ s/Constructor$//;
- $implIncludes{"V8${constructorType}.h"} = 1;
- if ($customAccessor) {
- $getter = "V8${customAccessor}AccessorGetter";
- } else {
- $data = "&V8${constructorType}::info";
- $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
- }
- $setter = "0";
- $propAttr = "v8::ReadOnly";
-
- } else {
- # Default Getter and Setter
- $getter = "${interfaceName}Internal::${attrName}AttrGetter";
- $setter = "${interfaceName}Internal::${attrName}AttrSetter";
-
- # Custom Setter
- if ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
- $hasCustomSetter = 1;
- $setter = "V8${customAccessor}AccessorSetter";
- }
-
- # Custom Getter
- if ($attrExt->{"CustomGetter"} || $attrExt->{"V8CustomGetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
- $getter = "V8${customAccessor}AccessorGetter";
- }
- }
-
- # Replaceable
- if ($attrExt->{"Replaceable"} && !$hasCustomSetter) {
- $setter = "0";
- # Handle the special case of window.top being marked as Replaceable.
- # 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";
- }
- }
-
- # Read only attributes
- if ($attribute->type =~ /^readonly/ || $attrExt->{"V8ReadOnly"}) {
- $setter = "0";
- }
-
- # An accessor can be installed on the proto
- if ($attrExt->{"v8OnProto"}) {
- $on_proto = "1 /* on proto */";
- }
-
- my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
- "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
-
- push(@implContent, $indent . " \/\/ $commentInfo\n");
- push(@implContent, $indent . " {\"$attrName\", $getter, $setter, $data, $accessControl, static_cast<v8::PropertyAttribute>($propAttr), $on_proto}" . $delimiter . "\n");
-}
-
-sub GenerateImplementationIndexer
-{
- my $dataNode = shift;
- my $indexer = shift;
- my $interfaceName = $dataNode->name;
-
- # FIXME: Figure out what HasNumericIndexGetter is really supposed to do. Right now, it's only set on WebGL-related files.
- my $hasCustomSetter = $dataNode->extendedAttributes->{"HasCustomIndexSetter"} && !$dataNode->extendedAttributes->{"HasNumericIndexGetter"};
- my $hasGetter = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
-
- # FIXME: Find a way to not have to special-case HTMLOptionsCollection.
- if ($interfaceName eq "HTMLOptionsCollection") {
- $hasGetter = 1;
- }
-
- # FIXME: Investigate and remove this nastinesss. In V8, named property handling and indexer handling are apparently decoupled,
- # which means that object[X] where X is a number doesn't reach named property indexer. So we need to provide
- # simplistic, mirrored indexer handling in addition to named property handling.
- my $isSpecialCase = exists $indexerSpecialCases{$interfaceName};
- if ($isSpecialCase) {
- $hasGetter = 1;
- if ($dataNode->extendedAttributes->{"DelegatingPutFunction"}) {
- $hasCustomSetter = 1;
- }
- }
-
- if (!$hasGetter) {
- return;
- }
-
- $implIncludes{"V8Collection.h"} = 1;
-
- my $indexerType = $indexer ? $indexer->type : 0;
-
- # FIXME: Remove this once toV8 helper methods are implemented (see https://bugs.webkit.org/show_bug.cgi?id=32563).
- if ($interfaceName eq "WebKitCSSKeyframesRule") {
- $indexerType = "WebKitCSSKeyframeRule";
- }
-
- # FIXME: The item() getter is not inherited from CSSValueList, seemingly due to the way
- # the CodeGenerator->AddMethodsConstantsAndAttributesFromParentClasses() method works,
- # so we need to set the indexerType manually in this case.
- if ($interfaceName eq "WebKitCSSTransformValue") {
- $indexerType = "CSSValue";
- }
-
- if ($indexerType && !$hasCustomSetter) {
- if ($indexerType eq "DOMString") {
- my $conversion = $indexer->extendedAttributes->{"ConvertNullStringTo"};
- if ($conversion && $conversion eq "Null") {
- push(@implContent, <<END);
- setCollectionStringOrNullIndexedGetter<${interfaceName}>(desc);
-END
- } else {
- push(@implContent, <<END);
- setCollectionStringIndexedGetter<${interfaceName}>(desc);
-END
- }
- } else {
- push(@implContent, <<END);
- setCollectionIndexedGetter<${interfaceName}, ${indexerType}>(desc);
-END
- # Include the header for this indexer type, because setCollectionIndexedGetter() requires toV8() for this type.
- $implIncludes{"V8${indexerType}.h"} = 1;
- }
-
- return;
- }
-
- my $hasDeleter = $dataNode->extendedAttributes->{"CustomDeleteProperty"};
- my $hasEnumerator = !$isSpecialCase && IsNodeSubType($dataNode);
- my $setOn = "Instance";
-
- # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
- # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
- # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
- # on the object.
- if ($interfaceName eq "DOMWindow") {
- $setOn = "Prototype";
- $hasDeleter = 0;
- }
-
- 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}>") if $hasEnumerator;
- push(@implContent, ");\n");
-}
-
-sub GenerateImplementationNamedPropertyGetter
-{
- my $dataNode = shift;
- my $namedPropertyGetter = shift;
- my $interfaceName = $dataNode->name;
- my $hasCustomGetter = $dataNode->extendedAttributes->{"HasOverridingNameGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
-
- # FIXME: Remove hard-coded HTMLOptionsCollection reference by changing HTMLOptionsCollection to not inherit
- # from HTMLCollection per W3C spec (http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/html.html#HTMLOptionsCollection).
- if ($interfaceName eq "HTMLOptionsCollection") {
- $interfaceName = "HTMLCollection";
- $hasCustomGetter = 1;
- }
-
- if ($interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
- $hasCustomGetter = 1;
- }
-
- if ($interfaceName eq "HTMLDocument") {
- $hasCustomGetter = 0;
- }
-
- my $hasGetter = $dataNode->extendedAttributes->{"HasNameGetter"} || $hasCustomGetter;
- if (!$hasGetter) {
- return;
- }
-
- if ($namedPropertyGetter && $namedPropertyGetter->type ne "Node" && !$namedPropertyGetter->extendedAttributes->{"Custom"} && !$hasCustomGetter) {
- $implIncludes{"V8Collection.h"} = 1;
- my $type = $namedPropertyGetter->type;
- push(@implContent, <<END);
- setCollectionNamedGetter<${interfaceName}, ${type}>(desc);
-END
- return;
- }
-
- my $hasSetter = $dataNode->extendedAttributes->{"DelegatingPutFunction"};
- my $hasDeleter = $dataNode->extendedAttributes->{"CustomDeleteProperty"};
- my $hasEnumerator = $dataNode->extendedAttributes->{"CustomGetPropertyNames"};
- my $setOn = "Instance";
-
- # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
- # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
- # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
- # on the object.
- if ($interfaceName eq "DOMWindow") {
- $setOn = "Prototype";
- $hasDeleter = 0;
- $hasEnumerator = 0;
- }
-
- push(@implContent, " desc->${setOn}Template()->SetNamedPropertyHandler(V8${interfaceName}::namedPropertyGetter, ");
- push(@implContent, $hasSetter ? "V8${interfaceName}::namedPropertySetter, " : "0, ");
- # If there is a custom enumerator, there MUST be custom query to properly communicate property attributes.
- push(@implContent, $hasEnumerator ? "V8${interfaceName}::namedPropertyQuery, " : "0, ");
- push(@implContent, $hasDeleter ? "V8${interfaceName}::namedPropertyDeleter, " : "0, ");
- push(@implContent, $hasEnumerator ? "V8${interfaceName}::namedPropertyEnumerator" : "0");
- push(@implContent, ");\n");
-}
-
-sub GenerateImplementationCustomCall
-{
- my $dataNode = shift;
- my $interfaceName = $dataNode->name;
- my $hasCustomCall = $dataNode->extendedAttributes->{"CustomCall"};
-
- # FIXME: Remove hard-coded HTMLOptionsCollection reference.
- if ($interfaceName eq "HTMLOptionsCollection") {
- $interfaceName = "HTMLCollection";
- $hasCustomCall = 1;
- }
-
- if ($hasCustomCall) {
- push(@implContent, " desc->InstanceTemplate()->SetCallAsFunctionHandler(V8${interfaceName}::callAsFunctionCallback);\n");
- }
-}
-
-sub GenerateImplementationMasqueradesAsUndefined
-{
- my $dataNode = shift;
- if ($dataNode->extendedAttributes->{"MasqueradesAsUndefined"})
- {
- push(@implContent, " desc->InstanceTemplate()->MarkAsUndetectable();\n");
- }
-}
-
-sub GenerateImplementation
-{
- my $object = shift;
- my $dataNode = shift;
- my $interfaceName = $dataNode->name;
- my $visibleInterfaceName = GetVisibleInterfaceName($interfaceName);
- my $className = "V8$interfaceName";
- my $implClassName = $interfaceName;
- my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
-
- # - Add default header template
- push(@implFixedHeader, GenerateImplementationContentHeader($dataNode));
-
- $implIncludes{"RuntimeEnabledFeatures.h"} = 1;
- $implIncludes{"V8Proxy.h"} = 1;
- $implIncludes{"V8Binding.h"} = 1;
- $implIncludes{"V8BindingState.h"} = 1;
- $implIncludes{"V8DOMWrapper.h"} = 1;
- $implIncludes{"V8IsolatedContext.h"} = 1;
-
- AddIncludesForType($interfaceName);
-
- 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];
- $attrName = $attribute->signature->name;
- $attrType = $attribute->signature->type;
-
- # Generate special code for the constructor attributes.
- if ($attrType =~ /Constructor$/) {
- if (!($attribute->signature->extendedAttributes->{"CustomGetter"} ||
- $attribute->signature->extendedAttributes->{"V8CustomGetter"})) {
- $hasConstructors = 1;
- }
- next;
- }
-
- if ($attrType eq "EventListener" && $interfaceName eq "DOMWindow") {
- $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.
- if ($attribute->signature->extendedAttributes->{"Custom"} ||
- $attribute->signature->extendedAttributes->{"V8Custom"}) {
- next;
- }
-
- # Generate the accessor.
- if (!($attribute->signature->extendedAttributes->{"CustomGetter"} ||
- $attribute->signature->extendedAttributes->{"V8CustomGetter"})) {
- GenerateNormalAttrGetter($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);
- }
-
- $codeGenerator->LinkOverloadedFunctions($dataNode);
-
- my $indexer;
- my $namedPropertyGetter;
- # Generate methods for functions.
- foreach my $function (@{$dataNode->functions}) {
- if (!($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"})) {
- GenerateFunctionCallback($function, $dataNode, $implClassName);
- if ($function->{overloadIndex} > 1 && $function->{overloadIndex} == @{$function->{overloads}}) {
- GenerateOverloadedFunctionCallback($function, $dataNode, $implClassName);
- }
- }
-
- if ($function->signature->name eq "item") {
- $indexer = $function->signature;
- }
-
- if ($function->signature->name eq "namedItem") {
- $namedPropertyGetter = $function->signature;
- }
-
- # If the function does not need domain security check, we need to
- # 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, $implClassName);
- }
- }
-
- # Attributes
- my $attributes = $dataNode->attributes;
-
- # For the DOMWindow interface we partition the attributes into the
- # ones that disallows shadowing and the rest.
- my @disallowsShadowing;
- # Also separate out attributes that are enabled at runtime so we can process them specially.
- my @enabledAtRuntime;
- my @normal;
- foreach my $attribute (@$attributes) {
-
- if ($interfaceName eq "DOMWindow" && $attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) {
- push(@disallowsShadowing, $attribute);
- } elsif ($attribute->signature->extendedAttributes->{"EnabledAtRuntime"}) {
- push(@enabledAtRuntime, $attribute);
- } else {
- push(@normal, $attribute);
- }
- }
- $attributes = \@normal;
- # Put the attributes that disallow shadowing on the shadow object.
- if (@disallowsShadowing) {
- push(@implContent, "static const BatchedAttribute shadowAttrs[] = {\n");
- GenerateBatchedAttributeData($dataNode, \@disallowsShadowing);
- push(@implContent, "};\n");
- }
-
- my $has_attributes = 0;
- if (@$attributes) {
- $has_attributes = 1;
- push(@implContent, "static const BatchedAttribute ${interfaceName}Attrs[] = {\n");
- GenerateBatchedAttributeData($dataNode, $attributes);
- push(@implContent, "};\n");
- }
-
- # Setup table of standard callback functions
- $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"}) {
- next;
- }
- if ($attrExt->{"ClassMethod"}) {
- next;
- }
- if ($attrExt->{"EnabledAtRuntime"} || RequiresCustomSignature($function) || $attrExt->{"V8DoNotCheckSignature"}) {
- next;
- }
- if ($attrExt->{"DoNotCheckDomainSecurity"} &&
- ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceName eq "DOMWindow")) {
- next;
- }
- if ($attrExt->{"DontEnum"} || $attrExt->{"V8ReadOnly"}) {
- next;
- }
- if (!$has_callbacks) {
- $has_callbacks = 1;
- push(@implContent, "static const BatchedCallback ${interfaceName}Callbacks[] = {\n");
- }
- my $name = $function->signature->name;
- my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
- push(@implContent, <<END);
- {"$name", $callback},
-END
- $num_callbacks++;
- }
- push(@implContent, "};\n") if $has_callbacks;
-
- # Setup constants
- my $has_constants = 0;
- if (@{$dataNode->constants}) {
- $has_constants = 1;
- push(@implContent, "static const BatchedConstant ${interfaceName}Consts[] = {\n");
- }
- foreach my $constant (@{$dataNode->constants}) {
- my $name = $constant->name;
- my $value = $constant->value;
- # FIXME: we need the static_cast here only because of one constant, NodeFilter.idl
- # 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)},
-END
- }
- if ($has_constants) {
- push(@implContent, "};\n");
- push(@implContent, $codeGenerator->GenerateCompileTimeCheckForEnumsIfNeeded($dataNode));
- }
-
- push(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n");
-
- # In namespace WebCore, add generated implementation for 'CanBeConstructed'.
- if ($dataNode->extendedAttributes->{"CanBeConstructed"} && !$dataNode->extendedAttributes->{"CustomConstructor"} && !$dataNode->extendedAttributes->{"V8CustomConstructor"}) {
- my $v8ConstructFunction;
- my $callWith = $dataNode->extendedAttributes->{"CallWith"};
- if ($callWith and $callWith eq "ScriptExecutionContext") {
- $v8ConstructFunction = "constructDOMObjectWithScriptExecutionContext";
- } else {
- $v8ConstructFunction = "constructDOMObject";
- }
- push(@implContent, <<END);
-v8::Handle<v8::Value> ${className}::constructorCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.${interfaceName}.Contructor");
- return V8Proxy::${v8ConstructFunction}<$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::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>(), shadowAttrs, WTF_ARRAY_LENGTH(shadowAttrs));
-
- // Install a security handler with V8.
- templ->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::External::Wrap(&V8DOMWindow::info));
- templ->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
- return templ;
-}
-END
- }
-
- # find the super descriptor
- my $parentClassTemplate = "";
- foreach (@{$dataNode->parents}) {
- my $parent = $codeGenerator->StripModule($_);
- if ($parent eq "EventTarget") { next; }
- $implIncludes{"V8${parent}.h"} = 1;
- $parentClassTemplate = "V8" . $parent . "::GetTemplate()";
- last;
- }
- if (!$parentClassTemplate) {
- $parentClassTemplate = "v8::Persistent<v8::FunctionTemplate>()";
- }
-
- # 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> 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, WTF_ARRAY_LENGTH(${interfaceName}Attrs),
-END
- } else {
- push(@implContent, <<END);
- 0, 0,
-END
- }
-
- if ($has_callbacks) {
- push(@implContent, <<END);
- ${interfaceName}Callbacks, WTF_ARRAY_LENGTH(${interfaceName}Callbacks));
-END
- } else {
- push(@implContent, <<END);
- 0, 0);
-END
- }
-
- if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"V8CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) {
- push(@implContent, <<END);
- 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();
-END
- }
-
- push(@implContent, " $access_check\n");
-
- # Setup the enable-at-runtime attrs if we have them
- foreach my $runtime_attr (@enabledAtRuntime) {
- my $enable_function = GetRuntimeEnableFunctionName($runtime_attr->signature);
- my $conditionalString = GenerateConditionalString($runtime_attr->signature);
- push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
- push(@implContent, " if (${enable_function}()) {\n");
- push(@implContent, " static const BatchedAttribute attrData =\\\n");
- GenerateSingleBatchedAttribute($interfaceName, $runtime_attr, ";", " ");
- push(@implContent, <<END);
- configureAttribute(instance, proto, attrData);
- }
-END
- push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
- }
-
- GenerateImplementationIndexer($dataNode, $indexer);
- GenerateImplementationNamedPropertyGetter($dataNode, $namedPropertyGetter);
- GenerateImplementationCustomCall($dataNode);
- GenerateImplementationMasqueradesAsUndefined($dataNode);
-
- # 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";
- }
- if ($attrExt->{"V8ReadOnly"}) {
- $property_attributes .= " | v8::ReadOnly";
- }
-
- my $commentInfo = "Function '$name' (ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
-
- my $template = "proto";
- if ($attrExt->{"V8OnInstance"}) {
- $template = "instance";
- }
- if ($attrExt->{"ClassMethod"}) {
- $template = "desc";
- }
-
- my $conditional = "";
- if ($attrExt->{"EnabledAtRuntime"}) {
- # Only call Set()/SetAccessor() if this method should be enabled
- $enable_function = GetRuntimeEnableFunctionName($function->signature);
- $conditional = "if (${enable_function}())\n ";
- }
-
- if ($attrExt->{"DoNotCheckDomainSecurity"} &&
- ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceName eq "DOMWindow")) {
- # Mark the accessor as ReadOnly and set it on the proto object so
- # it can be shadowed. This is really a hack to make it work.
- # There are several sceneria to call into the accessor:
- # 1) from the same domain: "window.open":
- # the accessor finds the DOM wrapper in the proto chain;
- # 2) from the same domain: "window.__proto__.open":
- # the accessor will NOT find a DOM wrapper in the prototype chain
- # 3) from another domain: "window.open":
- # the access find the DOM wrapper in the prototype chain
- # "window.__proto__.open" from another domain will fail when
- # accessing '__proto__'
- #
- # The solution is very hacky and fragile, it really needs to be replaced
- # by a better solution.
- $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));
-END
- $num_callbacks++;
- next;
- }
-
- my $signature = "defaultSignature";
- if ($attrExt->{"V8DoNotCheckSignature"} || $attrExt->{"ClassMethod"}) {
- $signature = "v8::Local<v8::Signature>()";
- }
-
- if (RequiresCustomSignature($function)) {
- $signature = "${name}Signature";
- push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function));
- }
-
- # Normal function call is a template
- my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
-
- if ($property_attributes eq "v8::DontDelete") {
- $property_attributes = "";
- } else {
- $property_attributes = ", static_cast<v8::PropertyAttribute>($property_attributes)";
- }
-
- 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);
-END
- $num_callbacks++;
- }
-
- die "Wrong number of callbacks generated for $interfaceName ($num_callbacks, should be $total_functions)" if $num_callbacks != $total_functions;
-
- if ($has_constants) {
- push(@implContent, <<END);
- batchConfigureConstants(desc, proto, ${interfaceName}Consts, WTF_ARRAY_LENGTH(${interfaceName}Consts));
-END
- }
-
- # Special cases
- 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::External::Wrap(&V8DOMWindow::info), false);
-END
- }
- if ($interfaceName eq "HTMLDocument") {
- push(@implContent, <<END);
- desc->SetHiddenPrototype(true);
-END
- }
- if ($interfaceName eq "Location") {
- push(@implContent, <<END);
-
- // 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
- }
-
- my $nativeType = GetNativeTypeForConversions($dataNode, $interfaceName);
- push(@implContent, <<END);
-
- // Custom toString template
- desc->Set(getToStringName(), getToStringTemplate());
- return desc;
-}
-
-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;
-}
-
-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> V8DOMWindowShadowObjectCache;
- if (V8DOMWindowShadowObjectCache.IsEmpty()) {
- V8DOMWindowShadowObjectCache = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
- ConfigureShadowObjectTemplate(V8DOMWindowShadowObjectCache);
- }
- return V8DOMWindowShadowObjectCache;
-}
-END
- }
-
- 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
-
- my $conditionalString = GenerateConditionalString($dataNode);
- 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 GenerateHeaderContentHeader
-{
- my $dataNode = shift;
- my $className = "V8" . $dataNode->name;
- my $conditionalString = GenerateConditionalString($dataNode);
-
- my @headerContentHeader = split("\r", $headerTemplate);
-
- push(@headerContentHeader, "\n#if ${conditionalString}\n") if $conditionalString;
- push(@headerContentHeader, "\n#ifndef ${className}" . "_h");
- push(@headerContentHeader, "\n#define ${className}" . "_h\n\n");
- return @headerContentHeader;
-}
-
-sub GenerateImplementationContentHeader
-{
- my $dataNode = shift;
- my $className = "V8" . $dataNode->name;
- my $conditionalString = GenerateConditionalString($dataNode);
-
- my @implContentHeader = split("\r", $headerTemplate);
-
- push(@implContentHeader, "\n#include \"config.h\"\n");
- push(@implContentHeader, "#include \"${className}.h\"\n\n");
- push(@implContentHeader, "#if ${conditionalString}\n\n") if $conditionalString;
- return @implContentHeader;
-}
-
-sub GenerateCallbackHeader
-{
- my $object = shift;
- my $dataNode = shift;
-
- my $interfaceName = $dataNode->name;
- my $className = "V8$interfaceName";
-
-
- # - Add default header template
- push(@headerContent, GenerateHeaderContentHeader($dataNode));
-
- my @unsortedIncludes = ();
- push(@unsortedIncludes, "#include \"ActiveDOMCallback.h\"");
- push(@unsortedIncludes, "#include \"$interfaceName.h\"");
- push(@unsortedIncludes, "#include \"WorldContextHandle.h\"");
- push(@unsortedIncludes, "#include <v8.h>");
- push(@unsortedIncludes, "#include <wtf/Forward.h>");
- push(@headerContent, join("\n", sort @unsortedIncludes));
-
- push(@headerContent, "\n\nnamespace WebCore {\n\n");
- push(@headerContent, "class ScriptExecutionContext;\n\n");
- push(@headerContent, "class $className : public $interfaceName, public ActiveDOMCallback {\n");
-
- push(@headerContent, <<END);
-public:
- static PassRefPtr<${className}> create(v8::Local<v8::Value> value, ScriptExecutionContext* context)
- {
- ASSERT(value->IsObject());
- ASSERT(context);
- return adoptRef(new ${className}(value->ToObject(), context));
- }
-
- virtual ~${className}();
-
-END
-
- # Functions
- my $numFunctions = @{$dataNode->functions};
- if ($numFunctions > 0) {
- push(@headerContent, " // Functions\n");
- foreach my $function (@{$dataNode->functions}) {
- my @params = @{$function->parameters};
- if (!$function->signature->extendedAttributes->{"Custom"} &&
- !(GetNativeType($function->signature->type) eq "bool")) {
- push(@headerContent, " COMPILE_ASSERT(false)");
- }
-
- push(@headerContent, " virtual " . GetNativeTypeForCallbacks($function->signature->type) . " " . $function->signature->name . "(");
-
- my @args = ();
- foreach my $param (@params) {
- push(@args, GetNativeTypeForCallbacks($param->type) . " " . $param->name);
- }
- push(@headerContent, join(", ", @args));
- push(@headerContent, ");\n");
- }
- }
-
- push(@headerContent, <<END);
-
-private:
- ${className}(v8::Local<v8::Object>, ScriptExecutionContext*);
-
- v8::Persistent<v8::Object> m_callback;
- WorldContextHandle m_worldContext;
-};
-
-END
-
- push(@headerContent, "}\n\n");
- push(@headerContent, "#endif // $className" . "_h\n\n");
-
- my $conditionalString = GenerateConditionalString($dataNode);
- push(@headerContent, "#endif // ${conditionalString}\n") if $conditionalString;
-}
-
-sub GenerateCallbackImplementation
-{
- my $object = shift;
- my $dataNode = shift;
- my $interfaceName = $dataNode->name;
- my $className = "V8$interfaceName";
-
- # - Add default header template
- push(@implFixedHeader, GenerateImplementationContentHeader($dataNode));
-
- $implIncludes{"ScriptExecutionContext.h"} = 1;
- $implIncludes{"V8CustomVoidCallback.h"} = 1;
- $implIncludes{"V8Proxy.h"} = 1;
-
- push(@implContent, "#include <wtf/Assertions.h>\n\n");
- push(@implContent, "namespace WebCore {\n\n");
- push(@implContent, <<END);
-${className}::${className}(v8::Local<v8::Object> callback, ScriptExecutionContext* context)
- : ActiveDOMCallback(context)
- , m_callback(v8::Persistent<v8::Object>::New(callback))
- , m_worldContext(UseCurrentWorld)
-{
-}
-
-${className}::~${className}()
-{
- m_callback.Dispose();
-}
-
-END
-
- # Functions
- my $numFunctions = @{$dataNode->functions};
- if ($numFunctions > 0) {
- push(@implContent, "// Functions\n");
- foreach my $function (@{$dataNode->functions}) {
- my @params = @{$function->parameters};
- if ($function->signature->extendedAttributes->{"Custom"} ||
- !(GetNativeTypeForCallbacks($function->signature->type) eq "bool")) {
- next;
- }
-
- AddIncludesForType($function->signature->type);
- push(@implContent, "\n" . GetNativeTypeForCallbacks($function->signature->type) . " ${className}::" . $function->signature->name . "(");
-
- my @args = ();
- foreach my $param (@params) {
- AddIncludesForType($param->type);
- push(@args, GetNativeTypeForCallbacks($param->type) . " " . $param->name);
- }
- push(@implContent, join(", ", @args));
-
- push(@implContent, ")\n");
- push(@implContent, "{\n");
- push(@implContent, " if (!canInvokeCallback())\n");
- push(@implContent, " return true;\n\n");
- push(@implContent, " v8::HandleScope handleScope;\n\n");
- push(@implContent, " v8::Handle<v8::Context> v8Context = toV8Context(scriptExecutionContext(), m_worldContext);\n");
- push(@implContent, " if (v8Context.IsEmpty())\n");
- push(@implContent, " return true;\n\n");
- push(@implContent, " v8::Context::Scope scope(v8Context);\n\n");
-
- @args = ();
- foreach my $param (@params) {
- my $paramName = $param->name;
- push(@implContent, " v8::Handle<v8::Value> ${paramName}Handle = toV8(${paramName});\n");
- push(@implContent, " if (${paramName}Handle.IsEmpty()) {\n");
- push(@implContent, " CRASH();\n");
- push(@implContent, " return true;\n");
- push(@implContent, " }\n");
- push(@args, " ${paramName}Handle");
- }
-
- push(@implContent, "\n v8::Handle<v8::Value> argv[] = {\n");
- push(@implContent, join(",\n", @args));
- push(@implContent, "\n };\n\n");
- push(@implContent, " bool callbackReturnValue = false;\n");
- push(@implContent, " return !invokeCallback(m_callback, " . scalar(@params) . ", argv, callbackReturnValue, scriptExecutionContext());\n");
- push(@implContent, "}\n");
- }
- }
-
- push(@implContent, "\n} // namespace WebCore\n\n");
-
- my $conditionalString = GenerateConditionalString($dataNode);
- push(@implContent, "#endif // ${conditionalString}\n") if $conditionalString;
-}
-
-sub GenerateToV8Converters
-{
- my $dataNode = shift;
- my $interfaceName = shift;
- my $className = shift;
- my $nativeType = shift;
- my $serializedAttribute = shift;
-
- my $domMapFunction = GetDomMapFunction($dataNode, $interfaceName);
- my $forceNewObjectInput = IsDOMNodeType($interfaceName) ? ", bool forceNewObject" : "";
- my $forceNewObjectCall = IsDOMNodeType($interfaceName) ? ", forceNewObject" : "";
-
- push(@implContent, <<END);
-
-v8::Handle<v8::Object> ${className}::wrapSlow(${nativeType}* impl)
-{
- 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)) {
- if (proxy->windowShell()->initContextIfNeeded()) {
- // initContextIfNeeded may have created a wrapper for the object, retry from the start.
- return ${className}::wrap(impl);
- }
- }
- }
-
-END
- }
-
- if (IsNodeSubType($dataNode)) {
- push(@implContent, <<END);
-
- 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();
-END
- }
-
- push(@implContent, <<END);
- 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();
-END
- }
-
- push(@implContent, <<END);
- 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
- }
-
- if ($domMapFunction) {
- push(@implContent, <<END);
- ${domMapFunction}.set(impl, v8::Persistent<v8::Object>::New(wrapper));
-END
- }
-
- push(@implContent, <<END);
- return wrapper;
-}
-END
-}
-
-sub HasCustomToV8Implementation {
- # FIXME: This subroutine is lame. Probably should be an .idl attribute (CustomToV8)?
- $dataNode = shift;
- $interfaceName = shift;
-
- # We generate a custom converter (but JSC doesn't) for the following:
- return 1 if $interfaceName eq "CSSStyleSheet";
- return 1 if $interfaceName eq "CanvasPixelArray";
- return 1 if $interfaceName eq "DOMStringMap";
- return 1 if $interfaceName eq "DOMWindow";
- return 1 if $interfaceName eq "DOMTokenList";
- return 1 if $interfaceName eq "Element";
- return 1 if $interfaceName eq "HTMLDocument";
- return 1 if $interfaceName eq "HTMLElement";
- return 1 if $interfaceName eq "Location";
- return 1 if $interfaceName eq "NamedNodeMap";
- return 1 if $interfaceName eq "SVGDocument";
- return 1 if $interfaceName eq "SVGElement";
- 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";
- return 0 if $interfaceName eq "CanvasRenderingContext";
- return 0 if $interfaceName eq "SVGElementInstance";
-
- # For everything else, do what JSC does.
- return $dataNode->extendedAttributes->{"CustomToJS"};
-}
-
-sub GetDomMapFunction
-{
- my $dataNode = shift;
- my $type = shift;
- return "getDOMSVGElementInstanceMap()" if $type eq "SVGElementInstance";
- return "getDOMNodeMap()" if ($dataNode && IsNodeSubType($dataNode));
- return "" if $type eq "DOMImplementation";
- return "getActiveDOMObjectMap()" if IsActiveDomType($type);
- return "getDOMObjectMap()";
-}
-
-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";
- return 1 if $type eq "Worker";
- return 1 if $type eq "SharedWorker";
- return 1 if $type eq "IDBRequest";
- return 1 if $type eq "FileReader";
- return 1 if $type eq "FileWriter";
- return 0;
-}
-
-sub GetNativeTypeForConversions
-{
- my $dataNode = shift;
- my $type = shift;
-
- $type = $codeGenerator->GetSVGTypeNeedingTearOff($type) if $codeGenerator->IsSVGTypeNeedingTearOff($type);
- return $type;
-}
-
-sub GenerateFunctionCallString()
-{
- my $function = shift;
- my $numberOfParameters = shift;
- my $indent = shift;
- my $implClassName = shift;
-
- my $name = $function->signature->name;
- my $returnType = GetTypeFromSignature($function->signature);
- my $nativeReturnType = GetNativeType($returnType, 0);
- my $result = "";
-
- my $isSVGTearOffType = ($codeGenerator->IsSVGTypeNeedingTearOff($returnType) and not $implClassName =~ /List$/);
- $nativeReturnType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($returnType) if $isSVGTearOffType;
-
- if ($function->signature->extendedAttributes->{"v8implname"}) {
- $name = $function->signature->extendedAttributes->{"v8implname"};
- }
-
- if ($function->signature->extendedAttributes->{"ImplementationFunction"}) {
- $name = $function->signature->extendedAttributes->{"ImplementationFunction"};
- }
-
- my $functionString = "imp->${name}(";
- if ($function->signature->extendedAttributes->{"ClassMethod"}) {
- $functionString = "${implClassName}::${name}(";
- }
-
- my $index = 0;
- my $hasScriptState = 0;
-
- my $callWith = $function->signature->extendedAttributes->{"CallWith"};
- if ($callWith) {
- my $callWithArg = "COMPILE_ASSERT(false)";
- if ($callWith eq "DynamicFrame") {
- $result .= $indent . "Frame* enteredFrame = V8Proxy::retrieveFrameForEnteredContext();\n";
- $result .= $indent . "if (!enteredFrame)\n";
- $result .= $indent . " return v8::Undefined();\n";
- $callWithArg = "enteredFrame";
- } elsif ($callWith eq "ScriptState") {
- $result .= $indent . "EmptyScriptState state;\n";
- $callWithArg = "&state";
- $hasScriptState = 1;
- } elsif ($callWith eq "ScriptExecutionContext") {
- $result .= $indent . "ScriptExecutionContext* scriptContext = getScriptExecutionContext();\n";
- $result .= $indent . "if (!scriptContext)\n";
- $result .= $indent . " return v8::Undefined();\n";
- $callWithArg = "scriptContext";
- }
- $functionString .= ", " if $index;
- $functionString .= $callWithArg;
- $index++;
- $numberOfParameters++
- }
-
- foreach my $parameter (@{$function->parameters}) {
- if ($index eq $numberOfParameters) {
- last;
- }
- $functionString .= ", " if $index;
- my $paramName = $parameter->name;
- my $paramType = $parameter->type;
-
- if ($parameter->type eq "NodeFilter" || $parameter->type eq "XPathNSResolver") {
- $functionString .= "$paramName.get()";
- } elsif ($codeGenerator->IsSVGTypeNeedingTearOff($parameter->type) and not $implClassName =~ /List$/) {
- $functionString .= "$paramName->propertyReference()";
- $result .= $indent . "if (!$paramName) {\n";
- $result .= $indent . " V8Proxy::setDOMException(WebCore::TYPE_MISMATCH_ERR);\n";
- $result .= $indent . " return v8::Handle<v8::Value>();\n";
- $result .= $indent . "}\n";
- } elsif ($parameter->type eq "SVGMatrix" and $implClassName eq "SVGTransformList") {
- $functionString .= "$paramName.get()";
- } else {
- $functionString .= $paramName;
- }
- $index++;
- }
-
- if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
- $functionString .= ", " if $index;
- $functionString .= "scriptArguments, callStack";
- $index += 2;
- }
-
- if ($function->signature->extendedAttributes->{"NeedsUserGestureCheck"}) {
- $functionString .= ", " if $index;
- # FIXME: We need to pass DOMWrapperWorld as a parameter.
- # See http://trac.webkit.org/changeset/54182
- $functionString .= "processingUserGesture()";
- $index++;
- }
-
- if (@{$function->raisesExceptions}) {
- $functionString .= ", " if $index;
- $functionString .= "ec";
- $index++;
- }
- $functionString .= ")";
-
- my $return = "result";
- my $returnIsRef = IsRefPtrType($returnType);
-
- if ($returnType eq "void") {
- $result .= $indent . "$functionString;\n";
- } elsif ($hasScriptState or @{$function->raisesExceptions}) {
- $result .= $indent . $nativeReturnType . " result = $functionString;\n";
- } else {
- # Can inline the function call into the return statement to avoid overhead of using a Ref<> temporary
- $return = $functionString;
- $returnIsRef = 0;
-
- if ($implClassName eq "SVGTransformList" and IsRefPtrType($returnType)) {
- $return = "WTF::getPtr(" . $return . ")";
- }
- }
-
- if (@{$function->raisesExceptions}) {
- $result .= $indent . "if (UNLIKELY(ec))\n";
- $result .= $indent . " goto fail;\n";
- }
-
- if ($hasScriptState) {
- $result .= $indent . "if (state.hadException())\n";
- $result .= $indent . " return throwError(state.exception());\n"
- }
-
- if ($isSVGTearOffType) {
- $implIncludes{"V8$returnType.h"} = 1;
- $implIncludes{"SVGPropertyTearOff.h"} = 1;
- my $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($returnType);
- $result .= $indent . "return toV8(WTF::getPtr(${svgNativeType}::create($return)));\n";
- return $result;
- }
-
- # If the implementing class is a POD type, commit changes
- if ($codeGenerator->IsSVGTypeNeedingTearOff($implClassName) and not $implClassName =~ /List$/) {
- $result .= $indent . "wrapper->commitChange();\n";
- }
-
- $return .= ".release()" if ($returnIsRef);
- $result .= $indent . ReturnNativeToJSValue($function->signature, $return, $indent) . ";\n";
-
- return $result;
-}
-
-
-sub GetTypeFromSignature
-{
- my $signature = shift;
-
- return $codeGenerator->StripModule($signature->type);
-}
-
-
-sub GetNativeTypeFromSignature
-{
- my $signature = shift;
- my $parameterIndex = shift;
-
- my $type = GetTypeFromSignature($signature);
-
- if ($type eq "unsigned long" and $signature->extendedAttributes->{"IsIndex"}) {
- # Special-case index arguments because we need to check that they aren't < 0.
- return "int";
- }
-
- $type = GetNativeType($type, $parameterIndex >= 0 ? 1 : 0);
-
- if ($parameterIndex >= 0 && $type eq "V8Parameter") {
- my $mode = "";
- if ($signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"}) {
- $mode = "WithUndefinedOrNullCheck";
- } elsif ($signature->extendedAttributes->{"ConvertNullToNullString"} || $signature->extendedAttributes->{"Reflect"}) {
- $mode = "WithNullCheck";
- }
- $type .= "<$mode>";
- }
-
- return $type;
-}
-
-sub IsRefPtrType
-{
- my $type = shift;
-
- return 0 if $type eq "boolean";
- return 0 if $type eq "float";
- return 0 if $type eq "int";
- return 0 if $type eq "Date";
- return 0 if $type eq "DOMString";
- return 0 if $type eq "double";
- return 0 if $type eq "short";
- return 0 if $type eq "long";
- return 0 if $type eq "unsigned";
- return 0 if $type eq "unsigned long";
- return 0 if $type eq "unsigned short";
-
- return 1;
-}
-
-sub GetNativeType
-{
- my $type = shift;
- my $isParameter = shift;
-
- my $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($type);
- if ($svgNativeType) {
- if ($svgNativeType =~ /List$/) {
- return "${svgNativeType}*";
- } else {
- return "RefPtr<${svgNativeType} >";
- }
- }
-
- if ($type eq "float" or $type eq "double") {
- return $type;
- }
-
- return "V8Parameter" if ($type eq "DOMString" or $type eq "DOMUserData") and $isParameter;
- return "int" if $type eq "int";
- return "int" if $type eq "short" or $type eq "unsigned short";
- return "unsigned" if $type eq "unsigned long";
- return "int" if $type eq "long";
- return "long long" if $type eq "long long";
- return "unsigned long long" if $type eq "unsigned long long";
- return "bool" if $type eq "boolean";
- return "String" if $type eq "DOMString";
- return "Range::CompareHow" if $type eq "CompareHow";
- return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType";
- return "DOMTimeStamp" if $type eq "DOMTimeStamp";
- 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 "OptionsObject" if $type eq "OptionsObject";
-
- return "String" if $type eq "DOMUserData"; # FIXME: Temporary hack?
-
- # temporary hack
- return "RefPtr<NodeFilter>" if $type eq "NodeFilter";
-
- return "RefPtr<SerializedScriptValue>" if $type eq "SerializedScriptValue";
-
- return "RefPtr<IDBKey>" if $type eq "IDBKey";
-
- # necessary as resolvers could be constructed on fly.
- return "RefPtr<XPathNSResolver>" if $type eq "XPathNSResolver";
-
- return "RefPtr<${type}>" if IsRefPtrType($type) and not $isParameter;
-
- return "RefPtr<MediaQueryListListener>" if $type eq "MediaQueryListListener";
-
- # Default, assume native type is a pointer with same type name as idl type
- return "${type}*";
-}
-
-sub GetNativeTypeForCallbacks
-{
- my $type = shift;
- return "const String&" if $type eq "DOMString";
-
- # Callbacks use raw pointers, so pass isParameter = 1
- return GetNativeType($type, 1);
-}
-
-sub TranslateParameter
-{
- my $signature = shift;
-
- # The IDL uses some pseudo-types which don't really exist.
- if ($signature->type eq "TimeoutHandler") {
- $signature->type("DOMString");
- }
-}
-
-sub TypeCanFailConversion
-{
- my $signature = shift;
-
- my $type = GetTypeFromSignature($signature);
-
- $implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr";
- return 1 if $type eq "Attr";
- return 1 if $type eq "VoidCallback";
- return 1 if $type eq "IDBKey";
- return 0;
-}
-
-sub JSValueToNative
-{
- my $signature = shift;
- my $value = shift;
-
- my $type = GetTypeFromSignature($signature);
-
- return "$value" if $type eq "JSObject";
- return "$value->BooleanValue()" if $type eq "boolean";
- return "static_cast<$type>($value->NumberValue())" if $type eq "float" or $type eq "double";
-
- return "toInt32($value)" if $type eq "long" or $type eq "short";
- return "toUInt32($value)" if $type eq "unsigned long" or $type eq "unsigned short";
- return "toInt64($value)" if $type eq "unsigned long long" or $type eq "long long";
- return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "CompareHow";
- return "static_cast<SVGPaint::SVGPaintType>($value->ToInt32()->Int32Value())" if $type eq "SVGPaintType";
- return "toWebCoreDate($value)" if $type eq "Date";
-
- if ($type eq "DOMString" or $type eq "DOMUserData") {
- return $value;
- }
-
- die "Unexpected SerializedScriptValue" if $type eq "SerializedScriptValue";
-
- if ($type eq "IDBKey") {
- $implIncludes{"IDBBindingUtilities.h"} = 1;
- $implIncludes{"IDBKey.h"} = 1;
- return "createIDBKeyFromValue($value)";
- }
-
- if ($type eq "OptionsObject") {
- $implIncludes{"OptionsObject.h"} = 1;
- return $value;
- }
-
- if ($type eq "DOMObject") {
- $implIncludes{"ScriptValue.h"} = 1;
- return "ScriptValue($value)";
- }
-
- if ($type eq "NodeFilter") {
- return "V8DOMWrapper::wrapNativeNodeFilter($value)";
- }
-
- if ($type eq "MediaQueryListListener") {
- $implIncludes{"MediaQueryListListener.h"} = 1;
- return "MediaQueryListListener::create(" . $value . ")";
- }
-
- # Default, assume autogenerated type conversion routines
- if ($type eq "EventTarget") {
- $implIncludes{"V8Node.h"} = 1;
-
- # EventTarget is not in DOM hierarchy, but all Nodes are EventTarget.
- return "V8Node::HasInstance($value) ? V8Node::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
- }
-
- if ($type eq "XPathNSResolver") {
- return "V8DOMWrapper::getXPathNSResolver($value)";
- }
-
- AddIncludesForType($type);
-
- if (IsDOMNodeType($type)) {
- $implIncludes{"V8${type}.h"} = 1;
-
- # Perform type checks on the parameter, if it is expected Node type,
- # return NULL.
- return "V8${type}::HasInstance($value) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
- } else {
- $implIncludes{"V8$type.h"} = 1;
-
- # Perform type checks on the parameter, if it is expected Node type,
- # return NULL.
- return "V8${type}::HasInstance($value) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
- }
-}
-
-sub GetV8HeaderName
-{
- my $type = shift;
- return "V8Event.h" if $type eq "DOMTimeStamp";
- 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 $first = 1;
- foreach my $parameter (@{$function->parameters}) {
- if ($first) { $first = 0; }
- else { $result .= ", "; }
- if (IsWrapperType($parameter->type)) {
- if ($parameter->type eq "XPathNSResolver") {
- # Special case for XPathNSResolver. All other browsers accepts a callable,
- # so, even though it's against IDL, accept objects here.
- $result .= "v8::Handle<v8::FunctionTemplate>()";
- } else {
- my $type = $parameter->type;
- my $header = GetV8HeaderName($type);
- $implIncludes{$header} = 1;
- $result .= "V8${type}::GetRawTemplate()";
- }
- } else {
- $result .= "v8::Handle<v8::FunctionTemplate>()";
- }
- }
- $result .= " };\n";
- $result .= " v8::Handle<v8::Signature> ${name}Signature = v8::Signature::New(desc, ${name}Argc, ${name}Argv);\n";
- return $result;
-}
-
-
-sub RequiresCustomSignature
-{
- my $function = shift;
- # No signature needed for Custom function
- if ($function->signature->extendedAttributes->{"Custom"} ||
- $function->signature->extendedAttributes->{"V8Custom"}) {
- return 0;
- }
- # No signature needed for overloaded function
- if (@{$function->{overloads}} > 1) {
- return 0;
- }
- # Type checking is performed in the generated code
- if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) {
- return 0;
- }
- foreach my $parameter (@{$function->parameters}) {
- if ($parameter->extendedAttributes->{"Optional"} || $parameter->extendedAttributes->{"Callback"}) {
- return 0;
- }
- }
-
- foreach my $parameter (@{$function->parameters}) {
- if (IsWrapperType($parameter->type)) {
- return 1;
- }
- }
- return 0;
-}
-
-
-# FIXME: Sort this array.
-my %non_wrapper_types = (
- 'float' => 1,
- 'double' => 1,
- 'int' => 1,
- 'unsigned int' => 1,
- 'short' => 1,
- 'unsigned short' => 1,
- 'long' => 1,
- 'unsigned long' => 1,
- 'boolean' => 1,
- 'long long' => 1,
- 'unsigned long long' => 1,
- 'DOMString' => 1,
- 'CompareHow' => 1,
- 'SerializedScriptValue' => 1,
- 'SVGPaintType' => 1,
- 'DOMTimeStamp' => 1,
- 'JSObject' => 1,
- 'DOMObject' => 1,
- 'EventTarget' => 1,
- 'NodeFilter' => 1,
- 'EventListener' => 1,
- 'IDBKey' => 1,
- 'OptionsObject' => 1,
- 'Date' => 1,
- 'MediaQueryListListener' => 1
-);
-
-
-sub IsWrapperType
-{
- my $type = $codeGenerator->StripModule(shift);
- return !($non_wrapper_types{$type});
-}
-
-sub IsDOMNodeType
-{
- my $type = shift;
-
- return 1 if $type eq 'Attr';
- return 1 if $type eq 'CDATASection';
- return 1 if $type eq 'Comment';
- return 1 if $type eq 'Document';
- return 1 if $type eq 'DocumentFragment';
- return 1 if $type eq 'DocumentType';
- return 1 if $type eq 'Element';
- return 1 if $type eq 'EntityReference';
- return 1 if $type eq 'HTMLCanvasElement';
- return 1 if $type eq 'HTMLDocument';
- return 1 if $type eq 'HTMLElement';
- return 1 if $type eq 'HTMLFormElement';
- return 1 if $type eq 'HTMLTableCaptionElement';
- return 1 if $type eq 'HTMLTableSectionElement';
- return 1 if $type eq 'Node';
- return 1 if $type eq 'ProcessingInstruction';
- return 1 if $type eq 'SVGElement';
- return 1 if $type eq 'SVGDocument';
- return 1 if $type eq 'SVGSVGElement';
- return 1 if $type eq 'SVGUseElement';
- return 1 if $type eq 'Text';
-
- return 0;
-}
-
-
-sub ReturnNativeToJSValue
-{
- my $signature = shift;
- my $value = shift;
- my $indent = shift;
- my $type = GetTypeFromSignature($signature);
-
- return "return v8Boolean($value)" if $type eq "boolean";
- return "return v8::Handle<v8::Value>()" if $type eq "void"; # equivalent to v8::Undefined()
-
- # HTML5 says that unsigned reflected attributes should be in the range
- # [0, 2^31). When a value isn't in this range, a default value (or 0)
- # should be returned instead.
- if ($signature->extendedAttributes->{"Reflect"} and ($type eq "unsigned long" or $type eq "unsigned short")) {
- $value =~ s/getUnsignedIntegralAttribute/getIntegralAttribute/g;
- return "return v8::Integer::NewFromUnsigned(std::max(0, " . $value . "))";
- }
-
- # For all the types where we use 'int' as the representation type,
- # we use Integer::New which has a fast Smi conversion check.
- my $nativeType = GetNativeType($type);
- 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";
- # long long and unsigned long long are not representable in ECMAScript.
- return "return v8::Number::New(static_cast<double>($value))" if $type eq "long long" or $type eq "unsigned long long" or $type eq "DOMTimeStamp";
- 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"};
- if (defined $conv) {
- return "return v8StringOrNull($value)" if $conv eq "Null";
- return "return v8StringOrUndefined($value)" if $conv eq "Undefined";
- return "return v8StringOrFalse($value)" if $conv eq "False";
-
- die "Unknown value for ConvertNullStringTo extended attribute";
- }
- $conv = $signature->extendedAttributes->{"ConvertScriptString"};
- return "return v8StringOrNull($value)" if $conv;
- return "return v8String($value)";
- }
-
- AddIncludesForType($type);
-
- # special case for non-DOM node interfaces
- if (IsDOMNodeType($type)) {
- return "return toV8(${value}" . ($signature->extendedAttributes->{"ReturnsNew"} ? ", true)" : ")");
- }
-
- if ($type eq "EventTarget") {
- return "return V8DOMWrapper::convertEventTargetToV8Object($value)";
- }
-
- if ($type eq "EventListener") {
- $implIncludes{"V8AbstractEventListener.h"} = 1;
- return "return ${value} ? v8::Handle<v8::Value>(static_cast<V8AbstractEventListener*>(${value})->getListenerObject(imp->scriptExecutionContext())) : v8::Handle<v8::Value>(v8::Null())";
- }
-
- if ($type eq "SerializedScriptValue") {
- $implIncludes{"$type.h"} = 1;
- return "return $value->deserialize()";
- }
-
- $implIncludes{"wtf/RefCounted.h"} = 1;
- $implIncludes{"wtf/RefPtr.h"} = 1;
- $implIncludes{"wtf/GetPtr.h"} = 1;
-
- return "return toV8($value)";
-}
-
-# Internal helper
-sub WriteData
-{
- if (defined($IMPL)) {
- # Write content to file.
- print $IMPL @implContentHeader;
-
- print $IMPL @implFixedHeader;
-
- foreach my $implInclude (sort keys(%implIncludes)) {
- my $checkType = $implInclude;
- $checkType =~ s/\.h//;
-
- if ($implInclude =~ /wtf/) {
- print $IMPL "#include \<$implInclude\>\n";
- } else {
- print $IMPL "#include \"$implInclude\"\n" unless $codeGenerator->IsSVGAnimatedType($checkType);
- }
- }
-
- print $IMPL "\n";
- print $IMPL @implContentDecls;
- print $IMPL @implContent;
- close($IMPL);
- undef($IMPL);
-
- %implIncludes = ();
- @implFixedHeader = ();
- @implHeaderContent = ();
- @implContentDecls = ();
- @implContent = ();
- }
-
- if (defined($HEADER)) {
- # Write content to file.
- print $HEADER @headerContent;
- close($HEADER);
- undef($HEADER);
-
- @headerContent = ();
- }
-}
-
-sub GetVisibleInterfaceName
-{
- my $interfaceName = shift;
-
- return "DOMException" if $interfaceName eq "DOMCoreException";
- return "FormData" if $interfaceName eq "DOMFormData";
- return $interfaceName;
-}
-
-sub GetCallbackClassName
-{
- my $interfaceName = shift;
-
- return "V8CustomVoidCallback" if $interfaceName eq "VoidCallback";
- return "V8$interfaceName";
-}
-
-sub ConvertToV8Parameter
-{
- my $signature = shift;
- my $nativeType = shift;
- my $variableName = shift;
- my $value = shift;
- my $suffix = shift;
-
- die "Wrong native type passed: $nativeType" unless $nativeType =~ /^V8Parameter/;
- if ($signature->type eq "DOMString") {
- $implIncludes{"V8BindingMacros.h"} = 1;
- my $macro = "STRING_TO_V8PARAMETER_EXCEPTION_BLOCK";
- $macro .= "_$suffix" if $suffix;
- return "$macro($nativeType, $variableName, $value);"
- } else {
- # Don't know how to properly check for conversion exceptions when $parameter->type is "DOMUserData"
- return "$nativeType $variableName($value, true);";
- }
-}
-
-# Returns the RuntimeEnabledFeatures function name that is hooked up to check if a method/attribute is enabled.
-sub GetRuntimeEnableFunctionName
-{
- my $signature = shift;
-
- # If a parameter is given (e.g. "EnabledAtRuntime=FeatureName") return the RuntimeEnabledFeatures::{FeatureName}Enabled() method.
- return "RuntimeEnabledFeatures::" . $codeGenerator->WK_lcfirst($signature->extendedAttributes->{"EnabledAtRuntime"}) . "Enabled" if ($signature->extendedAttributes->{"EnabledAtRuntime"} && $signature->extendedAttributes->{"EnabledAtRuntime"} ne "1");
-
- # Otherwise return a function named RuntimeEnabledFeatures::{methodName}Enabled().
- return "RuntimeEnabledFeatures::" . $codeGenerator->WK_lcfirst($signature->name) . "Enabled";
-}
-
-sub DebugPrint
-{
- my $output = shift;
-
- print $output;
- print "\n";
-}