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"; |
+} |