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 # along 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);
87 # Workaround for V8 bindings difference where RGBColor is not a POD type.
91 return $codeGenerator->IsPodType($type);
94 # Params: 'domClass' struct
101 # Start actual generation
102 if ($dataNode->extendedAttributes->{"Callback"}) {
103 $object->GenerateCallbackHeader($dataNode);
104 $object->GenerateCallbackImplementation($dataNode);
106 $object->GenerateHeader($dataNode);
107 $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 AvoidInclusionOfType
133 # Special case: SVGRect.h / SVGPoint.h / SVGNumber.h / SVGMatrix.h do not exist.
134 return 1 if $type eq "SVGRect" or $type eq "SVGPoint" or $type eq "SVGNumber" or $type eq "SVGMatrix";
138 sub AddIncludesForType
140 my $type = $codeGenerator->StripModule(shift);
142 # When we're finished with the one-file-per-class
143 # reorganization, we won't need these special cases.
144 if (!$codeGenerator->IsPrimitiveType($type) and !AvoidInclusionOfType($type) and $type ne "Date") {
145 # default, include the same named file
146 $implIncludes{GetV8HeaderName(${type})} = 1;
148 if ($type =~ /SVGPathSeg/) {
150 $joinedName =~ s/Abs|Rel//;
151 $implIncludes{"${joinedName}.h"} = 1;
155 # additional includes (things needed to compile the bindings but not the header)
157 if ($type eq "CanvasRenderingContext2D") {
158 $implIncludes{"CanvasGradient.h"} = 1;
159 $implIncludes{"CanvasPattern.h"} = 1;
160 $implIncludes{"CanvasStyle.h"} = 1;
163 if ($type eq "CanvasGradient" or $type eq "XPathNSResolver") {
164 $implIncludes{"PlatformString.h"} = 1;
167 if ($type eq "CSSStyleDeclaration") {
168 $implIncludes{"CSSMutableStyleDeclaration.h"} = 1;
171 if ($type eq "Plugin" or $type eq "PluginArray" or $type eq "MimeTypeArray") {
172 # So we can get String -> AtomicString conversion for namedItem().
173 $implIncludes{"AtomicString.h"} = 1;
177 sub AddIncludesForSVGAnimatedType
180 $type =~ s/SVGAnimated//;
182 if ($type eq "Point" or $type eq "Rect") {
183 $implIncludes{"Float$type.h"} = 1;
184 } elsif ($type eq "String") {
185 $implIncludes{"PlatformString.h"} = 1;
188 $implIncludes{"SVGAnimatedTemplate.h"} = 1;
191 # If the node has a [Conditional=XXX] attribute, returns an "ENABLE(XXX)" string for use in an #if.
192 sub GenerateConditionalString
195 my $conditional = $node->extendedAttributes->{"Conditional"};
197 if ($conditional =~ /&/) {
198 return "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
199 } elsif ($conditional =~ /\|/) {
200 return "ENABLE(" . join(") || ENABLE(", split(/\|/, $conditional)) . ")";
202 return "ENABLE(" . $conditional . ")";
209 sub LinkOverloadedFunctions
211 my $dataNode = shift;
213 # Identifies overloaded functions and for each function adds an array with
214 # links to its respective overloads (including itself).
215 my %nameToFunctionsMap = ();
216 foreach my $function (@{$dataNode->functions}) {
217 my $name = $function->signature->name;
218 $nameToFunctionsMap{$name} = [] if !exists $nameToFunctionsMap{$name};
219 push(@{$nameToFunctionsMap{$name}}, $function);
220 $function->{overloads} = $nameToFunctionsMap{$name};
221 $function->{overloadIndex} = @{$nameToFunctionsMap{$name}};
229 my $dataNode = shift;
231 my $interfaceName = $dataNode->name;
232 my $className = "V8$interfaceName";
233 my $implClassName = $interfaceName;
235 # Copy contents of parent classes except the first parent or if it is
237 $codeGenerator->AddMethodsConstantsAndAttributesFromParentClasses($dataNode, \@allParents, 1);
239 my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
241 # - Add default header template
242 push(@headerContent, GenerateHeaderContentHeader($dataNode));
244 # Get correct pass/store types respecting PODType flag
245 my $podType = $dataNode->extendedAttributes->{"PODType"};
247 my %headerInclues = ();
248 $headerIncludes{"$podType.h"} = 1 if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
249 $headerIncludes{"StringHash.h"} = 1;
250 $headerIncludes{"WrapperTypeInfo.h"} = 1;
251 my $headerClassInclude = GetHeaderClassInclude($implClassName);
252 $headerIncludes{$headerClassInclude} = 1 if $headerClassInclude ne "";
254 foreach my $headerInclude (sort keys(%headerIncludes)) {
255 push(@headerContent, "#include \"${headerInclude}\"\n");
258 push(@headerContent, "#include <v8.h>\n");
259 push(@headerContent, "#include <wtf/HashMap.h>\n");
261 push(@headerContent, "\nnamespace WebCore {\n");
263 push(@headerContent, "\ntemplate<typename PODType> class V8SVGPODTypeWrapper;\n");
265 push(@headerContent, "\nclass $className {\n");
267 my $nativeType = GetNativeTypeForConversions($interfaceName);
269 $nativeType = "V8SVGPODTypeWrapper<${nativeType} >";
271 my $forceNewObjectParameter = IsDOMNodeType($interfaceName) ? ", bool forceNewObject = false" : "";
272 push(@headerContent, <<END);
275 static bool HasInstance(v8::Handle<v8::Value> value);
276 static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
277 static v8::Persistent<v8::FunctionTemplate> GetTemplate();
278 static ${nativeType}* toNative(v8::Handle<v8::Object>);
279 static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
280 static void derefObject(void*);
281 static WrapperTypeInfo info;
283 if (IsActiveDomType($implClassName)) {
284 push(@headerContent, " static ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object>);\n");
287 if ($implClassName eq "DOMWindow") {
288 push(@headerContent, <<END);
289 static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
293 my @enabledAtRuntime;
294 foreach my $function (@{$dataNode->functions}) {
295 my $name = $function->signature->name;
296 my $attrExt = $function->signature->extendedAttributes;
298 if ($attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
299 push(@headerContent, <<END);
300 static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments&);
304 if ($attrExt->{"EnabledAtRuntime"}) {
305 push(@enabledAtRuntime, $function);
309 if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) {
310 push(@headerContent, <<END);
311 static v8::Handle<v8::Value> constructorCallback(const v8::Arguments& args);
315 foreach my $attribute (@{$dataNode->attributes}) {
316 my $name = $attribute->signature->name;
317 my $attrExt = $attribute->signature->extendedAttributes;
318 if ($attrExt->{"V8CustomGetter"} || $attrExt->{"CustomGetter"}
319 || $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) {
320 push(@headerContent, <<END);
321 static v8::Handle<v8::Value> ${name}AccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
324 if ($attrExt->{"V8CustomSetter"} || $attrExt->{"CustomSetter"}
325 || $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) {
326 push(@headerContent, <<END);
327 static void ${name}AccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
330 if ($attrExt->{"EnabledAtRuntime"}) {
331 push(@enabledAtRuntime, $attribute);
335 GenerateHeaderNamedAndIndexedPropertyAccessors($dataNode);
336 GenerateHeaderCustomCall($dataNode);
337 GenerateHeaderCustomInternalFieldIndices($dataNode);
339 if ($dataNode->extendedAttributes->{"CheckDomainSecurity"}) {
340 push(@headerContent, <<END);
341 static bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType, v8::Local<v8::Value> data);
342 static bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType, v8::Local<v8::Value> data);
346 push(@headerContent, <<END);
349 v8::Handle<v8::Value> toV8(${nativeType}*${forceNewObjectParameter});
351 if (IsRefPtrType($implClassName)) {
352 push(@headerContent, <<END);
353 v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} >${forceNewObjectParameter});
357 push(@headerContent, "}\n\n");
358 push(@headerContent, "#endif // $className" . "_h\n");
360 my $conditionalString = GenerateConditionalString($dataNode);
361 push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditionalString;
364 sub GetInternalFields
366 my $dataNode = shift;
367 my $name = $dataNode->name;
369 my @customInternalFields = ();
371 # We can't ask whether a parent type has a given extendedAttribute, so special-case Node, AbstractWorker and WorkerContext to include all sub-types.
372 # FIXME: SVGElementInstance should probably have the EventTarget extended attribute, but doesn't.
373 if ($dataNode->extendedAttributes->{"EventTarget"} || IsNodeSubType($dataNode) || IsSubType($dataNode, "AbstractWorker") || IsSubType($dataNode, "WorkerContext")
374 || $name eq "SVGElementInstance") {
375 push(@customInternalFields, "eventListenerCacheIndex");
378 if (IsSubType($dataNode, "Document")) {
379 push(@customInternalFields, "implementationIndex");
380 if ($name eq "HTMLDocument") {
381 push(@customInternalFields, ("markerIndex", "shadowIndex"));
383 } elsif ($name eq "DOMWindow") {
384 push(@customInternalFields, "enteredIsolatedWorldIndex");
386 return @customInternalFields;
389 sub GetHeaderClassInclude
391 my $className = shift;
392 if ($className =~ /SVGPathSeg/) {
393 $className =~ s/Abs|Rel//;
395 return "" if (AvoidInclusionOfType($className));
396 return "SVGAnimatedTemplate.h" if ($codeGenerator->IsSVGAnimatedType($className));
397 return "${className}.h";
400 sub GenerateHeaderCustomInternalFieldIndices
402 my $dataNode = shift;
403 my @customInternalFields = GetInternalFields($dataNode);
404 my $customFieldCounter = 0;
405 foreach my $customInternalField (@customInternalFields) {
406 push(@headerContent, <<END);
407 static const int ${customInternalField} = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
409 $customFieldCounter++;
411 push(@headerContent, <<END);
412 static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
416 my %indexerSpecialCases = (
418 "HTMLAppletElement" => 1,
420 "HTMLEmbedElement" => 1,
421 "HTMLObjectElement" => 1
424 sub GenerateHeaderNamedAndIndexedPropertyAccessors
426 my $dataNode = shift;
427 my $interfaceName = $dataNode->name;
428 my $hasCustomIndexedGetter = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
429 my $hasCustomIndexedSetter = $dataNode->extendedAttributes->{"HasCustomIndexSetter"} && !$dataNode->extendedAttributes->{"HasNumericIndexGetter"};
430 my $hasCustomNamedGetter = $dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
431 my $hasCustomNamedSetter = $dataNode->extendedAttributes->{"DelegatingPutFunction"};
432 my $hasCustomDeleters = $dataNode->extendedAttributes->{"CustomDeleteProperty"};
433 my $hasCustomEnumerator = $dataNode->extendedAttributes->{"CustomGetPropertyNames"};
434 if ($interfaceName eq "HTMLOptionsCollection") {
435 $interfaceName = "HTMLCollection";
436 $hasCustomIndexedGetter = 1;
437 $hasCustomNamedGetter = 1;
439 if ($interfaceName eq "DOMWindow") {
440 $hasCustomDeleterr = 0;
443 if ($interfaceName eq "HTMLSelectElement" || $interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
444 $hasCustomNamedGetter = 1;
446 my $isIndexerSpecialCase = exists $indexerSpecialCases{$interfaceName};
448 if ($hasCustomIndexedGetter || $isIndexerSpecialCase) {
449 push(@headerContent, <<END);
450 static v8::Handle<v8::Value> indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info);
454 if ($isIndexerSpecialCase || $hasCustomIndexedSetter) {
455 push(@headerContent, <<END);
456 static v8::Handle<v8::Value> indexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
459 if ($hasCustomDeleters) {
460 push(@headerContent, <<END);
461 static v8::Handle<v8::Boolean> indexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info);
464 if ($hasCustomNamedGetter) {
465 push(@headerContent, <<END);
466 static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
469 if ($hasCustomNamedSetter) {
470 push(@headerContent, <<END);
471 static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
474 if ($hasCustomDeleters || $interfaceName eq "HTMLDocument") {
475 push(@headerContent, <<END);
476 static v8::Handle<v8::Boolean> namedPropertyDeleter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
479 if ($hasCustomEnumerator) {
480 push(@headerContent, <<END);
481 static v8::Handle<v8::Array> namedPropertyEnumerator(const v8::AccessorInfo& info);
486 sub GenerateHeaderCustomCall
488 my $dataNode = shift;
490 if ($dataNode->extendedAttributes->{"CustomCall"}) {
491 push(@headerContent, " static v8::Handle<v8::Value> callAsFunctionCallback(const v8::Arguments&);\n");
493 if ($dataNode->name eq "Event") {
494 push(@headerContent, " static v8::Handle<v8::Value> dataTransferAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
495 push(@headerContent, " static void valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);\n");
497 if ($dataNode->name eq "Location") {
498 push(@headerContent, " static v8::Handle<v8::Value> assignAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
499 push(@headerContent, " static v8::Handle<v8::Value> reloadAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
500 push(@headerContent, " static v8::Handle<v8::Value> replaceAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
504 sub GenerateSetDOMException
509 $result .= $indent . "if (UNLIKELY(ec)) {\n";
510 $result .= $indent . " V8Proxy::setDOMException(ec);\n";
511 $result .= $indent . " return v8::Handle<v8::Value>();\n";
512 $result .= $indent . "}\n";
519 my $dataNode = shift;
520 my $parentType = shift;
521 return 1 if ($dataNode->name eq $parentType);
522 foreach (@allParents) {
523 my $parent = $codeGenerator->StripModule($_);
524 return 1 if $parent eq $parentType;
531 my $dataNode = shift;
532 return IsSubType($dataNode, "Node");
535 sub GenerateDomainSafeFunctionGetter
537 my $function = shift;
538 my $implClassName = shift;
540 my $className = "V8" . $implClassName;
541 my $funcName = $function->signature->name;
543 my $signature = "v8::Signature::New(" . $className . "::GetRawTemplate())";
544 if ($function->signature->extendedAttributes->{"V8DoNotCheckSignature"}) {
545 $signature = "v8::Local<v8::Signature>()";
548 my $newTemplateString = GenerateNewFunctionTemplate($function, $implClassName, $signature);
550 push(@implContentDecls, <<END);
551 static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
553 INC_STATS(\"DOM.$implClassName.$funcName._get\");
554 static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
555 v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(${className}::GetTemplate(), info.This());
556 if (holder.IsEmpty()) {
557 // can only reach here by 'object.__proto__.func', and it should passed
558 // domain security check already
559 return privateTemplate->GetFunction();
561 ${implClassName}* imp = ${className}::toNative(holder);
562 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false)) {
563 static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
564 return sharedTemplate->GetFunction();
566 return privateTemplate->GetFunction();
572 sub GenerateConstructorGetter
574 my $implClassName = shift;
576 push(@implContentDecls, <<END);
577 static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
579 INC_STATS(\"DOM.$implClassName.constructors._get\");
580 v8::Handle<v8::Value> data = info.Data();
581 ASSERT(data->IsExternal() || data->IsNumber());
582 WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data);
585 if ($implClassName eq "DOMWindow") {
586 push(@implContentDecls, <<END);
587 // Get the proxy corresponding to the DOMWindow if possible to
588 // make sure that the constructor function is constructed in the
589 // context of the DOMWindow and not in the context of the caller.
590 return V8DOMWrapper::getConstructor(type, V8DOMWindow::toNative(info.Holder()));
592 } elsif ($implClassName eq "DedicatedWorkerContext" or $implClassName eq "WorkerContext" or $implClassName eq "SharedWorkerContext") {
593 push(@implContentDecls, <<END);
594 return V8DOMWrapper::getConstructor(type, V8WorkerContext::toNative(info.Holder()));
597 push(@implContentDecls, " return v8::Handle<v8::Value>();");
600 push(@implContentDecls, <<END);
606 sub GenerateNormalAttrGetter
608 my $attribute = shift;
609 my $dataNode = shift;
610 my $implClassName = shift;
611 my $interfaceName = shift;
613 my $attrExt = $attribute->signature->extendedAttributes;
615 my $attrName = $attribute->signature->name;
617 my $attrType = GetTypeFromSignature($attribute->signature);
618 my $attrIsPodType = IsPodType($attrType);
620 my $nativeType = GetNativeTypeFromSignature($attribute->signature, -1);
621 my $isPodType = IsPodType($implClassName);
625 $implClassName = GetNativeType($implClassName);
626 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
629 # Special case: SVGZoomEvent's attributes are all read-only
630 if ($implClassName eq "SVGZoomEvent") {
635 # Special case: SVGSVGEelement::viewport is read-only
636 if (($implClassName eq "SVGSVGElement") and ($attrName eq "viewport")) {
641 # Special case for SVGColor
642 if (($implClassName eq "SVGColor") and ($attrName eq "rgbColor")) {
646 my $getterStringUsesImp = $implClassName ne "float";
649 push(@implContentDecls, <<END);
650 static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
652 INC_STATS(\"DOM.$implClassName.$attrName._get\");
656 push(@implContentDecls, <<END);
657 V8SVGPODTypeWrapper<$implClassName>* impWrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder());
658 $implClassName impInstance = *impWrapper;
660 if ($getterStringUsesImp) {
661 push(@implContentDecls, <<END);
662 $implClassName* imp = &impInstance;
666 } elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) {
667 if ($interfaceName eq "DOMWindow") {
668 push(@implContentDecls, <<END);
669 v8::Handle<v8::Object> holder = info.Holder();
672 # perform lookup first
673 push(@implContentDecls, <<END);
674 v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8${interfaceName}::GetTemplate(), info.This());
675 if (holder.IsEmpty())
676 return v8::Handle<v8::Value>();
679 push(@implContentDecls, <<END);
680 ${implClassName}* imp = V8${implClassName}::toNative(holder);
683 my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
684 if ($getterStringUsesImp && $reflect && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) {
685 # Generate super-compact call for regular attribute getter:
686 my $contentAttributeName = $reflect eq "1" ? $attrName : $reflect;
687 my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
688 $implIncludes{"${namespace}.h"} = 1;
689 push(@implContentDecls, " return getElementStringAttr(info, ${namespace}::${contentAttributeName}Attr);\n");
690 push(@implContentDecls, "}\n\n");
692 # Skip the rest of the function!
694 push(@implContentDecls, <<END);
695 ${implClassName}* imp = V8${implClassName}::toNative(info.Holder());
699 # Generate security checks if necessary
700 if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
701 push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->$attrName()))\n return v8::Handle<v8::Value>();\n\n");
702 } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
703 push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->contentDocument()))\n return v8::Handle<v8::Value>();\n\n");
706 my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType);
707 if ($useExceptions) {
708 $implIncludes{"ExceptionCode.h"} = 1;
709 push(@implContentDecls, " ExceptionCode ec = 0;\n");
712 if ($attribute->signature->extendedAttributes->{"v8referenceattr"}) {
713 $attrName = $attribute->signature->extendedAttributes->{"v8referenceattr"};
716 my $getterFunc = $codeGenerator->WK_lcfirst($attrName);
718 if ($codeGenerator->IsSVGAnimatedType($attribute->signature->type)) {
719 # Some SVGFE*Element.idl use 'operator' as attribute name; rewrite as '_operator' to avoid clashes with C/C++
720 $getterFunc = "_" . $getterFunc if ($attrName =~ /operator/);
721 $getterFunc .= "Animated";
724 my $returnType = GetTypeFromSignature($attribute->signature);
727 if ($getterStringUsesImp) {
728 my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
729 my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
730 if ($reflect || $reflectURL) {
731 my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
732 my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
733 $implIncludes{"${namespace}.h"} = 1;
734 my $getAttributeFunctionName = $reflectURL ? "getURLAttribute" : "getAttribute";
735 $getterString = "imp->$getAttributeFunctionName(${namespace}::${contentAttributeName}Attr";
737 $getterString = "imp->$getterFunc(";
739 $getterString .= "ec" if $useExceptions;
740 $getterString .= ")";
741 if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
742 $getterString .= ".toInt()";
745 $getterString = "impInstance";
751 if ($attrIsPodType) {
752 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
754 my $getter = $getterString;
755 $getter =~ s/imp->//;
757 my $setter = "set" . $codeGenerator->WK_ucfirst($getter);
759 my $implClassIsAnimatedType = $codeGenerator->IsSVGAnimatedType($implClassName);
760 if (not $implClassIsAnimatedType and $codeGenerator->IsPodTypeWithWriteableProperties($attrType) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
761 if (IsPodType($implClassName)) {
762 my $wrapper = "V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>::create($getterString, impWrapper)";
763 push(@implContentDecls, " RefPtr<V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName> > wrapper = $wrapper;\n");
765 my $wrapper = "V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName>::create(imp, &${implClassName}::$getter, &${implClassName}::$setter)";
766 push(@implContentDecls, " RefPtr<V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName> > wrapper = $wrapper;\n");
769 if ($implClassIsAnimatedType) {
770 # We can't hash member function pointers, so instead generate
771 # some hashing material based on the names of the methods.
772 my $hashhex = substr(Digest::MD5::md5_hex("${implClassName}::$getter ${implClassName}::$setter)"), 0, 8);
773 my $wrapper = "V8SVGDynamicPODTypeWrapperCache<$nativeType, $implClassName>::lookupOrCreateWrapper(imp, &${implClassName}::$getter, &${implClassName}::$setter, 0x$hashhex)";
774 push(@implContentDecls, " RefPtr<V8SVGPODTypeWrapper<" . $nativeType . "> > wrapper = $wrapper;\n");
776 my $wrapper = GenerateSVGStaticPodTypeWrapper($returnType, $getterString);
777 push(@implContentDecls, " RefPtr<V8SVGStaticPODTypeWrapper<" . $nativeType . "> > wrapper = $wrapper;\n");
782 if ($attribute->signature->type eq "EventListener" && $dataNode->name eq "DOMWindow") {
783 push(@implContentDecls, " if (!imp->document())\n");
784 push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
787 if ($useExceptions) {
788 push(@implContentDecls, " $nativeType v = ");
789 push(@implContentDecls, "$getterString;\n");
790 push(@implContentDecls, GenerateSetDOMException(" "));
792 $result .= ".release()" if (IsRefPtrType($returnType));
794 # Can inline the function call into the return statement to avoid overhead of using a Ref<> temporary
795 $result = $getterString;
798 # Special case for readonly or Replaceable attributes (with a few exceptions). This attempts to ensure that JS wrappers don't get
799 # garbage-collected prematurely when their lifetime is strongly tied to their owner. We accomplish this by inserting a reference to
800 # the newly created wrapper into an internal field of the holder object.
801 if (!IsNodeSubType($dataNode) && $attrName ne "self" && (IsWrapperType($returnType) && ($attribute->type =~ /^readonly/ || $attribute->signature->extendedAttributes->{"Replaceable"})
802 && $returnType ne "EventTarget" && $returnType ne "SerializedScriptValue" && $returnType ne "DOMWindow"
803 && $returnType !~ /SVG/ && $returnType !~ /HTML/ && !IsDOMNodeType($returnType))) {
804 AddIncludesForType($returnType);
805 my $domMapFunction = GetDomMapFunction(0, $returnType);
806 # Check for a wrapper in the wrapper cache. If there is one, we know that a hidden reference has already
807 # been created. If we don't find a wrapper, we create both a wrapper and a hidden reference.
808 push(@implContentDecls, " RefPtr<$returnType> result = ${getterString};\n");
809 push(@implContentDecls, " v8::Handle<v8::Value> wrapper = result.get() ? ${domMapFunction}.get(result.get()) : v8::Handle<v8::Value>();\n");
810 push(@implContentDecls, " if (wrapper.IsEmpty()) {\n");
811 push(@implContentDecls, " wrapper = toV8(result.get());\n");
812 push(@implContentDecls, " if (!wrapper.IsEmpty())\n");
813 if ($dataNode->name eq "DOMWindow") {
814 push(@implContentDecls, " V8DOMWrapper::setHiddenWindowReference(imp->frame(), wrapper);\n");
816 push(@implContentDecls, " V8DOMWrapper::setHiddenReference(info.Holder(), wrapper);\n");
818 push(@implContentDecls, " }\n");
819 push(@implContentDecls, " return wrapper;\n");
820 push(@implContentDecls, "}\n\n");
825 if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) {
826 if ($attrIsPodType) {
827 push(@implContentDecls, GenerateSVGContextAssignment($implClassName, "wrapper.get()", " "));
829 push(@implContentDecls, GenerateSVGContextRetrieval($implClassName, " "));
830 # The templating associated with passing withSVGContext()'s return value directly into toV8 can get compilers confused,
831 # so just manually set the return value to a PassRefPtr of the expected type.
832 push(@implContentDecls, " PassRefPtr<$attrType> resultAsPassRefPtr = V8Proxy::withSVGContext($result, context);\n");
833 $result = "resultAsPassRefPtr";
837 if ($attrIsPodType) {
838 $implIncludes{"V8${attrType}.h"} = 1;
839 push(@implContentDecls, " return toV8(wrapper.release().get());\n");
841 push(@implContentDecls, " " . ReturnNativeToJSValue($attribute->signature, $result, " ").";\n");
844 push(@implContentDecls, "}\n\n"); # end of getter
847 sub GenerateNormalAttrSetter
849 my $attribute = shift;
850 my $dataNode = shift;
851 my $implClassName = shift;
852 my $interfaceName = shift;
854 my $attrExt = $attribute->signature->extendedAttributes;
856 push(@implContentDecls, "static void ${attrName}AttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)\n{\n");
857 push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
859 my $isPodType = IsPodType($implClassName);
862 $implClassName = GetNativeType($implClassName);
863 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
864 push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder());\n");
865 push(@implContentDecls, " $implClassName impInstance = *wrapper;\n");
866 push(@implContentDecls, " $implClassName* imp = &impInstance;\n");
868 } elsif ($attrExt->{"v8OnProto"}) {
869 if ($interfaceName eq "DOMWindow") {
870 push(@implContentDecls, <<END);
871 v8::Handle<v8::Object> holder = info.Holder();
874 # perform lookup first
875 push(@implContentDecls, <<END);
876 v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8${interfaceName}::GetTemplate(), info.This());
877 if (holder.IsEmpty())
881 push(@implContentDecls, <<END);
882 ${implClassName}* imp = V8${implClassName}::toNative(holder);
885 my $attrType = GetTypeFromSignature($attribute->signature);
886 my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
887 my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
888 if (($reflect || $reflectURL) && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) {
889 # Generate super-compact call for regular attribute setter:
890 my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
891 my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
892 $implIncludes{"${namespace}.h"} = 1;
893 push(@implContentDecls, " setElementStringAttr(info, ${namespace}::${contentAttributeName}Attr, value);\n");
894 push(@implContentDecls, "}\n\n");
896 # Skip the rest of the function!
899 push(@implContentDecls, <<END);
900 ${implClassName}* imp = V8${implClassName}::toNative(info.Holder());
904 my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
905 if ($attribute->signature->type eq "EventListener") {
906 if ($dataNode->name eq "DOMWindow") {
907 push(@implContentDecls, " if (!imp->document())\n");
908 push(@implContentDecls, " return;\n");
911 push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n");
915 if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
916 $result .= "WebCore::String::number(";
919 if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
922 my $returnType = GetTypeFromSignature($attribute->signature);
923 if (IsRefPtrType($returnType)) {
924 $result = "WTF::getPtr(" . $result . ")";
927 my $useExceptions = 1 if @{$attribute->setterExceptions} and !($isPodType);
929 if ($useExceptions) {
930 $implIncludes{"ExceptionCode.h"} = 1;
931 push(@implContentDecls, " ExceptionCode ec = 0;\n");
934 if ($implClassName eq "float") {
935 push(@implContentDecls, " *imp = $result;\n");
937 my $implSetterFunctionName = $codeGenerator->WK_ucfirst($attrName);
938 my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
939 my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
940 if ($reflect || $reflectURL) {
941 my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
942 my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
943 $implIncludes{"${namespace}.h"} = 1;
944 push(@implContentDecls, " imp->setAttribute(${namespace}::${contentAttributeName}Attr, $result");
945 } elsif ($attribute->signature->type eq "EventListener") {
946 $implIncludes{"V8AbstractEventListener.h"} = 1;
947 push(@implContentDecls, " transferHiddenDependency(info.Holder(), imp->$attrName(), value, V8${interfaceName}::eventListenerCacheIndex);\n");
948 if ($interfaceName eq "WorkerContext" and $attribute->signature->name eq "onerror") {
949 $implIncludes{"V8EventListenerList.h"} = 1;
950 $implIncludes{"V8WorkerContextErrorHandler.h"} = 1;
951 push(@implContentDecls, " imp->set$implSetterFunctionName(V8EventListenerList::findOrCreateWrapper<V8WorkerContextErrorHandler>(value, true)");
953 push(@implContentDecls, " imp->set$implSetterFunctionName(V8DOMWrapper::getEventListener(value, true, ListenerFindOrCreate)");
956 push(@implContentDecls, " imp->set$implSetterFunctionName($result");
958 push(@implContentDecls, ", ec") if $useExceptions;
959 push(@implContentDecls, ");\n");
962 if ($useExceptions) {
963 push(@implContentDecls, " if (UNLIKELY(ec))\n");
964 push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
968 push(@implContentDecls, " wrapper->commitChange(*imp, V8Proxy::svgContext(wrapper));\n");
969 } elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
970 $implIncludes{"SVGElement.h"} = 1;
972 my $currentObject = "imp";
974 $currentObject = "wrapper";
977 push(@implContentDecls, " if (SVGElement* context = V8Proxy::svgContext($currentObject))\n");
978 push(@implContentDecls, " context->svgAttributeChanged(imp->associatedAttributeName());\n");
981 push(@implContentDecls, " return;\n");
982 push(@implContentDecls, "}\n\n"); # end of setter
985 sub GetFunctionTemplateCallbackName
988 $interfaceName = shift;
990 my $name = $function->signature->name;
992 if ($function->signature->extendedAttributes->{"Custom"} ||
993 $function->signature->extendedAttributes->{"V8Custom"}) {
994 if ($function->signature->extendedAttributes->{"Custom"} &&
995 $function->signature->extendedAttributes->{"V8Custom"}) {
996 die "Custom and V8Custom should be mutually exclusive!"
998 return "V8${interfaceName}::${name}Callback";
1000 return "${interfaceName}Internal::${name}Callback";
1004 sub GenerateNewFunctionTemplate
1007 $interfaceName = shift;
1010 my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
1011 return "v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), $signature)";
1014 sub GenerateEventListenerCallback
1016 my $implClassName = shift;
1017 my $functionName = shift;
1018 my $lookupType = ($functionName eq "add") ? "OrCreate" : "Only";
1019 my $passRefPtrHandling = ($functionName eq "add") ? "" : ".get()";
1020 my $hiddenDependencyAction = ($functionName eq "add") ? "create" : "remove";
1022 push(@implContentDecls, <<END);
1023 static v8::Handle<v8::Value> ${functionName}EventListenerCallback(const v8::Arguments& args)
1025 INC_STATS("DOM.${implClassName}.${functionName}EventListener()");
1026 RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(args[1], false, ListenerFind${lookupType});
1028 V8${implClassName}::toNative(args.Holder())->${functionName}EventListener(v8ValueToAtomicWebCoreString(args[0]), listener${passRefPtrHandling}, args[2]->BooleanValue());
1029 ${hiddenDependencyAction}HiddenDependency(args.Holder(), args[1], V8${implClassName}::eventListenerCacheIndex);
1031 return v8::Undefined();
1037 sub GenerateParametersCheckExpression
1039 my $numParameters = shift;
1040 my $function = shift;
1042 my @andExpression = ();
1043 push(@andExpression, "args.Length() == $numParameters");
1044 my $parameterIndex = 0;
1045 foreach $parameter (@{$function->parameters}) {
1046 last if $parameterIndex >= $numParameters;
1047 my $value = "args[$parameterIndex]";
1048 my $type = GetTypeFromSignature($parameter);
1050 # Only DOMString or wrapper types are checked.
1051 # For DOMString, Null, Undefined and any Object are accepted too, as
1052 # these are acceptable values for a DOMString argument (any Object can
1053 # be converted to a string via .toString).
1054 push(@andExpression, "(${value}->IsNull() || ${value}->IsUndefined() || ${value}->IsString() || ${value}->IsObject())") if $codeGenerator->IsStringType($type);
1055 push(@andExpression, "(${value}->IsNull() || V8${type}::HasInstance($value))") if IsWrapperType($type);
1059 my $res = join(" && ", @andExpression);
1060 $res = "($res)" if @andExpression > 1;
1064 sub GenerateFunctionParametersCheck
1066 my $function = shift;
1068 my @orExpression = ();
1069 my $numParameters = 0;
1070 foreach $parameter (@{$function->parameters}) {
1071 if ($parameter->extendedAttributes->{"Optional"}) {
1072 push(@orExpression, GenerateParametersCheckExpression($numParameters, $function));
1076 push(@orExpression, GenerateParametersCheckExpression($numParameters, $function));
1077 return join(" || ", @orExpression);
1080 sub GenerateOverloadedFunctionCallback
1082 my $function = shift;
1083 my $dataNode = shift;
1084 my $implClassName = shift;
1086 # Generate code for choosing the correct overload to call. Overloads are
1087 # chosen based on the total number of arguments passed and the type of
1088 # values passed in non-primitive argument slots. When more than a single
1089 # overload is applicable, precedence is given according to the order of
1090 # declaration in the IDL.
1092 my $name = $function->signature->name;
1093 push(@implContentDecls, <<END);
1094 static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args)
1096 INC_STATS(\"DOM.$implClassName.$name\");
1099 foreach my $overload (@{$function->{overloads}}) {
1100 my $parametersCheck = GenerateFunctionParametersCheck($overload);
1101 push(@implContentDecls, " if ($parametersCheck)\n");
1102 push(@implContentDecls, " return ${name}$overload->{overloadIndex}Callback(args);\n");
1104 push(@implContentDecls, <<END);
1105 V8Proxy::setDOMException(SYNTAX_ERR);
1106 return notHandledByInterceptor();
1108 push(@implContentDecls, "}\n\n");
1111 sub GenerateFunctionCallback
1113 my $function = shift;
1114 my $dataNode = shift;
1115 my $implClassName = shift;
1117 my $interfaceName = $dataNode->name;
1118 my $name = $function->signature->name;
1120 if (@{$function->{overloads}} > 1) {
1121 # Append a number to an overloaded method's name to make it unique:
1122 $name = $name . $function->{overloadIndex};
1125 # Adding and removing event listeners are not standard callback behavior,
1126 # but they are extremely consistent across the various classes that take event listeners,
1127 # so we can generate them as a "special case".
1128 if ($name eq "addEventListener") {
1129 GenerateEventListenerCallback($implClassName, "add");
1131 } elsif ($name eq "removeEventListener") {
1132 GenerateEventListenerCallback($implClassName, "remove");
1136 push(@implContentDecls, <<END);
1137 static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args)
1139 INC_STATS(\"DOM.$implClassName.$name\");
1142 my $numParameters = @{$function->parameters};
1144 if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) {
1145 push(@implContentDecls, " if (args.Length() < $numParameters)\n return v8::Handle<v8::Value>();\n");
1148 if (IsPodType($implClassName)) {
1149 my $nativeClassName = GetNativeType($implClassName);
1150 push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* impWrapper = V8SVGPODTypeWrapper<$nativeClassName>::toNative(args.Holder());\n");
1151 push(@implContentDecls, " $nativeClassName impInstance = *impWrapper;\n");
1152 push(@implContentDecls, " $nativeClassName* imp = &impInstance;\n");
1154 push(@implContentDecls, <<END);
1155 ${implClassName}* imp = V8${implClassName}::toNative(args.Holder());
1159 # Check domain security if needed
1160 if (($dataNode->extendedAttributes->{"CheckDomainSecurity"}
1161 || $interfaceName eq "DOMWindow")
1162 && !$function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
1163 # We have not find real use cases yet.
1164 push(@implContentDecls, <<END);
1165 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true))
1166 return v8::Handle<v8::Value>();
1170 my $raisesExceptions = @{$function->raisesExceptions};
1171 if (!$raisesExceptions) {
1172 foreach my $parameter (@{$function->parameters}) {
1173 if (TypeCanFailConversion($parameter) or $parameter->extendedAttributes->{"IsIndex"}) {
1174 $raisesExceptions = 1;
1179 if ($raisesExceptions) {
1180 $implIncludes{"ExceptionCode.h"} = 1;
1181 push(@implContentDecls, " ExceptionCode ec = 0;\n");
1182 push(@implContentDecls, " {\n");
1183 # The brace here is needed to prevent the ensuing 'goto fail's from jumping past constructors
1184 # of objects (like Strings) declared later, causing compile errors. The block scope ends
1185 # right before the label 'fail:'.
1188 if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
1189 push(@implContentDecls, <<END);
1190 OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, $numParameters));
1192 return v8::Undefined();
1194 $implIncludes{"ScriptCallStack.h"} = 1;
1196 if ($function->signature->extendedAttributes->{"SVGCheckSecurityDocument"}) {
1197 push(@implContentDecls, <<END);
1198 if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->getSVGDocument(ec)))
1199 return v8::Handle<v8::Value>();
1204 foreach my $parameter (@{$function->parameters}) {
1205 TranslateParameter($parameter);
1207 my $parameterName = $parameter->name;
1209 if ($parameter->extendedAttributes->{"Optional"}) {
1210 # Generate early call if there are not enough parameters.
1211 push(@implContentDecls, " if (args.Length() <= $paramIndex) {\n");
1212 my $functionCall = GenerateFunctionCallString($function, $paramIndex, " " x 2, $implClassName);
1213 push(@implContentDecls, $functionCall);
1214 push(@implContentDecls, " }\n");
1217 if ($parameter->type eq "SerializedScriptValue") {
1218 $implIncludes{"SerializedScriptValue.h"} = 1;
1219 push(@implContentDecls, " bool ${parameterName}DidThrow = false;\n");
1220 } elsif (BasicTypeCanFailConversion($parameter)) {
1221 push(@implContentDecls, " bool ${parameterName}Ok;\n");
1224 push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, $paramIndex) . " $parameterName = ");
1226 if ($parameter->type eq "SerializedScriptValue") {
1227 push(@implContentDecls, "SerializedScriptValue::create(args[$paramIndex], ${parameterName}DidThrow);\n");
1228 push(@implContentDecls, " if (${parameterName}DidThrow)\n");
1229 push(@implContentDecls, " return v8::Undefined();\n");
1231 push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]",
1232 BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n");
1235 if (TypeCanFailConversion($parameter)) {
1236 $implIncludes{"ExceptionCode.h"} = 1;
1237 push(@implContentDecls,
1238 " if (UNLIKELY(!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "") . ")) {\n" .
1239 " ec = TYPE_MISMATCH_ERR;\n" .
1244 if ($parameter->extendedAttributes->{"IsIndex"}) {
1245 $implIncludes{"ExceptionCode.h"} = 1;
1246 push(@implContentDecls,
1247 " if (UNLIKELY($parameterName < 0)) {\n" .
1248 " ec = INDEX_SIZE_ERR;\n" .
1256 # Build the function call string.
1257 my $callString = GenerateFunctionCallString($function, $paramIndex, " ", $implClassName);
1258 push(@implContentDecls, "$callString");
1260 if ($raisesExceptions) {
1261 push(@implContentDecls, " }\n");
1262 push(@implContentDecls, " fail:\n");
1263 push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
1264 push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
1267 push(@implContentDecls, "}\n\n");
1270 sub GenerateBatchedAttributeData
1272 my $dataNode = shift;
1273 my $interfaceName = $dataNode->name;
1274 my $attributes = shift;
1276 foreach my $attribute (@$attributes) {
1277 my $conditionalString = GenerateConditionalString($attribute->signature);
1278 push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
1279 GenerateSingleBatchedAttribute($interfaceName, $attribute, ",", "");
1280 push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
1284 sub GenerateSingleBatchedAttribute
1286 my $interfaceName = shift;
1287 my $attribute = shift;
1288 my $delimiter = shift;
1290 my $attrName = $attribute->signature->name;
1291 my $attrExt = $attribute->signature->extendedAttributes;
1293 # Attributes of type SerializedScriptValue are set in the
1294 # constructor and don't require callbacks.
1295 return if ($attribute->signature->type eq "SerializedScriptValue");
1297 my $accessControl = "v8::DEFAULT";
1298 if ($attrExt->{"DoNotCheckDomainSecurityOnGet"}) {
1299 $accessControl = "v8::ALL_CAN_READ";
1300 } elsif ($attrExt->{"DoNotCheckDomainSecurityOnSet"}) {
1301 $accessControl = "v8::ALL_CAN_WRITE";
1302 } elsif ($attrExt->{"DoNotCheckDomainSecurity"}) {
1303 $accessControl = "v8::ALL_CAN_READ";
1304 if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) {
1305 $accessControl .= " | v8::ALL_CAN_WRITE";
1308 if ($attrExt->{"V8DisallowShadowing"}) {
1309 $accessControl .= " | v8::PROHIBITS_OVERWRITING";
1311 $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";
1313 my $customAccessor =
1314 $attrExt->{"Custom"} ||
1315 $attrExt->{"CustomSetter"} ||
1316 $attrExt->{"CustomGetter"} ||
1317 $attrExt->{"V8Custom"} ||
1318 $attrExt->{"V8CustomSetter"} ||
1319 $attrExt->{"V8CustomGetter"} ||
1321 if ($customAccessor eq 1) {
1322 # use the naming convension, interface + (capitalize) attr name
1323 $customAccessor = $interfaceName . "::" . $attrName;
1328 my $propAttr = "v8::None";
1329 my $hasCustomSetter = 0;
1332 if ($attrExt->{"DontEnum"}) {
1333 $propAttr .= " | v8::DontEnum";
1335 if ($attrExt->{"V8DisallowShadowing"}) {
1336 $propAttr .= " | v8::DontDelete";
1339 my $on_proto = "0 /* on instance */";
1340 my $data = "0 /* no data */";
1343 if ($attribute->signature->type =~ /Constructor$/) {
1344 my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
1345 $constructorType =~ s/Constructor$//;
1346 $implIncludes{"V8${constructorType}.h"} = 1;
1347 if ($customAccessor) {
1348 $getter = "V8${customAccessor}AccessorGetter";
1350 $data = "&V8${constructorType}::info";
1351 $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
1354 $propAttr = "v8::ReadOnly";
1357 # Default Getter and Setter
1358 $getter = "${interfaceName}Internal::${attrName}AttrGetter";
1359 $setter = "${interfaceName}Internal::${attrName}AttrSetter";
1362 if ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
1363 $hasCustomSetter = 1;
1364 $setter = "V8${customAccessor}AccessorSetter";
1368 if ($attrExt->{"CustomGetter"} || $attrExt->{"V8CustomGetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
1369 $getter = "V8${customAccessor}AccessorGetter";
1374 if ($attrExt->{"Replaceable"} && !$hasCustomSetter) {
1376 # Handle the special case of window.top being marked as Replaceable.
1377 # FIXME: Investigate whether we could treat window.top as replaceable
1378 # and allow shadowing without it being a security hole.
1379 if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) {
1380 $propAttr .= " | v8::ReadOnly";
1384 # Read only attributes
1385 if ($attribute->type =~ /^readonly/ || $attrExt->{"V8ReadOnly"}) {
1389 # An accessor can be installed on the proto
1390 if ($attrExt->{"v8OnProto"}) {
1391 $on_proto = "1 /* on proto */";
1394 my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
1395 "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
1397 push(@implContent, $indent . " \/\/ $commentInfo\n");
1398 push(@implContent, $indent . " {\"$attrName\", $getter, $setter, $data, $accessControl, static_cast<v8::PropertyAttribute>($propAttr), $on_proto}" . $delimiter . "\n");
1401 sub GenerateImplementationIndexer
1403 my $dataNode = shift;
1404 my $indexer = shift;
1405 my $interfaceName = $dataNode->name;
1407 # FIXME: Figure out what HasNumericIndexGetter is really supposed to do. Right now, it's only set on WebGL-related files.
1408 my $hasCustomSetter = $dataNode->extendedAttributes->{"HasCustomIndexSetter"} && !$dataNode->extendedAttributes->{"HasNumericIndexGetter"};
1409 my $hasGetter = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
1411 # FIXME: Find a way to not have to special-case HTMLOptionsCollection.
1412 if ($interfaceName eq "HTMLOptionsCollection") {
1415 # FIXME: If the parent interface of $dataNode already has
1416 # HasIndexGetter, we don't need to handle the getter here.
1417 if ($interfaceName eq "WebKitCSSTransformValue") {
1421 # FIXME: Investigate and remove this nastinesss. In V8, named property handling and indexer handling are apparently decoupled,
1422 # which means that object[X] where X is a number doesn't reach named property indexer. So we need to provide
1423 # simplistic, mirrored indexer handling in addition to named property handling.
1424 my $isSpecialCase = exists $indexerSpecialCases{$interfaceName};
1425 if ($isSpecialCase) {
1427 if ($dataNode->extendedAttributes->{"DelegatingPutFunction"}) {
1428 $hasCustomSetter = 1;
1436 $implIncludes{"V8Collection.h"} = 1;
1438 my $indexerType = $indexer ? $indexer->type : 0;
1440 # FIXME: Remove this once toV8 helper methods are implemented (see https://bugs.webkit.org/show_bug.cgi?id=32563).
1441 if ($interfaceName eq "WebKitCSSKeyframesRule") {
1442 $indexerType = "WebKitCSSKeyframeRule";
1445 if ($indexerType && !$hasCustomSetter) {
1446 if ($indexerType eq "DOMString") {
1447 my $conversion = $indexer->extendedAttributes->{"ConvertNullStringTo"};
1448 if ($conversion && $conversion eq "Null") {
1449 push(@implContent, <<END);
1450 setCollectionStringOrNullIndexedGetter<${interfaceName}>(desc);
1453 push(@implContent, <<END);
1454 setCollectionStringIndexedGetter<${interfaceName}>(desc);
1458 push(@implContent, <<END);
1459 setCollectionIndexedGetter<${interfaceName}, ${indexerType}>(desc);
1461 # Include the header for this indexer type, because setCollectionIndexedGetter() requires toV8() for this type.
1462 $implIncludes{"V8${indexerType}.h"} = 1;
1468 my $hasDeleter = $dataNode->extendedAttributes->{"CustomDeleteProperty"};
1469 my $hasEnumerator = !$isSpecialCase && IsNodeSubType($dataNode);
1470 my $setOn = "Instance";
1472 # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
1473 # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
1474 # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
1476 if ($interfaceName eq "DOMWindow") {
1477 $setOn = "Prototype";
1481 push(@implContent, " desc->${setOn}Template()->SetIndexedPropertyHandler(V8${interfaceName}::indexedPropertyGetter");
1482 push(@implContent, $hasCustomSetter ? ", V8${interfaceName}::indexedPropertySetter" : ", 0");
1483 push(@implContent, ", 0"); # IndexedPropertyQuery -- not being used at the moment.
1484 push(@implContent, $hasDeleter ? ", V8${interfaceName}::indexedPropertyDeleter" : ", 0");
1485 push(@implContent, ", nodeCollectionIndexedPropertyEnumerator<${interfaceName}>") if $hasEnumerator;
1486 push(@implContent, ");\n");
1489 sub GenerateImplementationNamedPropertyGetter
1491 my $dataNode = shift;
1492 my $namedPropertyGetter = shift;
1493 my $interfaceName = $dataNode->name;
1494 my $hasCustomGetter = $dataNode->extendedAttributes->{"HasOverridingNameGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
1496 # FIXME: Remove hard-coded HTMLOptionsCollection reference by changing HTMLOptionsCollection to not inherit
1497 # from HTMLCollection per W3C spec (http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/html.html#HTMLOptionsCollection).
1498 if ($interfaceName eq "HTMLOptionsCollection") {
1499 $interfaceName = "HTMLCollection";
1500 $hasCustomGetter = 1;
1503 if ($interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
1504 $hasCustomGetter = 1;
1507 my $hasGetter = $dataNode->extendedAttributes->{"HasNameGetter"} || $hasCustomGetter || $namedPropertyGetter;
1512 if ($namedPropertyGetter && $namedPropertyGetter->type ne "Node" && !$namedPropertyGetter->extendedAttributes->{"Custom"} && !$hasCustomGetter) {
1513 $implIncludes{"V8Collection.h"} = 1;
1514 my $type = $namedPropertyGetter->type;
1515 push(@implContent, <<END);
1516 setCollectionNamedGetter<${interfaceName}, ${type}>(desc);
1521 my $hasSetter = $dataNode->extendedAttributes->{"DelegatingPutFunction"};
1522 # FIXME: Try to remove hard-coded HTMLDocument reference by aligning handling of document.all with JSC bindings.
1523 my $hasDeleter = $dataNode->extendedAttributes->{"CustomDeleteProperty"} || $interfaceName eq "HTMLDocument";
1524 my $hasEnumerator = $dataNode->extendedAttributes->{"CustomGetPropertyNames"};
1525 my $setOn = "Instance";
1527 # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
1528 # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
1529 # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
1531 if ($interfaceName eq "DOMWindow") {
1532 $setOn = "Prototype";
1537 push(@implContent, " desc->${setOn}Template()->SetNamedPropertyHandler(V8${interfaceName}::namedPropertyGetter, ");
1538 push(@implContent, $hasSetter ? "V8${interfaceName}::namedPropertySetter, " : "0, ");
1539 push(@implContent, "0, "); # NamedPropertyQuery -- not being used at the moment.
1540 push(@implContent, $hasDeleter ? "V8${interfaceName}::namedPropertyDeleter, " : "0, ");
1541 push(@implContent, $hasEnumerator ? "V8${interfaceName}::namedPropertyEnumerator" : "0");
1542 push(@implContent, ");\n");
1545 sub GenerateImplementationCustomCall
1547 my $dataNode = shift;
1548 my $interfaceName = $dataNode->name;
1549 my $hasCustomCall = $dataNode->extendedAttributes->{"CustomCall"};
1551 # FIXME: Remove hard-coded HTMLOptionsCollection reference.
1552 if ($interfaceName eq "HTMLOptionsCollection") {
1553 $interfaceName = "HTMLCollection";
1557 if ($hasCustomCall) {
1558 push(@implContent, " desc->InstanceTemplate()->SetCallAsFunctionHandler(V8${interfaceName}::callAsFunctionCallback);\n");
1562 sub GenerateImplementationMasqueradesAsUndefined
1564 my $dataNode = shift;
1565 if ($dataNode->extendedAttributes->{"MasqueradesAsUndefined"})
1567 push(@implContent, " desc->InstanceTemplate()->MarkAsUndetectable();\n");
1571 sub GenerateImplementation
1574 my $dataNode = shift;
1575 my $interfaceName = $dataNode->name;
1576 my $visibleInterfaceName = GetVisibleInterfaceName($interfaceName);
1577 my $className = "V8$interfaceName";
1578 my $implClassName = $interfaceName;
1580 my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
1582 # - Add default header template
1583 push(@implFixedHeader, GenerateImplementationContentHeader($dataNode));
1585 $implIncludes{"RuntimeEnabledFeatures.h"} = 1;
1586 $implIncludes{"V8Proxy.h"} = 1;
1587 $implIncludes{"V8Binding.h"} = 1;
1588 $implIncludes{"V8BindingState.h"} = 1;
1589 $implIncludes{"V8DOMWrapper.h"} = 1;
1590 $implIncludes{"V8IsolatedContext.h"} = 1;
1592 if ($className =~ /^V8SVGAnimated/) {
1593 AddIncludesForSVGAnimatedType($interfaceName);
1596 AddIncludesForType($interfaceName);
1598 my $toActive = IsActiveDomType($interfaceName) ? "${className}::toActiveDOMObject" : "0";
1600 push(@implContentDecls, "namespace WebCore {\n\n");
1601 push(@implContentDecls, "WrapperTypeInfo ${className}::info = { ${className}::GetTemplate, ${className}::derefObject, ${toActive} };\n\n");
1602 push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n");
1603 push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n");
1605 my $hasConstructors = 0;
1606 my $serializedAttribute;
1607 # Generate property accessors for attributes.
1608 for ($index = 0; $index < @{$dataNode->attributes}; $index++) {
1609 $attribute = @{$dataNode->attributes}[$index];
1610 $attrName = $attribute->signature->name;
1611 $attrType = $attribute->signature->type;
1613 # Generate special code for the constructor attributes.
1614 if ($attrType =~ /Constructor$/) {
1615 if (!($attribute->signature->extendedAttributes->{"CustomGetter"} ||
1616 $attribute->signature->extendedAttributes->{"V8CustomGetter"})) {
1617 $hasConstructors = 1;
1622 if ($attrType eq "EventListener" && $interfaceName eq "DOMWindow") {
1623 $attribute->signature->extendedAttributes->{"v8OnProto"} = 1;
1626 # Attributes of type SerializedScriptValue are set in the
1627 # constructor and don't require callbacks.
1628 if ($attrType eq "SerializedScriptValue") {
1629 die "Only one attribute of type SerializedScriptValue supported" if $serializedAttribute;
1630 $implIncludes{"SerializedScriptValue.h"} = 1;
1631 $serializedAttribute = $attribute;
1635 # Do not generate accessor if this is a custom attribute. The
1636 # call will be forwarded to a hand-written accessor
1638 if ($attribute->signature->extendedAttributes->{"Custom"} ||
1639 $attribute->signature->extendedAttributes->{"V8Custom"}) {
1643 # Generate the accessor.
1644 if (!($attribute->signature->extendedAttributes->{"CustomGetter"} ||
1645 $attribute->signature->extendedAttributes->{"V8CustomGetter"})) {
1646 GenerateNormalAttrGetter($attribute, $dataNode, $implClassName, $interfaceName);
1648 if (!$attribute->signature->extendedAttributes->{"CustomSetter"} &&
1649 !$attribute->signature->extendedAttributes->{"V8CustomSetter"} &&
1650 !$attribute->signature->extendedAttributes->{"Replaceable"} &&
1651 $attribute->type !~ /^readonly/ &&
1652 !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
1653 GenerateNormalAttrSetter($attribute, $dataNode, $implClassName, $interfaceName);
1657 if ($hasConstructors) {
1658 GenerateConstructorGetter($implClassName);
1661 LinkOverloadedFunctions($dataNode);
1664 my $namedPropertyGetter;
1665 # Generate methods for functions.
1666 foreach my $function (@{$dataNode->functions}) {
1667 if (!($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"})) {
1668 GenerateFunctionCallback($function, $dataNode, $implClassName);
1669 if ($function->{overloadIndex} > 1 && $function->{overloadIndex} == @{$function->{overloads}}) {
1670 GenerateOverloadedFunctionCallback($function, $dataNode, $implClassName);
1674 if ($function->signature->name eq "item") {
1675 $indexer = $function->signature;
1678 if ($function->signature->name eq "namedItem") {
1679 $namedPropertyGetter = $function->signature;
1682 # If the function does not need domain security check, we need to
1683 # generate an access getter that returns different function objects
1684 # for different calling context.
1685 if (($dataNode->extendedAttributes->{"CheckDomainSecurity"} || ($interfaceName eq "DOMWindow")) && $function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
1686 GenerateDomainSafeFunctionGetter($function, $implClassName);
1691 my $attributes = $dataNode->attributes;
1693 # For the DOMWindow interface we partition the attributes into the
1694 # ones that disallows shadowing and the rest.
1695 my @disallowsShadowing;
1696 # Also separate out attributes that are enabled at runtime so we can process them specially.
1697 my @enabledAtRuntime;
1699 foreach my $attribute (@$attributes) {
1701 if ($interfaceName eq "DOMWindow" && $attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) {
1702 push(@disallowsShadowing, $attribute);
1703 } elsif ($attribute->signature->extendedAttributes->{"EnabledAtRuntime"}) {
1704 push(@enabledAtRuntime, $attribute);
1706 push(@normal, $attribute);
1709 $attributes = \@normal;
1710 # Put the attributes that disallow shadowing on the shadow object.
1711 if (@disallowsShadowing) {
1712 push(@implContent, "static const BatchedAttribute shadowAttrs[] = {\n");
1713 GenerateBatchedAttributeData($dataNode, \@disallowsShadowing);
1714 push(@implContent, "};\n");
1717 my $has_attributes = 0;
1719 $has_attributes = 1;
1720 push(@implContent, "static const BatchedAttribute ${interfaceName}Attrs[] = {\n");
1721 GenerateBatchedAttributeData($dataNode, $attributes);
1722 push(@implContent, "};\n");
1725 # Setup table of standard callback functions
1728 foreach my $function (@{$dataNode->functions}) {
1729 # Only one table entry is needed for overloaded methods:
1730 next if $function->{overloadIndex} > 1;
1732 my $attrExt = $function->signature->extendedAttributes;
1733 # Don't put any nonstandard functions into this table:
1734 if ($attrExt->{"V8OnInstance"}) {
1737 if ($attrExt->{"EnabledAtRuntime"} || RequiresCustomSignature($function) || $attrExt->{"V8DoNotCheckSignature"}) {
1740 if ($attrExt->{"DoNotCheckDomainSecurity"} &&
1741 ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceName eq "DOMWindow")) {
1744 if ($attrExt->{"DontEnum"} || $attrExt->{"V8ReadOnly"}) {
1747 if (!$has_callbacks) {
1749 push(@implContent, "static const BatchedCallback ${interfaceName}Callbacks[] = {\n");
1751 my $name = $function->signature->name;
1752 my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
1753 push(@implContent, <<END);
1754 {"$name", $callback},
1758 push(@implContent, "};\n") if $has_callbacks;
1761 my $has_constants = 0;
1762 if (@{$dataNode->constants}) {
1764 push(@implContent, "static const BatchedConstant ${interfaceName}Consts[] = {\n");
1766 foreach my $constant (@{$dataNode->constants}) {
1767 my $name = $constant->name;
1768 my $value = $constant->value;
1769 # FIXME: we need the static_cast here only because of one constant, NodeFilter.idl
1770 # defines "const unsigned long SHOW_ALL = 0xFFFFFFFF". It would be better if we
1771 # handled this here, and converted it to a -1 constant in the c++ output.
1772 push(@implContent, <<END);
1773 {"${name}", static_cast<signed int>($value)},
1776 if ($has_constants) {
1777 push(@implContent, "};\n");
1780 push(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n");
1782 # In namespace WebCore, add generated implementation for 'CanBeConstructed'.
1783 if ($dataNode->extendedAttributes->{"CanBeConstructed"} && !$dataNode->extendedAttributes->{"CustomConstructor"}) {
1784 my $v8ConstructFunction;
1785 my $callWith = $dataNode->extendedAttributes->{"CallWith"};
1786 if ($callWith and $callWith eq "ScriptExecutionContext") {
1787 $v8ConstructFunction = "constructDOMObjectWithScriptExecutionContext";
1789 $v8ConstructFunction = "constructDOMObject";
1791 push(@implContent, <<END);
1792 v8::Handle<v8::Value> ${className}::constructorCallback(const v8::Arguments& args)
1794 INC_STATS("DOM.${interfaceName}.Contructor");
1795 return V8Proxy::${v8ConstructFunction}<$interfaceName>(args, &info);
1800 my $access_check = "";
1801 if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !($interfaceName eq "DOMWindow")) {
1802 $access_check = "instance->SetAccessCheckCallbacks(V8${interfaceName}::namedSecurityCheck, V8${interfaceName}::indexedSecurityCheck, v8::External::Wrap(&V8${interfaceName}::info));";
1805 # For the DOMWindow interface, generate the shadow object template
1806 # configuration method.
1807 if ($implClassName eq "DOMWindow") {
1808 push(@implContent, <<END);
1809 static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ)
1811 batchConfigureAttributes(templ, v8::Handle<v8::ObjectTemplate>(), shadowAttrs, sizeof(shadowAttrs) / sizeof(*shadowAttrs));
1813 // Install a security handler with V8.
1814 templ->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::External::Wrap(&V8DOMWindow::info));
1815 templ->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
1821 # find the super descriptor
1822 my $parentClassTemplate = "";
1823 foreach (@{$dataNode->parents}) {
1824 my $parent = $codeGenerator->StripModule($_);
1825 if ($parent eq "EventTarget") { next; }
1826 $implIncludes{"V8${parent}.h"} = 1;
1827 $parentClassTemplate = "V8" . $parent . "::GetTemplate()";
1830 if (!$parentClassTemplate) {
1831 $parentClassTemplate = "v8::Persistent<v8::FunctionTemplate>()";
1834 # Generate the template configuration method
1835 push(@implContent, <<END);
1836 static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc)
1838 v8::Local<v8::Signature> defaultSignature = configureTemplate(desc, \"${visibleInterfaceName}\", $parentClassTemplate, V8${interfaceName}::internalFieldCount,
1840 # Set up our attributes if we have them
1841 if ($has_attributes) {
1842 push(@implContent, <<END);
1843 ${interfaceName}Attrs, sizeof(${interfaceName}Attrs) / sizeof(*${interfaceName}Attrs),
1846 push(@implContent, <<END);
1851 if ($has_callbacks) {
1852 push(@implContent, <<END);
1853 ${interfaceName}Callbacks, sizeof(${interfaceName}Callbacks) / sizeof(*${interfaceName}Callbacks));
1856 push(@implContent, <<END);
1861 if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) {
1862 push(@implContent, <<END);
1863 desc->SetCallHandler(V8${interfaceName}::constructorCallback);
1867 if ($access_check or @enabledAtRuntime or @{$dataNode->functions} or $has_constants) {
1868 push(@implContent, <<END);
1869 v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
1870 v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
1874 push(@implContent, " $access_check\n");
1876 # Setup the enable-at-runtime attrs if we have them
1877 foreach my $runtime_attr (@enabledAtRuntime) {
1878 # A function named RuntimeEnabledFeatures::{methodName}Enabled() need to be written by hand.
1879 $enable_function = "RuntimeEnabledFeatures::" . $codeGenerator->WK_lcfirst($runtime_attr->signature->name) . "Enabled";
1880 my $conditionalString = GenerateConditionalString($runtime_attr->signature);
1881 push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
1882 push(@implContent, " if (${enable_function}()) {\n");
1883 push(@implContent, " static const BatchedAttribute attrData =\\\n");
1884 GenerateSingleBatchedAttribute($interfaceName, $runtime_attr, ";", " ");
1885 push(@implContent, <<END);
1886 configureAttribute(instance, proto, attrData);
1889 push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
1892 GenerateImplementationIndexer($dataNode, $indexer);
1893 GenerateImplementationNamedPropertyGetter($dataNode, $namedPropertyGetter);
1894 GenerateImplementationCustomCall($dataNode);
1895 GenerateImplementationMasqueradesAsUndefined($dataNode);
1897 # Define our functions with Set() or SetAccessor()
1898 $total_functions = 0;
1899 foreach my $function (@{$dataNode->functions}) {
1900 # Only one accessor is needed for overloaded methods:
1901 next if $function->{overloadIndex} > 1;
1904 my $attrExt = $function->signature->extendedAttributes;
1905 my $name = $function->signature->name;
1907 my $property_attributes = "v8::DontDelete";
1908 if ($attrExt->{"DontEnum"}) {
1909 $property_attributes .= " | v8::DontEnum";
1911 if ($attrExt->{"V8ReadOnly"}) {
1912 $property_attributes .= " | v8::ReadOnly";
1915 my $commentInfo = "Function '$name' (ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
1917 my $template = "proto";
1918 if ($attrExt->{"V8OnInstance"}) {
1919 $template = "instance";
1922 my $conditional = "";
1923 if ($attrExt->{"EnabledAtRuntime"}) {
1924 # Only call Set()/SetAccessor() if this method should be enabled
1925 $enable_function = "RuntimeEnabledFeatures::" . $codeGenerator->WK_lcfirst($function->signature->name) . "Enabled";
1926 $conditional = "if (${enable_function}())\n ";
1929 if ($attrExt->{"DoNotCheckDomainSecurity"} &&
1930 ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceName eq "DOMWindow")) {
1931 # Mark the accessor as ReadOnly and set it on the proto object so
1932 # it can be shadowed. This is really a hack to make it work.
1933 # There are several sceneria to call into the accessor:
1934 # 1) from the same domain: "window.open":
1935 # the accessor finds the DOM wrapper in the proto chain;
1936 # 2) from the same domain: "window.__proto__.open":
1937 # the accessor will NOT find a DOM wrapper in the prototype chain
1938 # 3) from another domain: "window.open":
1939 # the access find the DOM wrapper in the prototype chain
1940 # "window.__proto__.open" from another domain will fail when
1941 # accessing '__proto__'
1943 # The solution is very hacky and fragile, it really needs to be replaced
1944 # by a better solution.
1945 $property_attributes .= " | v8::ReadOnly";
1946 push(@implContent, <<END);
1949 ${conditional}$template->SetAccessor(v8::String::New("$name"), ${interfaceName}Internal::${name}AttrGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>($property_attributes));
1955 my $signature = "defaultSignature";
1956 if ($attrExt->{"V8DoNotCheckSignature"}) {
1957 $signature = "v8::Local<v8::Signature>()";
1960 if (RequiresCustomSignature($function)) {
1961 $signature = "${name}Signature";
1962 push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function));
1965 # Normal function call is a template
1966 my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
1968 if ($property_attributes eq "v8::DontDelete") {
1969 $property_attributes = "";
1971 $property_attributes = ", static_cast<v8::PropertyAttribute>($property_attributes)";
1974 if ($template eq "proto" && $conditional eq "" && $signature eq "defaultSignature" && $property_attributes eq "") {
1975 # Standard type of callback, already created in the batch, so skip it here.
1979 push(@implContent, <<END);
1980 ${conditional}$template->Set(v8::String::New("$name"), v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), ${signature})$property_attributes);
1985 die "Wrong number of callbacks generated for $interfaceName ($num_callbacks, should be $total_functions)" if $num_callbacks != $total_functions;
1987 if ($has_constants) {
1988 push(@implContent, <<END);
1989 batchConfigureConstants(desc, proto, ${interfaceName}Consts, sizeof(${interfaceName}Consts) / sizeof(*${interfaceName}Consts));
1994 if ($interfaceName eq "DOMWindow") {
1995 push(@implContent, <<END);
1997 proto->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
1998 desc->SetHiddenPrototype(true);
1999 instance->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
2000 // Set access check callbacks, but turned off initially.
2001 // When a context is detached from a frame, turn on the access check.
2002 // Turning on checks also invalidates inline caches of the object.
2003 instance->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::External::Wrap(&V8DOMWindow::info), false);
2006 if ($interfaceName eq "Location") {
2007 push(@implContent, <<END);
2009 // For security reasons, these functions are on the instance instead
2010 // of on the prototype object to ensure that they cannot be overwritten.
2011 instance->SetAccessor(v8::String::New("reload"), V8Location::reloadAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
2012 instance->SetAccessor(v8::String::New("replace"), V8Location::replaceAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
2013 instance->SetAccessor(v8::String::New("assign"), V8Location::assignAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
2017 my $nativeType = GetNativeTypeForConversions($interfaceName);
2018 if ($dataNode->extendedAttributes->{"PODType"}) {
2019 $nativeType = "V8SVGPODTypeWrapper<${nativeType}>";
2021 push(@implContent, <<END);
2023 // Custom toString template
2024 desc->Set(getToStringName(), getToStringTemplate());
2028 v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate()
2030 static v8::Persistent<v8::FunctionTemplate> ${className}RawCache = createRawTemplate();
2031 return ${className}RawCache;
2034 v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate()\
2036 static v8::Persistent<v8::FunctionTemplate> ${className}Cache = Configure${className}Template(GetRawTemplate());
2037 return ${className}Cache;
2040 ${nativeType}* ${className}::toNative(v8::Handle<v8::Object> object)
2042 return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
2045 bool ${className}::HasInstance(v8::Handle<v8::Value> value)
2047 return GetRawTemplate()->HasInstance(value);
2052 if (IsActiveDomType($interfaceName)) {
2053 # MessagePort is handled like an active dom object even though it doesn't inherit
2054 # from ActiveDOMObject, so don't try to cast it to ActiveDOMObject.
2055 my $returnValue = $interfaceName eq "MessagePort" ? "0" : "toNative(object)";
2056 push(@implContent, <<END);
2057 ActiveDOMObject* ${className}::toActiveDOMObject(v8::Handle<v8::Object> object)
2059 return ${returnValue};
2064 if ($implClassName eq "DOMWindow") {
2065 push(@implContent, <<END);
2066 v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate()
2068 static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObjectCache;
2069 if (V8DOMWindowShadowObjectCache.IsEmpty()) {
2070 V8DOMWindowShadowObjectCache = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
2071 ConfigureShadowObjectTemplate(V8DOMWindowShadowObjectCache);
2073 return V8DOMWindowShadowObjectCache;
2078 GenerateToV8Converters($dataNode, $interfaceName, $className, $nativeType, $serializedAttribute);
2080 push(@implContent, <<END);
2082 void ${className}::derefObject(void* object)
2086 if (IsRefPtrType($interfaceName)) {
2087 push(@implContent, <<END);
2088 static_cast<${nativeType}*>(object)->deref();
2092 push(@implContent, <<END);
2095 } // namespace WebCore
2098 my $conditionalString = GenerateConditionalString($dataNode);
2099 push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
2101 # We've already added the header for this file in implFixedHeader, so remove
2102 # it from implIncludes to ensure we don't #include it twice.
2103 delete $implIncludes{"${className}.h"};
2106 sub GenerateHeaderContentHeader
2108 my $dataNode = shift;
2109 my $className = "V8" . $dataNode->name;
2110 my $conditionalString = GenerateConditionalString($dataNode);
2112 my @headerContentHeader = split("\r", $headerTemplate);
2114 push(@headerContentHeader, "\n#if ${conditionalString}\n") if $conditionalString;
2115 push(@headerContentHeader, "\n#ifndef ${className}" . "_h");
2116 push(@headerContentHeader, "\n#define ${className}" . "_h\n\n");
2117 return @headerContentHeader;
2120 sub GenerateImplementationContentHeader
2122 my $dataNode = shift;
2123 my $className = "V8" . $dataNode->name;
2124 my $conditionalString = GenerateConditionalString($dataNode);
2126 my @implContentHeader = split("\r", $headerTemplate);
2128 push(@implContentHeader, "\n#include \"config.h\"\n");
2129 push(@implContentHeader, "#include \"${className}.h\"\n\n");
2130 push(@implContentHeader, "#if ${conditionalString}\n\n") if $conditionalString;
2131 return @implContentHeader;
2134 sub GenerateCallbackHeader
2137 my $dataNode = shift;
2139 my $interfaceName = $dataNode->name;
2140 my $className = "V8$interfaceName";
2143 # - Add default header template
2144 push(@headerContent, GenerateHeaderContentHeader($dataNode));
2146 if ("$interfaceName.h" lt "WorldContextHandle.h") {
2147 push(@headerContent, "#include \"$interfaceName.h\"\n");
2148 push(@headerContent, "#include \"WorldContextHandle.h\"\n");
2150 push(@headerContent, "#include \"WorldContextHandle.h\"\n");
2151 push(@headerContent, "#include \"$interfaceName.h\"\n");
2153 push(@headerContent, "#include <v8.h>\n");
2154 push(@headerContent, "#include <wtf/Forward.h>\n");
2156 push(@headerContent, "\nnamespace WebCore {\n\n");
2157 push(@headerContent, "class Frame;\n\n");
2158 push(@headerContent, "class $className : public $interfaceName {\n");
2160 push(@headerContent, <<END);
2162 static PassRefPtr<${className}> create(v8::Local<v8::Value> value, Frame* frame)
2164 ASSERT(value->IsObject());
2165 return adoptRef(new ${className}(value->ToObject(), frame));
2168 virtual ~${className}();
2173 my $numFunctions = @{$dataNode->functions};
2174 if ($numFunctions > 0) {
2175 push(@headerContent, " // Functions\n");
2176 foreach my $function (@{$dataNode->functions}) {
2177 my @params = @{$function->parameters};
2178 if (!$function->signature->extendedAttributes->{"Custom"} &&
2179 !(GetNativeType($function->signature->type) eq "bool")) {
2180 push(@headerContent, " COMPILE_ASSERT(false)");
2183 push(@headerContent, " virtual " . GetNativeTypeForCallbacks($function->signature->type) . " " . $function->signature->name . "(ScriptExecutionContext*");
2184 foreach my $param (@params) {
2185 push(@headerContent, ", " . GetNativeTypeForCallbacks($param->type) . " " . $param->name);
2188 push(@headerContent, ");\n");
2192 push(@headerContent, <<END);
2195 ${className}(v8::Local<v8::Object>, Frame*);
2197 v8::Persistent<v8::Object> m_callback;
2198 RefPtr<Frame> m_frame;
2199 WorldContextHandle m_worldContext;
2204 push(@headerContent, "}\n\n");
2205 push(@headerContent, "#endif // $className" . "_h\n\n");
2207 my $conditionalString = GenerateConditionalString($dataNode);
2208 push(@headerContent, "#endif // ${conditionalString}\n") if $conditionalString;
2211 sub GenerateCallbackImplementation
2214 my $dataNode = shift;
2215 my $interfaceName = $dataNode->name;
2216 my $className = "V8$interfaceName";
2218 # - Add default header template
2219 push(@implFixedHeader, GenerateImplementationContentHeader($dataNode));
2221 $implIncludes{"Frame.h"} = 1;
2222 $implIncludes{"ScriptExecutionContext.h"} = 1;
2223 $implIncludes{"V8CustomVoidCallback.h"} = 1;
2225 push(@implContent, "namespace WebCore {\n\n");
2226 push(@implContent, <<END);
2227 ${className}::${className}(v8::Local<v8::Object> callback, Frame* frame)
2228 : m_callback(v8::Persistent<v8::Object>::New(callback))
2230 , m_worldContext(UseCurrentWorld)
2234 ${className}::~${className}()
2236 m_callback.Dispose();
2242 my $numFunctions = @{$dataNode->functions};
2243 if ($numFunctions > 0) {
2244 push(@implContent, "// Functions\n");
2245 foreach my $function (@{$dataNode->functions}) {
2246 my @params = @{$function->parameters};
2247 if ($function->signature->extendedAttributes->{"Custom"} ||
2248 !(GetNativeTypeForCallbacks($function->signature->type) eq "bool")) {
2252 AddIncludesForType($function->signature->type);
2253 push(@implContent, "\n" . GetNativeTypeForCallbacks($function->signature->type) . " ${className}::" . $function->signature->name . "(ScriptExecutionContext* context");
2255 foreach my $param (@params) {
2256 AddIncludesForType($param->type);
2257 push(@implContent, ", " . GetNativeTypeForCallbacks($param->type) . " " . $param->name);
2260 push(@implContent, ")\n");
2261 push(@implContent, "{\n");
2262 push(@implContent, " v8::HandleScope handleScope;\n\n");
2263 push(@implContent, " v8::Handle<v8::Context> v8Context = toV8Context(context, m_worldContext);\n");
2264 push(@implContent, " if (v8Context.IsEmpty())\n");
2265 push(@implContent, " return true;\n\n");
2266 push(@implContent, " v8::Context::Scope scope(v8Context);\n\n");
2267 push(@implContent, " v8::Handle<v8::Value> argv[] = {\n");
2270 foreach my $param (@params) {
2271 my $paramName = $param->name;
2272 push(@argvs, " toV8(${paramName})");
2274 push(@implContent, join(",\n", @argvs));
2276 push(@implContent, "\n };\n\n");
2277 push(@implContent, " RefPtr<Frame> protect(m_frame);\n\n");
2278 push(@implContent, " bool callbackReturnValue = false;\n");
2279 push(@implContent, " return !invokeCallback(m_callback, " . scalar(@params). ", argv, callbackReturnValue);\n");
2280 push(@implContent, "}\n");
2284 push(@implContent, "\n} // namespace WebCore\n\n");
2286 my $conditionalString = GenerateConditionalString($dataNode);
2287 push(@implContent, "#endif // ${conditionalString}\n") if $conditionalString;
2290 sub GenerateToV8Converters
2292 my $dataNode = shift;
2293 my $interfaceName = shift;
2294 my $className = shift;
2295 my $nativeType = shift;
2296 my $serializedAttribute = shift;
2298 my $domMapFunction = GetDomMapFunction($dataNode, $interfaceName);
2299 my $forceNewObjectInput = IsDOMNodeType($interfaceName) ? ", bool forceNewObject" : "";
2300 my $forceNewObjectCall = IsDOMNodeType($interfaceName) ? ", forceNewObject" : "";
2302 push(@implContent, <<END);
2304 v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput})
2306 v8::Handle<v8::Object> wrapper;
2310 if (IsNodeSubType($dataNode)) {
2311 push(@implContent, <<END);
2312 if (impl->document()) {
2313 proxy = V8Proxy::retrieve(impl->document()->frame());
2314 if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl))
2315 proxy->windowShell()->initContextIfNeeded();
2321 if ($domMapFunction) {
2322 push(@implContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
2323 if (IsNodeSubType($dataNode)) {
2324 push(@implContent, " wrapper = V8DOMWrapper::getWrapper(impl);\n");
2326 push(@implContent, " wrapper = ${domMapFunction}.get(impl);\n");
2328 push(@implContent, <<END);
2329 if (!wrapper.IsEmpty())
2332 push(@implContent, " }\n") if IsDOMNodeType($interfaceName);
2334 if (IsNodeSubType($dataNode)) {
2335 push(@implContent, <<END);
2337 v8::Handle<v8::Context> context;
2339 context = proxy->context();
2341 // Enter the node's context and create the wrapper in that context.
2342 if (!context.IsEmpty())
2347 push(@implContent, <<END);
2348 wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl);
2350 if (IsNodeSubType($dataNode)) {
2351 push(@implContent, <<END);
2352 // Exit the node's context if it was entered.
2353 if (!context.IsEmpty())
2358 push(@implContent, <<END);
2359 if (wrapper.IsEmpty())
2362 push(@implContent, "\n impl->ref();\n") if IsRefPtrType($interfaceName);
2364 # Eagerly deserialize attributes of type SerializedScriptValue
2365 # while we're in the right context.
2366 if ($serializedAttribute) {
2367 die "Attribute of type SerializedScriptValue expected" if $serializedAttribute->signature->type ne "SerializedScriptValue";
2368 my $attrName = $serializedAttribute->signature->name;
2369 my $attrAttr = "v8::DontDelete";
2370 if ($serializedAttribute->type =~ /^readonly/) {
2371 $attrAttr .= " | v8::ReadOnly";
2373 $attrAttr = "static_cast<v8::PropertyAttribute>($attrAttr)";
2374 my $getterFunc = $codeGenerator->WK_lcfirst($attrName);
2375 push(@implContent, <<END);
2376 SerializedScriptValue::deserializeAndSetProperty(wrapper, "${attrName}", ${attrAttr}, impl->${getterFunc}());
2380 if ($domMapFunction) {
2381 push(@implContent, <<END);
2382 ${domMapFunction}.set(impl, v8::Persistent<v8::Object>::New(wrapper));
2386 push(@implContent, <<END);
2391 if (IsRefPtrType($interfaceName)) {
2392 push(@implContent, <<END);
2394 v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl${forceNewObjectInput})
2396 return toV8(impl.get()${forceNewObjectCall});
2401 if (!HasCustomToV8Implementation($dataNode, $interfaceName)) {
2402 push(@implContent, <<END);
2404 v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectInput})
2408 return ${className}::wrap(impl${forceNewObjectCall});
2414 sub HasCustomToV8Implementation {
2415 # FIXME: This subroutine is lame. Probably should be an .idl attribute (CustomToV8)?
2417 $interfaceName = shift;
2419 # We generate a custom converter (but JSC doesn't) for the following:
2420 return 1 if $interfaceName eq "CSSStyleSheet";
2421 return 1 if $interfaceName eq "CanvasPixelArray";
2422 return 1 if $interfaceName eq "DOMWindow";
2423 return 1 if $interfaceName eq "Element";
2424 return 1 if $interfaceName eq "HTMLDocument";
2425 return 1 if $interfaceName eq "HTMLElement";
2426 return 1 if $interfaceName eq "Location";
2427 return 1 if $interfaceName eq "NamedNodeMap";
2428 return 1 if $interfaceName eq "SVGDocument";
2429 return 1 if $interfaceName eq "SVGElement";
2430 return 1 if $interfaceName eq "ScriptProfile";
2431 return 1 if $interfaceName eq "ScriptProfileNode";
2432 return 1 if $interfaceName eq "WorkerContext";
2433 # We don't generate a custom converter (but JSC does) for the following:
2434 return 0 if $interfaceName eq "AbstractWorker";
2435 return 0 if $interfaceName eq "CanvasRenderingContext";
2436 return 0 if $interfaceName eq "ImageData";
2437 return 0 if $interfaceName eq "SVGElementInstance";
2439 # For everything else, do what JSC does.
2440 return $dataNode->extendedAttributes->{"CustomToJS"};
2443 sub GetDomMapFunction
2445 my $dataNode = shift;
2447 return "getDOMSVGElementInstanceMap()" if $type eq "SVGElementInstance";
2448 return "getDOMNodeMap()" if ($dataNode && IsNodeSubType($dataNode));
2449 # Only use getDOMSVGObjectWithContextMap() for non-node svg objects
2450 return "getDOMSVGObjectWithContextMap()" if $type =~ /SVG/;
2451 return "" if $type eq "DOMImplementation";
2452 return "getActiveDOMObjectMap()" if IsActiveDomType($type);
2453 return "getDOMObjectMap()";
2458 # FIXME: Consider making this an .idl attribute.
2460 return 1 if $type eq "EventSource";
2461 return 1 if $type eq "MessagePort";
2462 return 1 if $type eq "XMLHttpRequest";
2463 return 1 if $type eq "WebSocket";
2464 return 1 if $type eq "Worker";
2465 return 1 if $type eq "SharedWorker";
2469 sub GetNativeTypeForConversions
2472 return "FloatRect" if $type eq "SVGRect";
2473 return "FloatPoint" if $type eq "SVGPoint";
2474 return "AffineTransform" if $type eq "SVGMatrix";
2475 return "float" if $type eq "SVGNumber";
2479 sub GenerateFunctionCallString()
2481 my $function = shift;
2482 my $numberOfParameters = shift;
2484 my $implClassName = shift;
2486 my $name = $function->signature->name;
2487 my $isPodType = IsPodType($implClassName);
2488 my $returnType = GetTypeFromSignature($function->signature);
2489 my $returnsPodType = IsPodType($returnType);
2490 my $nativeReturnType = GetNativeType($returnType, 0);
2493 # Special case: SVG matrix transform methods should not mutate
2494 # the matrix but return a copy
2496 if ($implClassName eq "SVGMatrix" && $function->signature->type eq "SVGMatrix") {
2500 if ($function->signature->extendedAttributes->{"v8implname"}) {
2501 $name = $function->signature->extendedAttributes->{"v8implname"};
2504 if ($function->signature->extendedAttributes->{"ImplementationFunction"}) {
2505 $name = $function->signature->extendedAttributes->{"ImplementationFunction"};
2508 my $functionString = "imp->${name}(";
2511 $functionString = "result.${name}(";
2514 my $returnsListItemPodType = 0;
2515 # SVG lists functions that return POD types require special handling
2516 if (IsSVGListTypeNeedingSpecialHandling($implClassName) && IsSVGListMethod($name) && $returnsPodType) {
2517 $returnsListItemPodType = 1;
2518 $result .= $indent . "SVGList<RefPtr<SVGPODListItem<$nativeReturnType> > >* listImp = imp;\n";
2519 $functionString = "listImp->${name}(";
2523 my $hasScriptState = 0;
2525 my $callWith = $function->signature->extendedAttributes->{"CallWith"};
2527 my $callWithArg = "COMPILE_ASSERT(false)";
2528 if ($callWith eq "DynamicFrame") {
2529 $result .= $indent . "Frame* enteredFrame = V8Proxy::retrieveFrameForEnteredContext();\n";
2530 $result .= $indent . "if (!enteredFrame)\n";
2531 $result .= $indent . " return v8::Undefined();\n";
2532 $callWithArg = "enteredFrame";
2533 } elsif ($callWith eq "ScriptState") {
2534 $result .= $indent . "EmptyScriptState state;\n";
2535 $callWithArg = "&state";
2536 $hasScriptState = 1;
2538 $functionString .= ", " if $index;
2539 $functionString .= $callWithArg;
2541 $numberOfParameters++
2544 foreach my $parameter (@{$function->parameters}) {
2545 if ($index eq $numberOfParameters) {
2548 $functionString .= ", " if $index;
2549 my $paramName = $parameter->name;
2550 my $paramType = $parameter->type;
2552 # This is a bit of a hack... we need to convert parameters to methods on SVG lists
2553 # of POD types which are items in the list to appropriate SVGList<> instances
2554 if ($returnsListItemPodType && $paramType . "List" eq $implClassName) {
2555 $paramName = "SVGPODListItem<" . GetNativeType($paramType, 1) . ">::copy($paramName)";
2558 if ($parameter->type eq "NodeFilter" || $parameter->type eq "XPathNSResolver") {
2559 $functionString .= "$paramName.get()";
2561 $functionString .= $paramName;
2566 if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
2567 $functionString .= ", " if $index;
2568 $functionString .= "callStack.get()";
2572 if ($function->signature->extendedAttributes->{"NeedsUserGestureCheck"}) {
2573 $functionString .= ", " if $index;
2574 # FIXME: We need to pass DOMWrapperWorld as a parameter.
2575 # See http://trac.webkit.org/changeset/54182
2576 $functionString .= "processingUserGesture()";
2580 if (@{$function->raisesExceptions}) {
2581 $functionString .= ", " if $index;
2582 $functionString .= "ec";
2585 $functionString .= ")";
2587 my $return = "result";
2588 my $returnIsRef = IsRefPtrType($returnType);
2590 if ($returnType eq "void") {
2591 $result .= $indent . "$functionString;\n";
2592 } elsif ($copyFirst) {
2593 $result .= $indent . GetNativeType($returnType, 0) . " result = *imp;\n" . $indent . "$functionString;\n";
2594 } elsif ($returnsListItemPodType) {
2595 $result .= $indent . "RefPtr<SVGPODListItem<$nativeReturnType> > result = $functionString;\n";
2596 } elsif ($hasScriptState or @{$function->raisesExceptions} or $returnsPodType or $isPodType or IsSVGTypeNeedingContextParameter($returnType)) {
2597 $result .= $indent . $nativeReturnType . " result = $functionString;\n";
2599 # Can inline the function call into the return statement to avoid overhead of using a Ref<> temporary
2600 $return = $functionString;
2604 if (@{$function->raisesExceptions}) {
2605 $result .= $indent . "if (UNLIKELY(ec))\n";
2606 $result .= $indent . " goto fail;\n";
2609 if ($hasScriptState) {
2610 $result .= $indent . "if (state.hadException())\n";
2611 $result .= $indent . " return throwError(state.exception());\n"
2614 # If the return type is a POD type, separate out the wrapper generation
2615 if ($returnsListItemPodType) {
2616 $result .= $indent . "RefPtr<V8SVGPODTypeWrapper<" . $nativeReturnType . "> > wrapper = ";
2617 $result .= "V8SVGPODTypeWrapperCreatorForList<" . $nativeReturnType . ">::create($return, imp->associatedAttributeName());\n";
2618 $return = "wrapper";
2619 } elsif ($returnsPodType) {
2620 $result .= $indent . "RefPtr<V8SVGPODTypeWrapper<" . $nativeReturnType . "> > wrapper = ";
2621 $result .= GenerateSVGStaticPodTypeWrapper($returnType, $return) . ";\n";
2622 $return = "wrapper";
2625 my $generatedSVGContextRetrieval = 0;
2626 # If the return type needs an SVG context, output it
2627 if (IsSVGTypeNeedingContextParameter($returnType)) {
2628 $result .= GenerateSVGContextAssignment($implClassName, $return . ".get()", $indent);
2629 $generatedSVGContextRetrieval = 1;
2632 if (IsSVGTypeNeedingContextParameter($implClassName) && $implClassName =~ /List$/ && IsSVGListMutator($name)) {
2633 if (!$generatedSVGContextRetrieval) {
2634 $result .= GenerateSVGContextRetrieval($implClassName, $indent);
2635 $generatedSVGContextRetrieval = 1;
2638 $result .= $indent . "context->svgAttributeChanged(imp->associatedAttributeName());\n";
2639 $implIncludes{"SVGElement.h"} = 1;
2642 # If the implementing class is a POD type, commit changes
2644 if (!$generatedSVGContextRetrieval) {
2645 $result .= GenerateSVGContextRetrieval($implClassName, $indent);
2646 $generatedSVGContextRetrieval = 1;
2649 $result .= $indent . "impWrapper->commitChange(impInstance, context);\n";
2652 if ($returnsPodType) {
2653 $implIncludes{"V8${returnType}.h"} = 1;
2654 $result .= $indent . "return toV8(wrapper.release());\n";
2656 $return .= ".release()" if ($returnIsRef);
2657 $result .= $indent . ReturnNativeToJSValue($function->signature, $return, $indent) . ";\n";
2664 sub GetTypeFromSignature
2666 my $signature = shift;
2668 return $codeGenerator->StripModule($signature->type);
2672 sub GetNativeTypeFromSignature
2674 my $signature = shift;
2675 my $parameterIndex = shift;
2677 my $type = GetTypeFromSignature($signature);
2679 if ($type eq "unsigned long" and $signature->extendedAttributes->{"IsIndex"}) {
2680 # Special-case index arguments because we need to check that they aren't < 0.
2684 $type = GetNativeType($type, $parameterIndex >= 0 ? 1 : 0);
2686 if ($parameterIndex >= 0 && $type eq "V8Parameter") {
2688 if ($signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"}) {
2689 $mode = "WithUndefinedOrNullCheck";
2690 } elsif ($signature->extendedAttributes->{"ConvertNullToNullString"}) {
2691 $mode = "WithNullCheck";
2703 return 0 if $type eq "boolean";
2704 return 0 if $type eq "float";
2705 return 0 if $type eq "int";
2706 return 0 if $type eq "Date";
2707 return 0 if $type eq "DOMString";
2708 return 0 if $type eq "double";
2709 return 0 if $type eq "short";
2710 return 0 if $type eq "long";
2711 return 0 if $type eq "unsigned";
2712 return 0 if $type eq "unsigned long";
2713 return 0 if $type eq "unsigned short";
2714 return 0 if $type eq "SVGAnimatedPoints";
2722 my $isParameter = shift;
2724 if ($type eq "float" or $type eq "double") {
2728 return "V8Parameter" if ($type eq "DOMString" or $type eq "DOMUserData") and $isParameter;
2729 return "int" if $type eq "int";
2730 return "int" if $type eq "short" or $type eq "unsigned short";
2731 return "unsigned" if $type eq "unsigned long";
2732 return "int" if $type eq "long";
2733 return "long long" if $type eq "long long";
2734 return "unsigned long long" if $type eq "unsigned long long";
2735 return "bool" if $type eq "boolean";
2736 return "String" if $type eq "DOMString";
2737 return "Range::CompareHow" if $type eq "CompareHow";
2738 return "FloatRect" if $type eq "SVGRect";
2739 return "FloatPoint" if $type eq "SVGPoint";
2740 return "AffineTransform" if $type eq "SVGMatrix";
2741 return "SVGTransform" if $type eq "SVGTransform";
2742 return "SVGLength" if $type eq "SVGLength";
2743 return "SVGAngle" if $type eq "SVGAngle";
2744 return "float" if $type eq "SVGNumber";
2745 return "SVGPreserveAspectRatio" if $type eq "SVGPreserveAspectRatio";
2746 return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType";
2747 return "DOMTimeStamp" if $type eq "DOMTimeStamp";
2748 return "unsigned" if $type eq "unsigned int";
2749 return "Node*" if $type eq "EventTarget" and $isParameter;
2750 return "double" if $type eq "Date";
2751 return "ScriptValue" if $type eq "DOMObject";
2753 return "String" if $type eq "DOMUserData"; # FIXME: Temporary hack?
2756 return "RefPtr<NodeFilter>" if $type eq "NodeFilter";
2758 return "RefPtr<SerializedScriptValue>" if $type eq "SerializedScriptValue";
2760 # necessary as resolvers could be constructed on fly.
2761 return "RefPtr<XPathNSResolver>" if $type eq "XPathNSResolver";
2763 return "RefPtr<${type}>" if IsRefPtrType($type) and not $isParameter;
2765 # Default, assume native type is a pointer with same type name as idl type
2769 sub GetNativeTypeForCallbacks
2772 return "const String&" if $type eq "DOMString";
2774 # Callbacks use raw pointers, so pass isParameter = 1
2775 return GetNativeType($type, 1);
2778 sub TranslateParameter
2780 my $signature = shift;
2782 # The IDL uses some pseudo-types which don't really exist.
2783 if ($signature->type eq "TimeoutHandler") {
2784 $signature->type("DOMString");
2788 sub BasicTypeCanFailConversion
2790 my $signature = shift;
2791 my $type = GetTypeFromSignature($signature);
2793 return 1 if $type eq "SVGAngle";
2794 return 1 if $type eq "SVGLength";
2795 return 1 if $type eq "SVGMatrix";
2796 return 1 if $type eq "SVGPoint";
2797 return 1 if $type eq "SVGPreserveAspectRatio";
2798 return 1 if $type eq "SVGRect";
2799 return 1 if $type eq "SVGTransform";
2803 sub TypeCanFailConversion
2805 my $signature = shift;
2807 my $type = GetTypeFromSignature($signature);
2809 $implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr";
2810 return 1 if $type eq "Attr";
2811 return 1 if $type eq "VoidCallback";
2812 return BasicTypeCanFailConversion($signature);
2817 my $signature = shift;
2819 my $okParam = shift;
2820 my $maybeOkParam = $okParam ? ", ${okParam}" : "";
2822 my $type = GetTypeFromSignature($signature);
2824 return "$value" if $type eq "JSObject";
2825 return "$value->BooleanValue()" if $type eq "boolean";
2826 return "static_cast<$type>($value->NumberValue())" if $type eq "float" or $type eq "double";
2827 return "$value->NumberValue()" if $type eq "SVGNumber";
2829 return "toInt32($value${maybeOkParam})" if $type eq "unsigned long" or $type eq "unsigned short" or $type eq "long";
2830 return "toInt64($value)" if $type eq "unsigned long long" or $type eq "long long";
2831 return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "CompareHow";
2832 return "static_cast<SVGPaint::SVGPaintType>($value->ToInt32()->Int32Value())" if $type eq "SVGPaintType";
2833 return "toWebCoreDate($value)" if $type eq "Date";
2835 if ($type eq "DOMString" or $type eq "DOMUserData") {
2839 die "Unexpected SerializedScriptValue" if $type eq "SerializedScriptValue";
2841 if ($type eq "DOMObject") {
2842 $implIncludes{"ScriptValue.h"} = 1;
2843 return "ScriptValue($value)";
2846 if ($type eq "NodeFilter") {
2847 return "V8DOMWrapper::wrapNativeNodeFilter($value)";
2850 if ($type eq "SVGRect") {
2851 $implIncludes{"FloatRect.h"} = 1;
2854 if ($type eq "SVGPoint") {
2855 $implIncludes{"FloatPoint.h"} = 1;
2858 # Default, assume autogenerated type conversion routines
2859 if ($type eq "EventTarget") {
2860 $implIncludes{"V8Node.h"} = 1;
2862 # EventTarget is not in DOM hierarchy, but all Nodes are EventTarget.
2863 return "V8Node::HasInstance($value) ? V8Node::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
2866 if ($type eq "XPathNSResolver") {
2867 return "V8DOMWrapper::getXPathNSResolver($value)";
2870 AddIncludesForType($type);
2872 if (IsDOMNodeType($type)) {
2873 $implIncludes{"V8${type}.h"} = 1;
2875 # Perform type checks on the parameter, if it is expected Node type,
2877 return "V8${type}::HasInstance($value) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
2879 $implIncludes{"V8$type.h"} = 1;
2881 if (IsPodType($type)) {
2882 my $nativeType = GetNativeType($type);
2883 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
2885 return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(&V8${type}::info, $value${maybeOkParam})"
2888 $implIncludes{"V8${type}.h"} = 1;
2890 # Perform type checks on the parameter, if it is expected Node type,
2892 return "V8${type}::HasInstance($value) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
2899 return "V8Event.h" if $type eq "DOMTimeStamp";
2900 return "EventListener.h" if $type eq "EventListener";
2901 return "EventTarget.h" if $type eq "EventTarget";
2902 return "SerializedScriptValue.h" if $type eq "SerializedScriptValue";
2903 return "ScriptValue.h" if $type eq "DOMObject";
2904 return "V8${type}.h";
2907 sub CreateCustomSignature
2909 my $function = shift;
2910 my $count = @{$function->parameters};
2911 my $name = $function->signature->name;
2912 my $result = " const int ${name}Argc = ${count};\n" .
2913 " v8::Handle<v8::FunctionTemplate> ${name}Argv[${name}Argc] = { ";
2915 foreach my $parameter (@{$function->parameters}) {
2916 if ($first) { $first = 0; }
2917 else { $result .= ", "; }
2918 if (IsWrapperType($parameter->type)) {
2919 if ($parameter->type eq "XPathNSResolver") {
2920 # Special case for XPathNSResolver. All other browsers accepts a callable,
2921 # so, even though it's against IDL, accept objects here.
2922 $result .= "v8::Handle<v8::FunctionTemplate>()";
2924 my $type = $parameter->type;
2925 my $header = GetV8HeaderName($type);
2926 $implIncludes{$header} = 1;
2927 $result .= "V8${type}::GetRawTemplate()";
2930 $result .= "v8::Handle<v8::FunctionTemplate>()";
2934 $result .= " v8::Handle<v8::Signature> ${name}Signature = v8::Signature::New(desc, ${name}Argc, ${name}Argv);\n";
2939 sub RequiresCustomSignature
2941 my $function = shift;
2942 # No signature needed for Custom function
2943 if ($function->signature->extendedAttributes->{"Custom"} ||
2944 $function->signature->extendedAttributes->{"V8Custom"}) {
2947 # No signature needed for overloaded function
2948 if (@{$function->{overloads}} > 1) {
2952 foreach my $parameter (@{$function->parameters}) {
2953 if ($parameter->extendedAttributes->{"Optional"}) {
2958 foreach my $parameter (@{$function->parameters}) {
2959 if (IsWrapperType($parameter->type)) {
2967 # FIXME: Sort this array.
2968 my %non_wrapper_types = (
2972 'unsigned int' => 1,
2974 'unsigned short' => 1,
2976 'unsigned long' => 1,
2979 'unsigned long long' => 1,
2982 'SerializedScriptValue' => 1,
2986 'SVGPreserveAspectRatio' => 1,
2988 'SVGTransform' => 1,
2991 'SVGPaintType' => 1,
2992 'DOMTimeStamp' => 1,
2997 'EventListener' => 1
3003 my $type = $codeGenerator->StripModule(shift);
3004 return !($non_wrapper_types{$type});
3011 return 1 if $type eq 'Attr';
3012 return 1 if $type eq 'CDATASection';
3013 return 1 if $type eq 'Comment';
3014 return 1 if $type eq 'Document';
3015 return 1 if $type eq 'DocumentFragment';
3016 return 1 if $type eq 'DocumentType';
3017 return 1 if $type eq 'Element';
3018 return 1 if $type eq 'EntityReference';
3019 return 1 if $type eq 'HTMLCanvasElement';
3020 return 1 if $type eq 'HTMLDocument';
3021 return 1 if $type eq 'HTMLElement';
3022 return 1 if $type eq 'HTMLFormElement';
3023 return 1 if $type eq 'HTMLTableCaptionElement';
3024 return 1 if $type eq 'HTMLTableSectionElement';
3025 return 1 if $type eq 'Node';
3026 return 1 if $type eq 'ProcessingInstruction';
3027 return 1 if $type eq 'SVGElement';
3028 return 1 if $type eq 'SVGDocument';
3029 return 1 if $type eq 'SVGSVGElement';
3030 return 1 if $type eq 'SVGUseElement';
3031 return 1 if $type eq 'Text';
3037 sub ReturnNativeToJSValue
3039 my $signature = shift;
3042 my $type = GetTypeFromSignature($signature);
3044 return "return v8::Date::New(static_cast<double>($value))" if $type eq "DOMTimeStamp";
3045 return "return v8Boolean($value)" if $type eq "boolean";
3046 return "return v8::Handle<v8::Value>()" if $type eq "void"; # equivalent to v8::Undefined()
3048 # For all the types where we use 'int' as the representation type,
3049 # we use Integer::New which has a fast Smi conversion check.
3050 my $nativeType = GetNativeType($type);
3051 return "return v8::Integer::New($value)" if $nativeType eq "int";
3052 return "return v8::Integer::NewFromUnsigned($value)" if $nativeType eq "unsigned";
3054 return "return v8DateOrNull($value)" if $type eq "Date";
3055 # long long and unsigned long long are not representable in ECMAScript.
3056 return "return v8::Number::New(static_cast<double>($value))" if $type eq "long long" or $type eq "unsigned long long";
3057 return "return v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType";
3058 return "return $value.v8Value()" if $nativeType eq "ScriptValue";
3060 if ($codeGenerator->IsStringType($type)) {
3061 my $conv = $signature->extendedAttributes->{"ConvertNullStringTo"};
3062 if (defined $conv) {
3063 return "return v8StringOrNull($value)" if $conv eq "Null";
3064 return "return v8StringOrUndefined($value)" if $conv eq "Undefined";
3065 return "return v8StringOrFalse($value)" if $conv eq "False";
3067 die "Unknown value for ConvertNullStringTo extended attribute";
3069 $conv = $signature->extendedAttributes->{"ConvertScriptString"};
3070 return "v8StringOrNull(exec, $value)" if $conv;
3071 return "return v8String($value)";
3074 AddIncludesForType($type);
3076 # special case for non-DOM node interfaces
3077 if (IsDOMNodeType($type)) {
3078 return "return toV8(${value}" . ($signature->extendedAttributes->{"ReturnsNew"} ? ", true)" : ")");
3081 if ($type eq "EventTarget") {
3082 return "return V8DOMWrapper::convertEventTargetToV8Object($value)";
3085 if ($type eq "EventListener") {
3086 $implIncludes{"V8AbstractEventListener.h"} = 1;
3087 return "return ${value} ? v8::Handle<v8::Value>(static_cast<V8AbstractEventListener*>(${value})->getListenerObject(imp->scriptExecutionContext())) : v8::Handle<v8::Value>(v8::Null())";
3090 if ($type eq "SerializedScriptValue") {
3091 $implIncludes{"$type.h"} = 1;
3092 return "return $value->deserialize()";
3095 $implIncludes{"wtf/RefCounted.h"} = 1;
3096 $implIncludes{"wtf/RefPtr.h"} = 1;
3097 $implIncludes{"wtf/GetPtr.h"} = 1;
3099 if (IsPodType($type)) {
3100 $value = GenerateSVGStaticPodTypeWrapper($type, $value) . ".get()";
3103 return "return toV8($value)";
3106 sub GenerateSVGStaticPodTypeWrapper {
3110 $implIncludes{"V8$type.h"}=1;
3111 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
3113 my $nativeType = GetNativeType($type);
3114 return "V8SVGStaticPODTypeWrapper<$nativeType>::create($value)";
3120 if (defined($IMPL)) {
3121 # Write content to file.
3122 print $IMPL @implContentHeader;
3124 print $IMPL @implFixedHeader;
3126 foreach my $implInclude (sort keys(%implIncludes)) {
3127 my $checkType = $implInclude;
3128 $checkType =~ s/\.h//;
3130 if ($implInclude =~ /wtf/) {
3131 print $IMPL "#include \<$implInclude\>\n";
3133 print $IMPL "#include \"$implInclude\"\n" unless $codeGenerator->IsSVGAnimatedType($checkType);
3138 print $IMPL @implContentDecls;
3139 print $IMPL @implContent;
3144 @implFixedHeader = ();
3145 @implHeaderContent = ();
3146 @implContentDecls = ();
3150 if (defined($HEADER)) {
3151 # Write content to file.
3152 print $HEADER @headerContent;
3156 @headerContent = ();
3160 sub IsSVGTypeNeedingContextParameter
3162 my $implClassName = shift;
3164 if ($implClassName =~ /SVG/ and not $implClassName =~ /Element/) {
3165 return 1 unless $implClassName =~ /SVGPaint/ or $implClassName =~ /SVGColor/ or $implClassName =~ /SVGDocument/;
3171 sub GenerateSVGContextAssignment
3173 my $srcType = shift;
3177 $result = GenerateSVGContextRetrieval($srcType, $indent);
3178 $result .= $indent . "V8Proxy::setSVGContext($value, context);\n";
3183 sub GenerateSVGContextRetrieval
3185 my $srcType = shift;
3188 my $srcIsPodType = IsPodType($srcType);
3190 my $srcObject = "imp";
3191 if ($srcIsPodType) {
3192 $srcObject = "impWrapper";
3197 if (IsSVGTypeNeedingContextParameter($srcType)) {
3198 $contextDecl = "V8Proxy::svgContext($srcObject)";
3200 $contextDecl = $srcObject;
3203 return $indent . "SVGElement* context = $contextDecl;\n";
3206 sub IsSVGListMutator
3208 my $functionName = shift;
3210 return 1 if $functionName eq "clear";
3211 return 1 if $functionName eq "initialize";
3212 return 1 if $functionName eq "insertItemBefore";
3213 return 1 if $functionName eq "replaceItem";
3214 return 1 if $functionName eq "removeItem";
3215 return 1 if $functionName eq "appendItem";
3222 my $functionName = shift;
3224 return 1 if $functionName eq "getFirst";
3225 return 1 if $functionName eq "getLast";
3226 return 1 if $functionName eq "getItem";
3228 return IsSVGListMutator($functionName);
3231 sub IsSVGListTypeNeedingSpecialHandling
3233 my $className = shift;
3235 return 1 if $className eq "SVGPointList";
3236 return 1 if $className eq "SVGTransformList";
3241 sub GetVisibleInterfaceName
3243 my $interfaceName = shift;
3245 return "DOMException" if $interfaceName eq "DOMCoreException";
3246 return "FormData" if $interfaceName eq "DOMFormData";
3247 return $interfaceName;