| Index: WebCore/bindings/scripts/CodeGeneratorV8.pm
|
| ===================================================================
|
| --- WebCore/bindings/scripts/CodeGeneratorV8.pm (revision 24197)
|
| +++ WebCore/bindings/scripts/CodeGeneratorV8.pm (working copy)
|
| @@ -1,2205 +1,2216 @@
|
| -
|
| -# 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.
|
| -#
|
| -# This file is part of the KDE project
|
| -#
|
| -# This library is free software; you can redistribute it and/or
|
| -# modify it under the terms of the GNU Library General Public
|
| -# License as published by the Free Software Foundation; either
|
| -# version 2 of the License, or (at your option) any later version.
|
| -#
|
| -# This library is distributed in the hope that it will be useful,
|
| -# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| -# Library General Public License for more details.
|
| -#
|
| -# You should have received a copy of the GNU Library General Public License
|
| -# aint with this library; see the file COPYING.LIB. If not, write to
|
| -# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
| -# Boston, MA 02111-1307, USA.
|
| -#
|
| -
|
| -package CodeGeneratorV8;
|
| -
|
| -use File::stat;
|
| -
|
| -my $module = "";
|
| -my $outputDir = "";
|
| -
|
| -my @headerContent = ();
|
| -my @implContentHeader = ();
|
| -my @implFixedHeader = ();
|
| -my @implContent = ();
|
| -my @implContentDecls = ();
|
| -my %implIncludes = ();
|
| -
|
| -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;
|
| -
|
| - bless($reference, $object);
|
| - return $reference;
|
| -}
|
| -
|
| -sub finish
|
| -{
|
| - my $object = shift;
|
| -
|
| - # Commit changes!
|
| - $object->WriteData();
|
| -}
|
| -
|
| -sub leftShift($$) {
|
| - my ($value, $distance) = @_;
|
| - return (($value << $distance) & 0xFFFFFFFF);
|
| -}
|
| -
|
| -# Uppercase the first letter, while respecting WebKit style guidelines.
|
| -# E.g., xmlEncoding becomes XMLEncoding, but xmlllang becomes Xmllang.
|
| -sub WK_ucfirst
|
| -{
|
| - my $param = shift;
|
| - my $ret = ucfirst($param);
|
| - $ret =~ s/Xml/XML/ if $ret =~ /^Xml[^a-z]/;
|
| - return $ret;
|
| -}
|
| -
|
| -# Lowercase the first letter while respecting WebKit style guidelines.
|
| -# URL becomes url, but SetURL becomes setURL.
|
| -sub WK_lcfirst
|
| -{
|
| - my $param = shift;
|
| - my $ret = lcfirst($param);
|
| - $ret =~ s/uRL/url/;
|
| - return $ret;
|
| -}
|
| -
|
| -# Workaround for V8 bindings difference where RGBColor is not a POD type.
|
| -sub IsPodType
|
| -{
|
| - my $type = shift;
|
| - return 0 if $type eq "RGBColor";
|
| - return $codeGenerator->IsPodType($type);
|
| -}
|
| -
|
| -# Params: 'domClass' struct
|
| -sub GenerateInterface
|
| -{
|
| - my $object = shift;
|
| - my $dataNode = shift;
|
| - my $defines = shift;
|
| -
|
| - # Start actual generation
|
| - $object->GenerateHeader($dataNode);
|
| - $object->GenerateImplementation($dataNode);
|
| -
|
| - my $name = $dataNode->name;
|
| -
|
| - # Open files for writing
|
| - my $headerFileName = "$outputDir/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 GetLegacyHeaderIncludes
|
| -{
|
| - my $legacyParent = shift;
|
| -
|
| - die "Don't know what headers to include for module $module";
|
| -}
|
| -
|
| -sub AvoidInclusionOfType
|
| -{
|
| - my $type = shift;
|
| -
|
| - # Special case: SVGRect.h / SVGPoint.h / SVGNumber.h / SVGMatrix.h do not exist.
|
| - return 1 if $type eq "SVGRect" or $type eq "SVGPoint" or $type eq "SVGNumber" or $type eq "SVGMatrix";
|
| - return 0;
|
| -}
|
| -
|
| -sub UsesManualToJSImplementation
|
| -{
|
| - my $type = shift;
|
| -
|
| - return 1 if $type eq "SVGPathSeg";
|
| - return 0;
|
| -}
|
| -
|
| -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) or AvoidInclusionOfType($type)) {
|
| - } elsif ($type =~ /SVGPathSeg/) {
|
| - $joinedName = $type;
|
| - $joinedName =~ s/Abs|Rel//;
|
| - $implIncludes{"${joinedName}.h"} = 1;
|
| - } else {
|
| - # default, include the same named file
|
| - $implIncludes{GetImplementationFileName(${type})} = 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{"AtomicString.h"} = 1;
|
| - }
|
| -}
|
| -
|
| -sub AddIncludesForSVGAnimatedType
|
| -{
|
| - my $type = shift;
|
| - $type =~ s/SVGAnimated//;
|
| -
|
| - if ($type eq "Point" or $type eq "Rect") {
|
| - $implIncludes{"Float$type.h"} = 1;
|
| - } elsif ($type eq "String") {
|
| - $implIncludes{"PlatformString.h"} = 1;
|
| - }
|
| -
|
| - $implIncludes{"SVGAnimatedTemplate.h"} = 1;
|
| -}
|
| -
|
| -sub AddClassForwardIfNeeded
|
| -{
|
| - my $implClassName = shift;
|
| -
|
| - # SVGAnimatedLength/Number/etc.. are typedefs to SVGAnimtatedTemplate, so don't use class forwards for them!
|
| - push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName);
|
| -}
|
| -
|
| -sub GetImplementationFileName
|
| -{
|
| - my $iface = shift;
|
| - return "HTMLCollection.h" if $iface eq "HTMLAllCollection";
|
| - return "Event.h" if $iface eq "DOMTimeStamp";
|
| - return "NamedAttrMap.h" if $iface eq "NamedNodeMap";
|
| - return "NameNodeList.h" if $iface eq "NodeList";
|
| - return "XMLHttpRequest.h" if $iface eq "XMLHttpRequest";
|
| -
|
| - return "${iface}.h";
|
| -}
|
| -
|
| -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);
|
| -
|
| - my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
|
| - my $conditional = $dataNode->extendedAttributes->{"Conditional"};
|
| -
|
| - # - Add default header template
|
| - @headerContent = split("\r", $headerTemplate);
|
| -
|
| - my $conditionalString;
|
| - if ($conditional) {
|
| - $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
|
| - push(@headerContent, "\n#if ${conditionalString}\n\n");
|
| - }
|
| -
|
| - push(@headerContent, "\n#ifndef $className" . "_H");
|
| - push(@headerContent, "\n#define $className" . "_H\n\n");
|
| -
|
| - # Get correct pass/store types respecting PODType flag
|
| - my $podType = $dataNode->extendedAttributes->{"PODType"};
|
| - my $passType = $podType ? "JSSVGPODTypeWrapper<$podType>*" : "$implClassName*";
|
| -
|
| - push(@headerContent, "#include \"$podType.h\"\n") if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
|
| -
|
| - push(@headerContent, "#include <v8.h>\n");
|
| - push(@headerContent, "#include <wtf/HashMap.h>\n");
|
| - push(@headerContent, "#include \"StringHash.h\"\n");
|
| -
|
| - push(@headerContent, "\nnamespace WebCore {\n\n");
|
| - push(@headerContent, "class V8ClassIndex;\n");
|
| - push(@headerContent, "\nclass $className {\n");
|
| - push(@headerContent, <<END);
|
| -
|
| - public:
|
| - static bool HasInstance(v8::Handle<v8::Value> value);
|
| - static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
|
| -END
|
| -
|
| - if ($implClassName eq "DOMWindow") {
|
| - push(@headerContent, <<END);
|
| - static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
|
| -END
|
| - }
|
| -
|
| - push(@headerContent, <<END);
|
| -
|
| - private:
|
| - static v8::Persistent<v8::FunctionTemplate> GetTemplate();
|
| -
|
| - friend class V8ClassIndex;
|
| -};
|
| -
|
| -END
|
| -
|
| - push(@headerContent, "}\n\n");
|
| - push(@headerContent, "#endif // $className" . "_H\n");
|
| -
|
| - push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditional;
|
| -}
|
| -
|
| -
|
| -sub GenerateSetDOMException
|
| -{
|
| - my $indent = shift;
|
| - my $result = "";
|
| -
|
| - $result .= $indent . "if (ec) {\n";
|
| - $result .= $indent . " V8Proxy::setDOMException(ec);\n";
|
| - $result .= $indent . " return v8::Handle<v8::Value>();\n";
|
| - $result .= $indent . "}\n";
|
| -
|
| - return $result;
|
| -}
|
| -
|
| -sub IsNodeSubType
|
| -{
|
| - my $dataNode = shift;
|
| - return 1 if ($dataNode->name eq "Node");
|
| - foreach (@allParents) {
|
| - my $parent = $codeGenerator->StripModule($_);
|
| - return 1 if $parent eq "Node";
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -sub HolderToNative
|
| -{
|
| - my $dataNode = shift;
|
| - my $implClassName = shift;
|
| - my $classIndex = shift;
|
| -
|
| - if (IsNodeSubType($dataNode)) {
|
| - push(@implContentDecls, <<END);
|
| - $implClassName* imp = V8DOMWrapper::convertDOMWrapperToNode<$implClassName>(holder);
|
| -END
|
| -
|
| - } else {
|
| - push(@implContentDecls, <<END);
|
| - $implClassName* imp = V8DOMWrapper::convertToNativeObject<$implClassName>(V8ClassIndex::$classIndex, holder);
|
| -END
|
| -
|
| - }
|
| -}
|
| -
|
| -sub GenerateDomainSafeFunctionGetter
|
| -{
|
| - my $function = shift;
|
| - my $dataNode = shift;
|
| - my $classIndex = shift;
|
| - my $implClassName = shift;
|
| -
|
| - my $className = "V8" . $dataNode->name;
|
| - 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, $dataNode, $signature);
|
| -
|
| - $implIncludes{"V8Proxy.h"} = 1;
|
| -
|
| - 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> private_template =
|
| - v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
|
| - v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
|
| - if (holder.IsEmpty()) {
|
| - // can only reach here by 'object.__proto__.func', and it should passed
|
| - // domain security check already
|
| -
|
| - return private_template->GetFunction();
|
| - }
|
| -END
|
| -
|
| - HolderToNative($dataNode, $implClassName, $classIndex);
|
| -
|
| - push(@implContentDecls, <<END);
|
| - if (!V8Proxy::canAccessFrame(imp->frame(), false)) {
|
| - static v8::Persistent<v8::FunctionTemplate> shared_template =
|
| - v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
|
| - return shared_template->GetFunction();
|
| -
|
| - } else {
|
| - return private_template->GetFunction();
|
| - }
|
| - }
|
| -
|
| -END
|
| -}
|
| -
|
| -sub GenerateConstructorGetter
|
| -{
|
| - my $implClassName = shift;
|
| - my $classIndex = shift;
|
| -
|
| - push(@implContentDecls, <<END);
|
| - static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
|
| - INC_STATS(\"DOM.$implClassName.constructors._get\");
|
| - v8::Handle<v8::Value> data = info.Data();
|
| - ASSERT(data->IsNumber());
|
| - V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(data->Int32Value());
|
| -END
|
| -
|
| - if ($classIndex eq "DOMWINDOW") {
|
| - push(@implContentDecls, <<END);
|
| - DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
|
| - // 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, window);
|
| -END
|
| - } elsif ($classIndex eq "WORKERCONTEXT") {
|
| - $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
|
| - push(@implContentDecls, <<END);
|
| - return WorkerContextExecutionProxy::retrieve()->GetConstructor(type);
|
| -END
|
| - } else {
|
| - push(@implContentDecls, " return v8::Undefined();");
|
| - }
|
| -
|
| - push(@implContentDecls, <<END);
|
| -
|
| - }
|
| -
|
| -END
|
| -}
|
| -
|
| -sub GenerateNormalAttrGetter
|
| -{
|
| - my $attribute = shift;
|
| - my $dataNode = shift;
|
| - my $classIndex = shift;
|
| - my $implClassName = shift;
|
| -
|
| - my $attrExt = $attribute->signature->extendedAttributes;
|
| -
|
| - my $attrName = $attribute->signature->name;
|
| - $implIncludes{"V8Proxy.h"} = 1;
|
| -
|
| - my $attrType = $codeGenerator->StripModule($attribute->signature->type);
|
| - my $attrIsPodType = IsPodType($attrType);
|
| -
|
| - my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
|
| - my $isPodType = IsPodType($implClassName);
|
| - my $skipContext = 0;
|
| -
|
| -
|
| - if ($isPodType) {
|
| - $implClassName = GetNativeType($implClassName);
|
| - $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
|
| - }
|
| -
|
| - # Special case: SVGZoomEvent's attributes are all read-only
|
| - if ($implClassName eq "SVGZoomEvent") {
|
| - $attrIsPodType = 0;
|
| - $skipContext = 1;
|
| - }
|
| -
|
| - # Special case: SVGSVGEelement::viewport is read-only
|
| - if (($implClassName eq "SVGSVGElement") and ($attrName eq "viewport")) {
|
| - $attrIsPodType = 0;
|
| - $skipContext = 1;
|
| - }
|
| -
|
| - # Special case for SVGColor
|
| - if (($implClassName eq "SVGColor") and ($attrName eq "rgbColor")) {
|
| - $attrIsPodType = 0;
|
| - }
|
| -
|
| - my $getterStringUsesImp = $implClassName ne "double";
|
| -
|
| - # Getter
|
| - 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 ($isPodType) {
|
| - push(@implContentDecls, <<END);
|
| - V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());
|
| - $implClassName imp_instance = *imp_wrapper;
|
| -END
|
| - if ($getterStringUsesImp) {
|
| - push(@implContentDecls, <<END);
|
| - $implClassName* imp = &imp_instance;
|
| -END
|
| - }
|
| -
|
| - } elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) {
|
| - # perform lookup first
|
| - push(@implContentDecls, <<END);
|
| - v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
|
| - if (holder.IsEmpty()) return v8::Undefined();
|
| -END
|
| - HolderToNative($dataNode, $implClassName, $classIndex);
|
| - } else {
|
| - push(@implContentDecls, <<END);
|
| - v8::Handle<v8::Object> holder = info.Holder();
|
| -END
|
| - HolderToNative($dataNode, $implClassName, $classIndex);
|
| - }
|
| -
|
| - # Generate security checks if necessary
|
| - if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
|
| - push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->$attrName())) return v8::Undefined();\n\n");
|
| - } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
|
| - push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->contentDocument())) return v8::Undefined();\n\n");
|
| - }
|
| -
|
| - my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType);
|
| - if ($useExceptions) {
|
| - $implIncludes{"ExceptionCode.h"} = 1;
|
| - push(@implContentDecls, " ExceptionCode ec = 0;\n");
|
| - }
|
| -
|
| - if ($attribute->signature->extendedAttributes->{"v8referenceattr"}) {
|
| - $attrName = $attribute->signature->extendedAttributes->{"v8referenceattr"};
|
| - }
|
| -
|
| - my $getterFunc = WK_lcfirst($attrName);
|
| - $getterFunc .= "Animated" if $codeGenerator->IsSVGAnimatedType($attribute->signature->type);
|
| -
|
| - my $returnType = $codeGenerator->StripModule($attribute->signature->type);
|
| -
|
| - my $getterString;
|
| - if ($getterStringUsesImp) {
|
| - my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
|
| - my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
|
| - if ($reflect || $reflectURL) {
|
| - $implIncludes{"HTMLNames.h"} = 1;
|
| - my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
|
| - my $getAttributeFunctionName = $reflectURL ? "getURLAttribute" : "getAttribute";
|
| - $getterString = "imp->$getAttributeFunctionName(HTMLNames::${contentAttributeName}Attr";
|
| - } else {
|
| - $getterString = "imp->$getterFunc(";
|
| - }
|
| - $getterString .= "ec" if $useExceptions;
|
| - $getterString .= ")";
|
| - if (IsRefPtrType($returnType)) {
|
| - $implIncludes{"wtf/GetPtr.h"} = 1;
|
| - $getterString = "WTF::getPtr(" . $getterString . ")";
|
| - }
|
| - if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
|
| - $getterString .= ".toInt()";
|
| - }
|
| - } else {
|
| - $getterString = "imp_instance";
|
| - }
|
| -
|
| - if ($nativeType eq "String") {
|
| - $getterString = "toString($getterString)";
|
| - }
|
| -
|
| - my $result;
|
| - my $wrapper;
|
| -
|
| - if ($attrIsPodType) {
|
| - $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
|
| -
|
| - my $getter = $getterString;
|
| - $getter =~ s/imp->//;
|
| - $getter =~ s/\(\)//;
|
| - my $setter = "set" . WK_ucfirst($getter);
|
| -
|
| - my $implClassIsAnimatedType = $codeGenerator->IsSVGAnimatedType($implClassName);
|
| - if (not $implClassIsAnimatedType and $codeGenerator->IsPodTypeWithWriteableProperties($attrType) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
|
| - if (IsPodType($implClassName)) {
|
| - $wrapper = "new V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>($getterString, imp_wrapper)";
|
| - } else {
|
| - $wrapper = "new V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName>(imp, &${implClassName}::$getter, &${implClassName}::$setter)";
|
| - }
|
| - } else {
|
| - if ($implClassIsAnimatedType) {
|
| - $wrapper = "V8SVGDynamicPODTypeWrapperCache<$nativeType, $implClassName>::lookupOrCreateWrapper(imp, &${implClassName}::$getter, &${implClassName}::$setter)";
|
| - } else {
|
| - $wrapper = GenerateSVGStaticPodTypeWrapper($returnType, $getterString);
|
| - }
|
| - }
|
| -
|
| - push(@implContentDecls, " void* wrapper = $wrapper;\n");
|
| - } elsif ($nativeType ne "RGBColor") {
|
| - push(@implContentDecls, " $nativeType v = ");
|
| -
|
| - push(@implContentDecls, "$getterString;\n");
|
| -
|
| - if ($useExceptions) {
|
| - push(@implContentDecls, GenerateSetDOMException(" "));
|
| - }
|
| -
|
| - $result = "v";
|
| - if (IsRefPtrType($returnType)) {
|
| - $result = "WTF::getPtr(" . $result . ")";
|
| - }
|
| - } else {
|
| - # Special case: RGBColor is noncopyable
|
| - $result = $getterString;
|
| - }
|
| -
|
| -
|
| - if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) {
|
| - my $resultObject = $result;
|
| - if ($attrIsPodType) {
|
| - $resultObject = "wrapper";
|
| - }
|
| -
|
| - push(@implContentDecls, GenerateSVGContextAssignment($implClassName, $resultObject, " "));
|
| - }
|
| -
|
| - if ($attrIsPodType) {
|
| - my $classIndex = uc($attrType);
|
| - push(@implContentDecls, " return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper);\n");
|
| - } else {
|
| - push(@implContentDecls, " " . ReturnNativeToJSValue($attribute->signature, $result, " ").";\n");
|
| - }
|
| -
|
| - push(@implContentDecls, " }\n\n"); # end of getter
|
| -}
|
| -
|
| -
|
| -sub GenerateReplaceableAttrSetter
|
| -{
|
| - my $implClassName = shift;
|
| -
|
| - $implIncludes{"V8Proxy.h"} = 1;
|
| -
|
| - push(@implContentDecls,
|
| - " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
|
| - " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
|
| -
|
| - push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
|
| -
|
| - push(@implContentDecls, " v8::Local<v8::String> ${attrName}_string = v8::String::New(\"${attrName}\");\n");
|
| - push(@implContentDecls, " info.Holder()->Delete(${attrName}_string);\n");
|
| - push(@implContentDecls, " info.This()->Set(${attrName}_string, value);\n");
|
| - push(@implContentDecls, " }\n\n");
|
| -}
|
| -
|
| -
|
| -sub GenerateNormalAttrSetter
|
| -{
|
| - my $attribute = shift;
|
| - my $dataNode = shift;
|
| - my $classIndex = shift;
|
| - my $implClassName = shift;
|
| -
|
| - my $attrExt = $attribute->signature->extendedAttributes;
|
| -
|
| - $implIncludes{"V8Proxy.h"} = 1;
|
| -
|
| - push(@implContentDecls,
|
| - " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
|
| - " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
|
| -
|
| - push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
|
| -
|
| - my $isPodType = IsPodType($implClassName);
|
| -
|
| - if ($isPodType) {
|
| - $implClassName = GetNativeType($implClassName);
|
| - $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
|
| - push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());\n");
|
| - push(@implContentDecls, " $implClassName imp_instance = *wrapper;\n");
|
| - push(@implContentDecls, " $implClassName* imp = &imp_instance;\n");
|
| -
|
| - } elsif ($attrExt->{"v8OnProto"}) {
|
| - # perform lookup first
|
| - push(@implContentDecls, <<END);
|
| - v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
|
| - if (holder.IsEmpty()) return v8::Undefined();
|
| -END
|
| - HolderToNative($dataNode, $implClassName, $classIndex);
|
| - } else {
|
| - push(@implContentDecls, <<END);
|
| - v8::Handle<v8::Object> holder = info.Holder();
|
| -END
|
| - HolderToNative($dataNode, $implClassName, $classIndex);
|
| - }
|
| -
|
| - my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
|
| - push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n");
|
| -
|
| - my $result = "";
|
| - if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
|
| - $result .= "WebCore::String::number(";
|
| - }
|
| - $result .= "v";
|
| - if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
|
| - $result .= ")";
|
| - }
|
| - my $returnType = $codeGenerator->StripModule($attribute->signature->type);
|
| - if (IsRefPtrType($returnType)) {
|
| - $result = "WTF::getPtr(" . $result . ")";
|
| - }
|
| -
|
| - my $useExceptions = 1 if @{$attribute->setterExceptions} and !($isPodType);
|
| -
|
| - if ($useExceptions) {
|
| - $implIncludes{"ExceptionCode.h"} = 1;
|
| - push(@implContentDecls, " ExceptionCode ec = 0;\n");
|
| - }
|
| -
|
| - if ($implClassName eq "double") {
|
| - push(@implContentDecls, " *imp = $result;\n");
|
| - } else {
|
| - my $implSetterFunctionName = WK_ucfirst($attrName);
|
| - my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
|
| - my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
|
| - if ($reflect || $reflectURL) {
|
| - $implIncludes{"HTMLNames.h"} = 1;
|
| - my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
|
| - push(@implContentDecls, " imp->setAttribute(HTMLNames::${contentAttributeName}Attr, $result");
|
| - } else {
|
| - push(@implContentDecls, " imp->set$implSetterFunctionName(" . $result);
|
| - }
|
| - push(@implContentDecls, ", ec") if $useExceptions;
|
| - push(@implContentDecls, ");\n");
|
| - }
|
| -
|
| - if ($useExceptions) {
|
| - push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
|
| - }
|
| -
|
| - if ($isPodType) {
|
| - push(@implContentDecls, " wrapper->commitChange(*imp, V8Proxy::svgContext(wrapper));\n");
|
| - } elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
|
| - $implIncludes{"SVGElement.h"} = 1;
|
| -
|
| - my $currentObject = "imp";
|
| - if ($isPodType) {
|
| - $currentObject = "wrapper";
|
| - }
|
| -
|
| - push(@implContentDecls, " if (SVGElement* context = V8Proxy::svgContext($currentObject)) {\n");
|
| - push(@implContentDecls, " context->svgAttributeChanged(imp->associatedAttributeName());\n");
|
| - push(@implContentDecls, " }\n");
|
| - }
|
| -
|
| - push(@implContentDecls, " return;\n");
|
| - push(@implContentDecls, " }\n\n"); # end of setter
|
| -}
|
| -
|
| -sub GenerateNewFunctionTemplate
|
| -{
|
| - $function = shift;
|
| - $dataNode = shift;
|
| - $signature = shift;
|
| -
|
| - my $interfaceName = $dataNode->name;
|
| - 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!"
|
| - }
|
| - my $customFunc = $function->signature->extendedAttributes->{"Custom"} ||
|
| - $function->signature->extendedAttributes->{"V8Custom"};
|
| - if ($customFunc eq 1) {
|
| - $customFunc = $interfaceName . WK_ucfirst($name);
|
| - }
|
| - return "v8::FunctionTemplate::New(V8Custom::v8${customFunc}Callback, v8::Handle<v8::Value>(), $signature)";
|
| - } else {
|
| - return "v8::FunctionTemplate::New(${interfaceName}Internal::${name}Callback, v8::Handle<v8::Value>(), $signature)";
|
| - }
|
| -}
|
| -
|
| -sub GenerateFunctionCallback
|
| -{
|
| - my $function = shift;
|
| - my $dataNode = shift;
|
| - my $classIndex = shift;
|
| - my $implClassName = shift;
|
| -
|
| - my $interfaceName = $dataNode->name;
|
| - my $name = $function->signature->name;
|
| -
|
| - push(@implContentDecls,
|
| -" static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {\n" .
|
| -" INC_STATS(\"DOM.$implClassName.$name\");\n");
|
| -
|
| - my $numParameters = @{$function->parameters};
|
| -
|
| - if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) {
|
| - push(@implContentDecls,
|
| - " if (args.Length() < $numParameters) return v8::Undefined();\n");
|
| - }
|
| -
|
| - if (IsPodType($implClassName)) {
|
| - my $nativeClassName = GetNativeType($implClassName);
|
| - push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$nativeClassName> >(V8ClassIndex::$classIndex, args.Holder());\n");
|
| - push(@implContentDecls, " $nativeClassName imp_instance = *imp_wrapper;\n");
|
| - push(@implContentDecls, " $nativeClassName* imp = &imp_instance;\n");
|
| - } else {
|
| - push(@implContentDecls, <<END);
|
| - v8::Handle<v8::Object> holder = args.Holder();
|
| -END
|
| - HolderToNative($dataNode, $implClassName, $classIndex);
|
| - }
|
| -
|
| - # Check domain security if needed
|
| - if (($dataNode->extendedAttributes->{"CheckDomainSecurity"}
|
| - || $interfaceName eq "DOMWindow")
|
| - && !$function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
|
| - # We have not find real use cases yet.
|
| - push(@implContentDecls,
|
| -" if (!V8Proxy::canAccessFrame(imp->frame(), true)) {\n".
|
| -" return v8::Undefined();\n" .
|
| -" }\n");
|
| - }
|
| -
|
| -
|
| - if (@{$function->raisesExceptions}) {
|
| - $implIncludes{"ExceptionCode.h"} = 1;
|
| - push(@implContentDecls, " ExceptionCode ec = 0;\n");
|
| - }
|
| -
|
| - if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
|
| - push(@implContentDecls, " ScriptCallStack callStack(args, $numParameters);\n");
|
| - $implIncludes{"ScriptCallStack.h"} = 1;
|
| - }
|
| -
|
| - my $paramIndex = 0;
|
| - foreach my $parameter (@{$function->parameters}) {
|
| - TranslateParameter($parameter);
|
| -
|
| - my $parameterName = $parameter->name;
|
| -
|
| - if ($parameter->extendedAttributes->{"Optional"}) {
|
| - # 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");
|
| - }
|
| -
|
| - if (BasicTypeCanFailConversion($parameter)) {
|
| - push(@implContentDecls, " bool ${parameterName}Ok;\n");
|
| - }
|
| -
|
| - push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, 1) . " $parameterName = ");
|
| - push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]",
|
| - BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n");
|
| -
|
| - if (TypeCanFailConversion($parameter)) {
|
| - $implIncludes{"ExceptionCode.h"} = 1;
|
| - push(@implContentDecls,
|
| -" if (!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "") . ") {\n" .
|
| -" V8Proxy::setDOMException(TYPE_MISMATCH_ERR);\n" .
|
| -" return v8::Handle<v8::Value>();\n" .
|
| -" }\n");
|
| - }
|
| -
|
| - if ($parameter->extendedAttributes->{"IsIndex"}) {
|
| - $implIncludes{"ExceptionCode.h"} = 1;
|
| - push(@implContentDecls,
|
| -" if ($parameterName < 0) {\n" .
|
| -" V8Proxy::setDOMException(INDEX_SIZE_ERR);\n" .
|
| -" return v8::Handle<v8::Value>();\n" .
|
| -" }\n");
|
| - }
|
| -
|
| - $paramIndex++;
|
| - }
|
| -
|
| - # Build the function call string.
|
| - my $callString = GenerateFunctionCallString($function, $paramIndex, " ", $implClassName);
|
| - push(@implContentDecls, "$callString");
|
| - push(@implContentDecls, " }\n\n");
|
| -}
|
| -
|
| -sub GenerateBatchedAttributeData
|
| -{
|
| - my $interfaceName = shift;
|
| - my $attributes = shift;
|
| -
|
| - foreach my $attribute (@$attributes) {
|
| - my $attrName = $attribute->signature->name;
|
| - my $attrExt = $attribute->signature->extendedAttributes;
|
| -
|
| - 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 . WK_ucfirst($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 = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";
|
| -
|
| - # Constructor
|
| - if ($attribute->signature->type =~ /Constructor$/) {
|
| - my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
|
| - $constructorType =~ s/Constructor$//;
|
| - my $constructorIndex = uc($constructorType);
|
| - $data = "V8ClassIndex::${constructorIndex}";
|
| - $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
|
| - $setter = "0";
|
| - $propAttr = "v8::ReadOnly";
|
| -
|
| - # EventListeners
|
| - } elsif ($attribute->signature->type eq "EventListener") {
|
| - if ($interfaceName eq "DOMWindow") {
|
| - $getter = "V8Custom::v8DOMWindowEventHandlerAccessorGetter";
|
| - $setter = "V8Custom::v8DOMWindowEventHandlerAccessorSetter";
|
| - } elsif ($interfaceName eq "Element" || $interfaceName eq "Document" || $interfaceName eq "HTMLBodyElement" || $interfaceName eq "SVGElementInstance" || $interfaceName eq "HTMLFrameSetElement") {
|
| - $getter = "V8Custom::v8ElementEventHandlerAccessorGetter";
|
| - $setter = "V8Custom::v8ElementEventHandlerAccessorSetter";
|
| - } else {
|
| - $getter = "V8Custom::v8${customAccessor}AccessorGetter";
|
| - if ($interfaceName eq "WorkerContext" and $attrName eq "self") {
|
| - $setter = "0";
|
| - $propAttr = "v8::ReadOnly";
|
| - } else {
|
| - $setter = "V8Custom::v8${customAccessor}AccessorSetter";
|
| - }
|
| - }
|
| -
|
| - # Custom Getter and Setter
|
| - } elsif ($attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
|
| - $getter = "V8Custom::v8${customAccessor}AccessorGetter";
|
| - if ($interfaceName eq "WorkerContext" and $attrName eq "self") {
|
| - $setter = "0";
|
| - $propAttr = "v8::ReadOnly";
|
| - } else {
|
| - $hasCustomSetter = 1;
|
| - $setter = "V8Custom::v8${customAccessor}AccessorSetter";
|
| - }
|
| -
|
| - # Custom Setter
|
| - } elsif ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"}) {
|
| - $hasCustomSetter = 1;
|
| - $getter = "${interfaceName}Internal::${attrName}AttrGetter";
|
| - $setter = "V8Custom::v8${customAccessor}AccessorSetter";
|
| -
|
| - # Custom Getter
|
| - } elsif ($attrExt->{"CustomGetter"}) {
|
| - $getter = "V8Custom::v8${customAccessor}AccessorGetter";
|
| - $setter = "${interfaceName}Internal::${attrName}AttrSetter";
|
| -
|
| - # Replaceable
|
| - } elsif ($attrExt->{"Replaceable"}) {
|
| - # Replaceable accessor is put on instance template with ReadOnly attribute.
|
| - $getter = "${interfaceName}Internal::${attrName}AttrGetter";
|
| - $setter = "0";
|
| -
|
| - # Mark to avoid duplicate v8::ReadOnly flags in output.
|
| - $hasCustomSetter = 1;
|
| -
|
| - # Handle the special case of window.top being marked upstream as Replaceable.
|
| - # FIXME: Investigate why [Replaceable] is not marked as ReadOnly
|
| - # upstream and reach parity.
|
| - if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) {
|
| - $propAttr .= "|v8::ReadOnly";
|
| - }
|
| -
|
| - # Normal
|
| - } else {
|
| - $getter = "${interfaceName}Internal::${attrName}AttrGetter";
|
| - $setter = "${interfaceName}Internal::${attrName}AttrSetter";
|
| - }
|
| -
|
| - if ($attrExt->{"Replaceable"} && !$hasCustomSetter) {
|
| - $setter = "0";
|
| - $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, <<END);
|
| - // $commentInfo
|
| - { "$attrName",
|
| - $getter,
|
| - $setter,
|
| - $data,
|
| - $accessControl,
|
| - static_cast<v8::PropertyAttribute>($propAttr),
|
| - $on_proto },
|
| -END
|
| - }
|
| -}
|
| -
|
| -
|
| -sub GenerateImplementation
|
| -{
|
| - my $object = shift;
|
| - my $dataNode = shift;
|
| - my $interfaceName = $dataNode->name;
|
| - my $className = "V8$interfaceName";
|
| - my $implClassName = $interfaceName;
|
| - my $classIndex = uc($codeGenerator->StripModule($interfaceName));
|
| -
|
| - my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
|
| - my $conditional = $dataNode->extendedAttributes->{"Conditional"};
|
| -
|
| - @allParents = $codeGenerator->FindParentsRecursively($dataNode);
|
| -
|
| - # - Add default header template
|
| - @implContentHeader = split("\r", $headerTemplate);
|
| -
|
| - push(@implFixedHeader,
|
| - "#include \"config.h\"\n" .
|
| - "#include \"V8Proxy.h\"\n" .
|
| - "#include \"V8Binding.h\"\n\n" .
|
| - "#undef LOG\n\n");
|
| -
|
| - my $conditionalString;
|
| - if ($conditional) {
|
| - $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
|
| - push(@implFixedHeader, "\n#if ${conditionalString}\n\n");
|
| - }
|
| -
|
| - if ($className =~ /^V8SVGAnimated/) {
|
| - AddIncludesForSVGAnimatedType($interfaceName);
|
| - }
|
| -
|
| - $implIncludes{"${className}.h"} = 1;
|
| -
|
| - AddIncludesForType($interfaceName);
|
| - $implIncludes{"V8Proxy.h"} = 1;
|
| -
|
| - push(@implContentDecls, "namespace WebCore {\n");
|
| - push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n");
|
| - push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n");
|
| -
|
| - my $hasConstructors = 0;
|
| -
|
| - # 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$/) {
|
| - $hasConstructors = 1;
|
| - next;
|
| - }
|
| -
|
| - # Make EventListeners always custom.
|
| - # FIXME: make the perl code capable of generating the
|
| - # event setters/getters. For now, WebKit has started removing the
|
| - # [Custom] attribute, so just automatically insert it to avoid forking
|
| - # other files. This should be okay because we can't generate stubs
|
| - # for any event getter/setters anyway.
|
| - if ($attrType eq "EventListener") {
|
| - $attribute->signature->extendedAttributes->{"Custom"} = 1;
|
| - $implIncludes{"V8CustomBinding.h"} = 1;
|
| - 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"}) {
|
| - $implIncludes{"V8CustomBinding.h"} = 1;
|
| - next;
|
| - }
|
| -
|
| - # Generate the accessor.
|
| - if ($attribute->signature->extendedAttributes->{"CustomGetter"}) {
|
| - $implIncludes{"V8CustomBinding.h"} = 1;
|
| - } else {
|
| - GenerateNormalAttrGetter($attribute, $dataNode, $classIndex, $implClassName);
|
| - }
|
| - if ($attribute->signature->extendedAttributes->{"CustomSetter"} ||
|
| - $attribute->signature->extendedAttributes->{"V8CustomSetter"}) {
|
| - $implIncludes{"V8CustomBinding.h"} = 1;
|
| - } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
|
| - $dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"} || die "Replaceable attribute can only be used in interface that defines ExtendsDOMGlobalObject attribute!";
|
| - # GenerateReplaceableAttrSetter($implClassName);
|
| - } elsif ($attribute->type !~ /^readonly/ && !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
|
| - GenerateNormalAttrSetter($attribute, $dataNode, $classIndex, $implClassName);
|
| - }
|
| - }
|
| -
|
| - if ($hasConstructors) {
|
| - GenerateConstructorGetter($implClassName, $classIndex);
|
| - }
|
| -
|
| - # Generate methods for functions.
|
| - foreach my $function (@{$dataNode->functions}) {
|
| - # hack for addEventListener/RemoveEventListener
|
| - # FIXME: avoid naming conflict
|
| - if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"}) {
|
| - $implIncludes{"V8CustomBinding.h"} = 1;
|
| - } else {
|
| - GenerateFunctionCallback($function, $dataNode, $classIndex, $implClassName);
|
| - }
|
| -
|
| - # 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, $dataNode, $classIndex, $implClassName);
|
| - }
|
| - }
|
| -
|
| - # Attributes
|
| - my $attributes = $dataNode->attributes;
|
| -
|
| - # For the DOMWindow interface we partition the attributes into the
|
| - # ones that disallows shadowing and the rest.
|
| - my @disallows_shadowing;
|
| - my @normal;
|
| - if ($interfaceName eq "DOMWindow") {
|
| - foreach my $attribute (@$attributes) {
|
| - if ($attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) {
|
| - push(@disallows_shadowing, $attribute);
|
| - } else {
|
| - push(@normal, $attribute);
|
| - }
|
| - }
|
| - # Put the attributes that disallow shadowing on the shadow object.
|
| - $attributes = \@normal;
|
| - push(@implContent, "static const BatchedAttribute shadow_attrs[] = {\n");
|
| - GenerateBatchedAttributeData($interfaceName, \@disallows_shadowing);
|
| - push(@implContent, "};\n");
|
| - }
|
| -
|
| - my $has_attributes = 0;
|
| - if (@$attributes) {
|
| - $has_attributes = 1;
|
| - push(@implContent, "static const BatchedAttribute ${interfaceName}_attrs[] = {\n");
|
| - GenerateBatchedAttributeData($interfaceName, $attributes);
|
| - push(@implContent, "};\n");
|
| - }
|
| -
|
| - # 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(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n");
|
| -
|
| - my $access_check = "/* no access check */";
|
| - if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !($interfaceName eq "DOMWindow")) {
|
| - $access_check = "instance->SetAccessCheckCallbacks(V8Custom::v8${interfaceName}NamedSecurityCheck, V8Custom::v8${interfaceName}IndexedSecurityCheck, v8::Integer::New(V8ClassIndex::ToInt(V8ClassIndex::${classIndex})));";
|
| - }
|
| -
|
| - # For the DOMWindow interface, generate the shadow object template
|
| - # configuration method.
|
| - if ($implClassName eq "DOMWindow") {
|
| - push(@implContent, <<END);
|
| -static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ) {
|
| - batchConfigureAttributes(templ,
|
| - v8::Handle<v8::ObjectTemplate>(),
|
| - shadow_attrs,
|
| - sizeof(shadow_attrs)/sizeof(*shadow_attrs));
|
| - return templ;
|
| -}
|
| -END
|
| - }
|
| -
|
| - # Generate the template configuration method
|
| - push(@implContent, <<END);
|
| -static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) {
|
| - v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
|
| - instance->SetInternalFieldCount(2);
|
| - v8::Local<v8::Signature> default_signature = v8::Signature::New(desc);
|
| - v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
|
| - $access_check
|
| -END
|
| -
|
| -
|
| - # Set up our attributes if we have them
|
| - if ($has_attributes) {
|
| - push(@implContent, <<END);
|
| - batchConfigureAttributes(instance, proto, ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs));
|
| -END
|
| - }
|
| -
|
| - # Define our functions with Set() or SetAccessor()
|
| - foreach my $function (@{$dataNode->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->{"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
|
| - $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
|
| - next;
|
| - }
|
| -
|
| - my $signature = "default_signature";
|
| - if ($attrExt->{"V8DoNotCheckSignature"}){
|
| - $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 $templateFunction = GenerateNewFunctionTemplate($function, $dataNode, $signature);
|
| -
|
| -
|
| - push(@implContent, <<END);
|
| -
|
| - // $commentInfo
|
| - ${template}->Set(
|
| - v8::String::New("$name"),
|
| - $templateFunction,
|
| - static_cast<v8::PropertyAttribute>($property_attributes));
|
| -END
|
| - }
|
| -
|
| - # set the super descriptor
|
| - foreach (@{$dataNode->parents}) {
|
| - my $parent = $codeGenerator->StripModule($_);
|
| - if ($parent eq "EventTarget") { next; }
|
| - $implIncludes{"V8${parent}.h"} = 1;
|
| - my $parentClassIndex = uc($codeGenerator->StripModule($parent));
|
| - push(@implContent, " desc->Inherit(V8DOMWrapper::getTemplate(V8ClassIndex::${parentClassIndex}));\n");
|
| - last;
|
| - }
|
| -
|
| - # Set the class name. This is used when printing objects.
|
| - push(@implContent, " desc->SetClassName(v8::String::New(\"" . GetClassName(${interfaceName}) . "\"));\n");
|
| -
|
| - if ($has_constants) {
|
| - push(@implContent, <<END);
|
| - batchConfigureConstants(desc, proto, ${interfaceName}_consts, sizeof(${interfaceName}_consts)/sizeof(*${interfaceName}_consts));
|
| -END
|
| - }
|
| -
|
| - push(@implContent, <<END);
|
| - return desc;
|
| -}
|
| -
|
| -v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() {
|
| - static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_;
|
| - if (${className}_raw_cache_.IsEmpty()) {
|
| - v8::HandleScope scope;
|
| - v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(V8Proxy::checkNewLegal);
|
| - ${className}_raw_cache_ = v8::Persistent<v8::FunctionTemplate>::New(result);
|
| - }
|
| - return ${className}_raw_cache_;
|
| -}
|
| -
|
| -v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() {
|
| - static v8::Persistent<v8::FunctionTemplate> ${className}_cache_;
|
| - if (${className}_cache_.IsEmpty())
|
| - ${className}_cache_ = Configure${className}Template(GetRawTemplate());
|
| - return ${className}_cache_;
|
| -}
|
| -
|
| -bool ${className}::HasInstance(v8::Handle<v8::Value> value) {
|
| - return GetRawTemplate()->HasInstance(value);
|
| -}
|
| -
|
| -END
|
| -
|
| - if ($implClassName eq "DOMWindow") {
|
| - push(@implContent, <<END);
|
| -v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate() {
|
| - static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_;
|
| - if (V8DOMWindowShadowObject_cache_.IsEmpty()) {
|
| - V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
|
| - ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_);
|
| - }
|
| - return V8DOMWindowShadowObject_cache_;
|
| -}
|
| -END
|
| - }
|
| -
|
| - push(@implContent, <<END);
|
| -} // namespace WebCore
|
| -END
|
| -
|
| - push(@implContent, "\n#endif // ${conditionalString}\n") if $conditional;
|
| -}
|
| -
|
| -
|
| -sub GenerateFunctionCallString()
|
| -{
|
| - my $function = shift;
|
| - my $numberOfParameters = shift;
|
| - my $indent = shift;
|
| - my $implClassName = shift;
|
| -
|
| - my $name = $function->signature->name;
|
| - my $isPodType = IsPodType($implClassName);
|
| - my $returnType = $codeGenerator->StripModule($function->signature->type);
|
| - my $returnsPodType = IsPodType($returnType);
|
| - my $nativeReturnType = GetNativeType($returnType, 0);
|
| - my $result = "";
|
| -
|
| - # Special case: SVG matrix transform methods should not mutate
|
| - # the matrix but return a copy
|
| - my $copyFirst = 0;
|
| - if ($implClassName eq "SVGMatrix" && $function->signature->type eq "SVGMatrix") {
|
| - $copyFirst = 1;
|
| - }
|
| -
|
| - 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 ($copyFirst) {
|
| - $functionString = "result.${name}(";
|
| - }
|
| -
|
| - my $returnsListItemPodType = 0;
|
| - # SVG lists functions that return POD types require special handling
|
| - if (IsSVGListTypeNeedingSpecialHandling($implClassName) && IsSVGListMethod($name) && $returnsPodType) {
|
| - $returnsListItemPodType = 1;
|
| - $result .= $indent . "SVGList<RefPtr<SVGPODListItem<$nativeReturnType> > >* listImp = imp;\n";
|
| - $functionString = "listImp->${name}(";
|
| - }
|
| -
|
| - my $first = 1;
|
| - my $index = 0;
|
| - my $nodeToReturn = 0;
|
| -
|
| - foreach my $parameter (@{$function->parameters}) {
|
| - if ($index eq $numberOfParameters) {
|
| - last;
|
| - }
|
| - if ($first) { $first = 0; }
|
| - else { $functionString .= ", "; }
|
| - my $paramName = $parameter->name;
|
| - my $paramType = $parameter->type;
|
| -
|
| - # This is a bit of a hack... we need to convert parameters to methods on SVG lists
|
| - # of POD types which are items in the list to appropriate SVGList<> instances
|
| - if ($returnsListItemPodType && $paramType . "List" eq $implClassName) {
|
| - $paramName = "SVGPODListItem<" . GetNativeType($paramType, 1) . ">::copy($paramName)";
|
| - }
|
| -
|
| - if ($parameter->type eq "NodeFilter") {
|
| - $functionString .= "$paramName.get()";
|
| - } else {
|
| - $functionString .= $paramName;
|
| - }
|
| -
|
| - if ($parameter->extendedAttributes->{"Return"}) {
|
| - $nodeToReturn = $parameter->name;
|
| - }
|
| - $index++;
|
| - }
|
| -
|
| - if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
|
| - $functionString .= ", " if not $first;
|
| - $functionString .= "&callStack";
|
| - if ($first) { $first = 0; }
|
| - }
|
| -
|
| - if (@{$function->raisesExceptions}) {
|
| - $functionString .= ", " if not $first;
|
| - $functionString .= "ec";
|
| - }
|
| - $functionString .= ")";
|
| -
|
| - if ((IsRefPtrType($returnType) || $returnsListItemPodType) && !$nodeToReturn) {
|
| - # We don't use getPtr when $nodeToReturn because that situation is
|
| - # special-cased below to return a bool.
|
| - $implIncludes{"wtf/GetPtr.h"} = 1;
|
| - $functionString = "WTF::getPtr(" . $functionString . ")";
|
| - }
|
| -
|
| - if ($nodeToReturn) {
|
| - # Special case for insertBefore, replaceChild, removeChild and
|
| - # appendChild functions from Node.
|
| - $result .= $indent . "bool success = $functionString;\n";
|
| - if (@{$function->raisesExceptions}) {
|
| - $result .= GenerateSetDOMException($indent);
|
| - }
|
| - $result .= $indent . "if (success)\n";
|
| - $result .= $indent . " " .
|
| - "return V8DOMWrapper::convertNodeToV8Object($nodeToReturn);\n";
|
| - $result .= $indent . "return v8::Null();\n";
|
| - return $result;
|
| - } elsif ($returnType eq "void") {
|
| - $result .= $indent . "$functionString;\n";
|
| - } elsif ($copyFirst) {
|
| - $result .=
|
| - $indent . GetNativeType($returnType, 0) . " result = *imp;\n" .
|
| - $indent . "$functionString;\n";
|
| - } elsif ($returnsListItemPodType) {
|
| - $result .= $indent . "RefPtr<SVGPODListItem<$nativeReturnType> > result = $functionString;\n";
|
| - } else {
|
| - $result .= $indent . $nativeReturnType . " result = $functionString;\n";
|
| - }
|
| -
|
| - if (@{$function->raisesExceptions}) {
|
| - $result .= GenerateSetDOMException($indent);
|
| - }
|
| -
|
| - my $return = "result";
|
| - if (IsRefPtrType($returnType) || $returnsListItemPodType) {
|
| - $implIncludes{"wtf/GetPtr.h"} = 1;
|
| - $return = "WTF::getPtr(" . $return . ")";
|
| - }
|
| -
|
| - # If the return type is a POD type, separate out the wrapper generation
|
| - if ($returnsListItemPodType) {
|
| - $result .= $indent . "V8SVGPODTypeWrapper<" . $nativeReturnType . ">* wrapper = new ";
|
| - $result .= "V8SVGPODTypeWrapperCreatorForList<" . $nativeReturnType . ">($return, imp->associatedAttributeName());\n";
|
| - $return = "wrapper";
|
| - } elsif ($returnsPodType) {
|
| - $result .= $indent . "V8SVGPODTypeWrapper<" . $nativeReturnType . ">* wrapper = ";
|
| - $result .= GenerateSVGStaticPodTypeWrapper($returnType, $return) . ";\n";
|
| - $return = "wrapper";
|
| - }
|
| -
|
| - my $generatedSVGContextRetrieval = 0;
|
| - # If the return type needs an SVG context, output it
|
| - if (IsSVGTypeNeedingContextParameter($returnType)) {
|
| - $result .= GenerateSVGContextAssignment($implClassName, $return, $indent);
|
| - $generatedSVGContextRetrieval = 1;
|
| - }
|
| -
|
| - if (IsSVGTypeNeedingContextParameter($implClassName) && $implClassName =~ /List$/ && IsSVGListMutator($name)) {
|
| - if (!$generatedSVGContextRetrieval) {
|
| - $result .= GenerateSVGContextRetrieval($implClassName, $indent);
|
| - $generatedSVGContextRetrieval = 1;
|
| - }
|
| -
|
| - $result .= $indent . "context->svgAttributeChanged(imp->associatedAttributeName());\n";
|
| - $implIncludes{"SVGElement.h"} = 1;
|
| - }
|
| -
|
| - # If the implementing class is a POD type, commit changes
|
| - if ($isPodType) {
|
| - if (!$generatedSVGContextRetrieval) {
|
| - $result .= GenerateSVGContextRetrieval($implClassName, $indent);
|
| - $generatedSVGContextRetrieval = 1;
|
| - }
|
| -
|
| - $result .= $indent . "imp_wrapper->commitChange(imp_instance, context);\n";
|
| - }
|
| -
|
| - if ($returnsPodType) {
|
| - my $classIndex = uc($returnType);
|
| - $result .= $indent . "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper);\n";
|
| - } else {
|
| - $result .= $indent . ReturnNativeToJSValue($function->signature, $return, $indent) . ";\n";
|
| - }
|
| -
|
| - return $result;
|
| -}
|
| -
|
| -
|
| -# Get the class name used for printing javascript DOM-object wrappers.
|
| -sub GetClassName
|
| -{
|
| - my $type = shift;
|
| - return "HTMLCollection" if $type eq "HTMLAllCollection";
|
| - return $type;
|
| -}
|
| -
|
| -
|
| -sub GetNativeTypeFromSignature
|
| -{
|
| - my $signature = shift;
|
| - my $isParameter = shift;
|
| -
|
| - my $type = $codeGenerator->StripModule($signature->type);
|
| -
|
| - return GetNativeType($type, $isParameter);
|
| -}
|
| -
|
| -sub IsRefPtrType
|
| -{
|
| - my $type = shift;
|
| - return 1 if $type eq "Attr";
|
| - return 1 if $type eq "CanvasGradient";
|
| - return 1 if $type eq "ClientRect";
|
| - return 1 if $type eq "ClientRectList";
|
| - return 1 if $type eq "CDATASection";
|
| - return 1 if $type eq "Comment";
|
| - return 1 if $type eq "CSSRule";
|
| - return 1 if $type eq "CSSStyleRule";
|
| - return 1 if $type eq "CSSCharsetRule";
|
| - return 1 if $type eq "CSSImportRule";
|
| - return 1 if $type eq "CSSMediaRule";
|
| - return 1 if $type eq "CSSFontFaceRule";
|
| - return 1 if $type eq "CSSPageRule";
|
| - return 1 if $type eq "CSSPrimitiveValue";
|
| - return 1 if $type eq "CSSStyleSheet";
|
| - return 1 if $type eq "CSSStyleDeclaration";
|
| - return 1 if $type eq "CSSValue";
|
| - return 1 if $type eq "CSSRuleList";
|
| - return 1 if $type eq "Database";
|
| - 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 "Event";
|
| - return 1 if $type eq "FileList";
|
| - return 1 if $type eq "HTMLCollection";
|
| - return 1 if $type eq "HTMLDocument";
|
| - return 1 if $type eq "HTMLElement";
|
| - return 1 if $type eq "HTMLOptionsCollection";
|
| - return 1 if $type eq "ImageData";
|
| - return 1 if $type eq "MediaError";
|
| - return 1 if $type eq "MimeType";
|
| - return 1 if $type eq "Node";
|
| - return 1 if $type eq "NodeList";
|
| - return 1 if $type eq "NodeFilter";
|
| - return 1 if $type eq "NodeIterator";
|
| - return 1 if $type eq "NSResolver";
|
| - return 1 if $type eq "Plugin";
|
| - return 1 if $type eq "ProcessingInstruction";
|
| - return 1 if $type eq "Range";
|
| - return 1 if $type eq "Text";
|
| - return 1 if $type eq "TextMetrics";
|
| - return 1 if $type eq "TimeRanges";
|
| - return 1 if $type eq "TreeWalker";
|
| - return 1 if $type eq "WebKitCSSMatrix";
|
| - return 1 if $type eq "WebKitPoint";
|
| - return 1 if $type eq "XPathExpression";
|
| - return 1 if $type eq "XPathNSResolver";
|
| - return 1 if $type eq "XPathResult";
|
| -
|
| - return 1 if $type eq "SVGAngle";
|
| - return 1 if $type eq "SVGElementInstance";
|
| - return 1 if $type eq "SVGElementInstanceList";
|
| - return 1 if $type =~ /^SVGPathSeg/;
|
| -
|
| - return 1 if $type =~ /^SVGAnimated/;
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -sub IsVideoClassName
|
| -{
|
| - my $class = shift;
|
| - return 1 if $class eq "V8HTMLAudioElement";
|
| - return 1 if $class eq "V8HTMLMediaElement";
|
| - return 1 if $class eq "V8HTMLSourceElement";
|
| - return 1 if $class eq "V8HTMLVideoElement";
|
| - return 1 if $class eq "V8MediaError";
|
| - return 1 if $class eq "V8TimeRanges";
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -sub IsWorkerClassName
|
| -{
|
| - my $class = shift;
|
| - return 1 if $class eq "V8Worker";
|
| - return 1 if $class eq "V8WorkerContext";
|
| - return 1 if $class eq "V8WorkerLocation";
|
| - return 1 if $class eq "V8WorkerNavigator";
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -sub GetNativeType
|
| -{
|
| - my $type = shift;
|
| - my $isParameter = shift;
|
| -
|
| - if ($type eq "float" or $type eq "AtomicString" or $type eq "double") {
|
| - return $type;
|
| - }
|
| -
|
| - return "int" if $type eq "int";
|
| - return "int" if $type eq "short" or $type eq "unsigned short";
|
| - return "int" if $type eq "long" or $type eq "unsigned 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 "FloatRect" if $type eq "SVGRect";
|
| - return "FloatPoint" if $type eq "SVGPoint";
|
| - return "TransformationMatrix" if $type eq "SVGMatrix";
|
| - return "SVGTransform" if $type eq "SVGTransform";
|
| - return "SVGLength" if $type eq "SVGLength";
|
| - return "double" if $type eq "SVGNumber";
|
| - return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType";
|
| - return "DOMTimeStamp" if $type eq "DOMTimeStamp";
|
| - return "unsigned" if $type eq "unsigned int";
|
| - return "unsigned" if $type eq "RGBColor";
|
| - return "Node*" if $type eq "EventTarget" and $isParameter;
|
| -
|
| - return "String" if $type eq "DOMUserData"; # FIXME: Temporary hack?
|
| -
|
| - # temporary hack
|
| - return "RefPtr<NodeFilter>" if $type eq "NodeFilter";
|
| -
|
| - return "RefPtr<${type}>" if IsRefPtrType($type) and not $isParameter;
|
| -
|
| - # Default, assume native type is a pointer with same type name as idl type
|
| - return "${type}*";
|
| -}
|
| -
|
| -
|
| -my %typeCanFailConversion = (
|
| - "AtomicString" => 0,
|
| - "Attr" => 1,
|
| - "CompareHow" => 0,
|
| - "DataGridColumn" => 0,
|
| - "DOMString" => 0,
|
| - "DOMWindow" => 0,
|
| - "DocumentType" => 0,
|
| - "Element" => 0,
|
| - "Event" => 0,
|
| - "EventListener" => 0,
|
| - "EventTarget" => 0,
|
| - "HTMLElement" => 0,
|
| - "HTMLOptionElement" => 0,
|
| - "Node" => 0,
|
| - "NodeFilter" => 0,
|
| - "MessagePort" => 0,
|
| - "NSResolver" => 0,
|
| - "Range" => 0,
|
| - "SQLResultSet" => 0,
|
| - "Storage" => 0,
|
| - "SVGAngle" => 0,
|
| - "SVGElement" => 0,
|
| - "SVGLength" => 1,
|
| - "SVGMatrix" => 1,
|
| - "SVGNumber" => 0,
|
| - "SVGPaintType" => 0,
|
| - "SVGPathSeg" => 0,
|
| - "SVGPoint" => 1,
|
| - "SVGRect" => 1,
|
| - "SVGTransform" => 1,
|
| - "VoidCallback" => 1,
|
| - "WebKitCSSMatrix" => 0,
|
| - "WebKitPoint" => 0,
|
| - "XPathEvaluator" => 0,
|
| - "XPathNSResolver" => 0,
|
| - "XPathResult" => 0,
|
| - "boolean" => 0,
|
| - "double" => 0,
|
| - "float" => 0,
|
| - "long" => 0,
|
| - "unsigned long" => 0,
|
| - "unsigned short" => 0,
|
| -);
|
| -
|
| -
|
| -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 BasicTypeCanFailConversion
|
| -{
|
| - my $signature = shift;
|
| - my $type = $codeGenerator->StripModule($signature->type);
|
| -
|
| - return 1 if $type eq "SVGLength";
|
| - return 1 if $type eq "SVGMatrix";
|
| - return 1 if $type eq "SVGPoint";
|
| - return 1 if $type eq "SVGRect";
|
| - return 1 if $type eq "SVGTransform";
|
| - return 0;
|
| -}
|
| -
|
| -sub TypeCanFailConversion
|
| -{
|
| - my $signature = shift;
|
| -
|
| - my $type = $codeGenerator->StripModule($signature->type);
|
| -
|
| - $implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr";
|
| -
|
| - return $typeCanFailConversion{$type} if exists $typeCanFailConversion{$type};
|
| -
|
| - die "Don't know whether a JS value can fail conversion to type $type.";
|
| -}
|
| -
|
| -sub JSValueToNative
|
| -{
|
| - my $signature = shift;
|
| - my $value = shift;
|
| - my $okParam = shift;
|
| - my $maybeOkParam = $okParam ? ", ${okParam}" : "";
|
| -
|
| - my $type = $codeGenerator->StripModule($signature->type);
|
| -
|
| - 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 "$value->NumberValue()" if $type eq "SVGNumber";
|
| -
|
| - return "toInt32($value${maybeOkParam})" if $type eq "unsigned long" or $type eq "unsigned short" or $type eq "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 "toWebCoreString($value)" if $type eq "AtomicString" or $type eq "DOMUserData";
|
| - if ($type eq "DOMString") {
|
| - return "toWebCoreStringWithNullCheck($value)" if $signature->extendedAttributes->{"ConvertNullToNullString"};
|
| - return "toWebCoreStringWithNullOrUndefinedCheck($value)" if $signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"};
|
| - return "toWebCoreString($value)";
|
| - }
|
| -
|
| - if ($type eq "NodeFilter") {
|
| - return "V8DOMWrapper::wrapNativeNodeFilter($value)";
|
| - }
|
| -
|
| - if ($type eq "SVGRect") {
|
| - $implIncludes{"FloatRect.h"} = 1;
|
| - }
|
| -
|
| - if ($type eq "SVGPoint") {
|
| - $implIncludes{"FloatPoint.h"} = 1;
|
| - }
|
| -
|
| - # Default, assume autogenerated type conversion routines
|
| - $implIncludes{"V8Proxy.h"} = 1;
|
| - if ($type eq "EventTarget") {
|
| - $implIncludes{"V8Node.h"} = 1;
|
| -
|
| - # EventTarget is not in DOM hierarchy, but all Nodes are EventTarget.
|
| - return "V8Node::HasInstance($value) ? V8DOMWrapper::convertDOMWrapperToNode<Node>($value) : 0";
|
| - }
|
| -
|
| - AddIncludesForType($type);
|
| - # $implIncludes{"$type.h"} = 1 unless AvoidInclusionOfType($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) ? V8DOMWrapper::convertDOMWrapperToNode<${type}>($value) : 0";
|
| - } else {
|
| - # TODO: Temporary to avoid Window name conflict.
|
| - my $classIndex = uc($type);
|
| - my $implClassName = ${type};
|
| -
|
| - $implIncludes{"V8$type.h"} = 1;
|
| -
|
| - if (IsPodType($type)) {
|
| - my $nativeType = GetNativeType($type);
|
| - $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
|
| -
|
| - return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(V8ClassIndex::${classIndex}, $value${maybeOkParam})"
|
| - }
|
| -
|
| - $implIncludes{"V8${type}.h"} = 1;
|
| -
|
| - # Perform type checks on the parameter, if it is expected Node type,
|
| - # return NULL.
|
| - return "V8${type}::HasInstance($value) ? V8DOMWrapper::convertToNativeObject<${implClassName}>(V8ClassIndex::${classIndex}, v8::Handle<v8::Object>::Cast($value)) : 0";
|
| - }
|
| -}
|
| -
|
| -
|
| -sub GetV8HeaderName
|
| -{
|
| - my $type = shift;
|
| - return "V8" . GetImplementationFileName($type);
|
| -}
|
| -
|
| -
|
| -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)) {
|
| - 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;
|
| - }
|
| -
|
| - foreach my $parameter (@{$function->parameters}) {
|
| - if (IsWrapperType($parameter->type)) {
|
| - return 1;
|
| - }
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -
|
| -my %non_wrapper_types = (
|
| - 'float' => 1,
|
| - 'AtomicString' => 1,
|
| - 'double' => 1,
|
| - 'short' => 1,
|
| - 'unsigned short' => 1,
|
| - 'long' => 1,
|
| - 'unsigned long' => 1,
|
| - 'boolean' => 1,
|
| - 'DOMString' => 1,
|
| - 'CompareHow' => 1,
|
| - 'SVGRect' => 1,
|
| - 'SVGPoint' => 1,
|
| - 'SVGMatrix' => 1,
|
| - 'SVGTransform' => 1,
|
| - 'SVGLength' => 1,
|
| - 'SVGNumber' => 1,
|
| - 'SVGPaintType' => 1,
|
| - 'DOMTimeStamp' => 1,
|
| - 'JSObject' => 1,
|
| - 'EventTarget' => 1,
|
| - 'NodeFilter' => 1,
|
| - 'EventListener' => 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 = $codeGenerator->StripModule($signature->type);
|
| - my $className= "V8$type";
|
| -
|
| - return "return v8::Date::New(static_cast<double>($value))" if $type eq "DOMTimeStamp";
|
| - return "return $value ? v8::True() : v8::False()" if $type eq "boolean";
|
| - return "return v8::Undefined()" if $type eq "void";
|
| -
|
| - # For all the types where we use 'int' as the representation type,
|
| - # we use Integer::New which has a fast Smi conversion check.
|
| - return "return v8::Integer::New($value)" if GetNativeType($type) eq "int";
|
| -
|
| - return "return v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType";
|
| -
|
| - 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";
|
| - }
|
| - return "return v8String($value)";
|
| - }
|
| -
|
| - # V8 specific.
|
| - my $implClassName = $type;
|
| - AddIncludesForType($type);
|
| - # $implIncludes{GetImplementationFileName($type)} = 1 unless AvoidInclusionOfType($type);
|
| -
|
| - # special case for non-DOM node interfaces
|
| - if (IsDOMNodeType($type)) {
|
| - return "return V8DOMWrapper::convertNodeToV8Object($value)";
|
| - }
|
| -
|
| - if ($type eq "EventTarget" or $type eq "SVGElementInstance") {
|
| - return "return V8DOMWrapper::convertEventTargetToV8Object($value)";
|
| - }
|
| -
|
| - if ($type eq "Event") {
|
| - return "return V8DOMWrapper::convertEventToV8Object($value)";
|
| - }
|
| -
|
| - if ($type eq "EventListener") {
|
| - return "return V8DOMWrapper::convertEventListenerToV8Object($value)";
|
| - }
|
| -
|
| - if ($type eq "RGBColor") {
|
| +
|
| +# 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.
|
| +#
|
| +# This file is part of the KDE project
|
| +#
|
| +# This library is free software; you can redistribute it and/or
|
| +# modify it under the terms of the GNU Library General Public
|
| +# License as published by the Free Software Foundation; either
|
| +# version 2 of the License, or (at your option) any later version.
|
| +#
|
| +# This library is distributed in the hope that it will be useful,
|
| +# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| +# Library General Public License for more details.
|
| +#
|
| +# You should have received a copy of the GNU Library General Public License
|
| +# aint with this library; see the file COPYING.LIB. If not, write to
|
| +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
| +# Boston, MA 02111-1307, USA.
|
| +#
|
| +
|
| +package CodeGeneratorV8;
|
| +
|
| +use File::stat;
|
| +
|
| +my $module = "";
|
| +my $outputDir = "";
|
| +
|
| +my @headerContent = ();
|
| +my @implContentHeader = ();
|
| +my @implFixedHeader = ();
|
| +my @implContent = ();
|
| +my @implContentDecls = ();
|
| +my %implIncludes = ();
|
| +
|
| +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;
|
| +
|
| + bless($reference, $object);
|
| + return $reference;
|
| +}
|
| +
|
| +sub finish
|
| +{
|
| + my $object = shift;
|
| +
|
| + # Commit changes!
|
| + $object->WriteData();
|
| +}
|
| +
|
| +sub leftShift($$) {
|
| + my ($value, $distance) = @_;
|
| + return (($value << $distance) & 0xFFFFFFFF);
|
| +}
|
| +
|
| +# Uppercase the first letter, while respecting WebKit style guidelines.
|
| +# E.g., xmlEncoding becomes XMLEncoding, but xmlllang becomes Xmllang.
|
| +sub WK_ucfirst
|
| +{
|
| + my $param = shift;
|
| + my $ret = ucfirst($param);
|
| + $ret =~ s/Xml/XML/ if $ret =~ /^Xml[^a-z]/;
|
| + return $ret;
|
| +}
|
| +
|
| +# Lowercase the first letter while respecting WebKit style guidelines.
|
| +# URL becomes url, but SetURL becomes setURL.
|
| +sub WK_lcfirst
|
| +{
|
| + my $param = shift;
|
| + my $ret = lcfirst($param);
|
| + $ret =~ s/uRL/url/;
|
| + return $ret;
|
| +}
|
| +
|
| +# Workaround for V8 bindings difference where RGBColor is not a POD type.
|
| +sub IsPodType
|
| +{
|
| + my $type = shift;
|
| + return 0 if $type eq "RGBColor";
|
| + return $codeGenerator->IsPodType($type);
|
| +}
|
| +
|
| +# Params: 'domClass' struct
|
| +sub GenerateInterface
|
| +{
|
| + my $object = shift;
|
| + my $dataNode = shift;
|
| + my $defines = shift;
|
| +
|
| + # Start actual generation
|
| + $object->GenerateHeader($dataNode);
|
| + $object->GenerateImplementation($dataNode);
|
| +
|
| + my $name = $dataNode->name;
|
| +
|
| + # Open files for writing
|
| + my $headerFileName = "$outputDir/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 GetLegacyHeaderIncludes
|
| +{
|
| + my $legacyParent = shift;
|
| +
|
| + die "Don't know what headers to include for module $module";
|
| +}
|
| +
|
| +sub AvoidInclusionOfType
|
| +{
|
| + my $type = shift;
|
| +
|
| + # Special case: SVGRect.h / SVGPoint.h / SVGNumber.h / SVGMatrix.h do not exist.
|
| + return 1 if $type eq "SVGRect" or $type eq "SVGPoint" or $type eq "SVGNumber" or $type eq "SVGMatrix";
|
| + return 0;
|
| +}
|
| +
|
| +sub UsesManualToJSImplementation
|
| +{
|
| + my $type = shift;
|
| +
|
| + return 1 if $type eq "SVGPathSeg";
|
| + return 0;
|
| +}
|
| +
|
| +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) or AvoidInclusionOfType($type)) {
|
| + } elsif ($type =~ /SVGPathSeg/) {
|
| + $joinedName = $type;
|
| + $joinedName =~ s/Abs|Rel//;
|
| + $implIncludes{"${joinedName}.h"} = 1;
|
| + } else {
|
| + # default, include the same named file
|
| + $implIncludes{GetImplementationFileName(${type})} = 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{"AtomicString.h"} = 1;
|
| + }
|
| +}
|
| +
|
| +sub AddIncludesForSVGAnimatedType
|
| +{
|
| + my $type = shift;
|
| + $type =~ s/SVGAnimated//;
|
| +
|
| + if ($type eq "Point" or $type eq "Rect") {
|
| + $implIncludes{"Float$type.h"} = 1;
|
| + } elsif ($type eq "String") {
|
| + $implIncludes{"PlatformString.h"} = 1;
|
| + }
|
| +
|
| + $implIncludes{"SVGAnimatedTemplate.h"} = 1;
|
| +}
|
| +
|
| +sub AddClassForwardIfNeeded
|
| +{
|
| + my $implClassName = shift;
|
| +
|
| + # SVGAnimatedLength/Number/etc.. are typedefs to SVGAnimtatedTemplate, so don't use class forwards for them!
|
| + push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName);
|
| +}
|
| +
|
| +sub GetImplementationFileName
|
| +{
|
| + my $iface = shift;
|
| + return "HTMLCollection.h" if $iface eq "HTMLAllCollection";
|
| + return "Event.h" if $iface eq "DOMTimeStamp";
|
| + return "NamedAttrMap.h" if $iface eq "NamedNodeMap";
|
| + return "NameNodeList.h" if $iface eq "NodeList";
|
| + return "XMLHttpRequest.h" if $iface eq "XMLHttpRequest";
|
| +
|
| + return "${iface}.h";
|
| +}
|
| +
|
| +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);
|
| +
|
| + my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
|
| + my $conditional = $dataNode->extendedAttributes->{"Conditional"};
|
| +
|
| + # - Add default header template
|
| + @headerContent = split("\r", $headerTemplate);
|
| +
|
| + my $conditionalString;
|
| + if ($conditional) {
|
| + $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
|
| + push(@headerContent, "\n#if ${conditionalString}\n\n");
|
| + }
|
| +
|
| + push(@headerContent, "\n#ifndef $className" . "_H");
|
| + push(@headerContent, "\n#define $className" . "_H\n\n");
|
| +
|
| + # Get correct pass/store types respecting PODType flag
|
| + my $podType = $dataNode->extendedAttributes->{"PODType"};
|
| + my $passType = $podType ? "JSSVGPODTypeWrapper<$podType>*" : "$implClassName*";
|
| +
|
| + push(@headerContent, "#include \"$podType.h\"\n") if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
|
| +
|
| + push(@headerContent, "#include <v8.h>\n");
|
| + push(@headerContent, "#include <wtf/HashMap.h>\n");
|
| + push(@headerContent, "#include \"StringHash.h\"\n");
|
| +
|
| + push(@headerContent, "\nnamespace WebCore {\n\n");
|
| + push(@headerContent, "class V8ClassIndex;\n");
|
| + push(@headerContent, "\nclass $className {\n");
|
| + push(@headerContent, <<END);
|
| +
|
| + public:
|
| + static bool HasInstance(v8::Handle<v8::Value> value);
|
| + static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
|
| +END
|
| +
|
| + if ($implClassName eq "DOMWindow") {
|
| + push(@headerContent, <<END);
|
| + static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
|
| +END
|
| + }
|
| +
|
| + push(@headerContent, <<END);
|
| +
|
| + private:
|
| + static v8::Persistent<v8::FunctionTemplate> GetTemplate();
|
| +
|
| + friend class V8ClassIndex;
|
| +};
|
| +
|
| +END
|
| +
|
| + push(@headerContent, "}\n\n");
|
| + push(@headerContent, "#endif // $className" . "_H\n");
|
| +
|
| + push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditional;
|
| +}
|
| +
|
| +
|
| +sub GenerateSetDOMException
|
| +{
|
| + my $indent = shift;
|
| + my $result = "";
|
| +
|
| + $result .= $indent . "if (ec) {\n";
|
| + $result .= $indent . " V8Proxy::setDOMException(ec);\n";
|
| + $result .= $indent . " return v8::Handle<v8::Value>();\n";
|
| + $result .= $indent . "}\n";
|
| +
|
| + return $result;
|
| +}
|
| +
|
| +sub IsNodeSubType
|
| +{
|
| + my $dataNode = shift;
|
| + return 1 if ($dataNode->name eq "Node");
|
| + foreach (@allParents) {
|
| + my $parent = $codeGenerator->StripModule($_);
|
| + return 1 if $parent eq "Node";
|
| + }
|
| + return 0;
|
| +}
|
| +
|
| +sub HolderToNative
|
| +{
|
| + my $dataNode = shift;
|
| + my $implClassName = shift;
|
| + my $classIndex = shift;
|
| +
|
| + if (IsNodeSubType($dataNode)) {
|
| + push(@implContentDecls, <<END);
|
| + $implClassName* imp = V8DOMWrapper::convertDOMWrapperToNode<$implClassName>(holder);
|
| +END
|
| +
|
| + } else {
|
| + push(@implContentDecls, <<END);
|
| + $implClassName* imp = V8DOMWrapper::convertToNativeObject<$implClassName>(V8ClassIndex::$classIndex, holder);
|
| +END
|
| +
|
| + }
|
| +}
|
| +
|
| +sub GenerateDomainSafeFunctionGetter
|
| +{
|
| + my $function = shift;
|
| + my $dataNode = shift;
|
| + my $classIndex = shift;
|
| + my $implClassName = shift;
|
| +
|
| + my $className = "V8" . $dataNode->name;
|
| + 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, $dataNode, $signature);
|
| +
|
| + $implIncludes{"V8Proxy.h"} = 1;
|
| +
|
| + 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> private_template =
|
| + v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
|
| + v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
|
| + if (holder.IsEmpty()) {
|
| + // can only reach here by 'object.__proto__.func', and it should passed
|
| + // domain security check already
|
| +
|
| + return private_template->GetFunction();
|
| + }
|
| +END
|
| +
|
| + HolderToNative($dataNode, $implClassName, $classIndex);
|
| +
|
| + push(@implContentDecls, <<END);
|
| + if (!V8Proxy::canAccessFrame(imp->frame(), false)) {
|
| + static v8::Persistent<v8::FunctionTemplate> shared_template =
|
| + v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
|
| + return shared_template->GetFunction();
|
| +
|
| + } else {
|
| + return private_template->GetFunction();
|
| + }
|
| + }
|
| +
|
| +END
|
| +}
|
| +
|
| +sub GenerateConstructorGetter
|
| +{
|
| + my $implClassName = shift;
|
| + my $classIndex = shift;
|
| +
|
| + push(@implContentDecls, <<END);
|
| + static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
|
| + INC_STATS(\"DOM.$implClassName.constructors._get\");
|
| + v8::Handle<v8::Value> data = info.Data();
|
| + ASSERT(data->IsNumber());
|
| + V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(data->Int32Value());
|
| +END
|
| +
|
| + if ($classIndex eq "DOMWINDOW") {
|
| + push(@implContentDecls, <<END);
|
| + DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
|
| + // 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, window);
|
| +END
|
| + } elsif ($classIndex eq "WORKERCONTEXT") {
|
| + $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
|
| + push(@implContentDecls, <<END);
|
| + return WorkerContextExecutionProxy::retrieve()->GetConstructor(type);
|
| +END
|
| + } else {
|
| + push(@implContentDecls, " return v8::Undefined();");
|
| + }
|
| +
|
| + push(@implContentDecls, <<END);
|
| +
|
| + }
|
| +
|
| +END
|
| +}
|
| +
|
| +sub GenerateNormalAttrGetter
|
| +{
|
| + my $attribute = shift;
|
| + my $dataNode = shift;
|
| + my $classIndex = shift;
|
| + my $implClassName = shift;
|
| +
|
| + my $attrExt = $attribute->signature->extendedAttributes;
|
| +
|
| + my $attrName = $attribute->signature->name;
|
| + $implIncludes{"V8Proxy.h"} = 1;
|
| +
|
| + my $attrType = $codeGenerator->StripModule($attribute->signature->type);
|
| + my $attrIsPodType = IsPodType($attrType);
|
| +
|
| + my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
|
| + my $isPodType = IsPodType($implClassName);
|
| + my $skipContext = 0;
|
| +
|
| +
|
| + if ($isPodType) {
|
| + $implClassName = GetNativeType($implClassName);
|
| + $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
|
| + }
|
| +
|
| + # Special case: SVGZoomEvent's attributes are all read-only
|
| + if ($implClassName eq "SVGZoomEvent") {
|
| + $attrIsPodType = 0;
|
| + $skipContext = 1;
|
| + }
|
| +
|
| + # Special case: SVGSVGEelement::viewport is read-only
|
| + if (($implClassName eq "SVGSVGElement") and ($attrName eq "viewport")) {
|
| + $attrIsPodType = 0;
|
| + $skipContext = 1;
|
| + }
|
| +
|
| + # Special case for SVGColor
|
| + if (($implClassName eq "SVGColor") and ($attrName eq "rgbColor")) {
|
| + $attrIsPodType = 0;
|
| + }
|
| +
|
| + my $getterStringUsesImp = $implClassName ne "double";
|
| +
|
| + # Getter
|
| + 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 ($isPodType) {
|
| + push(@implContentDecls, <<END);
|
| + V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());
|
| + $implClassName imp_instance = *imp_wrapper;
|
| +END
|
| + if ($getterStringUsesImp) {
|
| + push(@implContentDecls, <<END);
|
| + $implClassName* imp = &imp_instance;
|
| +END
|
| + }
|
| +
|
| + } elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) {
|
| + # perform lookup first
|
| + push(@implContentDecls, <<END);
|
| + v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
|
| + if (holder.IsEmpty()) return v8::Undefined();
|
| +END
|
| + HolderToNative($dataNode, $implClassName, $classIndex);
|
| + } else {
|
| + push(@implContentDecls, <<END);
|
| + v8::Handle<v8::Object> holder = info.Holder();
|
| +END
|
| + HolderToNative($dataNode, $implClassName, $classIndex);
|
| + }
|
| +
|
| + # Generate security checks if necessary
|
| + if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
|
| + push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->$attrName())) return v8::Undefined();\n\n");
|
| + } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
|
| + push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->contentDocument())) return v8::Undefined();\n\n");
|
| + }
|
| +
|
| + my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType);
|
| + if ($useExceptions) {
|
| + $implIncludes{"ExceptionCode.h"} = 1;
|
| + push(@implContentDecls, " ExceptionCode ec = 0;\n");
|
| + }
|
| +
|
| + if ($attribute->signature->extendedAttributes->{"v8referenceattr"}) {
|
| + $attrName = $attribute->signature->extendedAttributes->{"v8referenceattr"};
|
| + }
|
| +
|
| + my $getterFunc = WK_lcfirst($attrName);
|
| + $getterFunc .= "Animated" if $codeGenerator->IsSVGAnimatedType($attribute->signature->type);
|
| +
|
| + my $returnType = $codeGenerator->StripModule($attribute->signature->type);
|
| +
|
| + my $getterString;
|
| + if ($getterStringUsesImp) {
|
| + my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
|
| + my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
|
| + if ($reflect || $reflectURL) {
|
| + $implIncludes{"HTMLNames.h"} = 1;
|
| + my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
|
| + my $getAttributeFunctionName = $reflectURL ? "getURLAttribute" : "getAttribute";
|
| + $getterString = "imp->$getAttributeFunctionName(HTMLNames::${contentAttributeName}Attr";
|
| + } else {
|
| + $getterString = "imp->$getterFunc(";
|
| + }
|
| + $getterString .= "ec" if $useExceptions;
|
| + $getterString .= ")";
|
| + if (IsRefPtrType($returnType)) {
|
| + $implIncludes{"wtf/GetPtr.h"} = 1;
|
| + $getterString = "WTF::getPtr(" . $getterString . ")";
|
| + }
|
| + if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
|
| + $getterString .= ".toInt()";
|
| + }
|
| + } else {
|
| + $getterString = "imp_instance";
|
| + }
|
| +
|
| + if ($nativeType eq "String") {
|
| + $getterString = "toString($getterString)";
|
| + }
|
| +
|
| + my $result;
|
| + my $wrapper;
|
| +
|
| + if ($attrIsPodType) {
|
| + $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
|
| +
|
| + my $getter = $getterString;
|
| + $getter =~ s/imp->//;
|
| + $getter =~ s/\(\)//;
|
| + my $setter = "set" . WK_ucfirst($getter);
|
| +
|
| + my $implClassIsAnimatedType = $codeGenerator->IsSVGAnimatedType($implClassName);
|
| + if (not $implClassIsAnimatedType and $codeGenerator->IsPodTypeWithWriteableProperties($attrType) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
|
| + if (IsPodType($implClassName)) {
|
| + $wrapper = "new V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>($getterString, imp_wrapper)";
|
| + } else {
|
| + $wrapper = "new V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName>(imp, &${implClassName}::$getter, &${implClassName}::$setter)";
|
| + }
|
| + } else {
|
| + if ($implClassIsAnimatedType) {
|
| + $wrapper = "V8SVGDynamicPODTypeWrapperCache<$nativeType, $implClassName>::lookupOrCreateWrapper(imp, &${implClassName}::$getter, &${implClassName}::$setter)";
|
| + } else {
|
| + $wrapper = GenerateSVGStaticPodTypeWrapper($returnType, $getterString);
|
| + }
|
| + }
|
| +
|
| + push(@implContentDecls, " void* wrapper = $wrapper;\n");
|
| + } elsif ($nativeType ne "RGBColor") {
|
| + push(@implContentDecls, " $nativeType v = ");
|
| +
|
| + push(@implContentDecls, "$getterString;\n");
|
| +
|
| + if ($useExceptions) {
|
| + push(@implContentDecls, GenerateSetDOMException(" "));
|
| + }
|
| +
|
| + $result = "v";
|
| + if (IsRefPtrType($returnType)) {
|
| + $result = "WTF::getPtr(" . $result . ")";
|
| + }
|
| + } else {
|
| + # Special case: RGBColor is noncopyable
|
| + $result = $getterString;
|
| + }
|
| +
|
| +
|
| + if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) {
|
| + my $resultObject = $result;
|
| + if ($attrIsPodType) {
|
| + $resultObject = "wrapper";
|
| + }
|
| +
|
| + push(@implContentDecls, GenerateSVGContextAssignment($implClassName, $resultObject, " "));
|
| + }
|
| +
|
| + if ($attrIsPodType) {
|
| + my $classIndex = uc($attrType);
|
| + push(@implContentDecls, " return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper);\n");
|
| + } else {
|
| + push(@implContentDecls, " " . ReturnNativeToJSValue($attribute->signature, $result, " ").";\n");
|
| + }
|
| +
|
| + push(@implContentDecls, " }\n\n"); # end of getter
|
| +}
|
| +
|
| +
|
| +sub GenerateReplaceableAttrSetter
|
| +{
|
| + my $implClassName = shift;
|
| +
|
| + $implIncludes{"V8Proxy.h"} = 1;
|
| +
|
| + push(@implContentDecls,
|
| + " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
|
| + " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
|
| +
|
| + push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
|
| +
|
| + push(@implContentDecls, " v8::Local<v8::String> ${attrName}_string = v8::String::New(\"${attrName}\");\n");
|
| + push(@implContentDecls, " info.Holder()->Delete(${attrName}_string);\n");
|
| + push(@implContentDecls, " info.This()->Set(${attrName}_string, value);\n");
|
| + push(@implContentDecls, " }\n\n");
|
| +}
|
| +
|
| +
|
| +sub GenerateNormalAttrSetter
|
| +{
|
| + my $attribute = shift;
|
| + my $dataNode = shift;
|
| + my $classIndex = shift;
|
| + my $implClassName = shift;
|
| +
|
| + my $attrExt = $attribute->signature->extendedAttributes;
|
| +
|
| + $implIncludes{"V8Proxy.h"} = 1;
|
| +
|
| + push(@implContentDecls,
|
| + " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
|
| + " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
|
| +
|
| + push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
|
| +
|
| + my $isPodType = IsPodType($implClassName);
|
| +
|
| + if ($isPodType) {
|
| + $implClassName = GetNativeType($implClassName);
|
| + $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
|
| + push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());\n");
|
| + push(@implContentDecls, " $implClassName imp_instance = *wrapper;\n");
|
| + push(@implContentDecls, " $implClassName* imp = &imp_instance;\n");
|
| +
|
| + } elsif ($attrExt->{"v8OnProto"}) {
|
| + # perform lookup first
|
| + push(@implContentDecls, <<END);
|
| + v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
|
| + if (holder.IsEmpty()) return v8::Undefined();
|
| +END
|
| + HolderToNative($dataNode, $implClassName, $classIndex);
|
| + } else {
|
| + push(@implContentDecls, <<END);
|
| + v8::Handle<v8::Object> holder = info.Holder();
|
| +END
|
| + HolderToNative($dataNode, $implClassName, $classIndex);
|
| + }
|
| +
|
| + my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
|
| + push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n");
|
| +
|
| + my $result = "";
|
| + if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
|
| + $result .= "WebCore::String::number(";
|
| + }
|
| + $result .= "v";
|
| + if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
|
| + $result .= ")";
|
| + }
|
| + my $returnType = $codeGenerator->StripModule($attribute->signature->type);
|
| + if (IsRefPtrType($returnType)) {
|
| + $result = "WTF::getPtr(" . $result . ")";
|
| + }
|
| +
|
| + my $useExceptions = 1 if @{$attribute->setterExceptions} and !($isPodType);
|
| +
|
| + if ($useExceptions) {
|
| + $implIncludes{"ExceptionCode.h"} = 1;
|
| + push(@implContentDecls, " ExceptionCode ec = 0;\n");
|
| + }
|
| +
|
| + if ($implClassName eq "double") {
|
| + push(@implContentDecls, " *imp = $result;\n");
|
| + } else {
|
| + my $implSetterFunctionName = WK_ucfirst($attrName);
|
| + my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
|
| + my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
|
| + if ($reflect || $reflectURL) {
|
| + $implIncludes{"HTMLNames.h"} = 1;
|
| + my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
|
| + push(@implContentDecls, " imp->setAttribute(HTMLNames::${contentAttributeName}Attr, $result");
|
| + } else {
|
| + push(@implContentDecls, " imp->set$implSetterFunctionName(" . $result);
|
| + }
|
| + push(@implContentDecls, ", ec") if $useExceptions;
|
| + push(@implContentDecls, ");\n");
|
| + }
|
| +
|
| + if ($useExceptions) {
|
| + push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
|
| + }
|
| +
|
| + if ($isPodType) {
|
| + push(@implContentDecls, " wrapper->commitChange(*imp, V8Proxy::svgContext(wrapper));\n");
|
| + } elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
|
| + $implIncludes{"SVGElement.h"} = 1;
|
| +
|
| + my $currentObject = "imp";
|
| + if ($isPodType) {
|
| + $currentObject = "wrapper";
|
| + }
|
| +
|
| + push(@implContentDecls, " if (SVGElement* context = V8Proxy::svgContext($currentObject)) {\n");
|
| + push(@implContentDecls, " context->svgAttributeChanged(imp->associatedAttributeName());\n");
|
| + push(@implContentDecls, " }\n");
|
| + }
|
| +
|
| + push(@implContentDecls, " return;\n");
|
| + push(@implContentDecls, " }\n\n"); # end of setter
|
| +}
|
| +
|
| +sub GenerateNewFunctionTemplate
|
| +{
|
| + $function = shift;
|
| + $dataNode = shift;
|
| + $signature = shift;
|
| +
|
| + my $interfaceName = $dataNode->name;
|
| + 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!"
|
| + }
|
| + my $customFunc = $function->signature->extendedAttributes->{"Custom"} ||
|
| + $function->signature->extendedAttributes->{"V8Custom"};
|
| + if ($customFunc eq 1) {
|
| + $customFunc = $interfaceName . WK_ucfirst($name);
|
| + }
|
| + return "v8::FunctionTemplate::New(V8Custom::v8${customFunc}Callback, v8::Handle<v8::Value>(), $signature)";
|
| + } else {
|
| + return "v8::FunctionTemplate::New(${interfaceName}Internal::${name}Callback, v8::Handle<v8::Value>(), $signature)";
|
| + }
|
| +}
|
| +
|
| +sub GenerateFunctionCallback
|
| +{
|
| + my $function = shift;
|
| + my $dataNode = shift;
|
| + my $classIndex = shift;
|
| + my $implClassName = shift;
|
| +
|
| + my $interfaceName = $dataNode->name;
|
| + my $name = $function->signature->name;
|
| +
|
| + push(@implContentDecls,
|
| +" static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {\n" .
|
| +" INC_STATS(\"DOM.$implClassName.$name\");\n");
|
| +
|
| + my $numParameters = @{$function->parameters};
|
| +
|
| + if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) {
|
| + push(@implContentDecls,
|
| + " if (args.Length() < $numParameters) return v8::Undefined();\n");
|
| + }
|
| +
|
| + if (IsPodType($implClassName)) {
|
| + my $nativeClassName = GetNativeType($implClassName);
|
| + push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$nativeClassName> >(V8ClassIndex::$classIndex, args.Holder());\n");
|
| + push(@implContentDecls, " $nativeClassName imp_instance = *imp_wrapper;\n");
|
| + push(@implContentDecls, " $nativeClassName* imp = &imp_instance;\n");
|
| + } else {
|
| + push(@implContentDecls, <<END);
|
| + v8::Handle<v8::Object> holder = args.Holder();
|
| +END
|
| + HolderToNative($dataNode, $implClassName, $classIndex);
|
| + }
|
| +
|
| + # Check domain security if needed
|
| + if (($dataNode->extendedAttributes->{"CheckDomainSecurity"}
|
| + || $interfaceName eq "DOMWindow")
|
| + && !$function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
|
| + # We have not find real use cases yet.
|
| + push(@implContentDecls,
|
| +" if (!V8Proxy::canAccessFrame(imp->frame(), true)) {\n".
|
| +" return v8::Undefined();\n" .
|
| +" }\n");
|
| + }
|
| +
|
| +
|
| + if (@{$function->raisesExceptions}) {
|
| + $implIncludes{"ExceptionCode.h"} = 1;
|
| + push(@implContentDecls, " ExceptionCode ec = 0;\n");
|
| + }
|
| +
|
| + if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
|
| + push(@implContentDecls, " ScriptCallStack callStack(args, $numParameters);\n");
|
| + $implIncludes{"ScriptCallStack.h"} = 1;
|
| + }
|
| +
|
| + my $paramIndex = 0;
|
| + foreach my $parameter (@{$function->parameters}) {
|
| + TranslateParameter($parameter);
|
| +
|
| + my $parameterName = $parameter->name;
|
| +
|
| + if ($parameter->extendedAttributes->{"Optional"}) {
|
| + # 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");
|
| + }
|
| +
|
| + if (BasicTypeCanFailConversion($parameter)) {
|
| + push(@implContentDecls, " bool ${parameterName}Ok;\n");
|
| + }
|
| +
|
| + push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, 1) . " $parameterName = ");
|
| + push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]",
|
| + BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n");
|
| +
|
| + if (TypeCanFailConversion($parameter)) {
|
| + $implIncludes{"ExceptionCode.h"} = 1;
|
| + push(@implContentDecls,
|
| +" if (!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "") . ") {\n" .
|
| +" V8Proxy::setDOMException(TYPE_MISMATCH_ERR);\n" .
|
| +" return v8::Handle<v8::Value>();\n" .
|
| +" }\n");
|
| + }
|
| +
|
| + if ($parameter->extendedAttributes->{"IsIndex"}) {
|
| + $implIncludes{"ExceptionCode.h"} = 1;
|
| + push(@implContentDecls,
|
| +" if ($parameterName < 0) {\n" .
|
| +" V8Proxy::setDOMException(INDEX_SIZE_ERR);\n" .
|
| +" return v8::Handle<v8::Value>();\n" .
|
| +" }\n");
|
| + }
|
| +
|
| + $paramIndex++;
|
| + }
|
| +
|
| + # Build the function call string.
|
| + my $callString = GenerateFunctionCallString($function, $paramIndex, " ", $implClassName);
|
| + push(@implContentDecls, "$callString");
|
| + push(@implContentDecls, " }\n\n");
|
| +}
|
| +
|
| +sub GenerateBatchedAttributeData
|
| +{
|
| + my $interfaceName = shift;
|
| + my $attributes = shift;
|
| +
|
| + foreach my $attribute (@$attributes) {
|
| + my $attrName = $attribute->signature->name;
|
| + my $attrExt = $attribute->signature->extendedAttributes;
|
| +
|
| + 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 . WK_ucfirst($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 = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";
|
| +
|
| + # Constructor
|
| + if ($attribute->signature->type =~ /Constructor$/) {
|
| + my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
|
| + $constructorType =~ s/Constructor$//;
|
| + my $constructorIndex = uc($constructorType);
|
| + $data = "V8ClassIndex::${constructorIndex}";
|
| + $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
|
| + $setter = "0";
|
| + $propAttr = "v8::ReadOnly";
|
| +
|
| + # EventListeners
|
| + } elsif ($attribute->signature->type eq "EventListener") {
|
| + if ($interfaceName eq "DOMWindow") {
|
| + $getter = "V8Custom::v8DOMWindowEventHandlerAccessorGetter";
|
| + $setter = "V8Custom::v8DOMWindowEventHandlerAccessorSetter";
|
| + } elsif ($interfaceName eq "Element" || $interfaceName eq "Document" || $interfaceName eq "HTMLBodyElement" || $interfaceName eq "SVGElementInstance" || $interfaceName eq "HTMLFrameSetElement") {
|
| + $getter = "V8Custom::v8NodeEventHandlerAccessorGetter";
|
| + $setter = "V8Custom::v8NodeEventHandlerAccessorSetter";
|
| + } else {
|
| + $getter = "V8Custom::v8${customAccessor}AccessorGetter";
|
| + if ($interfaceName eq "WorkerContext" and $attrName eq "self") {
|
| + $setter = "0";
|
| + $propAttr = "v8::ReadOnly";
|
| + } else {
|
| + $setter = "V8Custom::v8${customAccessor}AccessorSetter";
|
| + }
|
| + }
|
| +
|
| + # Custom Getter and Setter
|
| + } elsif ($attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
|
| + $getter = "V8Custom::v8${customAccessor}AccessorGetter";
|
| + if ($interfaceName eq "WorkerContext" and $attrName eq "self") {
|
| + $setter = "0";
|
| + $propAttr = "v8::ReadOnly";
|
| + } else {
|
| + $hasCustomSetter = 1;
|
| + $setter = "V8Custom::v8${customAccessor}AccessorSetter";
|
| + }
|
| +
|
| + # Custom Setter
|
| + } elsif ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"}) {
|
| + $hasCustomSetter = 1;
|
| + $getter = "${interfaceName}Internal::${attrName}AttrGetter";
|
| + $setter = "V8Custom::v8${customAccessor}AccessorSetter";
|
| +
|
| + # Custom Getter
|
| + } elsif ($attrExt->{"CustomGetter"}) {
|
| + $getter = "V8Custom::v8${customAccessor}AccessorGetter";
|
| + $setter = "${interfaceName}Internal::${attrName}AttrSetter";
|
| +
|
| + # Replaceable
|
| + } elsif ($attrExt->{"Replaceable"}) {
|
| + # Replaceable accessor is put on instance template with ReadOnly attribute.
|
| + $getter = "${interfaceName}Internal::${attrName}AttrGetter";
|
| + $setter = "0";
|
| +
|
| + # Mark to avoid duplicate v8::ReadOnly flags in output.
|
| + $hasCustomSetter = 1;
|
| +
|
| + # Handle the special case of window.top being marked upstream as Replaceable.
|
| + # FIXME: Investigate why [Replaceable] is not marked as ReadOnly
|
| + # upstream and reach parity.
|
| + if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) {
|
| + $propAttr .= "|v8::ReadOnly";
|
| + }
|
| +
|
| + # Normal
|
| + } else {
|
| + $getter = "${interfaceName}Internal::${attrName}AttrGetter";
|
| + $setter = "${interfaceName}Internal::${attrName}AttrSetter";
|
| + }
|
| +
|
| + if ($attrExt->{"Replaceable"} && !$hasCustomSetter) {
|
| + $setter = "0";
|
| + $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, <<END);
|
| + // $commentInfo
|
| + { "$attrName",
|
| + $getter,
|
| + $setter,
|
| + $data,
|
| + $accessControl,
|
| + static_cast<v8::PropertyAttribute>($propAttr),
|
| + $on_proto },
|
| +END
|
| + }
|
| +}
|
| +
|
| +
|
| +sub GenerateImplementation
|
| +{
|
| + my $object = shift;
|
| + my $dataNode = shift;
|
| + my $interfaceName = $dataNode->name;
|
| + my $className = "V8$interfaceName";
|
| + my $implClassName = $interfaceName;
|
| + my $classIndex = uc($codeGenerator->StripModule($interfaceName));
|
| +
|
| + my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
|
| + my $conditional = $dataNode->extendedAttributes->{"Conditional"};
|
| +
|
| + @allParents = $codeGenerator->FindParentsRecursively($dataNode);
|
| +
|
| + # - Add default header template
|
| + @implContentHeader = split("\r", $headerTemplate);
|
| +
|
| + push(@implFixedHeader,
|
| + "#include \"config.h\"\n" .
|
| + "#include \"V8Proxy.h\"\n" .
|
| + "#include \"V8Binding.h\"\n\n" .
|
| + "#undef LOG\n\n");
|
| +
|
| + my $conditionalString;
|
| + if ($conditional) {
|
| + $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
|
| + push(@implFixedHeader, "\n#if ${conditionalString}\n\n");
|
| + }
|
| +
|
| + if ($className =~ /^V8SVGAnimated/) {
|
| + AddIncludesForSVGAnimatedType($interfaceName);
|
| + }
|
| +
|
| + $implIncludes{"${className}.h"} = 1;
|
| +
|
| + AddIncludesForType($interfaceName);
|
| + $implIncludes{"V8Proxy.h"} = 1;
|
| +
|
| + push(@implContentDecls, "namespace WebCore {\n");
|
| + push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n");
|
| + push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n");
|
| +
|
| + my $hasConstructors = 0;
|
| +
|
| + # 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$/) {
|
| + $hasConstructors = 1;
|
| + next;
|
| + }
|
| +
|
| + # Make EventListeners always custom.
|
| + # FIXME: make the perl code capable of generating the
|
| + # event setters/getters. For now, WebKit has started removing the
|
| + # [Custom] attribute, so just automatically insert it to avoid forking
|
| + # other files. This should be okay because we can't generate stubs
|
| + # for any event getter/setters anyway.
|
| + if ($attrType eq "EventListener") {
|
| + $attribute->signature->extendedAttributes->{"Custom"} = 1;
|
| + $implIncludes{"V8CustomBinding.h"} = 1;
|
| + 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"}) {
|
| + $implIncludes{"V8CustomBinding.h"} = 1;
|
| + next;
|
| + }
|
| +
|
| + # Generate the accessor.
|
| + if ($attribute->signature->extendedAttributes->{"CustomGetter"}) {
|
| + $implIncludes{"V8CustomBinding.h"} = 1;
|
| + } else {
|
| + GenerateNormalAttrGetter($attribute, $dataNode, $classIndex, $implClassName);
|
| + }
|
| + if ($attribute->signature->extendedAttributes->{"CustomSetter"} ||
|
| + $attribute->signature->extendedAttributes->{"V8CustomSetter"}) {
|
| + $implIncludes{"V8CustomBinding.h"} = 1;
|
| + } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
|
| + $dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"} || die "Replaceable attribute can only be used in interface that defines ExtendsDOMGlobalObject attribute!";
|
| + # GenerateReplaceableAttrSetter($implClassName);
|
| + } elsif ($attribute->type !~ /^readonly/ && !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
|
| + GenerateNormalAttrSetter($attribute, $dataNode, $classIndex, $implClassName);
|
| + }
|
| + }
|
| +
|
| + if ($hasConstructors) {
|
| + GenerateConstructorGetter($implClassName, $classIndex);
|
| + }
|
| +
|
| + # Generate methods for functions.
|
| + foreach my $function (@{$dataNode->functions}) {
|
| + # hack for addEventListener/RemoveEventListener
|
| + # FIXME: avoid naming conflict
|
| + if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"}) {
|
| + $implIncludes{"V8CustomBinding.h"} = 1;
|
| + } else {
|
| + GenerateFunctionCallback($function, $dataNode, $classIndex, $implClassName);
|
| + }
|
| +
|
| + # 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, $dataNode, $classIndex, $implClassName);
|
| + }
|
| + }
|
| +
|
| + # Attributes
|
| + my $attributes = $dataNode->attributes;
|
| +
|
| + # For the DOMWindow interface we partition the attributes into the
|
| + # ones that disallows shadowing and the rest.
|
| + my @disallows_shadowing;
|
| + my @normal;
|
| + if ($interfaceName eq "DOMWindow") {
|
| + foreach my $attribute (@$attributes) {
|
| + if ($attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) {
|
| + push(@disallows_shadowing, $attribute);
|
| + } else {
|
| + push(@normal, $attribute);
|
| + }
|
| + }
|
| + # Put the attributes that disallow shadowing on the shadow object.
|
| + $attributes = \@normal;
|
| + push(@implContent, "static const BatchedAttribute shadow_attrs[] = {\n");
|
| + GenerateBatchedAttributeData($interfaceName, \@disallows_shadowing);
|
| + push(@implContent, "};\n");
|
| + }
|
| +
|
| + my $has_attributes = 0;
|
| + if (@$attributes) {
|
| + $has_attributes = 1;
|
| + push(@implContent, "static const BatchedAttribute ${interfaceName}_attrs[] = {\n");
|
| + GenerateBatchedAttributeData($interfaceName, $attributes);
|
| + push(@implContent, "};\n");
|
| + }
|
| +
|
| + # 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(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n");
|
| +
|
| + my $access_check = "/* no access check */";
|
| + if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !($interfaceName eq "DOMWindow")) {
|
| + $access_check = "instance->SetAccessCheckCallbacks(V8Custom::v8${interfaceName}NamedSecurityCheck, V8Custom::v8${interfaceName}IndexedSecurityCheck, v8::Integer::New(V8ClassIndex::ToInt(V8ClassIndex::${classIndex})));";
|
| + }
|
| +
|
| + # For the DOMWindow interface, generate the shadow object template
|
| + # configuration method.
|
| + if ($implClassName eq "DOMWindow") {
|
| + push(@implContent, <<END);
|
| +static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ) {
|
| + batchConfigureAttributes(templ,
|
| + v8::Handle<v8::ObjectTemplate>(),
|
| + shadow_attrs,
|
| + sizeof(shadow_attrs)/sizeof(*shadow_attrs));
|
| + return templ;
|
| +}
|
| +END
|
| + }
|
| +
|
| + # Generate the template configuration method
|
| + push(@implContent, <<END);
|
| +static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) {
|
| + v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
|
| +END
|
| + if (IsNodeSubType($dataNode)) {
|
| + push(@implContent, <<END);
|
| + instance->SetInternalFieldCount(V8Custom::kNodeMinimumInternalFieldCount);
|
| +END
|
| + } else {
|
| + push(@implContent, <<END);
|
| + instance->SetInternalFieldCount(V8Custom::kDefaultWrapperInternalFieldCount);
|
| +END
|
| + }
|
| +
|
| + push(@implContent, <<END);
|
| + v8::Local<v8::Signature> default_signature = v8::Signature::New(desc);
|
| + v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
|
| + $access_check
|
| +END
|
| +
|
| +
|
| + # Set up our attributes if we have them
|
| + if ($has_attributes) {
|
| + push(@implContent, <<END);
|
| + batchConfigureAttributes(instance, proto, ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs));
|
| +END
|
| + }
|
| +
|
| + # Define our functions with Set() or SetAccessor()
|
| + foreach my $function (@{$dataNode->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->{"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
|
| + $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
|
| + next;
|
| + }
|
| +
|
| + my $signature = "default_signature";
|
| + if ($attrExt->{"V8DoNotCheckSignature"}){
|
| + $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 $templateFunction = GenerateNewFunctionTemplate($function, $dataNode, $signature);
|
| +
|
| +
|
| + push(@implContent, <<END);
|
| +
|
| + // $commentInfo
|
| + ${template}->Set(
|
| + v8::String::New("$name"),
|
| + $templateFunction,
|
| + static_cast<v8::PropertyAttribute>($property_attributes));
|
| +END
|
| + }
|
| +
|
| + # set the super descriptor
|
| + foreach (@{$dataNode->parents}) {
|
| + my $parent = $codeGenerator->StripModule($_);
|
| + if ($parent eq "EventTarget") { next; }
|
| + $implIncludes{"V8${parent}.h"} = 1;
|
| + my $parentClassIndex = uc($codeGenerator->StripModule($parent));
|
| + push(@implContent, " desc->Inherit(V8DOMWrapper::getTemplate(V8ClassIndex::${parentClassIndex}));\n");
|
| + last;
|
| + }
|
| +
|
| + # Set the class name. This is used when printing objects.
|
| + push(@implContent, " desc->SetClassName(v8::String::New(\"" . GetClassName(${interfaceName}) . "\"));\n");
|
| +
|
| + if ($has_constants) {
|
| + push(@implContent, <<END);
|
| + batchConfigureConstants(desc, proto, ${interfaceName}_consts, sizeof(${interfaceName}_consts)/sizeof(*${interfaceName}_consts));
|
| +END
|
| + }
|
| +
|
| + push(@implContent, <<END);
|
| + return desc;
|
| +}
|
| +
|
| +v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() {
|
| + static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_;
|
| + if (${className}_raw_cache_.IsEmpty()) {
|
| + v8::HandleScope scope;
|
| + v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(V8Proxy::checkNewLegal);
|
| + ${className}_raw_cache_ = v8::Persistent<v8::FunctionTemplate>::New(result);
|
| + }
|
| + return ${className}_raw_cache_;
|
| +}
|
| +
|
| +v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() {
|
| + static v8::Persistent<v8::FunctionTemplate> ${className}_cache_;
|
| + if (${className}_cache_.IsEmpty())
|
| + ${className}_cache_ = Configure${className}Template(GetRawTemplate());
|
| + return ${className}_cache_;
|
| +}
|
| +
|
| +bool ${className}::HasInstance(v8::Handle<v8::Value> value) {
|
| + return GetRawTemplate()->HasInstance(value);
|
| +}
|
| +
|
| +END
|
| +
|
| + if ($implClassName eq "DOMWindow") {
|
| + push(@implContent, <<END);
|
| +v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate() {
|
| + static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_;
|
| + if (V8DOMWindowShadowObject_cache_.IsEmpty()) {
|
| + V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
|
| + ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_);
|
| + }
|
| + return V8DOMWindowShadowObject_cache_;
|
| +}
|
| +END
|
| + }
|
| +
|
| + push(@implContent, <<END);
|
| +} // namespace WebCore
|
| +END
|
| +
|
| + push(@implContent, "\n#endif // ${conditionalString}\n") if $conditional;
|
| +}
|
| +
|
| +
|
| +sub GenerateFunctionCallString()
|
| +{
|
| + my $function = shift;
|
| + my $numberOfParameters = shift;
|
| + my $indent = shift;
|
| + my $implClassName = shift;
|
| +
|
| + my $name = $function->signature->name;
|
| + my $isPodType = IsPodType($implClassName);
|
| + my $returnType = $codeGenerator->StripModule($function->signature->type);
|
| + my $returnsPodType = IsPodType($returnType);
|
| + my $nativeReturnType = GetNativeType($returnType, 0);
|
| + my $result = "";
|
| +
|
| + # Special case: SVG matrix transform methods should not mutate
|
| + # the matrix but return a copy
|
| + my $copyFirst = 0;
|
| + if ($implClassName eq "SVGMatrix" && $function->signature->type eq "SVGMatrix") {
|
| + $copyFirst = 1;
|
| + }
|
| +
|
| + 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 ($copyFirst) {
|
| + $functionString = "result.${name}(";
|
| + }
|
| +
|
| + my $returnsListItemPodType = 0;
|
| + # SVG lists functions that return POD types require special handling
|
| + if (IsSVGListTypeNeedingSpecialHandling($implClassName) && IsSVGListMethod($name) && $returnsPodType) {
|
| + $returnsListItemPodType = 1;
|
| + $result .= $indent . "SVGList<RefPtr<SVGPODListItem<$nativeReturnType> > >* listImp = imp;\n";
|
| + $functionString = "listImp->${name}(";
|
| + }
|
| +
|
| + my $first = 1;
|
| + my $index = 0;
|
| + my $nodeToReturn = 0;
|
| +
|
| + foreach my $parameter (@{$function->parameters}) {
|
| + if ($index eq $numberOfParameters) {
|
| + last;
|
| + }
|
| + if ($first) { $first = 0; }
|
| + else { $functionString .= ", "; }
|
| + my $paramName = $parameter->name;
|
| + my $paramType = $parameter->type;
|
| +
|
| + # This is a bit of a hack... we need to convert parameters to methods on SVG lists
|
| + # of POD types which are items in the list to appropriate SVGList<> instances
|
| + if ($returnsListItemPodType && $paramType . "List" eq $implClassName) {
|
| + $paramName = "SVGPODListItem<" . GetNativeType($paramType, 1) . ">::copy($paramName)";
|
| + }
|
| +
|
| + if ($parameter->type eq "NodeFilter") {
|
| + $functionString .= "$paramName.get()";
|
| + } else {
|
| + $functionString .= $paramName;
|
| + }
|
| +
|
| + if ($parameter->extendedAttributes->{"Return"}) {
|
| + $nodeToReturn = $parameter->name;
|
| + }
|
| + $index++;
|
| + }
|
| +
|
| + if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
|
| + $functionString .= ", " if not $first;
|
| + $functionString .= "&callStack";
|
| + if ($first) { $first = 0; }
|
| + }
|
| +
|
| + if (@{$function->raisesExceptions}) {
|
| + $functionString .= ", " if not $first;
|
| + $functionString .= "ec";
|
| + }
|
| + $functionString .= ")";
|
| +
|
| + if ((IsRefPtrType($returnType) || $returnsListItemPodType) && !$nodeToReturn) {
|
| + # We don't use getPtr when $nodeToReturn because that situation is
|
| + # special-cased below to return a bool.
|
| + $implIncludes{"wtf/GetPtr.h"} = 1;
|
| + $functionString = "WTF::getPtr(" . $functionString . ")";
|
| + }
|
| +
|
| + if ($nodeToReturn) {
|
| + # Special case for insertBefore, replaceChild, removeChild and
|
| + # appendChild functions from Node.
|
| + $result .= $indent . "bool success = $functionString;\n";
|
| + if (@{$function->raisesExceptions}) {
|
| + $result .= GenerateSetDOMException($indent);
|
| + }
|
| + $result .= $indent . "if (success)\n";
|
| + $result .= $indent . " " .
|
| + "return V8DOMWrapper::convertNodeToV8Object($nodeToReturn);\n";
|
| + $result .= $indent . "return v8::Null();\n";
|
| + return $result;
|
| + } elsif ($returnType eq "void") {
|
| + $result .= $indent . "$functionString;\n";
|
| + } elsif ($copyFirst) {
|
| + $result .=
|
| + $indent . GetNativeType($returnType, 0) . " result = *imp;\n" .
|
| + $indent . "$functionString;\n";
|
| + } elsif ($returnsListItemPodType) {
|
| + $result .= $indent . "RefPtr<SVGPODListItem<$nativeReturnType> > result = $functionString;\n";
|
| + } else {
|
| + $result .= $indent . $nativeReturnType . " result = $functionString;\n";
|
| + }
|
| +
|
| + if (@{$function->raisesExceptions}) {
|
| + $result .= GenerateSetDOMException($indent);
|
| + }
|
| +
|
| + my $return = "result";
|
| + if (IsRefPtrType($returnType) || $returnsListItemPodType) {
|
| + $implIncludes{"wtf/GetPtr.h"} = 1;
|
| + $return = "WTF::getPtr(" . $return . ")";
|
| + }
|
| +
|
| + # If the return type is a POD type, separate out the wrapper generation
|
| + if ($returnsListItemPodType) {
|
| + $result .= $indent . "V8SVGPODTypeWrapper<" . $nativeReturnType . ">* wrapper = new ";
|
| + $result .= "V8SVGPODTypeWrapperCreatorForList<" . $nativeReturnType . ">($return, imp->associatedAttributeName());\n";
|
| + $return = "wrapper";
|
| + } elsif ($returnsPodType) {
|
| + $result .= $indent . "V8SVGPODTypeWrapper<" . $nativeReturnType . ">* wrapper = ";
|
| + $result .= GenerateSVGStaticPodTypeWrapper($returnType, $return) . ";\n";
|
| + $return = "wrapper";
|
| + }
|
| +
|
| + my $generatedSVGContextRetrieval = 0;
|
| + # If the return type needs an SVG context, output it
|
| + if (IsSVGTypeNeedingContextParameter($returnType)) {
|
| + $result .= GenerateSVGContextAssignment($implClassName, $return, $indent);
|
| + $generatedSVGContextRetrieval = 1;
|
| + }
|
| +
|
| + if (IsSVGTypeNeedingContextParameter($implClassName) && $implClassName =~ /List$/ && IsSVGListMutator($name)) {
|
| + if (!$generatedSVGContextRetrieval) {
|
| + $result .= GenerateSVGContextRetrieval($implClassName, $indent);
|
| + $generatedSVGContextRetrieval = 1;
|
| + }
|
| +
|
| + $result .= $indent . "context->svgAttributeChanged(imp->associatedAttributeName());\n";
|
| + $implIncludes{"SVGElement.h"} = 1;
|
| + }
|
| +
|
| + # If the implementing class is a POD type, commit changes
|
| + if ($isPodType) {
|
| + if (!$generatedSVGContextRetrieval) {
|
| + $result .= GenerateSVGContextRetrieval($implClassName, $indent);
|
| + $generatedSVGContextRetrieval = 1;
|
| + }
|
| +
|
| + $result .= $indent . "imp_wrapper->commitChange(imp_instance, context);\n";
|
| + }
|
| +
|
| + if ($returnsPodType) {
|
| + my $classIndex = uc($returnType);
|
| + $result .= $indent . "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper);\n";
|
| + } else {
|
| + $result .= $indent . ReturnNativeToJSValue($function->signature, $return, $indent) . ";\n";
|
| + }
|
| +
|
| + return $result;
|
| +}
|
| +
|
| +
|
| +# Get the class name used for printing javascript DOM-object wrappers.
|
| +sub GetClassName
|
| +{
|
| + my $type = shift;
|
| + return "HTMLCollection" if $type eq "HTMLAllCollection";
|
| + return $type;
|
| +}
|
| +
|
| +
|
| +sub GetNativeTypeFromSignature
|
| +{
|
| + my $signature = shift;
|
| + my $isParameter = shift;
|
| +
|
| + my $type = $codeGenerator->StripModule($signature->type);
|
| +
|
| + return GetNativeType($type, $isParameter);
|
| +}
|
| +
|
| +sub IsRefPtrType
|
| +{
|
| + my $type = shift;
|
| + return 1 if $type eq "Attr";
|
| + return 1 if $type eq "CanvasGradient";
|
| + return 1 if $type eq "ClientRect";
|
| + return 1 if $type eq "ClientRectList";
|
| + return 1 if $type eq "CDATASection";
|
| + return 1 if $type eq "Comment";
|
| + return 1 if $type eq "CSSRule";
|
| + return 1 if $type eq "CSSStyleRule";
|
| + return 1 if $type eq "CSSCharsetRule";
|
| + return 1 if $type eq "CSSImportRule";
|
| + return 1 if $type eq "CSSMediaRule";
|
| + return 1 if $type eq "CSSFontFaceRule";
|
| + return 1 if $type eq "CSSPageRule";
|
| + return 1 if $type eq "CSSPrimitiveValue";
|
| + return 1 if $type eq "CSSStyleSheet";
|
| + return 1 if $type eq "CSSStyleDeclaration";
|
| + return 1 if $type eq "CSSValue";
|
| + return 1 if $type eq "CSSRuleList";
|
| + return 1 if $type eq "Database";
|
| + 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 "Event";
|
| + return 1 if $type eq "FileList";
|
| + return 1 if $type eq "HTMLCollection";
|
| + return 1 if $type eq "HTMLDocument";
|
| + return 1 if $type eq "HTMLElement";
|
| + return 1 if $type eq "HTMLOptionsCollection";
|
| + return 1 if $type eq "ImageData";
|
| + return 1 if $type eq "MediaError";
|
| + return 1 if $type eq "MimeType";
|
| + return 1 if $type eq "Node";
|
| + return 1 if $type eq "NodeList";
|
| + return 1 if $type eq "NodeFilter";
|
| + return 1 if $type eq "NodeIterator";
|
| + return 1 if $type eq "NSResolver";
|
| + return 1 if $type eq "Plugin";
|
| + return 1 if $type eq "ProcessingInstruction";
|
| + return 1 if $type eq "Range";
|
| + return 1 if $type eq "Text";
|
| + return 1 if $type eq "TextMetrics";
|
| + return 1 if $type eq "TimeRanges";
|
| + return 1 if $type eq "TreeWalker";
|
| + return 1 if $type eq "WebKitCSSMatrix";
|
| + return 1 if $type eq "WebKitPoint";
|
| + return 1 if $type eq "XPathExpression";
|
| + return 1 if $type eq "XPathNSResolver";
|
| + return 1 if $type eq "XPathResult";
|
| +
|
| + return 1 if $type eq "SVGAngle";
|
| + return 1 if $type eq "SVGElementInstance";
|
| + return 1 if $type eq "SVGElementInstanceList";
|
| + return 1 if $type =~ /^SVGPathSeg/;
|
| +
|
| + return 1 if $type =~ /^SVGAnimated/;
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +sub IsVideoClassName
|
| +{
|
| + my $class = shift;
|
| + return 1 if $class eq "V8HTMLAudioElement";
|
| + return 1 if $class eq "V8HTMLMediaElement";
|
| + return 1 if $class eq "V8HTMLSourceElement";
|
| + return 1 if $class eq "V8HTMLVideoElement";
|
| + return 1 if $class eq "V8MediaError";
|
| + return 1 if $class eq "V8TimeRanges";
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +sub IsWorkerClassName
|
| +{
|
| + my $class = shift;
|
| + return 1 if $class eq "V8Worker";
|
| + return 1 if $class eq "V8WorkerContext";
|
| + return 1 if $class eq "V8WorkerLocation";
|
| + return 1 if $class eq "V8WorkerNavigator";
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +sub GetNativeType
|
| +{
|
| + my $type = shift;
|
| + my $isParameter = shift;
|
| +
|
| + if ($type eq "float" or $type eq "AtomicString" or $type eq "double") {
|
| + return $type;
|
| + }
|
| +
|
| + return "int" if $type eq "int";
|
| + return "int" if $type eq "short" or $type eq "unsigned short";
|
| + return "int" if $type eq "long" or $type eq "unsigned 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 "FloatRect" if $type eq "SVGRect";
|
| + return "FloatPoint" if $type eq "SVGPoint";
|
| + return "TransformationMatrix" if $type eq "SVGMatrix";
|
| + return "SVGTransform" if $type eq "SVGTransform";
|
| + return "SVGLength" if $type eq "SVGLength";
|
| + return "double" if $type eq "SVGNumber";
|
| + return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType";
|
| + return "DOMTimeStamp" if $type eq "DOMTimeStamp";
|
| + return "unsigned" if $type eq "unsigned int";
|
| + return "unsigned" if $type eq "RGBColor";
|
| + return "Node*" if $type eq "EventTarget" and $isParameter;
|
| +
|
| + return "String" if $type eq "DOMUserData"; # FIXME: Temporary hack?
|
| +
|
| + # temporary hack
|
| + return "RefPtr<NodeFilter>" if $type eq "NodeFilter";
|
| +
|
| + return "RefPtr<${type}>" if IsRefPtrType($type) and not $isParameter;
|
| +
|
| + # Default, assume native type is a pointer with same type name as idl type
|
| + return "${type}*";
|
| +}
|
| +
|
| +
|
| +my %typeCanFailConversion = (
|
| + "AtomicString" => 0,
|
| + "Attr" => 1,
|
| + "CompareHow" => 0,
|
| + "DataGridColumn" => 0,
|
| + "DOMString" => 0,
|
| + "DOMWindow" => 0,
|
| + "DocumentType" => 0,
|
| + "Element" => 0,
|
| + "Event" => 0,
|
| + "EventListener" => 0,
|
| + "EventTarget" => 0,
|
| + "HTMLElement" => 0,
|
| + "HTMLOptionElement" => 0,
|
| + "Node" => 0,
|
| + "NodeFilter" => 0,
|
| + "MessagePort" => 0,
|
| + "NSResolver" => 0,
|
| + "Range" => 0,
|
| + "SQLResultSet" => 0,
|
| + "Storage" => 0,
|
| + "SVGAngle" => 0,
|
| + "SVGElement" => 0,
|
| + "SVGLength" => 1,
|
| + "SVGMatrix" => 1,
|
| + "SVGNumber" => 0,
|
| + "SVGPaintType" => 0,
|
| + "SVGPathSeg" => 0,
|
| + "SVGPoint" => 1,
|
| + "SVGRect" => 1,
|
| + "SVGTransform" => 1,
|
| + "VoidCallback" => 1,
|
| + "WebKitCSSMatrix" => 0,
|
| + "WebKitPoint" => 0,
|
| + "XPathEvaluator" => 0,
|
| + "XPathNSResolver" => 0,
|
| + "XPathResult" => 0,
|
| + "boolean" => 0,
|
| + "double" => 0,
|
| + "float" => 0,
|
| + "long" => 0,
|
| + "unsigned long" => 0,
|
| + "unsigned short" => 0,
|
| +);
|
| +
|
| +
|
| +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 BasicTypeCanFailConversion
|
| +{
|
| + my $signature = shift;
|
| + my $type = $codeGenerator->StripModule($signature->type);
|
| +
|
| + return 1 if $type eq "SVGLength";
|
| + return 1 if $type eq "SVGMatrix";
|
| + return 1 if $type eq "SVGPoint";
|
| + return 1 if $type eq "SVGRect";
|
| + return 1 if $type eq "SVGTransform";
|
| + return 0;
|
| +}
|
| +
|
| +sub TypeCanFailConversion
|
| +{
|
| + my $signature = shift;
|
| +
|
| + my $type = $codeGenerator->StripModule($signature->type);
|
| +
|
| + $implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr";
|
| +
|
| + return $typeCanFailConversion{$type} if exists $typeCanFailConversion{$type};
|
| +
|
| + die "Don't know whether a JS value can fail conversion to type $type.";
|
| +}
|
| +
|
| +sub JSValueToNative
|
| +{
|
| + my $signature = shift;
|
| + my $value = shift;
|
| + my $okParam = shift;
|
| + my $maybeOkParam = $okParam ? ", ${okParam}" : "";
|
| +
|
| + my $type = $codeGenerator->StripModule($signature->type);
|
| +
|
| + 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 "$value->NumberValue()" if $type eq "SVGNumber";
|
| +
|
| + return "toInt32($value${maybeOkParam})" if $type eq "unsigned long" or $type eq "unsigned short" or $type eq "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 "toWebCoreString($value)" if $type eq "AtomicString" or $type eq "DOMUserData";
|
| + if ($type eq "DOMString") {
|
| + return "toWebCoreStringWithNullCheck($value)" if $signature->extendedAttributes->{"ConvertNullToNullString"};
|
| + return "toWebCoreStringWithNullOrUndefinedCheck($value)" if $signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"};
|
| + return "toWebCoreString($value)";
|
| + }
|
| +
|
| + if ($type eq "NodeFilter") {
|
| + return "V8DOMWrapper::wrapNativeNodeFilter($value)";
|
| + }
|
| +
|
| + if ($type eq "SVGRect") {
|
| + $implIncludes{"FloatRect.h"} = 1;
|
| + }
|
| +
|
| + if ($type eq "SVGPoint") {
|
| + $implIncludes{"FloatPoint.h"} = 1;
|
| + }
|
| +
|
| + # Default, assume autogenerated type conversion routines
|
| + $implIncludes{"V8Proxy.h"} = 1;
|
| + if ($type eq "EventTarget") {
|
| + $implIncludes{"V8Node.h"} = 1;
|
| +
|
| + # EventTarget is not in DOM hierarchy, but all Nodes are EventTarget.
|
| + return "V8Node::HasInstance($value) ? V8DOMWrapper::convertDOMWrapperToNode<Node>($value) : 0";
|
| + }
|
| +
|
| + AddIncludesForType($type);
|
| + # $implIncludes{"$type.h"} = 1 unless AvoidInclusionOfType($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) ? V8DOMWrapper::convertDOMWrapperToNode<${type}>($value) : 0";
|
| + } else {
|
| + # TODO: Temporary to avoid Window name conflict.
|
| + my $classIndex = uc($type);
|
| + my $implClassName = ${type};
|
| +
|
| + $implIncludes{"V8$type.h"} = 1;
|
| +
|
| + if (IsPodType($type)) {
|
| + my $nativeType = GetNativeType($type);
|
| + $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
|
| +
|
| + return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(V8ClassIndex::${classIndex}, $value${maybeOkParam})"
|
| + }
|
| +
|
| + $implIncludes{"V8${type}.h"} = 1;
|
| +
|
| + # Perform type checks on the parameter, if it is expected Node type,
|
| + # return NULL.
|
| + return "V8${type}::HasInstance($value) ? V8DOMWrapper::convertToNativeObject<${implClassName}>(V8ClassIndex::${classIndex}, v8::Handle<v8::Object>::Cast($value)) : 0";
|
| + }
|
| +}
|
| +
|
| +
|
| +sub GetV8HeaderName
|
| +{
|
| + my $type = shift;
|
| + return "V8" . GetImplementationFileName($type);
|
| +}
|
| +
|
| +
|
| +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)) {
|
| + 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;
|
| + }
|
| +
|
| + foreach my $parameter (@{$function->parameters}) {
|
| + if (IsWrapperType($parameter->type)) {
|
| + return 1;
|
| + }
|
| + }
|
| + return 0;
|
| +}
|
| +
|
| +
|
| +my %non_wrapper_types = (
|
| + 'float' => 1,
|
| + 'AtomicString' => 1,
|
| + 'double' => 1,
|
| + 'short' => 1,
|
| + 'unsigned short' => 1,
|
| + 'long' => 1,
|
| + 'unsigned long' => 1,
|
| + 'boolean' => 1,
|
| + 'DOMString' => 1,
|
| + 'CompareHow' => 1,
|
| + 'SVGRect' => 1,
|
| + 'SVGPoint' => 1,
|
| + 'SVGMatrix' => 1,
|
| + 'SVGTransform' => 1,
|
| + 'SVGLength' => 1,
|
| + 'SVGNumber' => 1,
|
| + 'SVGPaintType' => 1,
|
| + 'DOMTimeStamp' => 1,
|
| + 'JSObject' => 1,
|
| + 'EventTarget' => 1,
|
| + 'NodeFilter' => 1,
|
| + 'EventListener' => 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 = $codeGenerator->StripModule($signature->type);
|
| + my $className= "V8$type";
|
| +
|
| + return "return v8::Date::New(static_cast<double>($value))" if $type eq "DOMTimeStamp";
|
| + return "return $value ? v8::True() : v8::False()" if $type eq "boolean";
|
| + return "return v8::Undefined()" if $type eq "void";
|
| +
|
| + # For all the types where we use 'int' as the representation type,
|
| + # we use Integer::New which has a fast Smi conversion check.
|
| + return "return v8::Integer::New($value)" if GetNativeType($type) eq "int";
|
| +
|
| + return "return v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType";
|
| +
|
| + 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";
|
| + }
|
| + return "return v8String($value)";
|
| + }
|
| +
|
| + # V8 specific.
|
| + my $implClassName = $type;
|
| + AddIncludesForType($type);
|
| + # $implIncludes{GetImplementationFileName($type)} = 1 unless AvoidInclusionOfType($type);
|
| +
|
| + # special case for non-DOM node interfaces
|
| + if (IsDOMNodeType($type)) {
|
| + return "return V8DOMWrapper::convertNodeToV8Object($value)";
|
| + }
|
| +
|
| + if ($type eq "EventTarget" or $type eq "SVGElementInstance") {
|
| + return "return V8DOMWrapper::convertEventTargetToV8Object($value)";
|
| + }
|
| +
|
| + if ($type eq "Event") {
|
| + return "return V8DOMWrapper::convertEventToV8Object($value)";
|
| + }
|
| +
|
| + if ($type eq "EventListener") {
|
| + return "return V8DOMWrapper::convertEventListenerToV8Object($value)";
|
| + }
|
| +
|
| + if ($type eq "RGBColor") {
|
| my $construct = "RefPtr<RGBColor> rgbcolor = RGBColor::create($value);\n";
|
| my $convert = "V8DOMWrapper::convertToV8Object(V8ClassIndex::RGBCOLOR, WTF::getPtr(rgbcolor))";
|
| - return $construct . $indent . "return " . $convert;
|
| - }
|
| -
|
| - if ($type eq "WorkerContext" or $type eq "WorkerLocation" or $type eq "WorkerNavigator") {
|
| - $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
|
| - my $classIndex = uc($type);
|
| -
|
| - return "return WorkerContextExecutionProxy::ToV8Object(V8ClassIndex::$classIndex, $value)";
|
| - }
|
| -
|
| - else {
|
| - $implIncludes{"wtf/RefCounted.h"} = 1;
|
| - $implIncludes{"wtf/RefPtr.h"} = 1;
|
| - my $classIndex = uc($type);
|
| -
|
| - if (IsPodType($type)) {
|
| - $value = GenerateSVGStaticPodTypeWrapper($type, $value);
|
| - }
|
| -
|
| - return "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, $value)";
|
| - }
|
| -}
|
| -
|
| -sub GenerateSVGStaticPodTypeWrapper {
|
| - my $type = shift;
|
| - my $value = shift;
|
| -
|
| - $implIncludes{"V8$type.h"}=1;
|
| - $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
|
| -
|
| - my $nativeType = GetNativeType($type);
|
| - return "new V8SVGStaticPODTypeWrapper<$nativeType>($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//;
|
| -
|
| - 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 IsSVGTypeNeedingContextParameter
|
| -{
|
| - my $implClassName = shift;
|
| -
|
| - if ($implClassName =~ /SVG/ and not $implClassName =~ /Element/) {
|
| - return 1 unless $implClassName =~ /SVGPaint/ or $implClassName =~ /SVGColor/ or $implClassName =~ /SVGDocument/;
|
| - }
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -sub GenerateSVGContextAssignment
|
| -{
|
| - my $srcType = shift;
|
| - my $value = shift;
|
| - my $indent = shift;
|
| -
|
| - $result = GenerateSVGContextRetrieval($srcType, $indent);
|
| - $result .= $indent . "V8Proxy::setSVGContext($value, context);\n";
|
| -
|
| - return $result;
|
| -}
|
| -
|
| -sub GenerateSVGContextRetrieval
|
| -{
|
| - my $srcType = shift;
|
| - my $indent = shift;
|
| -
|
| - my $srcIsPodType = IsPodType($srcType);
|
| -
|
| - my $srcObject = "imp";
|
| - if ($srcIsPodType) {
|
| - $srcObject = "imp_wrapper";
|
| - }
|
| -
|
| - my $contextDecl;
|
| -
|
| - if (IsSVGTypeNeedingContextParameter($srcType)) {
|
| - $contextDecl = "V8Proxy::svgContext($srcObject)";
|
| - } else {
|
| - $contextDecl = $srcObject;
|
| - }
|
| -
|
| - return $indent . "SVGElement* context = $contextDecl;\n";
|
| -}
|
| -
|
| -sub IsSVGListMutator
|
| -{
|
| - my $functionName = shift;
|
| -
|
| - return 1 if $functionName eq "clear";
|
| - return 1 if $functionName eq "initialize";
|
| - return 1 if $functionName eq "insertItemBefore";
|
| - return 1 if $functionName eq "replaceItem";
|
| - return 1 if $functionName eq "removeItem";
|
| - return 1 if $functionName eq "appendItem";
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -sub IsSVGListMethod
|
| -{
|
| - my $functionName = shift;
|
| -
|
| - return 1 if $functionName eq "getFirst";
|
| - return 1 if $functionName eq "getLast";
|
| - return 1 if $functionName eq "getItem";
|
| -
|
| - return IsSVGListMutator($functionName);
|
| -}
|
| -
|
| -sub IsSVGListTypeNeedingSpecialHandling
|
| -{
|
| - my $className = shift;
|
| -
|
| - return 1 if $className eq "SVGPointList";
|
| - return 1 if $className eq "SVGTransformList";
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -sub DebugPrint
|
| -{
|
| - my $output = shift;
|
| -
|
| - print $output;
|
| - print "\n";
|
| -}
|
| + return $construct . $indent . "return " . $convert;
|
| + }
|
| +
|
| + if ($type eq "WorkerContext" or $type eq "WorkerLocation" or $type eq "WorkerNavigator") {
|
| + $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
|
| + my $classIndex = uc($type);
|
| +
|
| + return "return WorkerContextExecutionProxy::ToV8Object(V8ClassIndex::$classIndex, $value)";
|
| + }
|
| +
|
| + else {
|
| + $implIncludes{"wtf/RefCounted.h"} = 1;
|
| + $implIncludes{"wtf/RefPtr.h"} = 1;
|
| + my $classIndex = uc($type);
|
| +
|
| + if (IsPodType($type)) {
|
| + $value = GenerateSVGStaticPodTypeWrapper($type, $value);
|
| + }
|
| +
|
| + return "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, $value)";
|
| + }
|
| +}
|
| +
|
| +sub GenerateSVGStaticPodTypeWrapper {
|
| + my $type = shift;
|
| + my $value = shift;
|
| +
|
| + $implIncludes{"V8$type.h"}=1;
|
| + $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
|
| +
|
| + my $nativeType = GetNativeType($type);
|
| + return "new V8SVGStaticPODTypeWrapper<$nativeType>($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//;
|
| +
|
| + 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 IsSVGTypeNeedingContextParameter
|
| +{
|
| + my $implClassName = shift;
|
| +
|
| + if ($implClassName =~ /SVG/ and not $implClassName =~ /Element/) {
|
| + return 1 unless $implClassName =~ /SVGPaint/ or $implClassName =~ /SVGColor/ or $implClassName =~ /SVGDocument/;
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +sub GenerateSVGContextAssignment
|
| +{
|
| + my $srcType = shift;
|
| + my $value = shift;
|
| + my $indent = shift;
|
| +
|
| + $result = GenerateSVGContextRetrieval($srcType, $indent);
|
| + $result .= $indent . "V8Proxy::setSVGContext($value, context);\n";
|
| +
|
| + return $result;
|
| +}
|
| +
|
| +sub GenerateSVGContextRetrieval
|
| +{
|
| + my $srcType = shift;
|
| + my $indent = shift;
|
| +
|
| + my $srcIsPodType = IsPodType($srcType);
|
| +
|
| + my $srcObject = "imp";
|
| + if ($srcIsPodType) {
|
| + $srcObject = "imp_wrapper";
|
| + }
|
| +
|
| + my $contextDecl;
|
| +
|
| + if (IsSVGTypeNeedingContextParameter($srcType)) {
|
| + $contextDecl = "V8Proxy::svgContext($srcObject)";
|
| + } else {
|
| + $contextDecl = $srcObject;
|
| + }
|
| +
|
| + return $indent . "SVGElement* context = $contextDecl;\n";
|
| +}
|
| +
|
| +sub IsSVGListMutator
|
| +{
|
| + my $functionName = shift;
|
| +
|
| + return 1 if $functionName eq "clear";
|
| + return 1 if $functionName eq "initialize";
|
| + return 1 if $functionName eq "insertItemBefore";
|
| + return 1 if $functionName eq "replaceItem";
|
| + return 1 if $functionName eq "removeItem";
|
| + return 1 if $functionName eq "appendItem";
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +sub IsSVGListMethod
|
| +{
|
| + my $functionName = shift;
|
| +
|
| + return 1 if $functionName eq "getFirst";
|
| + return 1 if $functionName eq "getLast";
|
| + return 1 if $functionName eq "getItem";
|
| +
|
| + return IsSVGListMutator($functionName);
|
| +}
|
| +
|
| +sub IsSVGListTypeNeedingSpecialHandling
|
| +{
|
| + my $className = shift;
|
| +
|
| + return 1 if $className eq "SVGPointList";
|
| + return 1 if $className eq "SVGTransformList";
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +sub DebugPrint
|
| +{
|
| + my $output = shift;
|
| +
|
| + print $output;
|
| + print "\n";
|
| +}
|
|
|