2 # Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
3 # Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
4 # Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
5 # Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
6 # Copyright (C) 2006 Apple Computer, Inc.
7 # Copyright (C) 2007, 2008, 2009 Google Inc.
8 # Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
10 # This library is free software; you can redistribute it and/or
11 # modify it under the terms of the GNU Library General Public
12 # License as published by the Free Software Foundation; either
13 # version 2 of the License, or (at your option) any later version.
15 # This library is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 # Library General Public License for more details.
20 # You should have received a copy of the GNU Library General Public License
21 # aint with this library; see the file COPYING.LIB. If not, write to
22 # the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 # Boston, MA 02111-1307, USA.
26 package CodeGeneratorV8;
34 my @headerContent = ();
35 my @implContentHeader = ();
36 my @implFixedHeader = ();
38 my @implContentDecls = ();
39 my %implIncludes = ();
44 my $headerTemplate = << "EOF";
46 This file is part of the WebKit open source project.
47 This file has been generated by generate-bindings.pl. DO NOT MODIFY!
49 This library is free software; you can redistribute it and/or
50 modify it under the terms of the GNU Library General Public
51 License as published by the Free Software Foundation; either
52 version 2 of the License, or (at your option) any later version.
54 This library is distributed in the hope that it will be useful,
55 but WITHOUT ANY WARRANTY; without even the implied warranty of
56 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
57 Library General Public License for more details.
59 You should have received a copy of the GNU Library General Public License
60 along with this library; see the file COPYING.LIB. If not, write to
61 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
62 Boston, MA 02111-1307, USA.
72 $codeGenerator = shift;
75 bless($reference, $object);
88 my ($value, $distance) = @_;
89 return (($value << $distance) & 0xFFFFFFFF);
92 # Workaround for V8 bindings difference where RGBColor is not a POD type.
96 return $codeGenerator->IsPodType($type);
99 # Params: 'domClass' struct
100 sub GenerateInterface
103 my $dataNode = shift;
106 # Start actual generation
107 $object->GenerateHeader($dataNode);
108 $object->GenerateImplementation($dataNode);
110 my $name = $dataNode->name;
112 # Open files for writing
113 my $headerFileName = "$outputDir/V8$name.h";
114 my $implFileName = "$outputDir/V8$name.cpp";
116 open($IMPL, ">$implFileName") || die "Couldn't open file $implFileName";
117 open($HEADER, ">$headerFileName") || die "Couldn't open file $headerFileName";
120 # Params: 'idlDocument' struct
124 my $dataNode = shift;
126 $module = $dataNode->module;
129 sub GetLegacyHeaderIncludes
131 my $legacyParent = shift;
133 die "Don't know what headers to include for module $module";
136 sub AvoidInclusionOfType
140 # Special case: SVGRect.h / SVGPoint.h / SVGNumber.h / SVGMatrix.h do not exist.
141 return 1 if $type eq "SVGRect" or $type eq "SVGPoint" or $type eq "SVGNumber" or $type eq "SVGMatrix";
145 sub UsesManualToJSImplementation
149 return 1 if $type eq "SVGPathSeg";
153 sub AddIncludesForType
155 my $type = $codeGenerator->StripModule(shift);
157 # When we're finished with the one-file-per-class
158 # reorganization, we won't need these special cases.
159 if ($codeGenerator->IsPrimitiveType($type) or AvoidInclusionOfType($type) or $type eq "Date") {
160 } elsif ($type =~ /SVGPathSeg/) {
162 $joinedName =~ s/Abs|Rel//;
163 $implIncludes{"${joinedName}.h"} = 1;
165 # default, include the same named file
166 $implIncludes{GetImplementationFileName(${type})} = 1;
169 # additional includes (things needed to compile the bindings but not the header)
171 if ($type eq "CanvasRenderingContext2D") {
172 $implIncludes{"CanvasGradient.h"} = 1;
173 $implIncludes{"CanvasPattern.h"} = 1;
174 $implIncludes{"CanvasStyle.h"} = 1;
177 if ($type eq "CanvasGradient" or $type eq "XPathNSResolver") {
178 $implIncludes{"PlatformString.h"} = 1;
181 if ($type eq "CSSStyleDeclaration") {
182 $implIncludes{"CSSMutableStyleDeclaration.h"} = 1;
185 if ($type eq "Plugin" or $type eq "PluginArray" or $type eq "MimeTypeArray") {
186 # So we can get String -> AtomicString conversion for namedItem().
187 $implIncludes{"AtomicString.h"} = 1;
191 sub AddIncludesForSVGAnimatedType
194 $type =~ s/SVGAnimated//;
196 if ($type eq "Point" or $type eq "Rect") {
197 $implIncludes{"Float$type.h"} = 1;
198 } elsif ($type eq "String") {
199 $implIncludes{"PlatformString.h"} = 1;
202 $implIncludes{"SVGAnimatedTemplate.h"} = 1;
205 sub AddClassForwardIfNeeded
207 my $implClassName = shift;
209 # SVGAnimatedLength/Number/etc.. are typedefs to SVGAnimtatedTemplate, so don't use class forwards for them!
210 push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName);
213 sub GetImplementationFileName
216 return "Event.h" if $iface eq "DOMTimeStamp";
217 return "NamedAttrMap.h" if $iface eq "NamedNodeMap";
218 return "NameNodeList.h" if $iface eq "NodeList";
219 return "XMLHttpRequest.h" if $iface eq "XMLHttpRequest";
224 # If the node has a [Conditional=XXX] attribute, returns an "ENABLE(XXX)" string for use in an #if.
225 sub GenerateConditionalString
228 my $conditional = $node->extendedAttributes->{"Conditional"};
230 return "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
239 my $dataNode = shift;
241 my $interfaceName = $dataNode->name;
242 my $className = "V8$interfaceName";
243 my $implClassName = $interfaceName;
245 # Copy contents of parent classes except the first parent or if it is
247 $codeGenerator->AddMethodsConstantsAndAttributesFromParentClasses($dataNode, \@allParents, 1);
249 my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
250 my $conditionalString = GenerateConditionalString($dataNode);
252 # - Add default header template
253 @headerContent = split("\r", $headerTemplate);
255 push(@headerContent, "\n#if ${conditionalString}\n\n") if $conditionalString;
256 push(@headerContent, "\n#ifndef $className" . "_H");
257 push(@headerContent, "\n#define $className" . "_H\n\n");
259 # Get correct pass/store types respecting PODType flag
260 my $podType = $dataNode->extendedAttributes->{"PODType"};
261 my $passType = $podType ? "JSSVGPODTypeWrapper<$podType>*" : "$implClassName*";
263 push(@headerContent, "#include \"$podType.h\"\n") if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
265 push(@headerContent, "#include <v8.h>\n");
266 push(@headerContent, "#include <wtf/HashMap.h>\n");
267 push(@headerContent, "#include \"StringHash.h\"\n");
269 push(@headerContent, "\nnamespace WebCore {\n\n");
270 push(@headerContent, "class V8ClassIndex;\n");
271 push(@headerContent, "\nclass $className {\n");
272 push(@headerContent, <<END);
275 static bool HasInstance(v8::Handle<v8::Value> value);
276 static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
279 if ($implClassName eq "DOMWindow") {
280 push(@headerContent, <<END);
281 static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
285 my @enabledAtRuntime;
286 foreach my $function (@{$dataNode->functions}) {
287 my $name = $function->signature->name;
288 my $attrExt = $function->signature->extendedAttributes;
290 push(@headerContent, <<END);
291 static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments&);
293 if ($attrExt->{"EnabledAtRuntime"}) {
294 push(@enabledAtRuntime, $function);
298 foreach my $attribute (@{$dataNode->attributes}) {
299 my $name = $attribute->signature->name;
300 my $attrExt = $attribute->signature->extendedAttributes;
301 if ($attrExt->{"V8CustomGetter"} || $attrExt->{"CustomGetter"}
302 || $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) {
303 push(@headerContent, <<END);
304 static v8::Handle<v8::Value> ${name}AccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
307 if ($attrExt->{"V8CustomSetter"} || $attrExt->{"CustomSetter"}
308 || $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) {
309 push(@headerContent, <<END);
310 static void ${name}AccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
313 if ($attrExt->{"EnabledAtRuntime"}) {
314 push(@enabledAtRuntime, $attribute);
318 GenerateHeaderRuntimeEnablerDeclarations(@enabledAtRuntime);
319 GenerateHeaderCustomCall($dataNode);
321 if ($dataNode->extendedAttributes->{"CheckDomainSecurity"}) {
322 push(@headerContent, <<END);
323 static bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType, v8::Local<v8::Value> data);
324 static bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType, v8::Local<v8::Value> data);
328 push(@headerContent, <<END);
331 static v8::Persistent<v8::FunctionTemplate> GetTemplate();
333 friend class V8ClassIndex;
338 push(@headerContent, "}\n\n");
339 push(@headerContent, "#endif // $className" . "_H\n");
341 push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditionalString;
344 sub GenerateHeaderRuntimeEnablerDeclarations
346 my @enabledAtRuntime = @_;
348 foreach my $runtime_attr (@enabledAtRuntime) {
349 my $enabledAtRuntimeConditionalString = GenerateConditionalString($runtime_attr->signature);
350 my $enabler = $codeGenerator->WK_ucfirst($runtime_attr->signature->name);
351 if ($enabledAtRuntimeConditionalString) {
352 push(@headerContent, "\n#if ${enabledAtRuntimeConditionalString}\n");
354 push(@headerContent, <<END);
355 static bool ${enabler}Enabled();
357 if ($enabledAtRuntimeConditionalString) {
358 push(@headerContent, "#endif\n");
363 sub GenerateHeaderCustomCall
365 my $dataNode = shift;
367 if ($dataNode->extendedAttributes->{"CustomCall"}) {
368 push(@headerContent, " static v8::Handle<v8::Value> callAsFunctionCallback(const v8::Arguments&);\n");
370 if ($dataNode->name eq "Event") {
371 push(@headerContent, " static v8::Handle<v8::Value> dataTransferAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
372 push(@headerContent, " static void valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);\n");
374 if ($dataNode->name eq "Location") {
375 push(@headerContent, " static v8::Handle<v8::Value> assignAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
376 push(@headerContent, " static v8::Handle<v8::Value> reloadAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
377 push(@headerContent, " static v8::Handle<v8::Value> replaceAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
381 sub GenerateSetDOMException
386 $result .= $indent . "if (UNLIKELY(ec)) {\n";
387 $result .= $indent . " V8Proxy::setDOMException(ec);\n";
388 $result .= $indent . " return v8::Handle<v8::Value>();\n";
389 $result .= $indent . "}\n";
396 my $dataNode = shift;
397 return 1 if ($dataNode->name eq "Node");
398 foreach (@allParents) {
399 my $parent = $codeGenerator->StripModule($_);
400 return 1 if $parent eq "Node";
405 sub GetHiddenDependencyIndex
407 my $dataNode = shift;
408 my $attribute = shift;
409 my $name = $dataNode->name;
410 return "V8Custom::kNodeEventListenerCacheIndex" if IsNodeSubType($dataNode);
411 return "V8Custom::kSVGElementInstanceEventListenerCacheIndex" if $name eq "SVGElementInstance";
412 return "V8Custom::kAbstractWorkerRequestCacheIndex" if $name eq "AbstractWorker";
413 return "V8Custom::kWorkerRequestCacheIndex" if $name eq "Worker";
414 return "V8Custom::kDedicatedWorkerContextRequestCacheIndex" if $name eq "DedicatedWorkerContext";
415 return "V8Custom::kWorkerContextRequestCacheIndex" if $name eq "WorkerContext";
416 return "V8Custom::kWorkerContextRequestCacheIndex" if $name eq "SharedWorkerContext";
417 return "V8Custom::kMessagePortRequestCacheIndex" if $name eq "MessagePort";
418 return "V8Custom::kWebSocketCacheIndex" if $name eq "WebSocket";
419 return "V8Custom::kXMLHttpRequestCacheIndex" if $name eq "XMLHttpRequest";
420 return "V8Custom::kXMLHttpRequestCacheIndex" if $name eq "XMLHttpRequestUpload";
421 return "V8Custom::kDOMApplicationCacheCacheIndex" if $name eq "DOMApplicationCache";
422 return "V8Custom::kNotificationRequestCacheIndex" if $name eq "Notification";
423 return "V8Custom::kDOMWindowEventListenerCacheIndex" if $name eq "DOMWindow";
424 die "Unexpected name " . $name . " when generating " . $attribute;
429 my $dataNode = shift;
430 my $implClassName = shift;
431 my $classIndex = shift;
432 my $holder = shift || "holder"; # optional param
434 if (IsNodeSubType($dataNode)) {
435 push(@implContentDecls, <<END);
436 $implClassName* imp = v8DOMWrapperToNode<$implClassName>($holder);
440 push(@implContentDecls, <<END);
441 $implClassName* imp = v8DOMWrapperTo<$implClassName>(V8ClassIndex::$classIndex, $holder);
447 sub GenerateDomainSafeFunctionGetter
449 my $function = shift;
450 my $dataNode = shift;
451 my $classIndex = shift;
452 my $implClassName = shift;
454 my $className = "V8" . $dataNode->name;
455 my $funcName = $function->signature->name;
457 my $signature = "v8::Signature::New(" . $className . "::GetRawTemplate())";
458 if ($function->signature->extendedAttributes->{"V8DoNotCheckSignature"}) {
459 $signature = "v8::Local<v8::Signature>()";
462 my $newTemplateString = GenerateNewFunctionTemplate($function, $dataNode, $signature);
464 $implIncludes{"V8Proxy.h"} = 1;
466 push(@implContentDecls, <<END);
467 static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
468 INC_STATS(\"DOM.$implClassName.$funcName._get\");
469 static v8::Persistent<v8::FunctionTemplate> private_template =
470 v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
471 v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
472 if (holder.IsEmpty()) {
473 // can only reach here by 'object.__proto__.func', and it should passed
474 // domain security check already
476 return private_template->GetFunction();
480 HolderToNative($dataNode, $implClassName, $classIndex);
482 push(@implContentDecls, <<END);
483 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false)) {
484 static v8::Persistent<v8::FunctionTemplate> shared_template =
485 v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
486 return shared_template->GetFunction();
489 return private_template->GetFunction();
496 sub GenerateConstructorGetter
498 my $implClassName = shift;
499 my $classIndex = shift;
501 push(@implContentDecls, <<END);
502 static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
503 INC_STATS(\"DOM.$implClassName.constructors._get\");
504 v8::Handle<v8::Value> data = info.Data();
505 ASSERT(data->IsNumber());
506 V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(data->Int32Value());
509 if ($classIndex eq "DOMWINDOW") {
510 push(@implContentDecls, <<END);
511 DOMWindow* window = v8DOMWrapperTo<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
512 // Get the proxy corresponding to the DOMWindow if possible to
513 // make sure that the constructor function is constructed in the
514 // context of the DOMWindow and not in the context of the caller.
515 return V8DOMWrapper::getConstructor(type, window);
517 } elsif ($classIndex eq "DEDICATEDWORKERCONTEXT" or $classIndex eq "WORKERCONTEXT" or $classIndex eq "SHAREDWORKERCONTEXT") {
518 $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
519 push(@implContentDecls, <<END);
520 WorkerContext* workerContext = v8DOMWrapperTo<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder());
521 return V8DOMWrapper::getConstructor(type, workerContext);
524 push(@implContentDecls, " return v8::Handle<v8::Value>();");
527 push(@implContentDecls, <<END);
534 sub GenerateNormalAttrGetter
536 my $attribute = shift;
537 my $dataNode = shift;
538 my $classIndex = shift;
539 my $implClassName = shift;
540 my $interfaceName = shift;
542 my $attrExt = $attribute->signature->extendedAttributes;
544 my $attrName = $attribute->signature->name;
545 $implIncludes{"V8Proxy.h"} = 1;
547 my $attrType = GetTypeFromSignature($attribute->signature);
548 my $attrIsPodType = IsPodType($attrType);
550 my $nativeType = GetNativeTypeFromSignature($attribute->signature, -1);
551 my $isPodType = IsPodType($implClassName);
556 $implClassName = GetNativeType($implClassName);
557 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
560 # Special case: SVGZoomEvent's attributes are all read-only
561 if ($implClassName eq "SVGZoomEvent") {
566 # Special case: SVGSVGEelement::viewport is read-only
567 if (($implClassName eq "SVGSVGElement") and ($attrName eq "viewport")) {
572 # Special case for SVGColor
573 if (($implClassName eq "SVGColor") and ($attrName eq "rgbColor")) {
577 my $getterStringUsesImp = $implClassName ne "double";
580 push(@implContentDecls, <<END);
581 static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
582 INC_STATS(\"DOM.$implClassName.$attrName._get\");
586 push(@implContentDecls, <<END);
587 V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = v8DOMWrapperTo<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());
588 $implClassName imp_instance = *imp_wrapper;
590 if ($getterStringUsesImp) {
591 push(@implContentDecls, <<END);
592 $implClassName* imp = &imp_instance;
596 } elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) {
597 if ($classIndex eq "DOMWINDOW") {
598 push(@implContentDecls, <<END);
599 v8::Handle<v8::Object> holder = info.Holder();
602 # perform lookup first
603 push(@implContentDecls, <<END);
604 v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
605 if (holder.IsEmpty()) return v8::Handle<v8::Value>();
608 HolderToNative($dataNode, $implClassName, $classIndex, "info");
610 my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
611 if ($getterStringUsesImp && $reflect && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) {
612 # Generate super-compact call for regular attribute getter:
613 my $contentAttributeName = $reflect eq "1" ? $attrName : $reflect;
614 my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
615 $implIncludes{"${namespace}.h"} = 1;
616 push(@implContentDecls, " return getElementStringAttr(info, ${namespace}::${contentAttributeName}Attr);\n");
617 push(@implContentDecls, " }\n\n");
619 # Skip the rest of the function!
622 push(@implContentDecls, <<END);
623 v8::Handle<v8::Object> holder = info.Holder();
625 HolderToNative($dataNode, $implClassName, $classIndex, "info");
628 # Generate security checks if necessary
629 if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
630 push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->$attrName())) return v8::Handle<v8::Value>();\n\n");
631 } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
632 push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->contentDocument())) return v8::Handle<v8::Value>();\n\n");
635 my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType);
636 if ($useExceptions) {
637 $implIncludes{"ExceptionCode.h"} = 1;
638 push(@implContentDecls, " ExceptionCode ec = 0;\n");
641 if ($attribute->signature->extendedAttributes->{"v8referenceattr"}) {
642 $attrName = $attribute->signature->extendedAttributes->{"v8referenceattr"};
645 my $getterFunc = $codeGenerator->WK_lcfirst($attrName);
647 if ($codeGenerator->IsSVGAnimatedType($attribute->signature->type)) {
648 # Some SVGFE*Element.idl use 'operator' as attribute name; rewrite as '_operator' to avoid clashes with C/C++
649 $getterFunc = "_" . $getterFunc if ($attrName =~ /operator/);
650 $getterFunc .= "Animated";
653 my $returnType = GetTypeFromSignature($attribute->signature);
656 if ($getterStringUsesImp) {
657 my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
658 my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
659 if ($reflect || $reflectURL) {
660 my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
661 my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
662 $implIncludes{"${namespace}.h"} = 1;
663 my $getAttributeFunctionName = $reflectURL ? "getURLAttribute" : "getAttribute";
664 $getterString = "imp->$getAttributeFunctionName(${namespace}::${contentAttributeName}Attr";
666 $getterString = "imp->$getterFunc(";
668 $getterString .= "ec" if $useExceptions;
669 $getterString .= ")";
670 if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
671 $getterString .= ".toInt()";
674 $getterString = "imp_instance";
680 if ($attrIsPodType) {
681 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
683 my $getter = $getterString;
684 $getter =~ s/imp->//;
686 my $setter = "set" . $codeGenerator->WK_ucfirst($getter);
688 my $implClassIsAnimatedType = $codeGenerator->IsSVGAnimatedType($implClassName);
689 if (not $implClassIsAnimatedType and $codeGenerator->IsPodTypeWithWriteableProperties($attrType) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
690 if (IsPodType($implClassName)) {
691 my $wrapper = "V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>::create($getterString, imp_wrapper)";
692 push(@implContentDecls, " RefPtr<V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName> > wrapper = $wrapper;\n");
694 my $wrapper = "V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName>::create(imp, &${implClassName}::$getter, &${implClassName}::$setter)";
695 push(@implContentDecls, " RefPtr<V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName> > wrapper = $wrapper;\n");
698 if ($implClassIsAnimatedType) {
699 # We can't hash member function pointers, so instead generate
700 # some hashing material based on the names of the methods.
701 my $hashhex = substr(Digest::MD5::md5_hex("${implClassName}::$getter ${implClassName}::$setter)"), 0, 8);
702 my $wrapper = "V8SVGDynamicPODTypeWrapperCache<$nativeType, $implClassName>::lookupOrCreateWrapper(imp, &${implClassName}::$getter, &${implClassName}::$setter, 0x$hashhex)";
703 push(@implContentDecls, " RefPtr<V8SVGPODTypeWrapper<" . $nativeType . "> > wrapper = $wrapper;\n");
705 my $wrapper = GenerateSVGStaticPodTypeWrapper($returnType, $getterString);
706 push(@implContentDecls, " RefPtr<V8SVGStaticPODTypeWrapper<" . $nativeType . "> > wrapper = $wrapper;\n");
711 if ($attribute->signature->type eq "EventListener" && $dataNode->name eq "DOMWindow") {
712 push(@implContentDecls, " if (!imp->document())\n");
713 push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
716 if ($useExceptions) {
717 push(@implContentDecls, " $nativeType v = ");
718 push(@implContentDecls, "$getterString;\n");
719 push(@implContentDecls, GenerateSetDOMException(" "));
721 $result .= ".release()" if (IsRefPtrType($returnType));
723 # Can inline the function call into the return statement to avoid overhead of using a Ref<> temporary
724 $result = $getterString;
728 if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) {
729 if ($attrIsPodType) {
730 push(@implContentDecls, GenerateSVGContextAssignment($implClassName, "wrapper.get()", " "));
732 push(@implContentDecls, GenerateSVGContextRetrieval($implClassName, " "));
733 $result = "V8Proxy::withSVGContext($result, context)";
737 if ($attrIsPodType) {
738 my $classIndex = uc($attrType);
739 push(@implContentDecls, " return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper.release());\n");
741 push(@implContentDecls, " " . ReturnNativeToJSValue($attribute->signature, $result, " ").";\n");
744 push(@implContentDecls, " }\n\n"); # end of getter
748 sub GenerateReplaceableAttrSetter
750 my $implClassName = shift;
752 $implIncludes{"V8Proxy.h"} = 1;
754 push(@implContentDecls,
755 " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
756 " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
758 push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
760 push(@implContentDecls, " v8::Local<v8::String> ${attrName}_string = v8::String::New(\"${attrName}\");\n");
761 push(@implContentDecls, " info.Holder()->Delete(${attrName}_string);\n");
762 push(@implContentDecls, " info.This()->Set(${attrName}_string, value);\n");
763 push(@implContentDecls, " }\n\n");
767 sub GenerateNormalAttrSetter
769 my $attribute = shift;
770 my $dataNode = shift;
771 my $classIndex = shift;
772 my $implClassName = shift;
773 my $interfaceName = shift;
775 my $attrExt = $attribute->signature->extendedAttributes;
777 $implIncludes{"V8Proxy.h"} = 1;
779 push(@implContentDecls,
780 " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
781 " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
783 push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
785 my $isPodType = IsPodType($implClassName);
788 $implClassName = GetNativeType($implClassName);
789 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
790 push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = v8DOMWrapperTo<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());\n");
791 push(@implContentDecls, " $implClassName imp_instance = *wrapper;\n");
792 push(@implContentDecls, " $implClassName* imp = &imp_instance;\n");
794 } elsif ($attrExt->{"v8OnProto"}) {
795 if ($classIndex eq "DOMWINDOW") {
796 push(@implContentDecls, <<END);
797 v8::Handle<v8::Object> holder = info.Holder();
800 # perform lookup first
801 push(@implContentDecls, <<END);
802 v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
803 if (holder.IsEmpty()) return;
806 HolderToNative($dataNode, $implClassName, $classIndex, "info");
808 my $attrType = GetTypeFromSignature($attribute->signature);
809 my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
810 my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
811 if (($reflect || $reflectURL) && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) {
812 # Generate super-compact call for regular attribute setter:
813 my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
814 my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
815 $implIncludes{"${namespace}.h"} = 1;
816 push(@implContentDecls, " setElementStringAttr(info, ${namespace}::${contentAttributeName}Attr, value);\n");
817 push(@implContentDecls, " }\n\n");
819 # Skip the rest of the function!
822 push(@implContentDecls, <<END);
823 v8::Handle<v8::Object> holder = info.Holder();
825 HolderToNative($dataNode, $implClassName, $classIndex, "info");
828 my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
829 if ($attribute->signature->type eq "EventListener") {
830 if ($dataNode->name eq "DOMWindow") {
831 push(@implContentDecls, " if (!imp->document())\n");
832 push(@implContentDecls, " return;\n");
835 push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n");
839 if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
840 $result .= "WebCore::String::number(";
843 if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
846 my $returnType = GetTypeFromSignature($attribute->signature);
847 if (IsRefPtrType($returnType)) {
848 $result = "WTF::getPtr(" . $result . ")";
851 my $useExceptions = 1 if @{$attribute->setterExceptions} and !($isPodType);
853 if ($useExceptions) {
854 $implIncludes{"ExceptionCode.h"} = 1;
855 push(@implContentDecls, " ExceptionCode ec = 0;\n");
858 if ($implClassName eq "double") {
859 push(@implContentDecls, " *imp = $result;\n");
861 my $implSetterFunctionName = $codeGenerator->WK_ucfirst($attrName);
862 my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
863 my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
864 if ($reflect || $reflectURL) {
865 my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
866 my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
867 $implIncludes{"${namespace}.h"} = 1;
868 push(@implContentDecls, " imp->setAttribute(${namespace}::${contentAttributeName}Attr, $result");
869 } elsif ($attribute->signature->type eq "EventListener") {
870 $implIncludes{"V8AbstractEventListener.h"} = 1;
871 $implIncludes{"V8CustomBinding.h"} = 1;
872 $cacheIndex = GetHiddenDependencyIndex($dataNode, $attrName);
873 push(@implContentDecls, " transferHiddenDependency(holder, imp->$attrName(), value, $cacheIndex);\n");
874 push(@implContentDecls, " imp->set$implSetterFunctionName(V8DOMWrapper::getEventListener(imp, value, true, ListenerFindOrCreate)");
876 push(@implContentDecls, " imp->set$implSetterFunctionName($result");
878 push(@implContentDecls, ", ec") if $useExceptions;
879 push(@implContentDecls, ");\n");
882 if ($useExceptions) {
883 push(@implContentDecls, " if (UNLIKELY(ec))\n");
884 push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
888 push(@implContentDecls, " wrapper->commitChange(*imp, V8Proxy::svgContext(wrapper));\n");
889 } elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
890 $implIncludes{"SVGElement.h"} = 1;
892 my $currentObject = "imp";
894 $currentObject = "wrapper";
897 push(@implContentDecls, " if (SVGElement* context = V8Proxy::svgContext($currentObject)) {\n");
898 push(@implContentDecls, " context->svgAttributeChanged(imp->associatedAttributeName());\n");
899 push(@implContentDecls, " }\n");
902 push(@implContentDecls, " return;\n");
903 push(@implContentDecls, " }\n\n"); # end of setter
906 sub GetFunctionTemplateCallbackName
911 my $interfaceName = $dataNode->name;
912 my $name = $function->signature->name;
914 if ($function->signature->extendedAttributes->{"Custom"} ||
915 $function->signature->extendedAttributes->{"V8Custom"}) {
916 if ($function->signature->extendedAttributes->{"Custom"} &&
917 $function->signature->extendedAttributes->{"V8Custom"}) {
918 die "Custom and V8Custom should be mutually exclusive!"
920 return "V8${interfaceName}::${name}Callback";
922 return "${interfaceName}Internal::${name}Callback";
926 sub GenerateNewFunctionTemplate
932 my $callback = GetFunctionTemplateCallbackName($function, $dataNode);
933 return "v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), $signature)";
936 sub GenerateFunctionCallback
938 my $function = shift;
939 my $dataNode = shift;
940 my $classIndex = shift;
941 my $implClassName = shift;
943 my $interfaceName = $dataNode->name;
944 my $name = $function->signature->name;
946 push(@implContentDecls,
947 " static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {\n" .
948 " INC_STATS(\"DOM.$implClassName.$name\");\n");
950 my $numParameters = @{$function->parameters};
952 if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) {
953 push(@implContentDecls,
954 " if (args.Length() < $numParameters) return v8::Handle<v8::Value>();\n");
957 if (IsPodType($implClassName)) {
958 my $nativeClassName = GetNativeType($implClassName);
959 push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = v8DOMWrapperTo<V8SVGPODTypeWrapper<$nativeClassName> >(V8ClassIndex::$classIndex, args.Holder());\n");
960 push(@implContentDecls, " $nativeClassName imp_instance = *imp_wrapper;\n");
961 push(@implContentDecls, " $nativeClassName* imp = &imp_instance;\n");
963 push(@implContentDecls, <<END);
964 v8::Handle<v8::Object> holder = args.Holder();
966 HolderToNative($dataNode, $implClassName, $classIndex);
969 # Check domain security if needed
970 if (($dataNode->extendedAttributes->{"CheckDomainSecurity"}
971 || $interfaceName eq "DOMWindow")
972 && !$function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
973 # We have not find real use cases yet.
974 push(@implContentDecls,
975 " if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) {\n".
976 " return v8::Handle<v8::Value>();\n" .
980 my $raisesExceptions = @{$function->raisesExceptions};
981 if (!$raisesExceptions) {
982 foreach my $parameter (@{$function->parameters}) {
983 if (TypeCanFailConversion($parameter) or $parameter->extendedAttributes->{"IsIndex"}) {
984 $raisesExceptions = 1;
989 if ($raisesExceptions) {
990 $implIncludes{"ExceptionCode.h"} = 1;
991 push(@implContentDecls, " ExceptionCode ec = 0;\n");
992 push(@implContentDecls, " {\n");
993 # The brace here is needed to prevent the ensuing 'goto fail's from jumping past constructors
994 # of objects (like Strings) declared later, causing compile errors. The block scope ends
995 # right before the label 'fail:'.
998 if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
999 push(@implContentDecls,
1000 " OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, $numParameters));\n".
1001 " if (!callStack)\n".
1002 " return v8::Undefined();\n");
1003 $implIncludes{"ScriptCallStack.h"} = 1;
1005 if ($function->signature->extendedAttributes->{"SVGCheckSecurityDocument"}) {
1006 push(@implContentDecls,
1007 " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->getSVGDocument(ec)))\n" .
1008 " return v8::Handle<v8::Value>();\n");
1012 foreach my $parameter (@{$function->parameters}) {
1013 TranslateParameter($parameter);
1015 my $parameterName = $parameter->name;
1017 if ($parameter->extendedAttributes->{"Optional"}) {
1018 # Generate early call if there are not enough parameters.
1019 push(@implContentDecls, " if (args.Length() <= $paramIndex) {\n");
1020 my $functionCall = GenerateFunctionCallString($function, $paramIndex, " " x 2, $implClassName);
1021 push(@implContentDecls, $functionCall);
1022 push(@implContentDecls, " }\n");
1025 if (BasicTypeCanFailConversion($parameter)) {
1026 push(@implContentDecls, " bool ${parameterName}Ok;\n");
1029 push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, $paramIndex) . " $parameterName = ");
1030 push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]",
1031 BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n");
1033 if (TypeCanFailConversion($parameter)) {
1034 $implIncludes{"ExceptionCode.h"} = 1;
1035 push(@implContentDecls,
1036 " if (UNLIKELY(!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "") . ")) {\n" .
1037 " ec = TYPE_MISMATCH_ERR;\n" .
1042 if ($parameter->extendedAttributes->{"IsIndex"}) {
1043 $implIncludes{"ExceptionCode.h"} = 1;
1044 push(@implContentDecls,
1045 " if (UNLIKELY($parameterName < 0)) {\n" .
1046 " ec = INDEX_SIZE_ERR;\n" .
1054 # Build the function call string.
1055 my $callString = GenerateFunctionCallString($function, $paramIndex, " ", $implClassName);
1056 push(@implContentDecls, "$callString");
1058 if ($raisesExceptions) {
1059 push(@implContentDecls, " }\n");
1060 push(@implContentDecls, " fail:\n");
1061 push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
1062 push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
1065 push(@implContentDecls, " }\n\n");
1068 sub GenerateBatchedAttributeData
1070 my $dataNode = shift;
1071 my $interfaceName = $dataNode->name;
1072 my $attributes = shift;
1074 foreach my $attribute (@$attributes) {
1075 my $conditionalString = GenerateConditionalString($attribute->signature);
1076 push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
1077 GenerateSingleBatchedAttribute($interfaceName, $attribute, ",", "");
1078 push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
1082 sub GenerateSingleBatchedAttribute
1084 my $interfaceName = shift;
1085 my $attribute = shift;
1086 my $delimiter = shift;
1088 my $attrName = $attribute->signature->name;
1089 my $attrExt = $attribute->signature->extendedAttributes;
1091 my $accessControl = "v8::DEFAULT";
1092 if ($attrExt->{"DoNotCheckDomainSecurityOnGet"}) {
1093 $accessControl = "v8::ALL_CAN_READ";
1094 } elsif ($attrExt->{"DoNotCheckDomainSecurityOnSet"}) {
1095 $accessControl = "v8::ALL_CAN_WRITE";
1096 } elsif ($attrExt->{"DoNotCheckDomainSecurity"}) {
1097 $accessControl = "v8::ALL_CAN_READ";
1098 if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) {
1099 $accessControl .= "|v8::ALL_CAN_WRITE";
1102 if ($attrExt->{"V8DisallowShadowing"}) {
1103 $accessControl .= "|v8::PROHIBITS_OVERWRITING";
1105 $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";
1107 my $customAccessor =
1108 $attrExt->{"Custom"} ||
1109 $attrExt->{"CustomSetter"} ||
1110 $attrExt->{"CustomGetter"} ||
1111 $attrExt->{"V8Custom"} ||
1112 $attrExt->{"V8CustomSetter"} ||
1113 $attrExt->{"V8CustomGetter"} ||
1115 if ($customAccessor eq 1) {
1116 # use the naming convension, interface + (capitalize) attr name
1117 $customAccessor = $interfaceName . "::" . $attrName;
1122 my $propAttr = "v8::None";
1123 my $hasCustomSetter = 0;
1126 if ($attrExt->{"DontEnum"}) {
1127 $propAttr .= "|v8::DontEnum";
1129 if ($attrExt->{"V8DisallowShadowing"}) {
1130 $propAttr .= "|v8::DontDelete";
1133 my $on_proto = "0 /* on instance */";
1134 my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";
1137 if ($attribute->signature->type =~ /Constructor$/) {
1138 my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
1139 $constructorType =~ s/Constructor$//;
1140 my $constructorIndex = uc($constructorType);
1141 if ($customAccessor) {
1142 $getter = "V8${customAccessor}AccessorGetter";
1144 $data = "V8ClassIndex::${constructorIndex}";
1145 $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
1148 $propAttr = "v8::ReadOnly";
1151 # Default Getter and Setter
1152 $getter = "${interfaceName}Internal::${attrName}AttrGetter";
1153 $setter = "${interfaceName}Internal::${attrName}AttrSetter";
1156 if ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
1157 $hasCustomSetter = 1;
1158 $setter = "V8${customAccessor}AccessorSetter";
1162 if ($attrExt->{"CustomGetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
1163 $getter = "V8${customAccessor}AccessorGetter";
1168 if ($attrExt->{"Replaceable"} && !$hasCustomSetter) {
1170 # Handle the special case of window.top being marked as Replaceable.
1171 # FIXME: Investigate whether we could treat window.top as replaceable
1172 # and allow shadowing without it being a security hole.
1173 if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) {
1174 $propAttr .= "|v8::ReadOnly";
1178 # Read only attributes
1179 if ($attribute->type =~ /^readonly/ || $attrExt->{"V8ReadOnly"}) {
1183 # An accessor can be installed on the proto
1184 if ($attrExt->{"v8OnProto"}) {
1185 $on_proto = "1 /* on proto */";
1188 my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
1189 "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
1191 push(@implContent, $indent . " {\n");
1192 push(@implContent, $indent . " \/\/ $commentInfo\n");
1193 push(@implContent, $indent . " \"$attrName\",\n");
1194 push(@implContent, $indent . " $getter,\n");
1195 push(@implContent, $indent . " $setter,\n");
1196 push(@implContent, $indent . " $data,\n");
1197 push(@implContent, $indent . " $accessControl,\n");
1198 push(@implContent, $indent . " static_cast<v8::PropertyAttribute>($propAttr),\n");
1199 push(@implContent, $indent . " $on_proto\n");
1200 push(@implContent, $indent . " }" . $delimiter . "\n");
1204 my %indexerSpecialCases = (
1206 "HTMLAppletElement" => 1,
1207 "HTMLEmbedElement" => 1,
1208 "HTMLObjectElement" => 1
1211 sub GenerateImplementationIndexer
1213 my $dataNode = shift;
1214 my $indexer = shift;
1215 my $interfaceName = $dataNode->name;
1217 # FIXME: Figure out what HasNumericIndexGetter is really supposed to do. Right now, it's only set on WebGL-related files.
1218 my $hasCustomSetter = $dataNode->extendedAttributes->{"HasCustomIndexSetter"} && !$dataNode->extendedAttributes->{"HasNumericIndexGetter"};
1219 my $hasGetter = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
1221 # FIXME: Find a way to not have to special-case HTMLOptionsCollection.
1222 if ($interfaceName eq "HTMLOptionsCollection") {
1225 # FIXME: If the parent interface of $dataNode already has
1226 # HasIndexGetter, we don't need to handle the getter here.
1227 if ($interfaceName eq "WebKitCSSTransformValue") {
1231 # FIXME: Investigate and remove this nastinesss. In V8, named property handling and indexer handling are apparently decoupled,
1232 # which means that object[X] where X is a number doesn't reach named property indexer. So we need to provide
1233 # simplistic, mirrored indexer handling in addition to named property handling.
1234 my $isSpecialCase = exists $indexerSpecialCases{$interfaceName};
1235 if ($isSpecialCase) {
1237 $hasCustomSetter = 1;
1244 $implIncludes{"V8Collection.h"} = 1;
1246 my $indexerType = $indexer ? $indexer->type : 0;
1248 # FIXME: Remove this once toV8 helper methods are implemented (see https://bugs.webkit.org/show_bug.cgi?id=32563).
1249 if ($interfaceName eq "WebKitCSSKeyframesRule") {
1250 $indexerType = "WebKitCSSKeyframeRule";
1253 if ($indexerType && !$hasCustomSetter) {
1254 if ($indexerType eq "DOMString") {
1255 my $conversion = $indexer->extendedAttributes->{"ConvertNullStringTo"};
1256 if ($conversion && $conversion eq "Null") {
1257 push(@implContent, <<END);
1258 setCollectionStringOrNullIndexedGetter<${interfaceName}>(desc);
1261 push(@implContent, <<END);
1262 setCollectionStringIndexedGetter<${interfaceName}>(desc);
1266 my $indexerClassIndex = uc($indexerType);
1267 push(@implContent, <<END);
1268 setCollectionIndexedGetter<${interfaceName}, ${indexerType}>(desc, V8ClassIndex::${indexerClassIndex});
1275 my $hasDeleter = $dataNode->extendedAttributes->{"CustomDeleteProperty"};
1276 my $hasEnumerator = !$isSpecialCase && IsNodeSubType($dataNode);
1277 my $setOn = "Instance";
1279 # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
1280 # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
1281 # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
1283 if ($interfaceName eq "DOMWindow") {
1284 $setOn = "Prototype";
1288 push(@implContent, " desc->${setOn}Template()->SetIndexedPropertyHandler(V8Custom::v8${interfaceName}IndexedPropertyGetter");
1289 push(@implContent, $hasCustomSetter ? ", V8Custom::v8${interfaceName}IndexedPropertySetter" : ", 0");
1290 push(@implContent, ", 0"); # IndexedPropertyQuery -- not being used at the moment.
1291 push(@implContent, $hasDeleter ? ", V8Custom::v8${interfaceName}IndexedPropertyDeleter" : ", 0");
1292 push(@implContent, ", nodeCollectionIndexedPropertyEnumerator<${interfaceName}>, v8::Integer::New(V8ClassIndex::NODE)") if $hasEnumerator;
1293 push(@implContent, ");\n");
1296 sub GenerateImplementationNamedPropertyGetter
1298 my $dataNode = shift;
1299 my $namedPropertyGetter = shift;
1300 my $interfaceName = $dataNode->name;
1301 my $hasCustomGetter = $dataNode->extendedAttributes->{"HasOverridingNameGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
1303 # FIXME: Remove hard-coded HTMLOptionsCollection reference by changing HTMLOptionsCollection to not inherit
1304 # from HTMLCollection per W3C spec (http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/html.html#HTMLOptionsCollection).
1305 if ($interfaceName eq "HTMLOptionsCollection") {
1306 $interfaceName = "HTMLCollection";
1307 $hasCustomGetter = 1;
1310 my $hasGetter = $dataNode->extendedAttributes->{"HasNameGetter"} || $hasCustomGetter || $namedPropertyGetter;
1315 if ($namedPropertyGetter && $namedPropertyGetter->type ne "Node" && !$namedPropertyGetter->extendedAttributes->{"Custom"} && !$hasCustomGetter) {
1316 $implIncludes{"V8Collection.h"} = 1;
1317 my $type = $namedPropertyGetter->type;
1318 my $classIndex = uc($type);
1319 push(@implContent, <<END);
1320 setCollectionNamedGetter<${interfaceName}, ${type}>(desc, V8ClassIndex::${classIndex});
1325 my $hasSetter = $dataNode->extendedAttributes->{"DelegatingPutFunction"};
1326 # FIXME: Try to remove hard-coded HTMLDocument reference by aligning handling of document.all with JSC bindings.
1327 my $hasDeleter = $dataNode->extendedAttributes->{"CustomDeleteProperty"} || $interfaceName eq "HTMLDocument";
1328 my $hasEnumerator = $dataNode->extendedAttributes->{"CustomGetPropertyNames"};
1329 my $setOn = "Instance";
1331 # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
1332 # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
1333 # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
1335 if ($interfaceName eq "DOMWindow") {
1336 $setOn = "Prototype";
1341 push(@implContent, " desc->${setOn}Template()->SetNamedPropertyHandler(V8Custom::v8${interfaceName}NamedPropertyGetter, ");
1342 push(@implContent, $hasSetter ? "V8Custom::v8${interfaceName}NamedPropertySetter, " : "0, ");
1343 push(@implContent, "0 ,"); # NamedPropertyQuery -- not being used at the moment.
1344 push(@implContent, $hasDeleter ? "V8Custom::v8${interfaceName}NamedPropertyDeleter, " : "0, ");
1345 push(@implContent, $hasEnumerator ? "V8Custom::v8${interfaceName}NamedPropertyEnumerator" : "0");
1346 push(@implContent, ");\n");
1349 sub GenerateImplementationCustomCall
1351 my $dataNode = shift;
1352 my $interfaceName = $dataNode->name;
1353 my $hasCustomCall = $dataNode->extendedAttributes->{"CustomCall"};
1355 # FIXME: Remove hard-coded HTMLOptionsCollection reference.
1356 if ($interfaceName eq "HTMLOptionsCollection") {
1357 $interfaceName = "HTMLCollection";
1361 if ($hasCustomCall) {
1362 push(@implContent, " desc->InstanceTemplate()->SetCallAsFunctionHandler(V8${interfaceName}::callAsFunctionCallback);\n");
1366 sub GenerateImplementationMasqueradesAsUndefined
1368 my $dataNode = shift;
1369 if ($dataNode->extendedAttributes->{"MasqueradesAsUndefined"})
1371 push(@implContent, " desc->InstanceTemplate()->MarkAsUndetectable();\n");
1375 sub GenerateImplementation
1378 my $dataNode = shift;
1379 my $interfaceName = $dataNode->name;
1380 my $className = "V8$interfaceName";
1381 my $implClassName = $interfaceName;
1382 my $classIndex = uc($codeGenerator->StripModule($interfaceName));
1384 my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
1385 my $conditionalString = GenerateConditionalString($dataNode);
1387 # - Add default header template
1388 @implContentHeader = split("\r", $headerTemplate);
1390 push(@implFixedHeader,
1391 "#include \"config.h\"\n" .
1392 "#include \"V8Proxy.h\"\n" .
1393 "#include \"V8Binding.h\"\n" .
1394 "#include \"V8BindingState.h\"\n\n" .
1397 push(@implFixedHeader, "\n#if ${conditionalString}\n\n") if $conditionalString;
1399 if ($className =~ /^V8SVGAnimated/) {
1400 AddIncludesForSVGAnimatedType($interfaceName);
1403 $implIncludes{"${className}.h"} = 1;
1405 AddIncludesForType($interfaceName);
1406 $implIncludes{"V8Proxy.h"} = 1;
1408 push(@implContentDecls, "namespace WebCore {\n");
1409 push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n");
1410 push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n");
1412 my $hasConstructors = 0;
1413 # Generate property accessors for attributes.
1414 for ($index = 0; $index < @{$dataNode->attributes}; $index++) {
1415 $attribute = @{$dataNode->attributes}[$index];
1416 $attrName = $attribute->signature->name;
1417 $attrType = $attribute->signature->type;
1419 # Generate special code for the constructor attributes.
1420 if ($attrType =~ /Constructor$/) {
1421 if ($attribute->signature->extendedAttributes->{"CustomGetter"}) {
1422 $implIncludes{"V8CustomBinding.h"} = 1;
1424 $hasConstructors = 1;
1429 if ($attrType eq "EventListener" && $interfaceName eq "DOMWindow") {
1430 $attribute->signature->extendedAttributes->{"v8OnProto"} = 1;
1433 # Do not generate accessor if this is a custom attribute. The
1434 # call will be forwarded to a hand-written accessor
1436 if ($attribute->signature->extendedAttributes->{"Custom"} ||
1437 $attribute->signature->extendedAttributes->{"V8Custom"}) {
1438 $implIncludes{"V8CustomBinding.h"} = 1;
1442 # Generate the accessor.
1443 if ($attribute->signature->extendedAttributes->{"CustomGetter"}) {
1444 $implIncludes{"V8CustomBinding.h"} = 1;
1446 GenerateNormalAttrGetter($attribute, $dataNode, $classIndex, $implClassName, $interfaceName);
1448 if ($attribute->signature->extendedAttributes->{"CustomSetter"} ||
1449 $attribute->signature->extendedAttributes->{"V8CustomSetter"}) {
1450 $implIncludes{"V8CustomBinding.h"} = 1;
1451 } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
1452 $dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"} || die "Replaceable attribute can only be used in interface that defines ExtendsDOMGlobalObject attribute!";
1453 # GenerateReplaceableAttrSetter($implClassName);
1454 } elsif ($attribute->type !~ /^readonly/ && !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
1455 GenerateNormalAttrSetter($attribute, $dataNode, $classIndex, $implClassName, $interfaceName);
1459 if ($hasConstructors) {
1460 GenerateConstructorGetter($implClassName, $classIndex);
1464 my $namedPropertyGetter;
1465 # Generate methods for functions.
1466 foreach my $function (@{$dataNode->functions}) {
1467 # hack for addEventListener/RemoveEventListener
1468 # FIXME: avoid naming conflict
1469 if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"}) {
1470 $implIncludes{"V8CustomBinding.h"} = 1;
1472 GenerateFunctionCallback($function, $dataNode, $classIndex, $implClassName);
1475 if ($function->signature->name eq "item") {
1476 $indexer = $function->signature;
1479 if ($function->signature->name eq "namedItem") {
1480 $namedPropertyGetter = $function->signature;
1483 # If the function does not need domain security check, we need to
1484 # generate an access getter that returns different function objects
1485 # for different calling context.
1486 if (($dataNode->extendedAttributes->{"CheckDomainSecurity"} || ($interfaceName eq "DOMWindow")) && $function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
1487 GenerateDomainSafeFunctionGetter($function, $dataNode, $classIndex, $implClassName);
1492 my $attributes = $dataNode->attributes;
1494 # For the DOMWindow interface we partition the attributes into the
1495 # ones that disallows shadowing and the rest.
1496 my @disallowsShadowing;
1497 # Also separate out attributes that are enabled at runtime so we can process them specially.
1498 my @enabledAtRuntime;
1500 foreach my $attribute (@$attributes) {
1502 if ($interfaceName eq "DOMWindow" && $attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) {
1503 push(@disallowsShadowing, $attribute);
1504 } elsif ($attribute->signature->extendedAttributes->{"EnabledAtRuntime"}) {
1505 push(@enabledAtRuntime, $attribute);
1507 push(@normal, $attribute);
1510 $attributes = \@normal;
1511 # Put the attributes that disallow shadowing on the shadow object.
1512 if (@disallowsShadowing) {
1513 push(@implContent, "static const BatchedAttribute shadow_attrs[] = {\n");
1514 GenerateBatchedAttributeData($dataNode, \@disallowsShadowing);
1515 push(@implContent, "};\n");
1518 my $has_attributes = 0;
1520 $has_attributes = 1;
1521 push(@implContent, "static const BatchedAttribute ${interfaceName}_attrs[] = {\n");
1522 GenerateBatchedAttributeData($dataNode, $attributes);
1523 push(@implContent, "};\n");
1526 # Setup table of standard callback functions
1529 foreach my $function (@{$dataNode->functions}) {
1530 my $attrExt = $function->signature->extendedAttributes;
1531 # Don't put any nonstandard functions into this table:
1532 if ($attrExt->{"V8OnInstance"}) {
1535 if ($attrExt->{"EnabledAtRuntime"} || RequiresCustomSignature($function) || $attrExt->{"V8DoNotCheckSignature"}) {
1538 if ($attrExt->{"DoNotCheckDomainSecurity"} &&
1539 ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceName eq "DOMWindow")) {
1542 if ($attrExt->{"DontEnum"} || $attrExt->{"V8ReadOnly"}) {
1545 if (!$has_callbacks) {
1547 push(@implContent, "static const BatchedCallback ${interfaceName}_callbacks[] = {\n");
1549 my $name = $function->signature->name;
1550 my $callback = GetFunctionTemplateCallbackName($function, $dataNode);
1551 push(@implContent, <<END);
1552 {"$name", $callback},
1556 push(@implContent, "};\n") if $has_callbacks;
1559 my $has_constants = 0;
1560 if (@{$dataNode->constants}) {
1562 push(@implContent, "static const BatchedConstant ${interfaceName}_consts[] = {\n");
1564 foreach my $constant (@{$dataNode->constants}) {
1565 my $name = $constant->name;
1566 my $value = $constant->value;
1567 # FIXME: we need the static_cast here only because of one constant, NodeFilter.idl
1568 # defines "const unsigned long SHOW_ALL = 0xFFFFFFFF". It would be better if we
1569 # handled this here, and converted it to a -1 constant in the c++ output.
1570 push(@implContent, <<END);
1571 { "${name}", static_cast<signed int>($value) },
1574 if ($has_constants) {
1575 push(@implContent, "};\n");
1578 push(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n");
1580 my $access_check = "";
1581 if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !($interfaceName eq "DOMWindow")) {
1582 $access_check = "instance->SetAccessCheckCallbacks(V8${interfaceName}::namedSecurityCheck, V8${interfaceName}::indexedSecurityCheck, v8::Integer::New(V8ClassIndex::ToInt(V8ClassIndex::${classIndex})));";
1585 # For the DOMWindow interface, generate the shadow object template
1586 # configuration method.
1587 if ($implClassName eq "DOMWindow") {
1588 push(@implContent, <<END);
1589 static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ) {
1590 batchConfigureAttributes(templ,
1591 v8::Handle<v8::ObjectTemplate>(),
1593 sizeof(shadow_attrs)/sizeof(*shadow_attrs));
1599 # find the super descriptor
1600 my $parentClassIndex = "INVALID_CLASS_INDEX";
1601 foreach (@{$dataNode->parents}) {
1602 my $parent = $codeGenerator->StripModule($_);
1603 if ($parent eq "EventTarget") { next; }
1604 $implIncludes{"V8${parent}.h"} = 1;
1605 $parentClassIndex = uc($codeGenerator->StripModule($parent));
1609 # find the field count
1610 my $fieldCount = "V8Custom::kDefaultWrapperInternalFieldCount";
1611 if (IsNodeSubType($dataNode)) {
1612 $fieldCount = "V8Custom::kNodeMinimumInternalFieldCount";
1615 # Generate the template configuration method
1616 push(@implContent, <<END);
1617 static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) {
1618 v8::Local<v8::Signature> default_signature = configureTemplate(desc, \"${interfaceName}\",
1619 V8ClassIndex::$parentClassIndex, $fieldCount,
1622 # Set up our attributes if we have them
1623 if ($has_attributes) {
1624 push(@implContent, <<END);
1625 ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs),
1628 push(@implContent, <<END);
1633 if ($has_callbacks) {
1634 push(@implContent, <<END);
1635 ${interfaceName}_callbacks, sizeof(${interfaceName}_callbacks)/sizeof(*${interfaceName}_callbacks));
1638 push(@implContent, <<END);
1643 if ($access_check or @enabledAtRuntime or @{$dataNode->functions} or $has_constants) {
1644 push(@implContent, <<END);
1645 v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
1646 v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
1650 push(@implContent, " $access_check\n");
1652 # Setup the enable-at-runtime attrs if we have them
1653 foreach my $runtime_attr (@enabledAtRuntime) {
1654 $enable_function = $interfaceName . "::" . $codeGenerator->WK_ucfirst($runtime_attr->signature->name);
1655 my $conditionalString = GenerateConditionalString($runtime_attr->signature);
1656 push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
1657 push(@implContent, " if (V8${enable_function}Enabled()) {\n");
1658 push(@implContent, " static const BatchedAttribute attrData =\\\n");
1659 GenerateSingleBatchedAttribute($interfaceName, $runtime_attr, ";", " ");
1660 push(@implContent, <<END);
1661 configureAttribute(instance, proto, attrData);
1664 push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
1667 GenerateImplementationIndexer($dataNode, $indexer);
1668 GenerateImplementationNamedPropertyGetter($dataNode, $namedPropertyGetter);
1669 GenerateImplementationCustomCall($dataNode);
1670 GenerateImplementationMasqueradesAsUndefined($dataNode);
1672 # Define our functions with Set() or SetAccessor()
1673 $total_functions = 0;
1674 foreach my $function (@{$dataNode->functions}) {
1676 my $attrExt = $function->signature->extendedAttributes;
1677 my $name = $function->signature->name;
1679 my $property_attributes = "v8::DontDelete";
1680 if ($attrExt->{"DontEnum"}) {
1681 $property_attributes .= "|v8::DontEnum";
1683 if ($attrExt->{"V8ReadOnly"}) {
1684 $property_attributes .= "|v8::ReadOnly";
1687 my $commentInfo = "Function '$name' (ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
1689 my $template = "proto";
1690 if ($attrExt->{"V8OnInstance"}) {
1691 $template = "instance";
1694 my $conditional = "";
1695 if ($attrExt->{"EnabledAtRuntime"}) {
1696 # Only call Set()/SetAccessor() if this method should be enabled
1697 $enable_function = $interfaceName . "::" . $codeGenerator->WK_ucfirst($function->signature->name);
1698 $conditional = "if (V8${enable_function}Enabled())\n";
1701 if ($attrExt->{"DoNotCheckDomainSecurity"} &&
1702 ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceName eq "DOMWindow")) {
1703 # Mark the accessor as ReadOnly and set it on the proto object so
1704 # it can be shadowed. This is really a hack to make it work.
1705 # There are several sceneria to call into the accessor:
1706 # 1) from the same domain: "window.open":
1707 # the accessor finds the DOM wrapper in the proto chain;
1708 # 2) from the same domain: "window.__proto__.open":
1709 # the accessor will NOT find a DOM wrapper in the prototype chain
1710 # 3) from another domain: "window.open":
1711 # the access find the DOM wrapper in the prototype chain
1712 # "window.__proto__.open" from another domain will fail when
1713 # accessing '__proto__'
1715 # The solution is very hacky and fragile, it really needs to be replaced
1716 # by a better solution.
1717 $property_attributes .= "|v8::ReadOnly";
1718 push(@implContent, <<END);
1721 $conditional $template->SetAccessor(
1722 v8::String::New("$name"),
1723 ${interfaceName}Internal::${name}AttrGetter,
1725 v8::Handle<v8::Value>(),
1727 static_cast<v8::PropertyAttribute>($property_attributes));
1733 my $signature = "default_signature";
1734 if ($attrExt->{"V8DoNotCheckSignature"}){
1735 $signature = "v8::Local<v8::Signature>()";
1738 if (RequiresCustomSignature($function)) {
1739 $signature = "${name}_signature";
1740 push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function));
1743 # Normal function call is a template
1744 my $callback = GetFunctionTemplateCallbackName($function, $dataNode);
1746 if ($property_attributes eq "v8::DontDelete") {
1747 $property_attributes = "";
1749 $property_attributes = ", static_cast<v8::PropertyAttribute>($property_attributes)";
1752 if ($template eq "proto" && $conditional eq "" && $signature eq "default_signature" && $property_attributes eq "") {
1753 # Standard type of callback, already created in the batch, so skip it here.
1757 push(@implContent, <<END);
1758 ${conditional}createCallback($template, "$name", $callback, ${signature}$property_attributes);
1763 die "Wrong number of callbacks generated for $interfaceName ($num_callbacks, should be $total_functions)" if $num_callbacks != $total_functions;
1765 if ($has_constants) {
1766 push(@implContent, <<END);
1767 batchConfigureConstants(desc, proto, ${interfaceName}_consts, sizeof(${interfaceName}_consts)/sizeof(*${interfaceName}_consts));
1771 push(@implContent, <<END);
1775 v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() {
1776 static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_ = createRawTemplate();
1777 return ${className}_raw_cache_;
1780 v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() {
1781 static v8::Persistent<v8::FunctionTemplate> ${className}_cache_ = Configure${className}Template(GetRawTemplate());
1782 return ${className}_cache_;
1785 bool ${className}::HasInstance(v8::Handle<v8::Value> value) {
1786 return GetRawTemplate()->HasInstance(value);
1791 if ($implClassName eq "DOMWindow") {
1792 push(@implContent, <<END);
1793 v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate() {
1794 static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_;
1795 if (V8DOMWindowShadowObject_cache_.IsEmpty()) {
1796 V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
1797 ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_);
1799 return V8DOMWindowShadowObject_cache_;
1804 push(@implContent, <<END);
1805 } // namespace WebCore
1808 push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
1812 sub GenerateFunctionCallString()
1814 my $function = shift;
1815 my $numberOfParameters = shift;
1817 my $implClassName = shift;
1819 my $name = $function->signature->name;
1820 my $isPodType = IsPodType($implClassName);
1821 my $returnType = GetTypeFromSignature($function->signature);
1822 my $returnsPodType = IsPodType($returnType);
1823 my $nativeReturnType = GetNativeType($returnType, 0);
1826 # Special case: SVG matrix transform methods should not mutate
1827 # the matrix but return a copy
1829 if ($implClassName eq "SVGMatrix" && $function->signature->type eq "SVGMatrix") {
1833 if ($function->signature->extendedAttributes->{"v8implname"}) {
1834 $name = $function->signature->extendedAttributes->{"v8implname"};
1837 if ($function->signature->extendedAttributes->{"ImplementationFunction"}) {
1838 $name = $function->signature->extendedAttributes->{"ImplementationFunction"};
1841 my $functionString = "imp->${name}(";
1844 $functionString = "result.${name}(";
1847 my $returnsListItemPodType = 0;
1848 # SVG lists functions that return POD types require special handling
1849 if (IsSVGListTypeNeedingSpecialHandling($implClassName) && IsSVGListMethod($name) && $returnsPodType) {
1850 $returnsListItemPodType = 1;
1851 $result .= $indent . "SVGList<RefPtr<SVGPODListItem<$nativeReturnType> > >* listImp = imp;\n";
1852 $functionString = "listImp->${name}(";
1857 my $nodeToReturn = 0;
1859 foreach my $parameter (@{$function->parameters}) {
1860 if ($index eq $numberOfParameters) {
1863 if ($first) { $first = 0; }
1864 else { $functionString .= ", "; }
1865 my $paramName = $parameter->name;
1866 my $paramType = $parameter->type;
1868 # This is a bit of a hack... we need to convert parameters to methods on SVG lists
1869 # of POD types which are items in the list to appropriate SVGList<> instances
1870 if ($returnsListItemPodType && $paramType . "List" eq $implClassName) {
1871 $paramName = "SVGPODListItem<" . GetNativeType($paramType, 1) . ">::copy($paramName)";
1874 if ($parameter->type eq "NodeFilter" || $parameter->type eq "XPathNSResolver") {
1875 $functionString .= "$paramName.get()";
1877 $functionString .= $paramName;
1880 if ($parameter->extendedAttributes->{"Return"}) {
1881 $nodeToReturn = $parameter->name;
1886 if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
1887 $functionString .= ", " if not $first;
1888 $functionString .= "callStack.get()";
1889 if ($first) { $first = 0; }
1892 if (@{$function->raisesExceptions}) {
1893 $functionString .= ", " if not $first;
1894 $functionString .= "ec";
1896 $functionString .= ")";
1898 my $return = "result";
1899 my $returnIsRef = IsRefPtrType($returnType);
1901 if ($nodeToReturn) {
1902 # Special case for insertBefore, replaceChild, removeChild and
1903 # appendChild functions from Node.
1904 $result .= $indent . "bool success = $functionString;\n";
1905 if (@{$function->raisesExceptions}) {
1906 $result .= $indent . "if (UNLIKELY(ec)) goto fail;\n";
1908 $result .= $indent . "if (success)\n";
1909 $result .= $indent . " " .
1910 "return V8DOMWrapper::convertNodeToV8Object($nodeToReturn);\n";
1911 $result .= $indent . "return v8::Null();\n";
1913 } elsif ($returnType eq "void") {
1914 $result .= $indent . "$functionString;\n";
1915 } elsif ($copyFirst) {
1917 $indent . GetNativeType($returnType, 0) . " result = *imp;\n" .
1918 $indent . "$functionString;\n";
1919 } elsif ($returnsListItemPodType) {
1920 $result .= $indent . "RefPtr<SVGPODListItem<$nativeReturnType> > result = $functionString;\n";
1921 } elsif (@{$function->raisesExceptions} or $returnsPodType or $isPodType or IsSVGTypeNeedingContextParameter($returnType)) {
1922 $result .= $indent . $nativeReturnType . " result = $functionString;\n";
1924 # Can inline the function call into the return statement to avoid overhead of using a Ref<> temporary
1925 $return = $functionString;
1929 if (@{$function->raisesExceptions}) {
1930 $result .= $indent . "if (UNLIKELY(ec)) goto fail;\n";
1933 # If the return type is a POD type, separate out the wrapper generation
1934 if ($returnsListItemPodType) {
1935 $result .= $indent . "RefPtr<V8SVGPODTypeWrapper<" . $nativeReturnType . "> > wrapper = ";
1936 $result .= "V8SVGPODTypeWrapperCreatorForList<" . $nativeReturnType . ">::create($return, imp->associatedAttributeName());\n";
1937 $return = "wrapper";
1938 } elsif ($returnsPodType) {
1939 $result .= $indent . "RefPtr<V8SVGPODTypeWrapper<" . $nativeReturnType . "> > wrapper = ";
1940 $result .= GenerateSVGStaticPodTypeWrapper($returnType, $return) . ";\n";
1941 $return = "wrapper";
1944 my $generatedSVGContextRetrieval = 0;
1945 # If the return type needs an SVG context, output it
1946 if (IsSVGTypeNeedingContextParameter($returnType)) {
1947 $result .= GenerateSVGContextAssignment($implClassName, $return . ".get()", $indent);
1948 $generatedSVGContextRetrieval = 1;
1951 if (IsSVGTypeNeedingContextParameter($implClassName) && $implClassName =~ /List$/ && IsSVGListMutator($name)) {
1952 if (!$generatedSVGContextRetrieval) {
1953 $result .= GenerateSVGContextRetrieval($implClassName, $indent);
1954 $generatedSVGContextRetrieval = 1;
1957 $result .= $indent . "context->svgAttributeChanged(imp->associatedAttributeName());\n";
1958 $implIncludes{"SVGElement.h"} = 1;
1961 # If the implementing class is a POD type, commit changes
1963 if (!$generatedSVGContextRetrieval) {
1964 $result .= GenerateSVGContextRetrieval($implClassName, $indent);
1965 $generatedSVGContextRetrieval = 1;
1968 $result .= $indent . "imp_wrapper->commitChange(imp_instance, context);\n";
1971 if ($returnsPodType) {
1972 my $classIndex = uc($returnType);
1973 $result .= $indent . "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper.release());\n";
1975 $return .= ".release()" if ($returnIsRef);
1976 $result .= $indent . ReturnNativeToJSValue($function->signature, $return, $indent) . ";\n";
1983 sub GetTypeFromSignature
1985 my $signature = shift;
1987 return $codeGenerator->StripModule($signature->type);
1991 sub GetNativeTypeFromSignature
1993 my $signature = shift;
1994 my $parameterIndex = shift;
1996 my $type = GetTypeFromSignature($signature);
1998 if ($type eq "unsigned long" and $signature->extendedAttributes->{"IsIndex"}) {
1999 # Special-case index arguments because we need to check that they aren't < 0.
2003 $type = GetNativeType($type, $parameterIndex >= 0 ? 1 : 0);
2005 if ($parameterIndex >= 0 && $type eq "V8Parameter") {
2007 if ($signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"}) {
2008 $mode = "WithUndefinedOrNullCheck";
2009 } elsif ($signature->extendedAttributes->{"ConvertNullToNullString"}) {
2010 $mode = "WithNullCheck";
2021 return 1 if $type eq "Attr";
2022 return 1 if $type eq "CanvasBooleanArray";
2023 return 1 if $type eq "CanvasGradient";
2024 return 1 if $type eq "CanvasObject";
2025 return 1 if $type eq "ClientRect";
2026 return 1 if $type eq "ClientRectList";
2027 return 1 if $type eq "CDATASection";
2028 return 1 if $type eq "Comment";
2029 return 1 if $type eq "CSSRule";
2030 return 1 if $type eq "CSSStyleRule";
2031 return 1 if $type eq "CSSCharsetRule";
2032 return 1 if $type eq "CSSImportRule";
2033 return 1 if $type eq "CSSMediaRule";
2034 return 1 if $type eq "CSSFontFaceRule";
2035 return 1 if $type eq "CSSPageRule";
2036 return 1 if $type eq "CSSPrimitiveValue";
2037 return 1 if $type eq "CSSStyleSheet";
2038 return 1 if $type eq "CSSStyleDeclaration";
2039 return 1 if $type eq "CSSValue";
2040 return 1 if $type eq "CSSRuleList";
2041 return 1 if $type eq "Database";
2042 return 1 if $type eq "Document";
2043 return 1 if $type eq "DocumentFragment";
2044 return 1 if $type eq "DocumentType";
2045 return 1 if $type eq "Element";
2046 return 1 if $type eq "EntityReference";
2047 return 1 if $type eq "Event";
2048 return 1 if $type eq "EventListener";
2049 return 1 if $type eq "FileList";
2050 return 1 if $type eq "HTMLCollection";
2051 return 1 if $type eq "HTMLAllCollection";
2052 return 1 if $type eq "HTMLDocument";
2053 return 1 if $type eq "HTMLElement";
2054 return 1 if $type eq "HTMLOptionsCollection";
2055 return 1 if $type eq "ImageData";
2056 return 1 if $type eq "Media";
2057 return 1 if $type eq "MediaError";
2058 return 1 if $type eq "MimeType";
2059 return 1 if $type eq "Node";
2060 return 1 if $type eq "NodeList";
2061 return 1 if $type eq "NodeFilter";
2062 return 1 if $type eq "NodeIterator";
2063 return 1 if $type eq "NSResolver";
2064 return 1 if $type eq "Plugin";
2065 return 1 if $type eq "ProcessingInstruction";
2066 return 1 if $type eq "Range";
2067 return 1 if $type eq "RGBColor";
2068 return 1 if $type eq "Text";
2069 return 1 if $type eq "TextMetrics";
2070 return 1 if $type eq "TimeRanges";
2071 return 1 if $type eq "TreeWalker";
2072 return 1 if $type eq "WebGLActiveInfo";
2073 return 1 if $type eq "WebGLArray";
2074 return 1 if $type eq "WebGLArrayBuffer";
2075 return 1 if $type eq "WebGLByteArray";
2076 return 1 if $type eq "WebGLBuffer";
2077 return 1 if $type eq "WebGLFloatArray";
2078 return 1 if $type eq "WebGLFramebuffer";
2079 return 1 if $type eq "WebGLIntArray";
2080 return 1 if $type eq "WebGLProgram";
2081 return 1 if $type eq "WebGLRenderbuffer";
2082 return 1 if $type eq "WebGLShader";
2083 return 1 if $type eq "WebGLShortArray";
2084 return 1 if $type eq "WebGLTexture";
2085 return 1 if $type eq "WebGLUniformLocation";
2086 return 1 if $type eq "WebGLUnsignedByteArray";
2087 return 1 if $type eq "WebGLUnsignedIntArray";
2088 return 1 if $type eq "WebGLUnsignedShortArray";
2089 return 1 if $type eq "WebKitCSSMatrix";
2090 return 1 if $type eq "WebKitPoint";
2091 return 1 if $type eq "XPathExpression";
2092 return 1 if $type eq "XPathNSResolver";
2093 return 1 if $type eq "XPathResult";
2095 return 1 if $type eq "SVGElementInstance";
2096 return 1 if $type eq "SVGElementInstanceList";
2097 return 1 if $type =~ /^SVGPathSeg/;
2099 return 1 if $type =~ /^SVGAnimated/;
2104 sub IsVideoClassName
2107 return 1 if $class eq "V8HTMLAudioElement";
2108 return 1 if $class eq "V8HTMLMediaElement";
2109 return 1 if $class eq "V8HTMLSourceElement";
2110 return 1 if $class eq "V8HTMLVideoElement";
2111 return 1 if $class eq "V8MediaError";
2112 return 1 if $class eq "V8TimeRanges";
2117 sub IsWorkerClassName
2120 return 1 if $class eq "V8Worker";
2121 return 1 if $class eq "V8WorkerContext";
2122 return 1 if $class eq "V8WorkerLocation";
2123 return 1 if $class eq "V8WorkerNavigator";
2131 my $isParameter = shift;
2133 if ($type eq "float" or $type eq "double") {
2137 return "V8Parameter" if ($type eq "DOMString" or $type eq "DOMUserData") and $isParameter;
2138 return "int" if $type eq "int";
2139 return "int" if $type eq "short" or $type eq "unsigned short";
2140 return "unsigned" if $type eq "unsigned long";
2141 return "int" if $type eq "long";
2142 return "unsigned long long" if $type eq "unsigned long long";
2143 return "bool" if $type eq "boolean";
2144 return "String" if $type eq "DOMString";
2145 return "Range::CompareHow" if $type eq "CompareHow";
2146 return "FloatRect" if $type eq "SVGRect";
2147 return "FloatPoint" if $type eq "SVGPoint";
2148 return "TransformationMatrix" if $type eq "SVGMatrix";
2149 return "SVGTransform" if $type eq "SVGTransform";
2150 return "SVGLength" if $type eq "SVGLength";
2151 return "SVGAngle" if $type eq "SVGAngle";
2152 return "double" if $type eq "SVGNumber";
2153 return "SVGPreserveAspectRatio" if $type eq "SVGPreserveAspectRatio";
2154 return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType";
2155 return "DOMTimeStamp" if $type eq "DOMTimeStamp";
2156 return "unsigned" if $type eq "unsigned int";
2157 return "Node*" if $type eq "EventTarget" and $isParameter;
2158 return "double" if $type eq "Date";
2160 return "String" if $type eq "DOMUserData"; # FIXME: Temporary hack?
2163 return "RefPtr<NodeFilter>" if $type eq "NodeFilter";
2165 # necessary as resolvers could be constructed on fly.
2166 return "RefPtr<XPathNSResolver>" if $type eq "XPathNSResolver";
2168 return "RefPtr<${type}>" if IsRefPtrType($type) and not $isParameter;
2170 # Default, assume native type is a pointer with same type name as idl type
2175 my %typeCanFailConversion = (
2179 "WebGLByteArray" => 0,
2180 "WebGLFloatArray" => 0,
2181 "WebGLFramebuffer" => 0,
2182 "CanvasGradient" => 0,
2183 "WebGLIntArray" => 0,
2184 "CanvasPixelArray" => 0,
2185 "WebGLProgram" => 0,
2186 "WebGLRenderbuffer" => 0,
2188 "WebGLShortArray" => 0,
2189 "WebGLTexture" => 0,
2190 "WebGLUniformLocation" => 0,
2192 "DataGridColumn" => 0,
2195 "DocumentType" => 0,
2198 "EventListener" => 0,
2200 "HTMLCanvasElement" => 0,
2202 "HTMLImageElement" => 0,
2203 "HTMLOptionElement" => 0,
2204 "HTMLVideoElement" => 0,
2210 "SQLResultSet" => 0,
2217 "SVGPaintType" => 0,
2220 "SVGPreserveAspectRatio" => 1,
2222 "SVGTransform" => 1,
2223 "VoidCallback" => 1,
2224 "WebKitCSSMatrix" => 0,
2226 "XPathEvaluator" => 0,
2227 "XPathNSResolver" => 0,
2233 "unsigned long" => 0,
2234 "unsigned short" => 0,
2238 sub TranslateParameter
2240 my $signature = shift;
2242 # The IDL uses some pseudo-types which don't really exist.
2243 if ($signature->type eq "TimeoutHandler") {
2244 $signature->type("DOMString");
2248 sub BasicTypeCanFailConversion
2250 my $signature = shift;
2251 my $type = GetTypeFromSignature($signature);
2253 return 1 if $type eq "SVGAngle";
2254 return 1 if $type eq "SVGLength";
2255 return 1 if $type eq "SVGMatrix";
2256 return 1 if $type eq "SVGPoint";
2257 return 1 if $type eq "SVGPreserveAspectRatio";
2258 return 1 if $type eq "SVGRect";
2259 return 1 if $type eq "SVGTransform";
2263 sub TypeCanFailConversion
2265 my $signature = shift;
2267 my $type = GetTypeFromSignature($signature);
2269 $implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr";
2271 return $typeCanFailConversion{$type} if exists $typeCanFailConversion{$type};
2273 die "Don't know whether a JS value can fail conversion to type $type.";
2278 my $signature = shift;
2280 my $okParam = shift;
2281 my $maybeOkParam = $okParam ? ", ${okParam}" : "";
2283 my $type = GetTypeFromSignature($signature);
2285 return "$value" if $type eq "JSObject";
2286 return "$value->BooleanValue()" if $type eq "boolean";
2287 return "static_cast<$type>($value->NumberValue())" if $type eq "float" or $type eq "double";
2288 return "$value->NumberValue()" if $type eq "SVGNumber";
2290 return "toInt32($value${maybeOkParam})" if $type eq "unsigned long" or $type eq "unsigned short" or $type eq "long";
2291 return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "CompareHow";
2292 return "static_cast<SVGPaint::SVGPaintType>($value->ToInt32()->Int32Value())" if $type eq "SVGPaintType";
2293 return "toWebCoreDate($value)" if $type eq "Date";
2295 if ($type eq "DOMString" or $type eq "DOMUserData") {
2299 if ($type eq "SerializedScriptValue") {
2300 $implIncludes{"SerializedScriptValue.h"} = 1;
2301 return "SerializedScriptValue::create($value)";
2304 if ($type eq "NodeFilter") {
2305 return "V8DOMWrapper::wrapNativeNodeFilter($value)";
2308 if ($type eq "SVGRect") {
2309 $implIncludes{"FloatRect.h"} = 1;
2312 if ($type eq "SVGPoint") {
2313 $implIncludes{"FloatPoint.h"} = 1;
2316 # Default, assume autogenerated type conversion routines
2317 $implIncludes{"V8Proxy.h"} = 1;
2318 if ($type eq "EventTarget") {
2319 $implIncludes{"V8Node.h"} = 1;
2321 # EventTarget is not in DOM hierarchy, but all Nodes are EventTarget.
2322 return "V8Node::HasInstance($value) ? v8DOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast($value)) : 0";
2325 if ($type eq "XPathNSResolver") {
2326 return "V8DOMWrapper::getXPathNSResolver($value)";
2329 AddIncludesForType($type);
2330 # $implIncludes{"$type.h"} = 1 unless AvoidInclusionOfType($type);
2332 if (IsDOMNodeType($type)) {
2333 $implIncludes{"V8${type}.h"} = 1;
2335 # Perform type checks on the parameter, if it is expected Node type,
2337 return "V8${type}::HasInstance($value) ? v8DOMWrapperToNode<${type}>(v8::Handle<v8::Object>::Cast($value)) : 0";
2339 # TODO: Temporary to avoid Window name conflict.
2340 my $classIndex = uc($type);
2341 my $implClassName = ${type};
2343 $implIncludes{"V8$type.h"} = 1;
2345 if (IsPodType($type)) {
2346 my $nativeType = GetNativeType($type);
2347 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
2349 return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(V8ClassIndex::${classIndex}, $value${maybeOkParam})"
2352 $implIncludes{"V8${type}.h"} = 1;
2354 # Perform type checks on the parameter, if it is expected Node type,
2356 return "V8${type}::HasInstance($value) ? v8DOMWrapperTo<${implClassName}>(V8ClassIndex::${classIndex}, v8::Handle<v8::Object>::Cast($value)) : 0";
2364 return "V8" . GetImplementationFileName($type);
2368 sub CreateCustomSignature
2370 my $function = shift;
2371 my $count = @{$function->parameters};
2372 my $name = $function->signature->name;
2373 my $result = " const int ${name}_argc = ${count};\n" .
2374 " v8::Handle<v8::FunctionTemplate> ${name}_argv[${name}_argc] = { ";
2376 foreach my $parameter (@{$function->parameters}) {
2377 if ($first) { $first = 0; }
2378 else { $result .= ", "; }
2379 if (IsWrapperType($parameter->type)) {
2380 if ($parameter->type eq "XPathNSResolver") {
2381 # Special case for XPathNSResolver. All other browsers accepts a callable,
2382 # so, even though it's against IDL, accept objects here.
2383 $result .= "v8::Handle<v8::FunctionTemplate>()";
2385 my $type = $parameter->type;
2386 my $header = GetV8HeaderName($type);
2387 $implIncludes{$header} = 1;
2388 $result .= "V8${type}::GetRawTemplate()";
2391 $result .= "v8::Handle<v8::FunctionTemplate>()";
2395 $result .= " v8::Handle<v8::Signature> ${name}_signature = v8::Signature::New(desc, ${name}_argc, ${name}_argv);\n";
2400 sub RequiresCustomSignature
2402 my $function = shift;
2403 # No signature needed for Custom function
2404 if ($function->signature->extendedAttributes->{"Custom"} ||
2405 $function->signature->extendedAttributes->{"V8Custom"}) {
2409 foreach my $parameter (@{$function->parameters}) {
2410 if (IsWrapperType($parameter->type)) {
2418 my %non_wrapper_types = (
2422 'unsigned short' => 1,
2424 'unsigned long' => 1,
2431 'SVGPreserveAspectRatio' => 1,
2433 'SVGTransform' => 1,
2436 'SVGPaintType' => 1,
2437 'DOMTimeStamp' => 1,
2441 'EventListener' => 1
2447 my $type = $codeGenerator->StripModule(shift);
2448 return !($non_wrapper_types{$type});
2455 return 1 if $type eq 'Attr';
2456 return 1 if $type eq 'CDATASection';
2457 return 1 if $type eq 'Comment';
2458 return 1 if $type eq 'Document';
2459 return 1 if $type eq 'DocumentFragment';
2460 return 1 if $type eq 'DocumentType';
2461 return 1 if $type eq 'Element';
2462 return 1 if $type eq 'EntityReference';
2463 return 1 if $type eq 'HTMLCanvasElement';
2464 return 1 if $type eq 'HTMLDocument';
2465 return 1 if $type eq 'HTMLElement';
2466 return 1 if $type eq 'HTMLFormElement';
2467 return 1 if $type eq 'HTMLTableCaptionElement';
2468 return 1 if $type eq 'HTMLTableSectionElement';
2469 return 1 if $type eq 'Node';
2470 return 1 if $type eq 'ProcessingInstruction';
2471 return 1 if $type eq 'SVGElement';
2472 return 1 if $type eq 'SVGDocument';
2473 return 1 if $type eq 'SVGSVGElement';
2474 return 1 if $type eq 'SVGUseElement';
2475 return 1 if $type eq 'Text';
2481 sub ReturnNativeToJSValue
2483 my $signature = shift;
2486 my $type = GetTypeFromSignature($signature);
2487 my $className= "V8$type";
2489 return "return v8::Date::New(static_cast<double>($value))" if $type eq "DOMTimeStamp";
2490 return "return v8Boolean($value)" if $type eq "boolean";
2491 return "return v8::Handle<v8::Value>()" if $type eq "void"; # equivalent to v8::Undefined()
2493 # For all the types where we use 'int' as the representation type,
2494 # we use Integer::New which has a fast Smi conversion check.
2495 my $nativeType = GetNativeType($type);
2496 return "return v8::Integer::New($value)" if $nativeType eq "int";
2497 return "return v8::Integer::NewFromUnsigned($value)" if $nativeType eq "unsigned";
2499 return "return v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType";
2501 if ($codeGenerator->IsStringType($type)) {
2502 my $conv = $signature->extendedAttributes->{"ConvertNullStringTo"};
2503 if (defined $conv) {
2504 return "return v8StringOrNull($value)" if $conv eq "Null";
2505 return "return v8StringOrUndefined($value)" if $conv eq "Undefined";
2506 return "return v8StringOrFalse($value)" if $conv eq "False";
2508 die "Unknown value for ConvertNullStringTo extended attribute";
2510 return "return v8String($value)";
2514 my $implClassName = $type;
2515 AddIncludesForType($type);
2516 # $implIncludes{GetImplementationFileName($type)} = 1 unless AvoidInclusionOfType($type);
2518 # special case for non-DOM node interfaces
2519 if (IsDOMNodeType($type)) {
2520 if ($signature->extendedAttributes->{"ReturnsNew"}) {
2521 return "return V8DOMWrapper::convertNewNodeToV8Object($value)";
2523 return "return V8DOMWrapper::convertNodeToV8Object($value)";
2527 if ($type eq "EventTarget" or $type eq "SVGElementInstance") {
2528 return "return V8DOMWrapper::convertEventTargetToV8Object($value)";
2531 if ($type eq "Event") {
2532 return "return V8DOMWrapper::convertEventToV8Object($value)";
2535 if ($type eq "EventListener") {
2536 return "return V8DOMWrapper::convertEventListenerToV8Object(imp->scriptExecutionContext(), $value)";
2539 if ($type eq "SerializedScriptValue") {
2540 $implIncludes{"$type.h"} = 1;
2541 return "return v8String($value->toString())";
2544 if ($type eq "DedicatedWorkerContext" or $type eq "WorkerContext" or $type eq "SharedWorkerContext") {
2545 $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
2546 return "return WorkerContextExecutionProxy::convertWorkerContextToV8Object($value)";
2549 if ($type eq "WorkerLocation" or $type eq "WorkerNavigator" or $type eq "NotificationCenter") {
2550 $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
2551 my $classIndex = uc($type);
2553 return "return WorkerContextExecutionProxy::convertToV8Object(V8ClassIndex::$classIndex, $value)";
2556 if ($type eq "Date") {
2557 return "return v8DateOrNull($value);";
2561 $implIncludes{"wtf/RefCounted.h"} = 1;
2562 $implIncludes{"wtf/RefPtr.h"} = 1;
2563 $implIncludes{"wtf/GetPtr.h"} = 1;
2564 my $classIndex = uc($type);
2566 if (IsPodType($type)) {
2567 $value = GenerateSVGStaticPodTypeWrapper($type, $value);
2570 return "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, $value)";
2574 sub GenerateSVGStaticPodTypeWrapper {
2578 $implIncludes{"V8$type.h"}=1;
2579 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
2581 my $nativeType = GetNativeType($type);
2582 return "V8SVGStaticPODTypeWrapper<$nativeType>::create($value)";
2588 if (defined($IMPL)) {
2589 # Write content to file.
2590 print $IMPL @implContentHeader;
2592 print $IMPL @implFixedHeader;
2594 foreach my $implInclude (sort keys(%implIncludes)) {
2595 my $checkType = $implInclude;
2596 $checkType =~ s/\.h//;
2598 print $IMPL "#include \"$implInclude\"\n" unless $codeGenerator->IsSVGAnimatedType($checkType);
2602 print $IMPL @implContentDecls;
2603 print $IMPL @implContent;
2608 @implFixedHeader = ();
2609 @implHeaderContent = ();
2610 @implContentDecls = ();
2614 if (defined($HEADER)) {
2615 # Write content to file.
2616 print $HEADER @headerContent;
2620 @headerContent = ();
2624 sub IsSVGTypeNeedingContextParameter
2626 my $implClassName = shift;
2628 if ($implClassName =~ /SVG/ and not $implClassName =~ /Element/) {
2629 return 1 unless $implClassName =~ /SVGPaint/ or $implClassName =~ /SVGColor/ or $implClassName =~ /SVGDocument/;
2635 sub GenerateSVGContextAssignment
2637 my $srcType = shift;
2641 $result = GenerateSVGContextRetrieval($srcType, $indent);
2642 $result .= $indent . "V8Proxy::setSVGContext($value, context);\n";
2647 sub GenerateSVGContextRetrieval
2649 my $srcType = shift;
2652 my $srcIsPodType = IsPodType($srcType);
2654 my $srcObject = "imp";
2655 if ($srcIsPodType) {
2656 $srcObject = "imp_wrapper";
2661 if (IsSVGTypeNeedingContextParameter($srcType)) {
2662 $contextDecl = "V8Proxy::svgContext($srcObject)";
2664 $contextDecl = $srcObject;
2667 return $indent . "SVGElement* context = $contextDecl;\n";
2670 sub IsSVGListMutator
2672 my $functionName = shift;
2674 return 1 if $functionName eq "clear";
2675 return 1 if $functionName eq "initialize";
2676 return 1 if $functionName eq "insertItemBefore";
2677 return 1 if $functionName eq "replaceItem";
2678 return 1 if $functionName eq "removeItem";
2679 return 1 if $functionName eq "appendItem";
2686 my $functionName = shift;
2688 return 1 if $functionName eq "getFirst";
2689 return 1 if $functionName eq "getLast";
2690 return 1 if $functionName eq "getItem";
2692 return IsSVGListMutator($functionName);
2695 sub IsSVGListTypeNeedingSpecialHandling
2697 my $className = shift;
2699 return 1 if $className eq "SVGPointList";
2700 return 1 if $className eq "SVGTransformList";