[V8] Add a "context type" parameter to GetTemplate and ConfigureV8SomethingTemplate...
[WebKit-https.git] / Source / WebCore / bindings / scripts / CodeGeneratorV8.pm
1 # Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
2 # Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
3 # Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
4 # Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
5 # Copyright (C) 2006 Apple Computer, Inc.
6 # Copyright (C) 2007, 2008, 2009, 2012 Google Inc.
7 # Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
8 # Copyright (C) Research In Motion Limited 2010. All rights reserved.
9 # Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
10 # Copyright (C) 2012 Ericsson AB. All rights reserved.
11 #
12 # This library is free software; you can redistribute it and/or
13 # modify it under the terms of the GNU Library General Public
14 # License as published by the Free Software Foundation; either
15 # version 2 of the License, or (at your option) any later version.
16 #
17 # This library is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 # Library General Public License for more details.
21 #
22 # You should have received a copy of the GNU Library General Public License
23 # along with this library; see the file COPYING.LIB.  If not, write to
24 # the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 # Boston, MA 02111-1307, USA.
26 #
27
28 package CodeGeneratorV8;
29
30 use strict;
31
32 use constant FileNamePrefix => "V8";
33
34 my $codeGenerator;
35
36
37 my @headerContent = ();
38 my @implContentHeader = ();
39 my @implContent = ();
40 my @implContentInternals = ();
41 my %implIncludes = ();
42 my %headerIncludes = ();
43
44 # Default .h template
45 my $headerTemplate = << "EOF";
46 /*
47     This file is part of the WebKit open source project.
48     This file has been generated by generate-bindings.pl. DO NOT MODIFY!
49
50     This library is free software; you can redistribute it and/or
51     modify it under the terms of the GNU Library General Public
52     License as published by the Free Software Foundation; either
53     version 2 of the License, or (at your option) any later version.
54
55     This library is distributed in the hope that it will be useful,
56     but WITHOUT ANY WARRANTY; without even the implied warranty of
57     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
58     Library General Public License for more details.
59
60     You should have received a copy of the GNU Library General Public License
61     along with this library; see the file COPYING.LIB.  If not, write to
62     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
63     Boston, MA 02111-1307, USA.
64 */
65 EOF
66
67 # Default constructor
68 sub new
69 {
70     my $object = shift;
71     my $reference = { };
72
73     $codeGenerator = shift;
74
75     bless($reference, $object);
76     return $reference;
77 }
78
79 sub GenerateInterface
80 {
81     my $object = shift;
82     my $interface = shift;
83
84     # Start actual generation
85     if ($interface->extendedAttributes->{"Callback"}) {
86         $object->GenerateCallbackHeader($interface);
87         $object->GenerateCallbackImplementation($interface);
88     } else {
89         $object->GenerateHeader($interface);
90         $object->GenerateImplementation($interface);
91     }
92 }
93
94 sub AddToImplIncludes
95 {
96     my $header = shift;
97     my $conditional = shift;
98
99     if (not $conditional) {
100         $implIncludes{$header} = 1;
101     } elsif (not exists($implIncludes{$header})) {
102         $implIncludes{$header} = $conditional;
103     } else {
104         my $oldValue = $implIncludes{$header};
105         if ($oldValue ne 1) {
106             my %newValue = ();
107             $newValue{$conditional} = 1;
108             foreach my $condition (split(/\|/, $oldValue)) {
109                 $newValue{$condition} = 1;
110             }
111             $implIncludes{$header} = join("|", sort keys %newValue);
112         }
113     }
114 }
115
116 sub AddIncludesForType
117 {
118     my $type = shift;
119
120     # When we're finished with the one-file-per-class
121     # reorganization, we won't need these special cases.
122     if ($codeGenerator->IsTypedArrayType($type)) {
123         AddToImplIncludes("wtf/${type}.h");
124     }
125     if (!$codeGenerator->IsPrimitiveType($type) and !$codeGenerator->IsStringType($type) and !$codeGenerator->SkipIncludeHeader($type) and $type ne "Date") {
126         # default, include the same named file
127         AddToImplIncludes(GetV8HeaderName(${type}));
128
129         if ($type =~ /SVGPathSeg/) {
130             my $joinedName = $type;
131             $joinedName =~ s/Abs|Rel//;
132             AddToImplIncludes("${joinedName}.h");
133         }
134     }
135
136     # additional includes (things needed to compile the bindings but not the header)
137
138     if ($type eq "CanvasRenderingContext2D") {
139         AddToImplIncludes("CanvasGradient.h");
140         AddToImplIncludes("CanvasPattern.h");
141         AddToImplIncludes("CanvasStyle.h");
142     }
143
144     if ($type eq "CanvasGradient" or $type eq "XPathNSResolver") {
145         AddToImplIncludes("wtf/text/WTFString.h");
146     }
147
148     if ($type eq "CSSStyleSheet" or $type eq "StyleSheet") {
149         AddToImplIncludes("CSSImportRule.h");
150     }
151
152     if ($type eq "CSSStyleDeclaration") {
153         AddToImplIncludes("StylePropertySet.h");
154     }
155
156     if ($type eq "Plugin" or $type eq "PluginArray" or $type eq "MimeTypeArray") {
157         # So we can get String -> AtomicString conversion for namedItem().
158         AddToImplIncludes("wtf/text/AtomicString.h");
159     }
160 }
161
162 sub NeedsCustomOpaqueRootForGC
163 {
164     my $interface = shift;
165     return GetGenerateIsReachable($interface) || GetCustomIsReachable($interface);
166 }
167
168 sub GetGenerateIsReachable
169 {
170     my $interface = shift;
171     return $interface->extendedAttributes->{"GenerateIsReachable"} || $interface->extendedAttributes->{"V8GenerateIsReachable"} || ""
172 }
173
174 sub GetCustomIsReachable
175 {
176     my $interface = shift;
177     return $interface->extendedAttributes->{"CustomIsReachable"} || $interface->extendedAttributes->{"V8CustomIsReachable"};
178 }
179
180 sub GenerateOpaqueRootForGC
181 {
182     my $interface = shift;
183     my $interfaceName = $interface->name;
184
185     if (GetCustomIsReachable($interface)) {
186         return;
187     }
188
189     push(@implContent, <<END);
190 void* V8${interfaceName}::opaqueRootForGC(void* object, v8::Persistent<v8::Object> wrapper, v8::Isolate* isolate)
191 {
192     ASSERT(!wrapper.IsIndependent(isolate));
193     ${interfaceName}* impl = static_cast<${interfaceName}*>(object);
194 END
195     if (GetGenerateIsReachable($interface) eq  "ImplDocument" ||
196         GetGenerateIsReachable($interface) eq  "ImplElementRoot" ||
197         GetGenerateIsReachable($interface) eq  "ImplOwnerRoot" ||
198         GetGenerateIsReachable($interface) eq  "ImplOwnerNodeRoot") {
199
200         $implIncludes{"V8GCController.h"} = 1;
201
202         my $methodName;
203         $methodName = "document" if (GetGenerateIsReachable($interface) eq "ImplDocument");
204         $methodName = "element" if (GetGenerateIsReachable($interface) eq "ImplElementRoot");
205         $methodName = "owner" if (GetGenerateIsReachable($interface) eq "ImplOwnerRoot");
206         $methodName = "ownerNode" if (GetGenerateIsReachable($interface) eq "ImplOwnerNodeRoot");
207
208         push(@implContent, <<END);
209     if (Node* owner = impl->${methodName}())
210         return V8GCController::opaqueRootForGC(owner, isolate);
211 END
212     }
213
214     push(@implContent, <<END);
215     return object;
216 }
217
218 END
219 }
220
221 sub GetSVGPropertyTypes
222 {
223     my $implType = shift;
224
225     my $svgPropertyType;
226     my $svgListPropertyType;
227     my $svgNativeType;
228
229     return ($svgPropertyType, $svgListPropertyType, $svgNativeType) if not $implType =~ /SVG/;
230
231     $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($implType);
232     return ($svgPropertyType, $svgListPropertyType, $svgNativeType) if not $svgNativeType;
233
234     # Append space to avoid compilation errors when using  PassRefPtr<$svgNativeType>
235     $svgNativeType = "$svgNativeType ";
236
237     my $svgWrappedNativeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($implType);
238     if ($svgNativeType =~ /SVGPropertyTearOff/) {
239         $svgPropertyType = $svgWrappedNativeType;
240         AddToImplIncludes("SVGAnimatedPropertyTearOff.h");
241     } elsif ($svgNativeType =~ /SVGListPropertyTearOff/ or $svgNativeType =~ /SVGStaticListPropertyTearOff/) {
242         $svgListPropertyType = $svgWrappedNativeType;
243         $headerIncludes{"SVGAnimatedListPropertyTearOff.h"} = 1;
244         $headerIncludes{"SVGStaticListPropertyTearOff.h"} = 1;
245     } elsif ($svgNativeType =~ /SVGTransformListPropertyTearOff/) {
246         $svgListPropertyType = $svgWrappedNativeType;
247         $headerIncludes{"SVGAnimatedListPropertyTearOff.h"} = 1;
248         $headerIncludes{"SVGTransformListPropertyTearOff.h"} = 1;
249     } elsif ($svgNativeType =~ /SVGPathSegListPropertyTearOff/) {
250         $svgListPropertyType = $svgWrappedNativeType;
251         $headerIncludes{"SVGPathSegListPropertyTearOff.h"} = 1;
252     }
253
254     if ($svgPropertyType) {
255         $svgPropertyType = "SVGPoint" if $svgPropertyType eq "FloatPoint";
256     }
257
258     return ($svgPropertyType, $svgListPropertyType, $svgNativeType);
259 }
260
261 sub GenerateHeader
262 {
263     my $object = shift;
264     my $interface = shift;
265
266     my $interfaceName = $interface->name;
267     my $v8InterfaceName = "V8$interfaceName";
268
269     # Copy contents of parent interfaces except the first parent.
270     my @parents;
271     $codeGenerator->AddMethodsConstantsAndAttributesFromParentInterfaces($interface, \@parents, 1);
272     $codeGenerator->LinkOverloadedFunctions($interface);
273
274     # Ensure the IsDOMNodeType function is in sync.
275     die("IsDOMNodeType is out of date with respect to $interfaceName") if IsDOMNodeType($interfaceName) != $codeGenerator->InheritsInterface($interface, "Node");
276
277     my $hasDependentLifetime = $interface->extendedAttributes->{"V8DependentLifetime"} || $codeGenerator->InheritsExtendedAttribute($interface, "ActiveDOMObject") || GetGenerateIsReachable($interface) || $v8InterfaceName =~ /SVG/;
278     if (!$hasDependentLifetime) {
279         foreach (@{$interface->parents}) {
280             my $parent = $_;
281             $headerIncludes{"V8${parent}.h"} = 1;
282         }
283     }
284
285     # - Add default header template
286     push(@headerContent, GenerateHeaderContentHeader($interface));
287
288     $headerIncludes{"wtf/text/StringHash.h"} = 1;
289     $headerIncludes{"WrapperTypeInfo.h"} = 1;
290     $headerIncludes{"V8Binding.h"} = 1;
291     $headerIncludes{"V8DOMWrapper.h"} = 1;
292     $headerIncludes{"wtf/HashMap.h"} = 1;
293     $headerIncludes{"v8.h"} = 1;
294
295     my $headerClassInclude = GetHeaderClassInclude($interfaceName);
296     $headerIncludes{$headerClassInclude} = 1 if $headerClassInclude ne "";
297
298     my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGPropertyTypes($interfaceName);
299
300     foreach my $headerInclude (sort keys(%headerIncludes)) {
301         if ($headerInclude =~ /wtf|v8\.h/) {
302             push(@headerContent, "#include \<${headerInclude}\>\n");
303         } else {
304             push(@headerContent, "#include \"${headerInclude}\"\n");
305         }
306     }
307
308     push(@headerContent, "\nnamespace WebCore {\n");
309     push(@headerContent, "\ntemplate<typename PropertyType> class SVGPropertyTearOff;\n") if $svgPropertyType;
310     if ($svgNativeType) {
311         if ($svgNativeType =~ /SVGStaticListPropertyTearOff/) {
312             push(@headerContent, "\ntemplate<typename PropertyType> class SVGStaticListPropertyTearOff;\n");
313         } else {
314             push(@headerContent, "\ntemplate<typename PropertyType> class SVGListPropertyTearOff;\n");
315         }
316     }
317
318     push(@headerContent, "\n");
319     push(@headerContent, "class FloatRect;\n") if $svgPropertyType && $svgPropertyType eq "FloatRect";
320     push(@headerContent, "class Dictionary;\n") if $codeGenerator->IsConstructorTemplate($interface, "Event");
321
322     my $nativeType = GetNativeTypeForConversions($interface);
323     if ($interface->extendedAttributes->{"NamedConstructor"}) {
324         push(@headerContent, <<END);
325 class V8${nativeType}Constructor {
326 public:
327     static v8::Persistent<v8::FunctionTemplate> GetTemplate(v8::Isolate*, WrapperWorldType);
328     static WrapperTypeInfo info;
329 };
330
331 END
332     }
333
334     push(@headerContent, "class $v8InterfaceName {\n");
335     push(@headerContent, "public:\n");
336
337     push(@headerContent, "    static const bool hasDependentLifetime = ");
338     if ($hasDependentLifetime) {
339         push(@headerContent, "true;\n");
340     } elsif (@{$interface->parents}) {
341         # Even if this type doesn't have the V8DependentLifetime attribute its parents may.
342         # Let the compiler statically determine this for us.
343         my $separator = "";
344         foreach (@{$interface->parents}) {
345             my $parent = $_;
346             $headerIncludes{"V8${parent}.h"} = 1;
347             push(@headerContent, "${separator}V8${parent}::hasDependentLifetime");
348             $separator = " || ";
349         }
350         push(@headerContent, ";\n");
351     } else {
352         push(@headerContent, "false;\n");
353     }
354
355     my $fromFunctionOpening = "";
356     my $fromFunctionClosing = "";
357     if ($interface->extendedAttributes->{"V8WrapAsFunction"}) {
358         $fromFunctionOpening = "V8DOMWrapper::fromFunction(";
359         $fromFunctionClosing = ")";
360     }
361
362     push(@headerContent, <<END);
363     static bool HasInstance(v8::Handle<v8::Value>, v8::Isolate*);
364     static v8::Persistent<v8::FunctionTemplate> GetRawTemplate(v8::Isolate*);
365     static v8::Persistent<v8::FunctionTemplate> GetTemplate(v8::Isolate*, WrapperWorldType);
366     static ${nativeType}* toNative(v8::Handle<v8::Object> object)
367     {
368         return reinterpret_cast<${nativeType}*>(${fromFunctionOpening}object${fromFunctionClosing}->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
369     }
370     static void derefObject(void*);
371     static WrapperTypeInfo info;
372 END
373
374     if (NeedsCustomOpaqueRootForGC($interface)) {
375         push(@headerContent, "    static void* opaqueRootForGC(void*, v8::Persistent<v8::Object>, v8::Isolate*);\n");
376     }
377
378     if ($codeGenerator->InheritsExtendedAttribute($interface, "ActiveDOMObject")) {
379         push(@headerContent, "    static ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object>);\n");
380     }
381
382     if ($codeGenerator->InheritsExtendedAttribute($interface, "EventTarget")) {
383         push(@headerContent, "    static EventTarget* toEventTarget(v8::Handle<v8::Object>);\n");
384     }
385
386     if ($interfaceName eq "DOMWindow") {
387         push(@headerContent, <<END);
388     static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate(v8::Isolate*);
389 END
390     }
391
392     if ($interfaceName eq "HTMLDocument") {
393       push(@headerContent, <<END);
394     static v8::Local<v8::Object> wrapInShadowObject(v8::Local<v8::Object> wrapper, Node* impl, v8::Isolate*);
395 END
396     }
397
398     my @enabledPerContextFunctions;
399     foreach my $function (@{$interface->functions}) {
400         my $name = $function->signature->name;
401         my $attrExt = $function->signature->extendedAttributes;
402
403         if (HasCustomMethod($attrExt) && !$attrExt->{"ImplementedBy"} && $function->{overloadIndex} == 1) {
404             my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature);
405             push(@headerContent, "#if ${conditionalString}\n") if $conditionalString;
406             push(@headerContent, <<END);
407     static v8::Handle<v8::Value> ${name}MethodCustom(const v8::Arguments&);
408 END
409             push(@headerContent, "#endif // ${conditionalString}\n") if $conditionalString;
410         }
411         if ($attrExt->{"V8EnabledPerContext"}) {
412             push(@enabledPerContextFunctions, $function);
413         }
414     }
415
416     if (IsConstructable($interface)) {
417         push(@headerContent, "    static v8::Handle<v8::Value> constructorCallback(const v8::Arguments&);\n");
418 END
419     }
420     if (HasCustomConstructor($interface)) {
421         push(@headerContent, "    static v8::Handle<v8::Value> constructorCustom(const v8::Arguments&);\n");
422     }
423
424     my @enabledPerContextAttributes;
425     foreach my $attribute (@{$interface->attributes}) {
426         my $name = $attribute->signature->name;
427         my $attrExt = $attribute->signature->extendedAttributes;
428         my $conditionalString = $codeGenerator->GenerateConditionalString($attribute->signature);
429         if (HasCustomGetter($attrExt) && !$attrExt->{"ImplementedBy"}) {
430             push(@headerContent, "#if ${conditionalString}\n") if $conditionalString;
431             push(@headerContent, <<END);
432     static v8::Handle<v8::Value> ${name}AttrGetterCustom(v8::Local<v8::String> name, const v8::AccessorInfo&);
433 END
434             push(@headerContent, "#endif // ${conditionalString}\n") if $conditionalString;
435         }
436         if (HasCustomSetter($attrExt) && !$attrExt->{"ImplementedBy"}) {
437             push(@headerContent, "#if ${conditionalString}\n") if $conditionalString;
438             push(@headerContent, <<END);
439     static void ${name}AttrSetterCustom(v8::Local<v8::String> name, v8::Local<v8::Value>, const v8::AccessorInfo&);
440 END
441             push(@headerContent, "#endif // ${conditionalString}\n") if $conditionalString;
442         }
443         if ($attrExt->{"V8EnabledPerContext"}) {
444             push(@enabledPerContextAttributes, $attribute);
445         }
446     }
447
448     GenerateHeaderNamedAndIndexedPropertyAccessors($interface);
449     GenerateHeaderCustomCall($interface);
450     GenerateHeaderCustomInternalFieldIndices($interface);
451
452     if ($interface->name eq "DOMWindow") {
453         push(@headerContent, <<END);
454     static bool namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType, v8::Local<v8::Value> data);
455     static bool indexedSecurityCheckCustom(v8::Local<v8::Object> host, uint32_t index, v8::AccessType, v8::Local<v8::Value> data);
456 END
457     }
458
459     if (@enabledPerContextAttributes) {
460         push(@headerContent, <<END);
461     static void installPerContextProperties(v8::Handle<v8::Object>, ${nativeType}*, v8::Isolate*);
462 END
463     } else {
464         push(@headerContent, <<END);
465     static void installPerContextProperties(v8::Handle<v8::Object>, ${nativeType}*, v8::Isolate*) { }
466 END
467     }
468
469     if (@enabledPerContextFunctions) {
470         push(@headerContent, <<END);
471     static void installPerContextPrototypeProperties(v8::Handle<v8::Object>, v8::Isolate*);
472 END
473     } else {
474         push(@headerContent, <<END);
475     static void installPerContextPrototypeProperties(v8::Handle<v8::Object>, v8::Isolate*) { }
476 END
477     }
478
479     if ($interfaceName eq "HTMLElement") {
480         push(@headerContent, <<END);
481     friend v8::Handle<v8::Object> createV8HTMLWrapper(HTMLElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
482     friend v8::Handle<v8::Object> createV8HTMLDirectWrapper(HTMLElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
483 END
484     } elsif ($interfaceName eq "SVGElement") {
485         push(@headerContent, <<END);
486     friend v8::Handle<v8::Object> createV8SVGWrapper(SVGElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
487     friend v8::Handle<v8::Object> createV8SVGDirectWrapper(SVGElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
488     friend v8::Handle<v8::Object> createV8SVGFallbackWrapper(SVGElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
489 END
490     } elsif ($interfaceName eq "HTMLUnknownElement") {
491         push(@headerContent, <<END);
492     friend v8::Handle<v8::Object> createV8HTMLFallbackWrapper(HTMLUnknownElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
493 END
494     } elsif ($interfaceName eq "Element") {
495         push(@headerContent, <<END);
496     // This is a performance optimization hack. See V8Element::wrap.
497     friend v8::Handle<v8::Object> wrap(Node*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
498 END
499     }
500
501         push(@headerContent, <<END);
502 private:
503 END
504
505     my $noToV8 = $interface->extendedAttributes->{"SuppressToJSObject"};
506     my $noWrap = $interface->extendedAttributes->{"V8NoWrapperCache"} || $noToV8;
507     if (!$noWrap) {
508         my $createWrapperArgumentType = GetPassRefPtrType($nativeType);
509         push(@headerContent, <<END);
510     friend v8::Handle<v8::Object> wrap(${nativeType}*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
511     static v8::Handle<v8::Object> createWrapper(${createWrapperArgumentType}, v8::Handle<v8::Object> creationContext, v8::Isolate*);
512 END
513     }
514
515     push(@headerContent, <<END);
516 };
517
518 END
519
520     my $customWrap = !!($interface->extendedAttributes->{"CustomToJSObject"} or $interface->extendedAttributes->{"V8CustomToJSObject"});
521     if ($noToV8) {
522         die "Can't suppress toV8 for subclass\n" if @parents;
523     } elsif ($noWrap) {
524         die "Must have custom toV8\n" if !$customWrap;
525         push(@headerContent, <<END);
526 class ${nativeType};
527 v8::Handle<v8::Value> toV8(${nativeType}*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
528
529 template<class HolderContainer, class Wrappable>
530 inline v8::Handle<v8::Value> toV8Fast(${nativeType}* impl, const HolderContainer& container, Wrappable*)
531 {
532     return toV8(impl, container.Holder(), container.GetIsolate());
533 }
534 END
535     } else {
536
537         my $createWrapperCall = $customWrap ? "${v8InterfaceName}::wrap" : "${v8InterfaceName}::createWrapper";
538         my $returningWrapper = $interface->extendedAttributes->{"V8WrapAsFunction"} ? "V8DOMWrapper::toFunction(wrapper)" : "wrapper";
539         my $returningCreatedWrapperOpening = $interface->extendedAttributes->{"V8WrapAsFunction"} ? "V8DOMWrapper::toFunction(" : "";
540         my $returningCreatedWrapperClosing = $interface->extendedAttributes->{"V8WrapAsFunction"} ? ", impl->name(), isolate)" : "";
541
542         if ($customWrap) {
543             push(@headerContent, <<END);
544
545 v8::Handle<v8::Object> wrap(${nativeType}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate*);
546 END
547         } else {
548             push(@headerContent, <<END);
549
550 inline v8::Handle<v8::Object> wrap(${nativeType}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
551 {
552     ASSERT(impl);
553     ASSERT(DOMDataStore::getWrapper(impl, isolate).IsEmpty());
554     return ${returningCreatedWrapperOpening}$createWrapperCall(impl, creationContext, isolate)${returningCreatedWrapperClosing};
555 }
556 END
557         }
558
559         push(@headerContent, <<END);
560
561 inline v8::Handle<v8::Value> toV8(${nativeType}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
562 {
563     if (UNLIKELY(!impl))
564         return v8NullWithCheck(isolate);
565     v8::Handle<v8::Value> wrapper = DOMDataStore::getWrapper(impl, isolate);
566     if (!wrapper.IsEmpty())
567         return $returningWrapper;
568     return wrap(impl, creationContext, isolate);
569 }
570
571 template<class HolderContainer, class Wrappable>
572 inline v8::Handle<v8::Value> toV8Fast(${nativeType}* impl, const HolderContainer& container, Wrappable* wrappable)
573 {
574     if (UNLIKELY(!impl))
575         return v8Null(container.GetIsolate());
576     v8::Handle<v8::Object> wrapper = DOMDataStore::getWrapperFast(impl, container, wrappable);
577     if (!wrapper.IsEmpty())
578         return $returningWrapper;
579     return wrap(impl, container.Holder(), container.GetIsolate());
580 }
581 END
582     }
583
584     push(@headerContent, <<END);
585
586 template<class HolderContainer, class Wrappable>
587 inline v8::Handle<v8::Value> toV8Fast(PassRefPtr< ${nativeType} > impl, const HolderContainer& container, Wrappable* wrappable)
588 {
589     return toV8Fast(impl.get(), container, wrappable);
590 }
591
592 inline v8::Handle<v8::Value> toV8(PassRefPtr< ${nativeType} > impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
593 {
594     return toV8(impl.get(), creationContext, isolate);
595 }
596 END
597
598     if ($codeGenerator->IsConstructorTemplate($interface, "Event")) {
599         push(@headerContent, "\nbool fill${interfaceName}Init(${interfaceName}Init&, const Dictionary&);\n");
600     }
601
602     push(@headerContent, "\n}\n\n");
603     push(@headerContent, "#endif // $v8InterfaceName" . "_h\n");
604
605     my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
606     push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditionalString;
607 }
608
609 sub GetInternalFields
610 {
611     my $interface = shift;
612
613     my @customInternalFields = ();
614     # Event listeners on DOM nodes are explicitly supported in the GC controller.
615     if (!$codeGenerator->InheritsInterface($interface, "Node") &&
616         $codeGenerator->InheritsExtendedAttribute($interface, "EventTarget")) {
617         push(@customInternalFields, "eventListenerCacheIndex");
618     }
619     return @customInternalFields;
620 }
621
622 sub GetHeaderClassInclude
623 {
624     my $v8InterfaceName = shift;
625     if ($v8InterfaceName =~ /SVGPathSeg/) {
626         $v8InterfaceName =~ s/Abs|Rel//;
627     }
628     return "wtf/${v8InterfaceName}.h" if $codeGenerator->IsTypedArrayType($v8InterfaceName);
629     return "" if ($codeGenerator->SkipIncludeHeader($v8InterfaceName));
630     return "${v8InterfaceName}.h";
631 }
632
633 sub GenerateHeaderCustomInternalFieldIndices
634 {
635     my $interface = shift;
636     my @customInternalFields = GetInternalFields($interface);
637     my $customFieldCounter = 0;
638     foreach my $customInternalField (@customInternalFields) {
639         push(@headerContent, <<END);
640     static const int ${customInternalField} = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
641 END
642         $customFieldCounter++;
643     }
644     push(@headerContent, <<END);
645     static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
646 END
647 }
648
649 my %indexerSpecialCases = (
650     "Storage" => 1,
651     "HTMLAppletElement" => 1,
652     "HTMLEmbedElement" => 1,
653     "HTMLObjectElement" => 1
654 );
655
656 sub GenerateHeaderNamedAndIndexedPropertyAccessors
657 {
658     my $interface = shift;
659     my $interfaceName = $interface->name;
660     my $hasCustomIndexedGetter = $interface->extendedAttributes->{"IndexedGetter"} || $interface->extendedAttributes->{"CustomGetOwnPropertySlot"};
661     my $hasCustomIndexedSetter = $interface->extendedAttributes->{"CustomIndexedSetter"} && !$interface->extendedAttributes->{"NumericIndexedGetter"};
662     my $hasCustomNamedGetter = $interface->extendedAttributes->{"NamedGetter"} || $interface->extendedAttributes->{"CustomNamedGetter"} || $interface->extendedAttributes->{"CustomGetOwnPropertySlot"};
663     my $hasCustomNamedSetter = $interface->extendedAttributes->{"CustomNamedSetter"};
664     my $hasCustomDeleters = $interface->extendedAttributes->{"CustomDeleteProperty"};
665     my $hasCustomEnumerator = $interface->extendedAttributes->{"CustomEnumerateProperty"};
666     if ($interfaceName eq "HTMLOptionsCollection") {
667         $interfaceName = "HTMLCollection";
668         $hasCustomIndexedGetter = 1;
669         $hasCustomNamedGetter = 1;
670     }
671     if ($interfaceName eq "DOMWindow") {
672         $hasCustomDeleters = 0;
673         $hasCustomEnumerator = 0;
674     }
675     if ($interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
676         $hasCustomNamedGetter = 1;
677     }
678     if ($interfaceName eq "HTMLDocument") {
679         $hasCustomNamedGetter = 0;
680         $hasCustomIndexedGetter = 0;
681     }
682     my $isIndexerSpecialCase = exists $indexerSpecialCases{$interfaceName};
683
684     if ($hasCustomIndexedGetter || $isIndexerSpecialCase) {
685         push(@headerContent, <<END);
686     static v8::Handle<v8::Value> indexedPropertyGetter(uint32_t, const v8::AccessorInfo&);
687 END
688     }
689
690     if ($isIndexerSpecialCase || $hasCustomIndexedSetter) {
691         push(@headerContent, <<END);
692     static v8::Handle<v8::Value> indexedPropertySetter(uint32_t, v8::Local<v8::Value>, const v8::AccessorInfo&);
693 END
694     }
695     if ($hasCustomDeleters) {
696         push(@headerContent, <<END);
697     static v8::Handle<v8::Boolean> indexedPropertyDeleter(uint32_t, const v8::AccessorInfo&);
698 END
699     }
700     if ($hasCustomNamedGetter) {
701         push(@headerContent, <<END);
702     static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String>, const v8::AccessorInfo&);
703 END
704     }
705     if ($hasCustomNamedSetter) {
706         push(@headerContent, <<END);
707     static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo&);
708 END
709     }
710     if ($hasCustomDeleters) {
711         push(@headerContent, <<END);
712     static v8::Handle<v8::Boolean> namedPropertyDeleter(v8::Local<v8::String>, const v8::AccessorInfo&);
713 END
714     }
715     if ($hasCustomEnumerator) {
716         push(@headerContent, <<END);
717     static v8::Handle<v8::Array> namedPropertyEnumerator(const v8::AccessorInfo&);
718     static v8::Handle<v8::Integer> namedPropertyQuery(v8::Local<v8::String>, const v8::AccessorInfo&);
719 END
720     }
721 }
722
723 sub GenerateHeaderCustomCall
724 {
725     my $interface = shift;
726
727     if ($interface->extendedAttributes->{"CustomCall"}) {
728         push(@headerContent, "    static v8::Handle<v8::Value> callAsFunctionCallback(const v8::Arguments&);\n");
729     }
730     if ($interface->name eq "Location") {
731         push(@headerContent, "    static v8::Handle<v8::Value> assignAttrGetterCustom(v8::Local<v8::String> name, const v8::AccessorInfo&);\n");
732         push(@headerContent, "    static v8::Handle<v8::Value> reloadAttrGetterCustom(v8::Local<v8::String> name, const v8::AccessorInfo&);\n");
733         push(@headerContent, "    static v8::Handle<v8::Value> replaceAttrGetterCustom(v8::Local<v8::String> name, const v8::AccessorInfo&);\n");
734     }
735 }
736
737 sub IsConstructable
738 {
739     my $interface = shift;
740
741     return $interface->extendedAttributes->{"CustomConstructor"} || $interface->extendedAttributes->{"V8CustomConstructor"} || $interface->extendedAttributes->{"Constructor"} || $interface->extendedAttributes->{"ConstructorTemplate"};
742 }
743
744 sub HasCustomConstructor
745 {
746     my $interface = shift;
747
748     return $interface->extendedAttributes->{"CustomConstructor"} || $interface->extendedAttributes->{"V8CustomConstructor"};
749 }
750
751 sub HasCustomGetter
752 {
753     my $attrExt = shift;
754     return $attrExt->{"Custom"} || $attrExt->{"V8Custom"} || $attrExt->{"CustomGetter"} || $attrExt->{"V8CustomGetter"};
755 }
756
757 sub HasCustomSetter
758 {
759     my $attrExt = shift;
760     return $attrExt->{"Custom"} || $attrExt->{"V8Custom"} || $attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"};
761 }
762
763 sub HasCustomMethod
764 {
765     my $attrExt = shift;
766     return $attrExt->{"Custom"} || $attrExt->{"V8Custom"};
767 }
768
769 sub IsReadonly
770 {
771     my $attribute = shift;
772     my $attrExt = $attribute->signature->extendedAttributes;
773     return ($attribute->type =~ /readonly/ || $attrExt->{"V8ReadOnly"}) && !$attrExt->{"Replaceable"};
774 }
775
776 sub GenerateDomainSafeFunctionGetter
777 {
778     my $function = shift;
779     my $interfaceName = shift;
780
781     my $v8InterfaceName = "V8" . $interfaceName;
782     my $funcName = $function->signature->name;
783
784     my $signature = "v8::Signature::New(" . $v8InterfaceName . "::GetRawTemplate(info.GetIsolate()))";
785     if ($function->signature->extendedAttributes->{"V8DoNotCheckSignature"}) {
786         $signature = "v8::Local<v8::Signature>()";
787     }
788
789     my $newTemplateString = "v8::FunctionTemplate::New(${interfaceName}V8Internal::${funcName}MethodCallback, v8Undefined(), $signature)";
790
791     AddToImplIncludes("Frame.h");
792     push(@implContentInternals, <<END);
793 static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
794 {
795     static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New(info.GetIsolate(), $newTemplateString);
796     v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(${v8InterfaceName}::GetTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
797     if (holder.IsEmpty()) {
798         // can only reach here by 'object.__proto__.func', and it should passed
799         // domain security check already
800         return privateTemplate->GetFunction();
801     }
802     ${interfaceName}* imp = ${v8InterfaceName}::toNative(holder);
803     if (!BindingSecurity::shouldAllowAccessToFrame(BindingState::instance(), imp->frame(), DoNotReportSecurityError)) {
804         static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(info.GetIsolate(), $newTemplateString);
805         return sharedTemplate->GetFunction();
806     }
807
808     v8::Local<v8::Value> hiddenValue = info.This()->GetHiddenValue(name);
809     if (!hiddenValue.IsEmpty())
810         return hiddenValue;
811
812     return privateTemplate->GetFunction();
813 }
814
815 static v8::Handle<v8::Value> ${funcName}AttrGetterCallback(v8::Local<v8::String> name, const v8::AccessorInfo& info)
816 {
817     return ${interfaceName}V8Internal::${funcName}AttrGetter(name, info);
818 }
819
820 END
821 }
822
823 sub GenerateDomainSafeFunctionSetter
824 {
825     my $interfaceName = shift;
826     my $v8InterfaceName = "V8" . $interfaceName;
827
828     push(@implContentInternals, <<END);
829 static void ${interfaceName}DomainSafeFunctionSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
830 {
831     v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(${v8InterfaceName}::GetTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
832     if (holder.IsEmpty())
833         return;
834     ${interfaceName}* imp = ${v8InterfaceName}::toNative(holder);
835     if (!BindingSecurity::shouldAllowAccessToFrame(BindingState::instance(), imp->frame()))
836         return;
837
838     info.This()->SetHiddenValue(name, value);
839 }
840
841 END
842 }
843
844 sub GenerateConstructorGetter
845 {
846     my $interface = shift;
847     my $interfaceName = $interface->name;
848
849     push(@implContentInternals, <<END);
850 static v8::Handle<v8::Value> ${interfaceName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
851 {
852     v8::Handle<v8::Value> data = info.Data();
853     ASSERT(data->IsExternal());
854     V8PerContextData* perContextData = V8PerContextData::from(info.Holder()->CreationContext());
855     if (!perContextData)
856         return v8Undefined();
857     return perContextData->constructorForType(WrapperTypeInfo::unwrap(data));
858 }
859 END
860 }
861
862 sub GenerateFeatureObservation
863 {
864     my $measureAs = shift;
865
866     if ($measureAs) {
867         AddToImplIncludes("FeatureObserver.h");
868         return "    FeatureObserver::observe(activeDOMWindow(BindingState::instance()), FeatureObserver::${measureAs});\n";
869     }
870
871     return "";
872 }
873
874 sub GenerateNormalAttrGetterCallback
875 {
876     my $attribute = shift;
877     my $interface = shift;
878
879     my $interfaceName = $interface->name;
880     my $v8InterfaceName = "V8$interfaceName";
881     my $attrExt = $attribute->signature->extendedAttributes;
882     my $attrName = $attribute->signature->name;
883
884     my $conditionalString = $codeGenerator->GenerateConditionalString($attribute->signature);
885     push(@implContentInternals, "#if ${conditionalString}\n\n") if $conditionalString;
886
887     push(@implContentInternals, "static v8::Handle<v8::Value> ${attrName}AttrGetterCallback(v8::Local<v8::String> name, const v8::AccessorInfo& info)\n");
888     push(@implContentInternals, "{\n");
889     push(@implContentInternals, GenerateFeatureObservation($attrExt->{"V8MeasureAs"}));
890     if (HasCustomGetter($attrExt)) {
891         push(@implContentInternals, "    return ${v8InterfaceName}::${attrName}AttrGetterCustom(name, info);\n");
892     } else {
893         push(@implContentInternals, "    return ${interfaceName}V8Internal::${attrName}AttrGetter(name, info);\n");
894     }
895     push(@implContentInternals, "}\n\n");
896     push(@implContentInternals, "#endif // ${conditionalString}\n\n") if $conditionalString;
897 }
898
899 sub GenerateNormalAttrGetter
900 {
901     my $attribute = shift;
902     my $interface = shift;
903
904     my $interfaceName = $interface->name;
905     my $v8InterfaceName = "V8$interfaceName";
906     my $attrExt = $attribute->signature->extendedAttributes;
907     my $attrName = $attribute->signature->name;
908     my $attrType = $attribute->signature->type;
909
910     if (HasCustomGetter($attrExt)) {
911         return;
912     }
913
914     $codeGenerator->AssertNotSequenceType($attrType);
915     my $getterStringUsesImp = $interfaceName ne "SVGNumber";
916     my $nativeType = GetNativeTypeFromSignature($attribute->signature, -1);
917     my $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($interfaceName);
918
919     my $conditionalString = $codeGenerator->GenerateConditionalString($attribute->signature);
920     push(@implContentInternals, "#if ${conditionalString}\n\n") if $conditionalString;
921     push(@implContentInternals, <<END);
922 static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
923 {
924 END
925     if ($svgNativeType) {
926         my $svgWrappedNativeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($interfaceName);
927         if ($svgWrappedNativeType =~ /List/) {
928             push(@implContentInternals, <<END);
929     $svgNativeType* imp = ${v8InterfaceName}::toNative(info.Holder());
930 END
931         } else {
932             push(@implContentInternals, <<END);
933     $svgNativeType* wrapper = ${v8InterfaceName}::toNative(info.Holder());
934     $svgWrappedNativeType& impInstance = wrapper->propertyReference();
935 END
936             if ($getterStringUsesImp) {
937                 push(@implContentInternals, <<END);
938     $svgWrappedNativeType* imp = &impInstance;
939 END
940             }
941         }
942     } elsif ($attrExt->{"V8OnProto"} || $attrExt->{"V8Unforgeable"}) {
943         if ($interfaceName eq "DOMWindow") {
944             push(@implContentInternals, <<END);
945     v8::Handle<v8::Object> holder = info.Holder();
946 END
947         } else {
948             # perform lookup first
949             push(@implContentInternals, <<END);
950     v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(${v8InterfaceName}::GetTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
951     if (holder.IsEmpty())
952         return v8Undefined();
953 END
954         }
955         push(@implContentInternals, <<END);
956     ${interfaceName}* imp = ${v8InterfaceName}::toNative(holder);
957 END
958     } else {
959         my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
960         my $url = $attribute->signature->extendedAttributes->{"URL"};
961         if ($getterStringUsesImp && $reflect && !$url && $codeGenerator->InheritsInterface($interface, "Node") && $codeGenerator->IsStringType($attrType)) {
962             # Generate super-compact call for regular attribute getter:
963             my ($functionName, @arguments) = $codeGenerator->GetterExpression(\%implIncludes, $interfaceName, $attribute);
964             push(@implContentInternals, "    Element* imp = V8Element::toNative(info.Holder());\n");
965             push(@implContentInternals, "    return v8String(imp->${functionName}(" . join(", ", @arguments) . "), info.GetIsolate(), ReturnUnsafeHandle);\n");
966             push(@implContentInternals, "}\n\n");
967             push(@implContentInternals, "#endif // ${conditionalString}\n\n") if $conditionalString;
968             return;
969             # Skip the rest of the function!
970         }
971         if ($attribute->signature->type eq "SerializedScriptValue" && $attrExt->{"CachedAttribute"}) {
972             push(@implContentInternals, <<END);
973     v8::Handle<v8::String> propertyName = v8::String::NewSymbol("${attrName}");
974     v8::Handle<v8::Value> value = info.Holder()->GetHiddenValue(propertyName);
975     if (!value.IsEmpty())
976         return value;
977 END
978         }
979         if (!$attribute->isStatic) {
980             push(@implContentInternals, <<END);
981     ${interfaceName}* imp = ${v8InterfaceName}::toNative(info.Holder());
982 END
983         }
984     }
985
986     # Generate security checks if necessary
987     if ($attribute->signature->extendedAttributes->{"CheckSecurityForNode"}) {
988         push(@implContentInternals, "    if (!BindingSecurity::shouldAllowAccessToNode(BindingState::instance(), imp->" . $attribute->signature->name . "()))\n        return v8::Handle<v8::Value>(v8Null(info.GetIsolate()));\n\n");
989     }
990
991     my $useExceptions = 1 if @{$attribute->getterExceptions};
992     if ($useExceptions) {
993         AddToImplIncludes("ExceptionCode.h");
994         push(@implContentInternals, "    ExceptionCode ec = 0;\n");
995     }
996
997     my $returnType = $attribute->signature->type;
998     my $getterString;
999
1000     if ($getterStringUsesImp) {
1001         my ($functionName, @arguments) = $codeGenerator->GetterExpression(\%implIncludes, $interfaceName, $attribute);
1002         push(@arguments, "ec") if $useExceptions;
1003         if ($attribute->signature->extendedAttributes->{"ImplementedBy"}) {
1004             my $implementedBy = $attribute->signature->extendedAttributes->{"ImplementedBy"};
1005             AddToImplIncludes("${implementedBy}.h");
1006             unshift(@arguments, "imp") if !$attribute->isStatic;
1007             $functionName = "${implementedBy}::${functionName}";
1008         } elsif ($attribute->isStatic) {
1009             $functionName = "${interfaceName}::${functionName}";
1010         } else {
1011             $functionName = "imp->${functionName}";
1012         }
1013         unshift(@arguments, GenerateCallWith($attribute->signature->extendedAttributes->{"CallWith"}, \@implContentInternals, "    ", 0));
1014         $getterString = "${functionName}(" . join(", ", @arguments) . ")";
1015     } else {
1016         $getterString = "impInstance";
1017     }
1018
1019     my $result;
1020     if ($attribute->signature->type eq "EventListener" && $interface->name eq "DOMWindow") {
1021         push(@implContentInternals, "    if (!imp->document())\n");
1022         push(@implContentInternals, "        return v8Undefined();\n");
1023     }
1024
1025     if ($useExceptions) {
1026         if ($nativeType =~ /^V8StringResource/) {
1027             push(@implContentInternals, "    " . ConvertToV8StringResource($attribute->signature, $nativeType, "v", $getterString) . ";\n");
1028         } else {
1029             push(@implContentInternals, "    $nativeType v = $getterString;\n");
1030         }
1031         push(@implContentInternals, "    if (UNLIKELY(ec))\n");
1032         push(@implContentInternals, "        return setDOMException(ec, info.GetIsolate());\n");
1033
1034         if ($codeGenerator->ExtendedAttributeContains($attribute->signature->extendedAttributes->{"CallWith"}, "ScriptState")) {
1035             push(@implContentInternals, "    if (state.hadException())\n");
1036             push(@implContentInternals, "        return throwError(state.exception(), info.GetIsolate());\n");
1037         }
1038
1039         $result = "v";
1040         $result .= ".release()" if ($codeGenerator->IsRefPtrType($returnType));
1041     } else {
1042         # Can inline the function call into the return statement to avoid overhead of using a Ref<> temporary
1043         $result = $getterString;
1044         # Fix amigious conversion problem, by casting to the base type first ($getterString returns a type that inherits from SVGAnimatedEnumeration, not the base class directly).
1045         $result = "static_pointer_cast<SVGAnimatedEnumeration>($result)" if $returnType eq "SVGAnimatedEnumeration";
1046     }
1047  
1048     # Special case for readonly or Replaceable attributes (with a few exceptions). This attempts to ensure that JS wrappers don't get
1049     # garbage-collected prematurely when their lifetime is strongly tied to their owner. We accomplish this by inserting a reference to
1050     # the newly created wrapper into an internal field of the holder object.
1051     if ((!$codeGenerator->InheritsInterface($interface, "Node") && $attrName ne "self" && IsWrapperType($returnType) && (IsReadonly($attribute) || $attribute->signature->extendedAttributes->{"Replaceable"} || $attrName eq "location")
1052          && $returnType ne "EventTarget" && $returnType ne "SerializedScriptValue" && $returnType ne "DOMWindow"
1053          && $returnType ne "MessagePortArray"
1054          && $returnType !~ /SVG/ && $returnType !~ /HTML/ && !IsDOMNodeType($returnType))
1055         || $attribute->signature->extendedAttributes->{"V8CacheAttributeForGC"}) {
1056
1057         my $arrayType = $codeGenerator->GetArrayType($returnType);
1058         if ($arrayType) {
1059             if (!$codeGenerator->SkipIncludeHeader($arrayType)) {
1060                 AddToImplIncludes("V8$arrayType.h");
1061                 AddToImplIncludes("$arrayType.h");
1062             }
1063             push(@implContentInternals, "    return v8Array(${getterString}, info.GetIsolate());\n");
1064             push(@implContentInternals, "}\n\n");
1065             return;
1066         }
1067
1068         AddIncludesForType($returnType);
1069         # Check for a wrapper in the wrapper cache. If there is one, we know that a hidden reference has already
1070         # been created. If we don't find a wrapper, we create both a wrapper and a hidden reference.
1071         push(@implContentInternals, "    RefPtr<$returnType> result = ${getterString};\n");
1072         push(@implContentInternals, "    v8::Handle<v8::Value> wrapper = result.get() ? v8::Handle<v8::Value>(DOMDataStore::getWrapper(result.get(), info.GetIsolate())) : v8Undefined();\n");
1073         push(@implContentInternals, "    if (wrapper.IsEmpty()) {\n");
1074         push(@implContentInternals, "        wrapper = toV8(result.get(), info.Holder(), info.GetIsolate());\n"); # FIXME: Could use wrap here since the wrapper is empty.
1075         push(@implContentInternals, "        if (!wrapper.IsEmpty())\n");
1076         push(@implContentInternals, "            V8HiddenPropertyName::setNamedHiddenReference(info.Holder(), \"${attrName}\", wrapper);\n");
1077         push(@implContentInternals, "    }\n");
1078         push(@implContentInternals, "    return wrapper;\n");
1079         push(@implContentInternals, "}\n\n");
1080         push(@implContentInternals, "#endif // ${conditionalString}\n\n") if $conditionalString;
1081         return;
1082     }
1083
1084     if (($codeGenerator->IsSVGAnimatedType($interfaceName) or $interfaceName eq "SVGViewSpec") and $codeGenerator->IsSVGTypeNeedingTearOff($attrType)) {
1085         AddToImplIncludes("V8$attrType.h");
1086         my $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($attrType);
1087         # Convert from abstract SVGProperty to real type, so the right toJS() method can be invoked.
1088         push(@implContentInternals, "    return toV8Fast(static_cast<$svgNativeType*>($result), info, imp);\n");
1089     } elsif ($codeGenerator->IsSVGTypeNeedingTearOff($attrType) and not $interfaceName =~ /List$/) {
1090         AddToImplIncludes("V8$attrType.h");
1091         AddToImplIncludes("SVGPropertyTearOff.h");
1092         my $tearOffType = $codeGenerator->GetSVGTypeNeedingTearOff($attrType);
1093         my $wrappedValue;
1094         if ($codeGenerator->IsSVGTypeWithWritablePropertiesNeedingTearOff($attrType) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
1095             my $getter = $result;
1096             $getter =~ s/imp->//;
1097             $getter =~ s/\(\)//;
1098
1099             my $updateMethod = "&${interfaceName}::update" . $codeGenerator->WK_ucfirst($getter);
1100
1101             my $selfIsTearOffType = $codeGenerator->IsSVGTypeNeedingTearOff($interfaceName);
1102             if ($selfIsTearOffType) {
1103                 AddToImplIncludes("SVGStaticPropertyWithParentTearOff.h");
1104                 $tearOffType =~ s/SVGPropertyTearOff</SVGStaticPropertyWithParentTearOff<$interfaceName, /;
1105
1106                 if ($result =~ /matrix/ and $interfaceName eq "SVGTransform") {
1107                     # SVGTransform offers a matrix() method for internal usage that returns an AffineTransform
1108                     # and a svgMatrix() method returning a SVGMatrix, used for the bindings.
1109                     $result =~ s/matrix/svgMatrix/;
1110                 }
1111
1112                 $wrappedValue = "WTF::getPtr(${tearOffType}::create(wrapper, $result, $updateMethod))";
1113             } else {
1114                 AddToImplIncludes("SVGStaticPropertyTearOff.h");
1115                 $tearOffType =~ s/SVGPropertyTearOff</SVGStaticPropertyTearOff<$interfaceName, /;
1116
1117                 $wrappedValue = "WTF::getPtr(${tearOffType}::create(imp, $result, $updateMethod))";
1118             }
1119         } elsif ($tearOffType =~ /SVGStaticListPropertyTearOff/) {
1120                 $wrappedValue = "WTF::getPtr(${tearOffType}::create(imp, $result))";
1121         } elsif ($tearOffType =~ /SVG(Point|PathSeg)List/) {
1122                 $wrappedValue = "WTF::getPtr($result)";
1123         } else {
1124                 $wrappedValue = "WTF::getPtr(${tearOffType}::create($result))";
1125         }
1126         push(@implContentInternals, "    return toV8Fast($wrappedValue, info, imp);\n");
1127     } elsif ($attribute->signature->type eq "MessagePortArray") {
1128         AddToImplIncludes("MessagePort.h");
1129         AddToImplIncludes("V8MessagePort.h");
1130         my $getterFunc = $codeGenerator->WK_lcfirst($attribute->signature->name);
1131         push(@implContentInternals, <<END);
1132     MessagePortArray* ports = imp->${getterFunc}();
1133     if (!ports)
1134         return v8::Array::New(0);
1135     MessagePortArray portsCopy(*ports);
1136     v8::Local<v8::Array> portArray = v8::Array::New(portsCopy.size());
1137     for (size_t i = 0; i < portsCopy.size(); ++i)
1138         portArray->Set(v8Integer(i, info.GetIsolate()), toV8Fast(portsCopy[i].get(), info, imp));
1139     return portArray;
1140 END
1141     } elsif ($attribute->signature->type eq "SerializedScriptValue" && $attrExt->{"CachedAttribute"}) {
1142         my $getterFunc = $codeGenerator->WK_lcfirst($attribute->signature->name);
1143         push(@implContentInternals, <<END);
1144     RefPtr<SerializedScriptValue> serialized = imp->${getterFunc}();
1145     value = serialized ? serialized->deserialize() : v8::Handle<v8::Value>(v8Null(info.GetIsolate()));
1146     info.Holder()->SetHiddenValue(propertyName, value);
1147     return value;
1148 END
1149     } else {
1150         push(@implContentInternals, "    return " . NativeToJSValue($attribute->signature, $result, "info.Holder()", "info.GetIsolate()", "info", "imp", "ReturnUnsafeHandle").";\n");
1151     }
1152
1153     push(@implContentInternals, "}\n\n");  # end of getter
1154     push(@implContentInternals, "#endif // ${conditionalString}\n\n") if $conditionalString;
1155 }
1156
1157 sub GenerateReplaceableAttrSetterCallback
1158 {
1159     my $interface = shift;
1160     my $interfaceName = $interface->name;
1161
1162     push(@implContentInternals, "static void ${interfaceName}ReplaceableAttrSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)\n");
1163     push(@implContentInternals, "{\n");
1164     push(@implContentInternals, GenerateFeatureObservation($interface->extendedAttributes->{"V8MeasureAs"}));
1165     push(@implContentInternals, "    return ${interfaceName}V8Internal::${interfaceName}ReplaceableAttrSetter(name, value, info);\n");
1166     push(@implContentInternals, "}\n\n");
1167 }
1168
1169 sub GenerateReplaceableAttrSetter
1170 {
1171     my $interface = shift;
1172     my $interfaceName = $interface->name;
1173
1174     push(@implContentInternals, <<END);
1175 static void ${interfaceName}ReplaceableAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
1176 {
1177 END
1178     if ($interface->extendedAttributes->{"CheckSecurity"}) {
1179         AddToImplIncludes("Frame.h");
1180         push(@implContentInternals, <<END);
1181     ${interfaceName}* imp = V8${interfaceName}::toNative(info.Holder());
1182     if (!BindingSecurity::shouldAllowAccessToFrame(BindingState::instance(), imp->frame()))
1183         return;
1184 END
1185     }
1186
1187     push(@implContentInternals, <<END);
1188     info.This()->ForceSet(name, value);
1189 }
1190
1191 END
1192 }
1193
1194 sub GenerateNormalAttrSetterCallback
1195 {
1196     my $attribute = shift;
1197     my $interface = shift;
1198
1199     my $interfaceName = $interface->name;
1200     my $v8InterfaceName = "V8$interfaceName";
1201     my $attrExt = $attribute->signature->extendedAttributes;
1202     my $attrName = $attribute->signature->name;
1203
1204     my $conditionalString = $codeGenerator->GenerateConditionalString($attribute->signature);
1205     push(@implContentInternals, "#if ${conditionalString}\n\n") if $conditionalString;
1206
1207     push(@implContentInternals, "static void ${attrName}AttrSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)\n");
1208     push(@implContentInternals, "{\n");
1209     push(@implContentInternals, GenerateFeatureObservation($attrExt->{"V8MeasureAs"}));
1210     if (HasCustomSetter($attrExt)) {
1211         push(@implContentInternals, "    ${v8InterfaceName}::${attrName}AttrSetterCustom(name, value, info);\n");
1212     } else {
1213         push(@implContentInternals, "    ${interfaceName}V8Internal::${attrName}AttrSetter(name, value, info);\n");
1214     }
1215     push(@implContentInternals, "}\n\n");
1216     push(@implContentInternals, "#endif // ${conditionalString}\n\n") if $conditionalString;
1217 }
1218
1219 sub GenerateNormalAttrSetter
1220 {
1221     my $attribute = shift;
1222     my $interface = shift;
1223
1224     my $interfaceName = $interface->name;
1225     my $v8InterfaceName = "V8$interfaceName";
1226     my $attrName = $attribute->signature->name;
1227     my $attrExt = $attribute->signature->extendedAttributes;
1228     my $attrType = $attribute->signature->type;
1229
1230     if (HasCustomSetter($attrExt)) {
1231         return;
1232     }
1233
1234     my $conditionalString = $codeGenerator->GenerateConditionalString($attribute->signature);
1235     push(@implContentInternals, "#if ${conditionalString}\n\n") if $conditionalString;
1236     push(@implContentInternals, "static void ${attrName}AttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)\n");
1237     push(@implContentInternals, "{\n");
1238
1239     # If the "StrictTypeChecking" extended attribute is present, and the attribute's type is an
1240     # interface type, then if the incoming value does not implement that interface, a TypeError is
1241     # thrown rather than silently passing NULL to the C++ code.
1242     # Per the Web IDL and ECMAScript specifications, incoming values can always be converted to both
1243     # strings and numbers, so do not throw TypeError if the attribute is of these types.
1244     if ($attribute->signature->extendedAttributes->{"StrictTypeChecking"}) {
1245         my $argType = $attribute->signature->type;
1246         if (IsWrapperType($argType)) {
1247             push(@implContentInternals, "    if (!isUndefinedOrNull(value) && !V8${argType}::HasInstance(value, info.GetIsolate())) {\n");
1248             push(@implContentInternals, "        throwTypeError(0, info.GetIsolate());\n");
1249             push(@implContentInternals, "        return;\n");
1250             push(@implContentInternals, "    }\n");
1251         }
1252     }
1253
1254     my $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($interfaceName);
1255     if ($svgNativeType) {
1256         my $svgWrappedNativeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($interfaceName);
1257         if ($svgWrappedNativeType =~ /List$/) {
1258             push(@implContentInternals, <<END);
1259     $svgNativeType* imp = ${v8InterfaceName}::toNative(info.Holder());
1260 END
1261         } else {
1262             AddToImplIncludes("ExceptionCode.h");
1263             push(@implContentInternals, "    $svgNativeType* wrapper = ${v8InterfaceName}::toNative(info.Holder());\n");
1264             push(@implContentInternals, "    if (wrapper->isReadOnly()) {\n");
1265             push(@implContentInternals, "        setDOMException(NO_MODIFICATION_ALLOWED_ERR, info.GetIsolate());\n");
1266             push(@implContentInternals, "        return;\n");
1267             push(@implContentInternals, "    }\n");
1268             push(@implContentInternals, "    $svgWrappedNativeType& impInstance = wrapper->propertyReference();\n");
1269             push(@implContentInternals, "    $svgWrappedNativeType* imp = &impInstance;\n");
1270         }
1271     } elsif ($attrExt->{"V8OnProto"}) {
1272         push(@implContentInternals, <<END);
1273     ${interfaceName}* imp = ${v8InterfaceName}::toNative(info.Holder());
1274 END
1275     } else {
1276         my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
1277         if ($reflect && $codeGenerator->InheritsInterface($interface, "Node") && $codeGenerator->IsStringType($attrType)) {
1278             # Generate super-compact call for regular attribute setter:
1279             my $contentAttributeName = $reflect eq "VALUE_IS_MISSING" ? lc $attrName : $reflect;
1280             my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
1281             AddToImplIncludes("${namespace}.h");
1282             push(@implContentInternals, "    Element* imp = V8Element::toNative(info.Holder());\n");
1283             push(@implContentInternals, "    V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, stringResource, value);\n");
1284             push(@implContentInternals, "    imp->setAttribute(${namespace}::${contentAttributeName}Attr, stringResource);\n");
1285             push(@implContentInternals, "}\n\n");
1286             push(@implContentInternals, "#endif // ${conditionalString}\n\n") if $conditionalString;
1287             return;
1288             # Skip the rest of the function!
1289         }
1290
1291         if (!$attribute->isStatic) {
1292             push(@implContentInternals, <<END);
1293     ${interfaceName}* imp = ${v8InterfaceName}::toNative(info.Holder());
1294 END
1295         }
1296     }
1297
1298     my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
1299     if ($attribute->signature->type eq "EventListener") {
1300         if ($interface->name eq "DOMWindow") {
1301             push(@implContentInternals, "    if (!imp->document())\n");
1302             push(@implContentInternals, "        return;\n");
1303         }
1304     } else {
1305         my $value = JSValueToNative($attribute->signature, "value", "info.GetIsolate()");
1306         my $arrayType = $codeGenerator->GetArrayType($nativeType);
1307
1308         if ($nativeType =~ /^V8StringResource/) {
1309             push(@implContentInternals, "    " . ConvertToV8StringResource($attribute->signature, $nativeType, "v", $value, "VOID") . "\n");
1310         } elsif ($arrayType) {
1311             push(@implContentInternals, "    Vector<$arrayType> v = $value;\n");
1312         } else {
1313             push(@implContentInternals, "    $nativeType v = $value;\n");
1314         }
1315     }
1316
1317     if ($codeGenerator->IsEnumType($attrType)) {
1318         # setter ignores invalid enumeration values
1319         my @enumValues = $codeGenerator->ValidEnumValues($attrType);
1320         my @validEqualities = ();
1321         foreach my $enumValue (@enumValues) {
1322             push(@validEqualities, "string == \"$enumValue\"");
1323         }
1324         my $enumValidationExpression = join(" || ", @validEqualities);
1325         push(@implContentInternals, <<END);
1326     String string = v;
1327     if (!($enumValidationExpression))
1328         return;
1329 END
1330     }
1331
1332     my $result = "v";
1333     my $returnType = $attribute->signature->type;
1334     if ($codeGenerator->IsRefPtrType($returnType) && !$codeGenerator->GetArrayType($returnType)) {
1335         $result = "WTF::getPtr(" . $result . ")";
1336     }
1337
1338     my $useExceptions = 1 if @{$attribute->setterExceptions};
1339
1340     if ($useExceptions) {
1341         AddToImplIncludes("ExceptionCode.h");
1342         push(@implContentInternals, "    ExceptionCode ec = 0;\n");
1343     }
1344
1345     if ($interfaceName eq "SVGNumber") {
1346         push(@implContentInternals, "    *imp = $result;\n");
1347     } else {
1348         if ($attribute->signature->type eq "EventListener") {
1349             my $implSetterFunctionName = $codeGenerator->WK_ucfirst($attrName);
1350             AddToImplIncludes("V8AbstractEventListener.h");
1351             if (!$codeGenerator->InheritsInterface($interface, "Node")) {
1352                 push(@implContentInternals, "    transferHiddenDependency(info.Holder(), imp->$attrName(), value, ${v8InterfaceName}::eventListenerCacheIndex, info.GetIsolate());\n");
1353             }
1354             AddToImplIncludes("V8EventListenerList.h");
1355             if ($interfaceName eq "WorkerContext" and $attribute->signature->name eq "onerror") {
1356                 AddToImplIncludes("V8WorkerContextErrorHandler.h");
1357                 push(@implContentInternals, "    imp->set$implSetterFunctionName(V8EventListenerList::findOrCreateWrapper<V8WorkerContextErrorHandler>(value, true)");
1358             } elsif ($interfaceName eq "DOMWindow" and $attribute->signature->name eq "onerror") {
1359                 AddToImplIncludes("V8WindowErrorHandler.h");
1360                 push(@implContentInternals, "    imp->set$implSetterFunctionName(V8EventListenerList::findOrCreateWrapper<V8WindowErrorHandler>(value, true)");
1361             } else {
1362                 push(@implContentInternals, "    imp->set$implSetterFunctionName(V8EventListenerList::getEventListener(value, true, ListenerFindOrCreate)");
1363             }
1364             push(@implContentInternals, ", ec") if $useExceptions;
1365             push(@implContentInternals, ");\n");
1366         } else {
1367             my ($functionName, @arguments) = $codeGenerator->SetterExpression(\%implIncludes, $interfaceName, $attribute);
1368             push(@arguments, $result);
1369             push(@arguments, "ec") if $useExceptions;
1370             if ($attribute->signature->extendedAttributes->{"ImplementedBy"}) {
1371                 my $implementedBy = $attribute->signature->extendedAttributes->{"ImplementedBy"};
1372                 AddToImplIncludes("${implementedBy}.h");
1373                 unshift(@arguments, "imp") if !$attribute->isStatic;
1374                 $functionName = "${implementedBy}::${functionName}";
1375             } elsif ($attribute->isStatic) {
1376                 $functionName = "${interfaceName}::${functionName}";
1377             } else {
1378                 $functionName = "imp->${functionName}";
1379             }
1380             unshift(@arguments, GenerateCallWith($attribute->signature->extendedAttributes->{"CallWith"}, \@implContentInternals, "    ", 1));
1381             push(@implContentInternals, "    ${functionName}(" . join(", ", @arguments) . ");\n");
1382         }
1383     }
1384
1385     if ($useExceptions) {
1386         push(@implContentInternals, "    if (UNLIKELY(ec))\n");
1387         push(@implContentInternals, "        setDOMException(ec, info.GetIsolate());\n");
1388     }
1389
1390     if ($codeGenerator->ExtendedAttributeContains($attribute->signature->extendedAttributes->{"CallWith"}, "ScriptState")) {
1391         push(@implContentInternals, "    if (state.hadException())\n");
1392         push(@implContentInternals, "        throwError(state.exception(), info.GetIsolate());\n");
1393     }
1394
1395     if ($svgNativeType) {
1396         if ($useExceptions) {
1397             push(@implContentInternals, "    if (!ec)\n");
1398             push(@implContentInternals, "        wrapper->commitChange();\n");
1399         } else {
1400             push(@implContentInternals, "    wrapper->commitChange();\n");
1401         }
1402     }
1403
1404     if ($attribute->signature->type eq "SerializedScriptValue" && $attribute->signature->extendedAttributes->{"CachedAttribute"}) {
1405         push(@implContentInternals, <<END);
1406     info.Holder()->DeleteHiddenValue(v8::String::NewSymbol("${attrName}")); // Invalidate the cached value.
1407 END
1408     }
1409
1410     push(@implContentInternals, "    return;\n");
1411     push(@implContentInternals, "}\n\n");  # end of setter
1412     push(@implContentInternals, "#endif // ${conditionalString}\n\n") if $conditionalString;
1413 }
1414
1415 sub GenerateParametersCheckExpression
1416 {
1417     my $numParameters = shift;
1418     my $function = shift;
1419
1420     my @andExpression = ();
1421     push(@andExpression, "args.Length() == $numParameters");
1422     my $parameterIndex = 0;
1423     foreach my $parameter (@{$function->parameters}) {
1424         last if $parameterIndex >= $numParameters;
1425         my $value = "args[$parameterIndex]";
1426         my $type = $parameter->type;
1427
1428         # Only DOMString or wrapper types are checked.
1429         # For DOMString with StrictTypeChecking only Null, Undefined and Object
1430         # are accepted for compatibility. Otherwise, no restrictions are made to
1431         # match the non-overloaded behavior.
1432         # FIXME: Implement WebIDL overload resolution algorithm.
1433         if ($codeGenerator->IsStringType($type)) {
1434             if ($parameter->extendedAttributes->{"StrictTypeChecking"}) {
1435                 push(@andExpression, "(${value}->IsNull() || ${value}->IsUndefined() || ${value}->IsString() || ${value}->IsObject())");
1436             }
1437         } elsif ($parameter->extendedAttributes->{"Callback"}) {
1438             # For Callbacks only checks if the value is null or object.
1439             push(@andExpression, "(${value}->IsNull() || ${value}->IsFunction())");
1440         } elsif ($codeGenerator->GetArrayType($type) || $codeGenerator->GetSequenceType($type)) {
1441             if ($parameter->isNullable) {
1442                 push(@andExpression, "(${value}->IsNull() || ${value}->IsArray())");
1443             } else {
1444                 push(@andExpression, "(${value}->IsArray())");
1445             }
1446         } elsif (IsWrapperType($type)) {
1447             if ($parameter->isNullable) {
1448                 push(@andExpression, "(${value}->IsNull() || V8${type}::HasInstance($value, args.GetIsolate()))");
1449             } else {
1450                 push(@andExpression, "(V8${type}::HasInstance($value, args.GetIsolate()))");
1451             }
1452         }
1453
1454         $parameterIndex++;
1455     }
1456     my $res = join(" && ", @andExpression);
1457     $res = "($res)" if @andExpression > 1;
1458     return $res;
1459 }
1460
1461 sub GenerateFunctionParametersCheck
1462 {
1463     my $function = shift;
1464
1465     my @orExpression = ();
1466     my $numParameters = 0;
1467     my $hasVariadic = 0;
1468     my $numMandatoryParams = @{$function->parameters};
1469     foreach my $parameter (@{$function->parameters}) {
1470         if ($parameter->extendedAttributes->{"Optional"}) {
1471             push(@orExpression, GenerateParametersCheckExpression($numParameters, $function));
1472             $numMandatoryParams--;
1473         }
1474         if ($parameter->isVariadic) {
1475             $hasVariadic = 1;
1476             last;
1477         }
1478         $numParameters++;
1479     }
1480     if (!$hasVariadic) {
1481         push(@orExpression, GenerateParametersCheckExpression($numParameters, $function));
1482     }
1483     return ($numMandatoryParams, join(" || ", @orExpression));
1484 }
1485
1486 sub GenerateOverloadedFunction
1487 {
1488     my $function = shift;
1489     my $interface = shift;
1490     my $interfaceName = $interface->name;
1491
1492     # Generate code for choosing the correct overload to call. Overloads are
1493     # chosen based on the total number of arguments passed and the type of
1494     # values passed in non-primitive argument slots. When more than a single
1495     # overload is applicable, precedence is given according to the order of
1496     # declaration in the IDL.
1497
1498     my $name = $function->signature->name;
1499     my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature);
1500     my $leastNumMandatoryParams = 255;
1501     push(@implContentInternals, "#if ${conditionalString}\n\n") if $conditionalString;
1502     push(@implContentInternals, <<END);
1503 static v8::Handle<v8::Value> ${name}Method(const v8::Arguments& args)
1504 {
1505 END
1506     push(@implContentInternals, GenerateFeatureObservation($function->signature->extendedAttributes->{"V8MeasureAs"}));
1507
1508     foreach my $overload (@{$function->{overloads}}) {
1509         my ($numMandatoryParams, $parametersCheck) = GenerateFunctionParametersCheck($overload);
1510         $leastNumMandatoryParams = $numMandatoryParams if ($numMandatoryParams < $leastNumMandatoryParams);
1511         push(@implContentInternals, "    if ($parametersCheck)\n");
1512         my $overloadedIndexString = $overload->{overloadIndex};
1513         push(@implContentInternals, "        return ${name}${overloadedIndexString}Method(args);\n");
1514     }
1515     if ($leastNumMandatoryParams >= 1) {
1516         push(@implContentInternals, "    if (args.Length() < $leastNumMandatoryParams)\n");
1517         push(@implContentInternals, "        return throwNotEnoughArgumentsError(args.GetIsolate());\n");
1518     }
1519     push(@implContentInternals, <<END);
1520     return throwTypeError(0, args.GetIsolate());
1521 END
1522     push(@implContentInternals, "}\n\n");
1523     push(@implContentInternals, "#endif // ${conditionalString}\n\n") if $conditionalString;
1524 }
1525
1526 sub GenerateFunctionCallback
1527 {
1528     my $function = shift;
1529     my $interface = shift;
1530
1531     my $interfaceName = $interface->name;
1532     my $v8InterfaceName = "V8$interfaceName";
1533     my $name = $function->signature->name;
1534
1535     my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature);
1536     push(@implContentInternals, "#if ${conditionalString}\n\n") if $conditionalString;
1537     push(@implContentInternals, <<END);
1538 static v8::Handle<v8::Value> ${name}MethodCallback(const v8::Arguments& args)
1539 {
1540 END
1541     push(@implContentInternals, GenerateFeatureObservation($function->signature->extendedAttributes->{"V8MeasureAs"}));
1542     if (HasCustomMethod($function->signature->extendedAttributes)) {
1543         push(@implContentInternals, "    return ${v8InterfaceName}::${name}MethodCustom(args);\n");
1544     } else {
1545         push(@implContentInternals, "    return ${interfaceName}V8Internal::${name}Method(args);\n");
1546     }
1547     push(@implContentInternals, "}\n\n");
1548     push(@implContentInternals, "#endif // ${conditionalString}\n\n") if $conditionalString;
1549 }
1550
1551 sub GenerateFunction
1552 {
1553     my $function = shift;
1554     my $interface = shift;
1555
1556     my $interfaceName = $interface->name;
1557     my $v8InterfaceName = "V8$interfaceName";
1558     my $name = $function->signature->name;
1559     my $funcExt = $function->signature->extendedAttributes;
1560
1561     if (HasCustomMethod($funcExt)) {
1562         return;
1563     }
1564
1565     if (@{$function->{overloads}} > 1) {
1566         # Append a number to an overloaded method's name to make it unique:
1567         $name = $name . $function->{overloadIndex};
1568     }
1569
1570     my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature);
1571     push(@implContentInternals, "#if ${conditionalString}\n\n") if $conditionalString;
1572     push(@implContentInternals, "static v8::Handle<v8::Value> ${name}Method(const v8::Arguments& args)\n");
1573     push(@implContentInternals, "{\n");
1574
1575     if ($name eq "addEventListener" || $name eq "removeEventListener") {
1576         my $lookupType = ($name eq "addEventListener") ? "OrCreate" : "Only";
1577         my $passRefPtrHandling = ($name eq "addEventListener") ? "" : ".get()";
1578         my $hiddenDependencyAction = ($name eq "addEventListener") ? "create" : "remove";
1579
1580         AddToImplIncludes("V8EventListenerList.h");
1581         push(@implContentInternals, <<END);
1582     RefPtr<EventListener> listener = V8EventListenerList::getEventListener(args[1], false, ListenerFind${lookupType});
1583     if (listener) {
1584         V8TRYCATCH_FOR_V8STRINGRESOURCE(V8StringResource<WithNullCheck>, stringResource, args[0]);
1585         V8${interfaceName}::toNative(args.Holder())->${name}(stringResource, listener${passRefPtrHandling}, args[2]->BooleanValue());
1586 END
1587         if (!$codeGenerator->InheritsInterface($interface, "Node")) {
1588             push(@implContentInternals, <<END);
1589         ${hiddenDependencyAction}HiddenDependency(args.Holder(), args[1], V8${interfaceName}::eventListenerCacheIndex, args.GetIsolate());
1590 END
1591         }
1592         push(@implContentInternals, <<END);
1593     }
1594     return v8Undefined();
1595 }
1596
1597 END
1598         push(@implContentInternals, "#endif // ${conditionalString}\n\n") if $conditionalString;
1599         return;
1600     }
1601
1602     push(@implContentInternals, GenerateArgumentsCountCheck($function, $interface));
1603
1604     if ($name eq "set" and $interface->extendedAttributes->{"TypedArray"}) {
1605         AddToImplIncludes("V8ArrayBufferViewCustom.h");
1606         push(@implContentInternals, <<END);
1607     return setWebGLArrayHelper<$interfaceName, ${v8InterfaceName}>(args);
1608 }
1609
1610 END
1611         return;
1612     }
1613
1614     my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGPropertyTypes($interfaceName);
1615
1616     if ($svgNativeType) {
1617         my $nativeClassName = GetNativeType($interfaceName); 
1618         if ($interfaceName =~ /List$/) {
1619             push(@implContentInternals, "    $nativeClassName imp = ${v8InterfaceName}::toNative(args.Holder());\n");
1620         } else {
1621             AddToImplIncludes("ExceptionCode.h");
1622             push(@implContentInternals, "    $nativeClassName wrapper = ${v8InterfaceName}::toNative(args.Holder());\n");
1623             push(@implContentInternals, "    if (wrapper->isReadOnly())\n");
1624             push(@implContentInternals, "        return setDOMException(NO_MODIFICATION_ALLOWED_ERR, args.GetIsolate());\n");
1625             my $svgWrappedNativeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($interfaceName);
1626             push(@implContentInternals, "    $svgWrappedNativeType& impInstance = wrapper->propertyReference();\n");
1627             push(@implContentInternals, "    $svgWrappedNativeType* imp = &impInstance;\n");
1628         }
1629     } elsif (!$function->isStatic) {
1630         push(@implContentInternals, <<END);
1631     ${interfaceName}* imp = ${v8InterfaceName}::toNative(args.Holder());
1632 END
1633     }
1634
1635     # Check domain security if needed
1636     if ($interface->extendedAttributes->{"CheckSecurity"} && !$function->signature->extendedAttributes->{"DoNotCheckSecurity"}) {
1637         # We have not find real use cases yet.
1638         AddToImplIncludes("Frame.h");
1639         push(@implContentInternals, <<END);
1640     if (!BindingSecurity::shouldAllowAccessToFrame(BindingState::instance(), imp->frame()))
1641         return v8Undefined();
1642 END
1643     }
1644
1645     my $raisesExceptions = @{$function->raisesExceptions};
1646     if (!$raisesExceptions) {
1647         foreach my $parameter (@{$function->parameters}) {
1648             if ((!$parameter->extendedAttributes->{"Callback"} and TypeCanFailConversion($parameter)) or $parameter->extendedAttributes->{"IsIndex"}) {
1649                 $raisesExceptions = 1;
1650             }
1651         }
1652     }
1653
1654     if ($raisesExceptions) {
1655         AddToImplIncludes("ExceptionCode.h");
1656         push(@implContentInternals, "    ExceptionCode ec = 0;\n");
1657         push(@implContentInternals, "    {\n");
1658         # The brace here is needed to prevent the ensuing 'goto fail's from jumping past constructors
1659         # of objects (like Strings) declared later, causing compile errors. The block scope ends
1660         # right before the label 'fail:'.
1661     }
1662
1663     if ($function->signature->extendedAttributes->{"CheckSecurityForNode"}) {
1664         push(@implContentInternals, "    if (!BindingSecurity::shouldAllowAccessToNode(BindingState::instance(), imp->" . $function->signature->name . "(ec)))\n");
1665         push(@implContentInternals, "        return v8::Handle<v8::Value>(v8Null(args.GetIsolate()));\n");
1666 END
1667     }
1668
1669     my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersCheck($function, $interfaceName);
1670     push(@implContentInternals, $parameterCheckString);
1671
1672     # Build the function call string.
1673     push(@implContentInternals, GenerateFunctionCallString($function, $paramIndex, "    ", $interfaceName, %replacements));
1674
1675     if ($raisesExceptions) {
1676         push(@implContentInternals, "    }\n");
1677         push(@implContentInternals, "    fail:\n");
1678         push(@implContentInternals, "    return setDOMException(ec, args.GetIsolate());\n");
1679     }
1680
1681     push(@implContentInternals, "}\n\n");
1682     push(@implContentInternals, "#endif // ${conditionalString}\n\n") if $conditionalString;
1683 }
1684
1685 sub GenerateCallWith
1686 {
1687     my $callWith = shift;
1688     return () unless $callWith;
1689     my $outputArray = shift;
1690     my $indent = shift;
1691     my $returnVoid = shift;
1692     my $function = shift;
1693
1694     my @callWithArgs;
1695     if ($codeGenerator->ExtendedAttributeContains($callWith, "ScriptState")) {
1696         push(@$outputArray, $indent . "ScriptState* currentState = ScriptState::current();\n");
1697         push(@$outputArray, $indent . "if (!currentState)\n");
1698         push(@$outputArray, $indent . "    return" . ($returnVoid ? "" : " v8Undefined()") . ";\n");
1699         push(@$outputArray, $indent . "ScriptState& state = *currentState;\n");
1700         push(@callWithArgs, "&state");
1701     }
1702     if ($codeGenerator->ExtendedAttributeContains($callWith, "ScriptExecutionContext")) {
1703         push(@$outputArray, $indent . "ScriptExecutionContext* scriptContext = getScriptExecutionContext();\n");
1704         push(@callWithArgs, "scriptContext");
1705     }
1706     if ($function and $codeGenerator->ExtendedAttributeContains($callWith, "ScriptArguments")) {
1707         push(@$outputArray, $indent . "RefPtr<ScriptArguments> scriptArguments(createScriptArguments(args, " . @{$function->parameters} . "));\n");
1708         push(@callWithArgs, "scriptArguments.release()");
1709         AddToImplIncludes("ScriptArguments.h");
1710         AddToImplIncludes("ScriptCallStackFactory.h");
1711     }
1712     return @callWithArgs;
1713 }
1714
1715 sub GenerateArgumentsCountCheck
1716 {
1717     my $function = shift;
1718     my $interface = shift;
1719
1720     my $numMandatoryParams = 0;
1721     my $allowNonOptional = 1;
1722     foreach my $param (@{$function->parameters}) {
1723         if ($param->extendedAttributes->{"Optional"} or $param->isVariadic) {
1724             $allowNonOptional = 0;
1725         } else {
1726             die "An argument must not be declared to be optional unless all subsequent arguments to the operation are also optional." if !$allowNonOptional;
1727             $numMandatoryParams++;
1728         }
1729     }
1730
1731     my $argumentsCountCheckString = "";
1732     if ($numMandatoryParams >= 1) {
1733         $argumentsCountCheckString .= "    if (args.Length() < $numMandatoryParams)\n";
1734         $argumentsCountCheckString .= "        return throwNotEnoughArgumentsError(args.GetIsolate());\n";
1735     }
1736     return $argumentsCountCheckString;
1737 }
1738
1739 sub GetIndexOf
1740 {
1741     my $paramName = shift;
1742     my @paramList = @_;
1743     my $index = 0;
1744     foreach my $param (@paramList) {
1745         if ($paramName eq $param) {
1746             return $index;
1747         }
1748         $index++;
1749     }
1750     return -1;
1751 }
1752
1753 sub GenerateParametersCheck
1754 {
1755     my $function = shift;
1756     my $interfaceName = shift;
1757
1758     my $parameterCheckString = "";
1759     my $paramIndex = 0;
1760     my @paramTransferListNames = ();
1761     my %replacements = ();
1762
1763     foreach my $parameter (@{$function->parameters}) {
1764         my $nativeType = GetNativeTypeFromSignature($parameter, $paramIndex);
1765
1766         # Optional arguments with [Optional] should generate an early call with fewer arguments.
1767         # Optional arguments with [Optional=...] should not generate the early call.
1768         # Optional Dictionary arguments always considered to have default of empty dictionary.
1769         my $optional = $parameter->extendedAttributes->{"Optional"};
1770         if ($optional && $optional ne "DefaultIsUndefined" && $optional ne "DefaultIsNullString" && $nativeType ne "Dictionary" && !$parameter->extendedAttributes->{"Callback"}) {
1771             $parameterCheckString .= "    if (args.Length() <= $paramIndex) {\n";
1772             my $functionCall = GenerateFunctionCallString($function, $paramIndex, "    " x 2, $interfaceName, %replacements);
1773             $parameterCheckString .= $functionCall;
1774             $parameterCheckString .= "    }\n";
1775         }
1776
1777         my $parameterDefaultPolicy = "DefaultIsUndefined";
1778         if ($optional and $optional eq "DefaultIsNullString") {
1779             $parameterDefaultPolicy = "DefaultIsNullString";
1780         }
1781
1782         my $parameterName = $parameter->name;
1783         if (GetIndexOf($parameterName, @paramTransferListNames) != -1) {
1784             $replacements{$parameterName} = "messagePortArray" . ucfirst($parameterName);
1785             $paramIndex++;
1786             next;
1787         }
1788
1789         AddToImplIncludes("ExceptionCode.h");
1790         if ($parameter->extendedAttributes->{"Callback"}) {
1791             my $v8InterfaceName = "V8" . $parameter->type;
1792             AddToImplIncludes("$v8InterfaceName.h");
1793             if ($optional) {
1794                 $parameterCheckString .= "    RefPtr<" . $parameter->type . "> $parameterName;\n";
1795                 $parameterCheckString .= "    if (args.Length() > $paramIndex && !args[$paramIndex]->IsNull() && !args[$paramIndex]->IsUndefined()) {\n";
1796                 $parameterCheckString .= "        if (!args[$paramIndex]->IsFunction())\n";
1797                 $parameterCheckString .= "            return throwTypeError(0, args.GetIsolate());\n";
1798                 $parameterCheckString .= "        $parameterName = ${v8InterfaceName}::create(args[$paramIndex], getScriptExecutionContext());\n";
1799                 $parameterCheckString .= "    }\n";
1800             } else {
1801                 $parameterCheckString .= "    if (args.Length() <= $paramIndex || !args[$paramIndex]->IsFunction())\n";
1802                 $parameterCheckString .= "        return throwTypeError(0, args.GetIsolate());\n";
1803                 $parameterCheckString .= "    RefPtr<" . $parameter->type . "> $parameterName = ${v8InterfaceName}::create(args[$paramIndex], getScriptExecutionContext());\n";
1804             }
1805         } elsif ($parameter->extendedAttributes->{"Clamp"}) {
1806                 my $nativeValue = "${parameterName}NativeValue";
1807                 my $paramType = $parameter->type;
1808                 $parameterCheckString .= "    $paramType $parameterName = 0;\n";
1809                 $parameterCheckString .= "    V8TRYCATCH(double, $nativeValue, args[$paramIndex]->NumberValue());\n";
1810                 $parameterCheckString .= "    if (!std::isnan($nativeValue))\n";
1811                 $parameterCheckString .= "        $parameterName = clampTo<$paramType>($nativeValue);\n";
1812         } elsif ($parameter->type eq "SerializedScriptValue") {
1813             AddToImplIncludes("SerializedScriptValue.h");
1814             my $useTransferList = 0;
1815             my $transferListName = "";
1816             my $TransferListName = "";
1817             if ($parameter->extendedAttributes->{"TransferList"}) {
1818                 $transferListName = $parameter->extendedAttributes->{"TransferList"};
1819                 push(@paramTransferListNames, $transferListName);
1820
1821                 my @allParameterNames = ();
1822                 foreach my $parameter (@{$function->parameters}) {
1823                     push(@allParameterNames, $parameter->name);
1824                 }
1825                 my $transferListIndex = GetIndexOf($transferListName, @allParameterNames);
1826                 if ($transferListIndex == -1) {
1827                     die "IDL error: TransferList refers to a nonexistent argument";
1828                 }
1829
1830                 AddToImplIncludes("wtf/ArrayBuffer.h");
1831                 AddToImplIncludes("MessagePort.h");
1832                 $TransferListName = ucfirst($transferListName);
1833                 $parameterCheckString .= "    MessagePortArray messagePortArray$TransferListName;\n";
1834                 $parameterCheckString .= "    ArrayBufferArray arrayBufferArray$TransferListName;\n";
1835                 $parameterCheckString .= "    if (args.Length() > $transferListIndex) {\n";
1836                 $parameterCheckString .= "        if (!extractTransferables(args[$transferListIndex], messagePortArray$TransferListName, arrayBufferArray$TransferListName, args.GetIsolate()))\n";
1837                 $parameterCheckString .= "            return throwTypeError(\"Could not extract transferables\", args.GetIsolate());\n";
1838                 $parameterCheckString .= "    }\n";
1839                 $useTransferList = 1;
1840             }
1841             $parameterCheckString .= "    bool ${parameterName}DidThrow = false;\n";
1842             if (!$useTransferList) {
1843                     $parameterCheckString .= "    $nativeType $parameterName = SerializedScriptValue::create(args[$paramIndex], 0, 0, ${parameterName}DidThrow, args.GetIsolate());\n";
1844             } else {
1845                     $parameterCheckString .= "    $nativeType $parameterName = SerializedScriptValue::create(args[$paramIndex], &messagePortArray$TransferListName, &arrayBufferArray$TransferListName, ${parameterName}DidThrow, args.GetIsolate());\n";
1846             }
1847             $parameterCheckString .= "    if (${parameterName}DidThrow)\n";
1848             $parameterCheckString .= "        return v8Undefined();\n";
1849         } elsif (TypeCanFailConversion($parameter)) {
1850             $parameterCheckString .= "    $nativeType $parameterName = " .
1851                  JSValueToNative($parameter, "args[$paramIndex]", "args.GetIsolate()") . ";\n";
1852             $parameterCheckString .= "    if (UNLIKELY(!$parameterName)) {\n";
1853             $parameterCheckString .= "        ec = TYPE_MISMATCH_ERR;\n";
1854             $parameterCheckString .= "        goto fail;\n";
1855             $parameterCheckString .= "    }\n";
1856         } elsif ($parameter->isVariadic) {
1857             my $nativeElementType = GetNativeType($parameter->type);
1858             if ($nativeElementType =~ />$/) {
1859                 $nativeElementType .= " ";
1860             }
1861
1862             my $argType = $parameter->type;
1863             if (IsWrapperType($argType)) {
1864                 $parameterCheckString .= "    Vector<$nativeElementType> $parameterName;\n";
1865                 $parameterCheckString .= "    for (int i = $paramIndex; i < args.Length(); ++i) {\n";
1866                 $parameterCheckString .= "        if (!V8${argType}::HasInstance(args[i], args.GetIsolate()))\n";
1867                 $parameterCheckString .= "            return throwTypeError(0, args.GetIsolate());\n";
1868                 $parameterCheckString .= "        $parameterName.append(V8${argType}::toNative(v8::Handle<v8::Object>::Cast(args[i])));\n";
1869                 $parameterCheckString .= "    }\n";
1870             } else {
1871                 $parameterCheckString .= "    V8TRYCATCH(Vector<$nativeElementType>, $parameterName, toNativeArguments<$nativeElementType>(args, $paramIndex));\n";
1872             }
1873         } elsif ($nativeType =~ /^V8StringResource/) {
1874             my $value = JSValueToNative($parameter, $optional && $optional eq "DefaultIsNullString" ? "argumentOrNull(args, $paramIndex)" : "args[$paramIndex]", "args.GetIsolate()");
1875             $parameterCheckString .= "    " . ConvertToV8StringResource($parameter, $nativeType, $parameterName, $value) . "\n";
1876         } else {
1877             # If the "StrictTypeChecking" extended attribute is present, and the argument's type is an
1878             # interface type, then if the incoming value does not implement that interface, a TypeError
1879             # is thrown rather than silently passing NULL to the C++ code.
1880             # Per the Web IDL and ECMAScript specifications, incoming values can always be converted
1881             # to both strings and numbers, so do not throw TypeError if the argument is of these
1882             # types.
1883             if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) {
1884                 my $argValue = "args[$paramIndex]";
1885                 my $argType = $parameter->type;
1886                 if (IsWrapperType($argType)) {
1887                     $parameterCheckString .= "    if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !V8${argType}::HasInstance($argValue, args.GetIsolate()))\n";
1888                     $parameterCheckString .= "        return throwTypeError(0, args.GetIsolate());\n";
1889                 }
1890             }
1891             $parameterCheckString .= "    V8TRYCATCH($nativeType, $parameterName, " .
1892                  JSValueToNative($parameter, $optional && $optional eq "DefaultIsNullString" ? "argumentOrNull(args, $paramIndex)" : "args[$paramIndex]", "args.GetIsolate()") . ");\n";
1893             if ($nativeType eq 'Dictionary') {
1894                $parameterCheckString .= "    if (!$parameterName.isUndefinedOrNull() && !$parameterName.isObject())\n";
1895                $parameterCheckString .= "        return throwTypeError(\"Not an object.\", args.GetIsolate());\n";
1896             }
1897         }
1898
1899         if ($parameter->extendedAttributes->{"IsIndex"}) {
1900             $parameterCheckString .= "    if (UNLIKELY($parameterName < 0)) {\n";
1901             $parameterCheckString .= "        ec = INDEX_SIZE_ERR;\n";
1902             $parameterCheckString .= "        goto fail;\n";
1903             $parameterCheckString .= "    }\n";
1904         }
1905
1906         $paramIndex++;
1907     }
1908     return ($parameterCheckString, $paramIndex, %replacements);
1909 }
1910
1911 sub GenerateOverloadedConstructorCallback
1912 {
1913     my $interface = shift;
1914     my $interfaceName = $interface->name;
1915
1916     push(@implContentInternals, <<END);
1917 static v8::Handle<v8::Value> constructor(const v8::Arguments& args)
1918 {
1919 END
1920     my $leastNumMandatoryParams = 255;
1921     foreach my $constructor (@{$interface->constructors}) {
1922         my $name = "constructor" . $constructor->{overloadedIndex};
1923         my ($numMandatoryParams, $parametersCheck) = GenerateFunctionParametersCheck($constructor);
1924         $leastNumMandatoryParams = $numMandatoryParams if ($numMandatoryParams < $leastNumMandatoryParams);
1925         push(@implContentInternals, "    if ($parametersCheck)\n");
1926         push(@implContentInternals, "        return ${interfaceName}V8Internal::${name}(args);\n");
1927     }
1928     if ($leastNumMandatoryParams >= 1) {
1929         push(@implContentInternals, "    if (args.Length() < $leastNumMandatoryParams)\n");
1930         push(@implContentInternals, "        return throwNotEnoughArgumentsError(args.GetIsolate());\n");
1931     }
1932     push(@implContentInternals, <<END);
1933     return throwTypeError(0, args.GetIsolate());
1934 END
1935     push(@implContentInternals, "}\n\n");
1936 }
1937
1938 sub GenerateSingleConstructorCallback
1939 {
1940     my $interface = shift;
1941     my $function = shift;
1942
1943     my $interfaceName = $interface->name;
1944     my $overloadedIndexString = "";
1945     if ($function->{overloadedIndex} > 0) {
1946         $overloadedIndexString .= $function->{overloadedIndex};
1947     }
1948
1949     my $raisesExceptions = @{$function->raisesExceptions};
1950     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) {
1951         $raisesExceptions = 1;
1952     }
1953     if (!$raisesExceptions) {
1954         foreach my $parameter (@{$function->parameters}) {
1955             if ((!$parameter->extendedAttributes->{"Callback"} and TypeCanFailConversion($parameter)) or $parameter->extendedAttributes->{"IsIndex"}) {
1956                 $raisesExceptions = 1;
1957             }
1958         }
1959     }
1960
1961     my @beforeArgumentList;
1962     my @afterArgumentList;
1963     push(@implContentInternals, <<END);
1964 static v8::Handle<v8::Value> constructor${overloadedIndexString}(const v8::Arguments& args)
1965 {
1966 END
1967
1968     if ($function->{overloadedIndex} == 0) {
1969         push(@implContentInternals, GenerateArgumentsCountCheck($function, $interface));
1970     }
1971
1972     if ($raisesExceptions) {
1973         AddToImplIncludes("ExceptionCode.h");
1974         push(@implContentInternals, "\n");
1975         push(@implContentInternals, "    ExceptionCode ec = 0;\n");
1976     }
1977
1978     # FIXME: Currently [Constructor(...)] does not yet support [Optional] arguments.
1979     # It just supports [Optional=DefaultIsUndefined] or [Optional=DefaultIsNullString].
1980     my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersCheck($function, $interfaceName);
1981     push(@implContentInternals, $parameterCheckString);
1982
1983     if ($interface->extendedAttributes->{"CallWith"} && $interface->extendedAttributes->{"CallWith"} eq "ScriptExecutionContext") {
1984         push(@beforeArgumentList, "context");
1985         push(@implContentInternals, <<END);
1986
1987     ScriptExecutionContext* context = getScriptExecutionContext();
1988 END
1989     }
1990
1991     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) {
1992         push(@afterArgumentList, "ec");
1993     }
1994
1995     my @argumentList;
1996     my $index = 0;
1997     foreach my $parameter (@{$function->parameters}) {
1998         last if $index eq $paramIndex;
1999         if ($replacements{$parameter->name}) {
2000             push(@argumentList, $replacements{$parameter->name});
2001         } else {
2002             push(@argumentList, $parameter->name);
2003         }
2004         $index++;
2005     }
2006
2007     my $argumentString = join(", ", @beforeArgumentList, @argumentList, @afterArgumentList);
2008     push(@implContentInternals, "\n");
2009     push(@implContentInternals, "    RefPtr<${interfaceName}> impl = ${interfaceName}::create(${argumentString});\n");
2010     push(@implContentInternals, "    v8::Handle<v8::Object> wrapper = args.Holder();\n");
2011
2012     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) {
2013         push(@implContentInternals, "    if (ec)\n");
2014         push(@implContentInternals, "        goto fail;\n");
2015     }
2016
2017     push(@implContentInternals, <<END);
2018
2019     V8DOMWrapper::associateObjectWithWrapper(impl.release(), &V8${interfaceName}::info, wrapper, args.GetIsolate(), WrapperConfiguration::Dependent);
2020     return wrapper;
2021 END
2022
2023     if ($raisesExceptions) {
2024         push(@implContentInternals, "    fail:\n");
2025         push(@implContentInternals, "    return setDOMException(ec, args.GetIsolate());\n");
2026     }
2027
2028     push(@implContentInternals, "}\n");
2029     push(@implContentInternals, "\n");
2030 }
2031
2032 sub GenerateConstructorCallback
2033 {
2034     my $interface = shift;
2035
2036     my $interfaceName = $interface->name;
2037     push(@implContent, "v8::Handle<v8::Value> V8${interfaceName}::constructorCallback(const v8::Arguments& args)\n");
2038     push(@implContent, "{\n");
2039     push(@implContent, GenerateFeatureObservation($interface->extendedAttributes->{"V8MeasureAs"}));
2040     push(@implContent, GenerateConstructorHeader());
2041     if (HasCustomConstructor($interface)) {
2042         push(@implContent, "    return V8${interfaceName}::constructorCustom(args);\n");
2043     } else {
2044         push(@implContent, "    return ${interfaceName}V8Internal::constructor(args);\n");
2045     }
2046     push(@implContent, "}\n\n");
2047 }
2048
2049 sub GenerateConstructor
2050 {
2051     my $interface = shift;
2052     my $interfaceName = $interface->name;
2053
2054     if (@{$interface->constructors} == 1) {
2055         GenerateSingleConstructorCallback($interface, @{$interface->constructors}[0]);
2056     } else {
2057         foreach my $constructor (@{$interface->constructors}) {
2058             GenerateSingleConstructorCallback($interface, $constructor);
2059         }
2060         GenerateOverloadedConstructorCallback($interface);
2061     }
2062 }
2063
2064 sub GenerateEventConstructor
2065 {
2066     my $interface = shift;
2067     my $interfaceName = $interface->name;
2068
2069     AddToImplIncludes("Dictionary.h");
2070     push(@implContentInternals, <<END);
2071 static v8::Handle<v8::Value> constructor(const v8::Arguments& args)
2072 {
2073 END
2074     push(@implContentInternals, <<END);
2075     if (args.Length() < 1)
2076         return throwNotEnoughArgumentsError(args.GetIsolate());
2077
2078     V8TRYCATCH_FOR_V8STRINGRESOURCE(V8StringResource<>, type, args[0]);
2079     ${interfaceName}Init eventInit;
2080     if (args.Length() >= 2) {
2081         V8TRYCATCH(Dictionary, options, Dictionary(args[1], args.GetIsolate()));
2082         if (!fill${interfaceName}Init(eventInit, options))
2083             return v8Undefined();
2084     }
2085
2086     RefPtr<${interfaceName}> event = ${interfaceName}::create(type, eventInit);
2087
2088     v8::Handle<v8::Object> wrapper = args.Holder();
2089     V8DOMWrapper::associateObjectWithWrapper(event.release(), &V8${interfaceName}::info, wrapper, args.GetIsolate(), WrapperConfiguration::Dependent);
2090     return wrapper;
2091 }
2092 END
2093
2094     push(@implContent, <<END);
2095 bool fill${interfaceName}Init(${interfaceName}Init& eventInit, const Dictionary& options)
2096 {
2097 END
2098
2099     foreach my $interfaceBase (@{$interface->parents}) {
2100         push(@implContent, <<END);
2101     if (!fill${interfaceBase}Init(eventInit, options))
2102         return false;
2103
2104 END
2105     }
2106
2107     for (my $index = 0; $index < @{$interface->attributes}; $index++) {
2108         my $attribute = @{$interface->attributes}[$index];
2109         if ($attribute->signature->extendedAttributes->{"InitializedByEventConstructor"}) {
2110             my $attributeName = $attribute->signature->name;
2111             push(@implContent, "    options.get(\"$attributeName\", eventInit.$attributeName);\n");
2112         }
2113     }
2114
2115     push(@implContent, <<END);
2116     return true;
2117 }
2118
2119 END
2120 }
2121
2122 sub GenerateTypedArrayConstructor
2123 {
2124     my $interface = shift;
2125     my $interfaceName = $interface->name;
2126     my $viewType = GetTypeNameOfExternalTypedArray($interface);
2127     my $type = $interface->extendedAttributes->{"TypedArray"};
2128     AddToImplIncludes("V8ArrayBufferViewCustom.h");
2129
2130     push(@implContentInternals, <<END);
2131 static v8::Handle<v8::Value> constructor(const v8::Arguments& args)
2132 {
2133     return constructWebGLArray<$interfaceName, V8${interfaceName}, $type>(args, &V8${interfaceName}::info, $viewType);
2134 }
2135
2136 END
2137 }
2138
2139 sub GenerateNamedConstructor
2140 {
2141     my $function = shift;
2142     my $interface = shift;
2143
2144     my $interfaceName = $interface->name;
2145     my $v8InterfaceName = "V8$interfaceName";
2146     my $raisesExceptions = @{$function->raisesExceptions};
2147     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) {
2148         $raisesExceptions = 1;
2149     }
2150     if (!$raisesExceptions) {
2151         foreach my $parameter (@{$function->parameters}) {
2152             if ((!$parameter->extendedAttributes->{"Callback"} and TypeCanFailConversion($parameter)) or $parameter->extendedAttributes->{"IsIndex"}) {
2153                 $raisesExceptions = 1;
2154             }
2155         }
2156     }
2157
2158     my $maybeObserveFeature = GenerateFeatureObservation($function->signature->extendedAttributes->{"V8MeasureAs"});
2159
2160     my @beforeArgumentList;
2161     my @afterArgumentList;
2162
2163     my $toActiveDOMObject = "0";
2164     if ($codeGenerator->InheritsExtendedAttribute($interface, "ActiveDOMObject")) {
2165         $toActiveDOMObject = "${v8InterfaceName}::toActiveDOMObject";
2166     }
2167
2168     my $toEventTarget = "0";
2169     if ($codeGenerator->InheritsExtendedAttribute($interface, "EventTarget")) {
2170         $toEventTarget = "${v8InterfaceName}::toEventTarget";
2171     }
2172
2173     AddToImplIncludes("Frame.h");
2174     push(@implContent, <<END);
2175 WrapperTypeInfo ${v8InterfaceName}Constructor::info = { ${v8InterfaceName}Constructor::GetTemplate, ${v8InterfaceName}::derefObject, $toActiveDOMObject, $toEventTarget, 0, ${v8InterfaceName}::installPerContextPrototypeProperties, 0, WrapperTypeObjectPrototype };
2176
2177 static v8::Handle<v8::Value> ${v8InterfaceName}ConstructorCallback(const v8::Arguments& args)
2178 {
2179     ${maybeObserveFeature}
2180 END
2181     push(@implContent, GenerateConstructorHeader());
2182     push(@implContent, <<END);
2183     Document* document = currentDocument(BindingState::instance());
2184
2185     // Make sure the document is added to the DOM Node map. Otherwise, the ${interfaceName} instance
2186     // may end up being the only node in the map and get garbage-collected prematurely.
2187     toV8(document, args.Holder(), args.GetIsolate());
2188
2189 END
2190
2191     push(@implContent, GenerateArgumentsCountCheck($function, $interface));
2192
2193     if ($raisesExceptions) {
2194         AddToImplIncludes("ExceptionCode.h");
2195         push(@implContent, "\n");
2196         push(@implContent, "    ExceptionCode ec = 0;\n");
2197     }
2198
2199     my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersCheck($function, $interfaceName);
2200     push(@implContent, $parameterCheckString);
2201
2202     push(@beforeArgumentList, "document");
2203
2204     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) {
2205         push(@afterArgumentList, "ec");
2206     }
2207
2208     my @argumentList;
2209     my $index = 0;
2210     foreach my $parameter (@{$function->parameters}) {
2211         last if $index eq $paramIndex;
2212         if ($replacements{$parameter->name}) {
2213             push(@argumentList, $replacements{$parameter->name});
2214         } else {
2215             push(@argumentList, $parameter->name);
2216         }
2217         $index++;
2218     }
2219
2220     my $argumentString = join(", ", @beforeArgumentList, @argumentList, @afterArgumentList);
2221     push(@implContent, "\n");
2222     push(@implContent, "    RefPtr<${interfaceName}> impl = ${interfaceName}::createForJSConstructor(${argumentString});\n");
2223     push(@implContent, "    v8::Handle<v8::Object> wrapper = args.Holder();\n");
2224
2225     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) {
2226         push(@implContent, "    if (ec)\n");
2227         push(@implContent, "        goto fail;\n");
2228     }
2229
2230     push(@implContent, <<END);
2231
2232     V8DOMWrapper::associateObjectWithWrapper(impl.release(), &${v8InterfaceName}Constructor::info, wrapper, args.GetIsolate(), WrapperConfiguration::Dependent);
2233     return wrapper;
2234 END
2235
2236     if ($raisesExceptions) {
2237         push(@implContent, "    fail:\n");
2238         push(@implContent, "    return setDOMException(ec, args.GetIsolate());\n");
2239     }
2240
2241     push(@implContent, "}\n");
2242
2243     push(@implContent, <<END);
2244
2245 v8::Persistent<v8::FunctionTemplate> ${v8InterfaceName}Constructor::GetTemplate(v8::Isolate* isolate, WrapperWorldType worldType)
2246 {
2247     static v8::Persistent<v8::FunctionTemplate> cachedTemplate;
2248     if (!cachedTemplate.IsEmpty())
2249         return cachedTemplate;
2250
2251     v8::HandleScope scope;
2252     v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(${v8InterfaceName}ConstructorCallback);
2253
2254     v8::Local<v8::ObjectTemplate> instance = result->InstanceTemplate();
2255     instance->SetInternalFieldCount(${v8InterfaceName}::internalFieldCount);
2256     result->SetClassName(v8::String::NewSymbol("${interfaceName}"));
2257     result->Inherit(${v8InterfaceName}::GetTemplate(isolate, worldType));
2258
2259     cachedTemplate = v8::Persistent<v8::FunctionTemplate>::New(isolate, result);
2260     return cachedTemplate;
2261 }
2262
2263 END
2264 }
2265
2266 sub GenerateConstructorHeader
2267 {
2268     my $content = <<END;
2269     if (!args.IsConstructCall())
2270         return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate());
2271
2272     if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
2273         return args.Holder();
2274
2275 END
2276     return $content;
2277 }
2278
2279 sub GenerateBatchedAttributeData
2280 {
2281     my $interface = shift;
2282     my $attributes = shift;
2283     my $interfaceName = $interface->name;
2284
2285     foreach my $attribute (@$attributes) {
2286         my $conditionalString = $codeGenerator->GenerateConditionalString($attribute->signature);
2287         push(@implContent, "#if ${conditionalString}\n") if $conditionalString;
2288         GenerateSingleBatchedAttribute($interfaceName, $attribute, ",", "");
2289         push(@implContent, "#endif // ${conditionalString}\n") if $conditionalString;
2290     }
2291 }
2292
2293 sub GenerateSingleBatchedAttribute
2294 {
2295     my $interfaceName = shift;
2296     my $attribute = shift;
2297     my $delimiter = shift;
2298     my $indent = shift;
2299     my $attrName = $attribute->signature->name;
2300     my $attrExt = $attribute->signature->extendedAttributes;
2301
2302     my $accessControl = "v8::DEFAULT";
2303     if ($attrExt->{"DoNotCheckSecurityOnGetter"}) {
2304         $accessControl = "v8::ALL_CAN_READ";
2305     } elsif ($attrExt->{"DoNotCheckSecurityOnSetter"}) {
2306         $accessControl = "v8::ALL_CAN_WRITE";
2307     } elsif ($attrExt->{"DoNotCheckSecurity"}) {
2308         $accessControl = "v8::ALL_CAN_READ";
2309         if (!IsReadonly($attribute)) {
2310             $accessControl .= " | v8::ALL_CAN_WRITE";
2311         }
2312     }
2313     if ($attrExt->{"V8Unforgeable"}) {
2314         $accessControl .= " | v8::PROHIBITS_OVERWRITING";
2315     }
2316     $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";
2317
2318     my $customAccessor = HasCustomGetter($attrExt) || HasCustomSetter($attrExt) || "";
2319     if ($customAccessor eq "VALUE_IS_MISSING") {
2320         # use the naming convension, interface + (capitalize) attr name
2321         $customAccessor = $interfaceName . "::" . $attrName;
2322     }
2323
2324     my $getter;
2325     my $setter;
2326     my $propAttr = "v8::None";
2327
2328     # Check attributes.
2329     if ($attrExt->{"NotEnumerable"}) {
2330         $propAttr .= " | v8::DontEnum";
2331     }
2332     if ($attrExt->{"V8Unforgeable"}) {
2333         $propAttr .= " | v8::DontDelete";
2334     }
2335
2336     my $on_proto = "0 /* on instance */";
2337     my $data = "0 /* no data */";
2338
2339     # Constructor
2340     if ($attribute->signature->type =~ /Constructor$/) {
2341         my $constructorType = $attribute->signature->type;
2342         $constructorType =~ s/Constructor$//;
2343         # $constructorType ~= /Constructor$/ indicates that it is NamedConstructor.
2344         # We do not generate the header file for NamedConstructor of class XXXX,
2345         # since we generate the NamedConstructor declaration into the header file of class XXXX.
2346         if ($constructorType !~ /Constructor$/ || $attribute->signature->extendedAttributes->{"V8CustomConstructor"} || $attribute->signature->extendedAttributes->{"CustomConstructor"}) {
2347             AddToImplIncludes("V8${constructorType}.h", $attribute->signature->extendedAttributes->{"Conditional"});
2348         }
2349         $data = "&V8${constructorType}::info";
2350         $getter = "${interfaceName}V8Internal::${interfaceName}ConstructorGetter";
2351         $setter = "${interfaceName}V8Internal::${interfaceName}ReplaceableAttrSetterCallback";
2352     } else {
2353         # Default Getter and Setter
2354         $getter = "${interfaceName}V8Internal::${attrName}AttrGetterCallback";
2355         $setter = "${interfaceName}V8Internal::${attrName}AttrSetterCallback";
2356
2357         if (!HasCustomSetter($attrExt) && $attrExt->{"Replaceable"}) {
2358             $setter = "${interfaceName}V8Internal::${interfaceName}ReplaceableAttrSetterCallback";
2359         }
2360     }
2361
2362     # Read only attributes
2363     if (IsReadonly($attribute)) {
2364         $setter = "0";
2365     }
2366
2367     # An accessor can be installed on the proto
2368     if ($attrExt->{"V8OnProto"}) {
2369         $on_proto = "1 /* on proto */";
2370     }
2371
2372     my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
2373                       "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
2374
2375     push(@implContent, $indent . "    \/\/ $commentInfo\n");
2376     push(@implContent, $indent . "    {\"$attrName\", $getter, $setter, $data, $accessControl, static_cast<v8::PropertyAttribute>($propAttr), $on_proto}" . $delimiter . "\n");
2377 }
2378
2379 sub IsStandardFunction
2380 {
2381     my $interface = shift;
2382     my $function = shift;
2383
2384     my $interfaceName = $interface->name;
2385     my $attrExt = $function->signature->extendedAttributes;
2386     return 0 if $attrExt->{"V8Unforgeable"};
2387     return 0 if $function->isStatic;
2388     return 0 if $attrExt->{"V8EnabledAtRuntime"};
2389     return 0 if $attrExt->{"V8EnabledPerContext"};
2390     return 0 if RequiresCustomSignature($function);
2391     return 0 if $attrExt->{"V8DoNotCheckSignature"};
2392     return 0 if ($attrExt->{"DoNotCheckSecurity"} && ($interface->extendedAttributes->{"CheckSecurity"} || $interfaceName eq "DOMWindow"));
2393     return 0 if $attrExt->{"NotEnumerable"};
2394     return 0 if $attrExt->{"V8ReadOnly"};
2395     return 1;
2396 }
2397
2398 sub GenerateNonStandardFunction
2399 {
2400     my $interface = shift;
2401     my $function = shift;
2402
2403     my $interfaceName = $interface->name;
2404     my $attrExt = $function->signature->extendedAttributes;
2405     my $name = $function->signature->name;
2406
2407     my $property_attributes = "v8::DontDelete";
2408     if ($attrExt->{"NotEnumerable"}) {
2409         $property_attributes .= " | v8::DontEnum";
2410     }
2411     if ($attrExt->{"V8ReadOnly"}) {
2412         $property_attributes .= " | v8::ReadOnly";
2413     }
2414
2415     my $commentInfo = "Function '$name' (ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
2416
2417     my $template = "proto";
2418     if ($attrExt->{"V8Unforgeable"}) {
2419         $template = "instance";
2420     }
2421     if ($function->isStatic) {
2422         $template = "desc";
2423     }
2424
2425     my $conditional = "";
2426     if ($attrExt->{"V8EnabledAtRuntime"}) {
2427         # Only call Set()/SetAccessor() if this method should be enabled
2428         my $enable_function = GetRuntimeEnableFunctionName($function->signature);
2429         $conditional = "if (${enable_function}())\n        ";
2430     }
2431     if ($attrExt->{"V8EnabledPerContext"}) {
2432         # Only call Set()/SetAccessor() if this method should be enabled
2433         my $enable_function = GetContextEnableFunction($function->signature);
2434         $conditional = "if (${enable_function}(impl->document()))\n        ";
2435     }
2436
2437     if ($interface->extendedAttributes->{"CheckSecurity"} && $attrExt->{"DoNotCheckSecurity"}) {
2438         # Functions that are marked DoNotCheckSecurity are always readable but if they are changed
2439         # and then accessed on a different domain we do not return the underlying value but instead
2440         # return a new copy of the original function. This is achieved by storing the changed value
2441         # as hidden property.
2442         push(@implContent, <<END);
2443
2444     // $commentInfo
2445     ${conditional}$template->SetAccessor(v8::String::NewSymbol("$name"), ${interfaceName}V8Internal::${name}AttrGetterCallback, ${interfaceName}V8Internal::${interfaceName}DomainSafeFunctionSetter, v8Undefined(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>($property_attributes));
2446 END
2447         return;
2448     }
2449
2450     my $signature = "defaultSignature";
2451     if ($attrExt->{"V8DoNotCheckSignature"} || $function->isStatic) {
2452        $signature = "v8::Local<v8::Signature>()";
2453     }
2454
2455     if (RequiresCustomSignature($function)) {
2456         $signature = "${name}Signature";
2457         push(@implContent, "\n    // Custom Signature '$name'\n", CreateCustomSignature($function));
2458     }
2459
2460     if ($property_attributes eq "v8::DontDelete") {
2461         $property_attributes = "";
2462     } else {
2463         $property_attributes = ", static_cast<v8::PropertyAttribute>($property_attributes)";
2464     }
2465
2466     if ($template eq "proto" && $conditional eq "" && $signature eq "defaultSignature" && $property_attributes eq "") {
2467         die "This shouldn't happen: Intraface '$interfaceName' $commentInfo\n";
2468     }
2469
2470     my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature);
2471     push(@implContent, "#if ${conditionalString}\n") if $conditionalString;
2472     push(@implContent, "    ${conditional}$template->Set(v8::String::NewSymbol(\"$name\"), v8::FunctionTemplate::New(${interfaceName}V8Internal::${name}MethodCallback, v8Undefined(), ${signature})$property_attributes);\n");
2473     push(@implContent, "#endif // ${conditionalString}\n") if $conditionalString;
2474 }
2475
2476 sub GenerateImplementationIndexer
2477 {
2478     my $interface = shift;
2479     my $indexer = shift;
2480     my $interfaceName = $interface->name;
2481     my $v8InterfaceName = "V8$interfaceName";
2482
2483     # FIXME: Figure out what NumericIndexedGetter is really supposed to do. Right now, it's only set on WebGL-related files.
2484     my $hasCustomSetter = $interface->extendedAttributes->{"CustomIndexedSetter"} && !$interface->extendedAttributes->{"NumericIndexedGetter"};
2485     my $hasGetter = $interface->extendedAttributes->{"IndexedGetter"} || $interface->extendedAttributes->{"CustomGetOwnPropertySlot"};
2486
2487     # FIXME: Investigate and remove this nastinesss. In V8, named property handling and indexer handling are apparently decoupled,
2488     # which means that object[X] where X is a number doesn't reach named property indexer. So we need to provide
2489     # simplistic, mirrored indexer handling in addition to named property handling.
2490     my $isSpecialCase = exists $indexerSpecialCases{$interfaceName};
2491     if ($isSpecialCase) {
2492         $hasGetter = 1;
2493         if ($interface->extendedAttributes->{"CustomNamedSetter"}) {
2494             $hasCustomSetter = 1;
2495         }
2496     }
2497
2498     my $hasEnumerator = !$isSpecialCase && $codeGenerator->InheritsInterface($interface, "Node");
2499
2500     # FIXME: Find a way to not have to special-case HTMLOptionsCollection.
2501     if ($interfaceName eq "HTMLOptionsCollection") {
2502         $hasEnumerator = 1;
2503         $hasGetter = 1;
2504     }
2505
2506     if (!$hasGetter) {
2507         return;
2508     }
2509
2510     AddToImplIncludes("V8Collection.h");
2511
2512     if (!$indexer) {
2513         $indexer = $codeGenerator->FindSuperMethod($interface, "item");
2514     }
2515
2516     my $indexerType = $indexer ? $indexer->type : 0;
2517
2518     # FIXME: Remove this once toV8 helper methods are implemented (see https://bugs.webkit.org/show_bug.cgi?id=32563).
2519     if ($interfaceName eq "WebKitCSSKeyframesRule") {
2520         $indexerType = "WebKitCSSKeyframeRule";
2521     }
2522
2523     if ($indexerType && !$hasCustomSetter) {
2524         if ($indexerType eq "DOMString") {
2525             my $conversion = $indexer->extendedAttributes->{"TreatReturnedNullStringAs"};
2526             if ($conversion && $conversion eq "Null") {
2527                 push(@implContent, <<END);
2528     setCollectionStringOrUndefinedIndexedGetter<${interfaceName}>(desc);
2529 END
2530             } else {
2531                 push(@implContent, <<END);
2532     setCollectionStringIndexedGetter<${interfaceName}>(desc);
2533 END
2534             }
2535         } else {
2536             push(@implContent, <<END);
2537     setCollectionIndexedGetter<${interfaceName}, ${indexerType}>(desc);
2538 END
2539             # Include the header for this indexer type, because setCollectionIndexedGetter() requires toV8() for this type.
2540             AddToImplIncludes("V8${indexerType}.h");
2541         }
2542
2543         return;
2544     }
2545
2546     my $hasDeleter = $interface->extendedAttributes->{"CustomDeleteProperty"};
2547     my $setOn = "Instance";
2548
2549     # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
2550     # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
2551     # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
2552     # on the object.
2553     if ($interfaceName eq "DOMWindow") {
2554         $setOn = "Prototype";
2555         $hasDeleter = 0;
2556     }
2557
2558     push(@implContent, "    desc->${setOn}Template()->SetIndexedPropertyHandler(${v8InterfaceName}::indexedPropertyGetter");
2559     push(@implContent, $hasCustomSetter ? ", ${v8InterfaceName}::indexedPropertySetter" : ", 0");
2560     push(@implContent, ", 0"); # IndexedPropertyQuery -- not being used at the moment.
2561     push(@implContent, $hasDeleter ? ", ${v8InterfaceName}::indexedPropertyDeleter" : ", 0");
2562     push(@implContent, ", nodeCollectionIndexedPropertyEnumerator<${interfaceName}>") if $hasEnumerator;
2563     push(@implContent, ");\n");
2564 }
2565
2566 sub GenerateImplementationNamedPropertyGetter
2567 {
2568     my $interface = shift;
2569     my $namedPropertyGetter = shift;
2570     my $interfaceName = $interface->name;
2571     my $v8InterfaceName = "V8$interfaceName";
2572     my $hasCustomNamedGetter = $interface->extendedAttributes->{"CustomNamedGetter"} || $interface->extendedAttributes->{"CustomGetOwnPropertySlot"};
2573
2574     if ($interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
2575         $hasCustomNamedGetter = 1;
2576     }
2577
2578     if ($interfaceName eq "HTMLDocument") {
2579         $hasCustomNamedGetter = 0;
2580     }
2581
2582     my $hasGetter = $interface->extendedAttributes->{"NamedGetter"} || $hasCustomNamedGetter;
2583     if (!$hasGetter) {
2584         return;
2585     }
2586
2587     if (!$namedPropertyGetter) {
2588         $namedPropertyGetter = $codeGenerator->FindSuperMethod($interface, "namedItem");
2589     }
2590
2591     if ($namedPropertyGetter && $namedPropertyGetter->type ne "Node" && !$namedPropertyGetter->extendedAttributes->{"Custom"} && !$hasCustomNamedGetter) {
2592         AddToImplIncludes("V8Collection.h");
2593         my $type = $namedPropertyGetter->type;
2594         push(@implContent, <<END);
2595     setCollectionNamedGetter<${interfaceName}, ${type}>(desc);
2596 END
2597         return;
2598     }
2599
2600     my $hasCustomNamedSetter = $interface->extendedAttributes->{"CustomNamedSetter"};
2601     my $hasDeleter = $interface->extendedAttributes->{"CustomDeleteProperty"};
2602     my $hasEnumerator = $interface->extendedAttributes->{"CustomEnumerateProperty"};
2603     my $setOn = "Instance";
2604
2605     # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
2606     # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
2607     # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
2608     # on the object.
2609     if ($interfaceName eq "DOMWindow") {
2610         $setOn = "Prototype";
2611         $hasDeleter = 0;
2612         $hasEnumerator = 0;
2613     }
2614
2615     if ($interfaceName eq "HTMLPropertiesCollection") {
2616         push(@implContent, "    desc->${setOn}Template()->SetNamedPropertyHandler(V8HTMLCollection::namedPropertyGetter, ");
2617     } else {
2618         push(@implContent, "    desc->${setOn}Template()->SetNamedPropertyHandler(${v8InterfaceName}::namedPropertyGetter, ");
2619     }
2620     push(@implContent, $hasCustomNamedSetter ? "${v8InterfaceName}::namedPropertySetter, " : "0, ");
2621     # If there is a custom enumerator, there MUST be custom query to properly communicate property attributes.
2622     push(@implContent, $hasEnumerator ? "${v8InterfaceName}::namedPropertyQuery, " : "0, ");
2623     push(@implContent, $hasDeleter ? "${v8InterfaceName}::namedPropertyDeleter, " : "0, ");
2624     push(@implContent, $hasEnumerator ? "${v8InterfaceName}::namedPropertyEnumerator" : "0");
2625     push(@implContent, ");\n");
2626 }
2627
2628 sub GenerateImplementationCustomCall
2629 {
2630     my $interface = shift;
2631     my $interfaceName = $interface->name;
2632
2633     if ($interface->extendedAttributes->{"CustomCall"}) {
2634         push(@implContent, "    desc->InstanceTemplate()->SetCallAsFunctionHandler(V8${interfaceName}::callAsFunctionCallback);\n");
2635     }
2636 }
2637
2638 sub GenerateImplementationMasqueradesAsUndefined
2639 {
2640     my $interface = shift;
2641     if ($interface->extendedAttributes->{"MasqueradesAsUndefined"})
2642     {
2643         push(@implContent, "    desc->InstanceTemplate()->MarkAsUndetectable();\n");
2644     }
2645 }
2646
2647 sub GenerateImplementation
2648 {
2649     my $object = shift;
2650     my $interface = shift;
2651     my $interfaceName = $interface->name;
2652     my $visibleInterfaceName = $codeGenerator->GetVisibleInterfaceName($interface);
2653     my $v8InterfaceName = "V8$interfaceName";
2654     my $nativeType = GetNativeTypeForConversions($interface);
2655     my $vtableNameGnu = GetGnuVTableNameForInterface($interface);
2656     my $vtableRefGnu = GetGnuVTableRefForInterface($interface);
2657     my $vtableRefWin = GetWinVTableRefForInterface($interface);
2658
2659     # - Add default header template
2660     push(@implContentHeader, GenerateImplementationContentHeader($interface));
2661
2662     AddToImplIncludes("BindingState.h");
2663     AddToImplIncludes("ContextFeatures.h");
2664     AddToImplIncludes("RuntimeEnabledFeatures.h");
2665     AddToImplIncludes("V8Binding.h");
2666     AddToImplIncludes("V8DOMWrapper.h");
2667
2668     AddIncludesForType($interfaceName);
2669
2670     my $toActiveDOMObject = $codeGenerator->InheritsExtendedAttribute($interface, "ActiveDOMObject") ? "${v8InterfaceName}::toActiveDOMObject" : "0";
2671     my $toEventTarget = $codeGenerator->InheritsExtendedAttribute($interface, "EventTarget") ? "${v8InterfaceName}::toEventTarget" : "0";
2672     my $rootForGC = NeedsCustomOpaqueRootForGC($interface) ? "${v8InterfaceName}::opaqueRootForGC" : "0";
2673
2674     # Find the super descriptor.
2675     my $parentClass = "";
2676     my $parentClassTemplate = "";
2677     foreach (@{$interface->parents}) {
2678         my $parent = $_;
2679         AddToImplIncludes("V8${parent}.h");
2680         $parentClass = "V8" . $parent;
2681         $parentClassTemplate = $parentClass . "::GetTemplate(isolate, worldType)";
2682         last;
2683     }
2684
2685     push(@implContentInternals, <<END) if $vtableNameGnu;
2686 #if ENABLE(BINDING_INTEGRITY)
2687 #if defined(OS_WIN)
2688 #pragma warning(disable: 4483)
2689 extern "C" { extern void (*const ${vtableRefWin}[])(); }
2690 #else
2691 extern "C" { extern void* ${vtableNameGnu}[]; }
2692 #endif
2693 #endif // ENABLE(BINDING_INTEGRITY)
2694
2695 END
2696
2697     push(@implContentInternals, "namespace WebCore {\n\n");
2698
2699     push(@implContentInternals, <<END) if $vtableNameGnu;
2700 #if ENABLE(BINDING_INTEGRITY)
2701 // This checks if a DOM object that is about to be wrapped is valid.
2702 // Specifically, it checks that a vtable of the DOM object is equal to
2703 // a vtable of an expected class.
2704 // Due to a dangling pointer, the DOM object you are wrapping might be
2705 // already freed or realloced. If freed, the check will fail because
2706 // a free list pointer should be stored at the head of the DOM object.
2707 // If realloced, the check will fail because the vtable of the DOM object
2708 // differs from the expected vtable (unless the same class of DOM object
2709 // is realloced on the slot).
2710 inline void checkTypeOrDieTrying(${nativeType}* object)
2711 {
2712     void* actualVTablePointer = *(reinterpret_cast<void**>(object));
2713 #if defined(OS_WIN)
2714     void* expectedVTablePointer = reinterpret_cast<void*>(${vtableRefWin});
2715 #else
2716     void* expectedVTablePointer = ${vtableRefGnu};
2717 #endif
2718     if (actualVTablePointer != expectedVTablePointer)
2719         CRASH();
2720 }
2721 #endif // ENABLE(BINDING_INTEGRITY)
2722
2723 END
2724
2725
2726     my $parentClassInfo = $parentClass ? "&${parentClass}::info" : "0";
2727
2728     my $WrapperTypePrototype = $interface->isException ? "WrapperTypeErrorPrototype" : "WrapperTypeObjectPrototype";
2729
2730     push(@implContentInternals, "WrapperTypeInfo ${v8InterfaceName}::info = { ${v8InterfaceName}::GetTemplate, ${v8InterfaceName}::derefObject, $toActiveDOMObject, $toEventTarget, $rootForGC, ${v8InterfaceName}::installPerContextPrototypeProperties, $parentClassInfo, $WrapperTypePrototype };\n\n");
2731     push(@implContentInternals, "namespace ${interfaceName}V8Internal {\n\n");
2732
2733     push(@implContentInternals, "template <typename T> void V8_USE(T) { }\n\n");
2734
2735     my $hasConstructors = 0;
2736     my $hasReplaceable = 0;
2737
2738     # Generate property accessors for attributes.
2739     for (my $index = 0; $index < @{$interface->attributes}; $index++) {
2740         my $attribute = @{$interface->attributes}[$index];
2741         my $attrType = $attribute->signature->type;
2742         my $attrExt = $attribute->signature->extendedAttributes;
2743
2744         # Generate special code for the constructor attributes.
2745         if ($attrType =~ /Constructor$/) {
2746             if (!HasCustomGetter($attrExt)) {
2747                 $hasConstructors = 1;
2748             }
2749             next;
2750         }
2751
2752         if ($attrType eq "EventListener" && $interfaceName eq "DOMWindow") {
2753             $attrExt->{"V8OnProto"} = 1;
2754         }
2755
2756         if ($attrType eq "SerializedScriptValue") {
2757             AddToImplIncludes("SerializedScriptValue.h");
2758         }
2759
2760         GenerateNormalAttrGetter($attribute, $interface);
2761         GenerateNormalAttrGetterCallback($attribute, $interface);
2762
2763         if (!HasCustomSetter($attrExt) && $attrExt->{"Replaceable"}) {
2764             $hasReplaceable = 1;
2765         } elsif (!IsReadonly($attribute)) {
2766             GenerateNormalAttrSetter($attribute, $interface);
2767             GenerateNormalAttrSetterCallback($attribute, $interface);
2768         }
2769     }
2770
2771     if ($hasConstructors) {
2772         GenerateConstructorGetter($interface);
2773     }
2774
2775     if ($hasConstructors || $hasReplaceable) {
2776         GenerateReplaceableAttrSetter($interface);
2777         GenerateReplaceableAttrSetterCallback($interface);
2778     }
2779
2780     if (NeedsCustomOpaqueRootForGC($interface)) {
2781         GenerateOpaqueRootForGC($interface);
2782     }
2783
2784     if ($interface->extendedAttributes->{"CheckSecurity"} && $interface->name ne "DOMWindow") {
2785         GenerateSecurityCheckFunctions($interface);
2786     }
2787
2788     if ($interface->extendedAttributes->{"TypedArray"}) {
2789         my $viewType = GetTypeNameOfExternalTypedArray($interface);
2790         push(@implContent, <<END);
2791 v8::Handle<v8::Object> wrap($interfaceName* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
2792 {
2793     ASSERT(impl);
2794     v8::Handle<v8::Object> wrapper = ${v8InterfaceName}::createWrapper(impl, creationContext, isolate);
2795     if (!wrapper.IsEmpty())
2796         wrapper->SetIndexedPropertiesToExternalArrayData(impl->baseAddress(), $viewType, impl->length());
2797     return wrapper;
2798 }
2799
2800 END
2801     }
2802
2803     my $indexer;
2804     my $namedPropertyGetter;
2805     my @enabledPerContextFunctions;
2806     my @normalFunctions;
2807     my $needsDomainSafeFunctionSetter = 0;
2808     # Generate methods for functions.
2809     foreach my $function (@{$interface->functions}) {
2810         GenerateFunction($function, $interface);
2811         if ($function->{overloadIndex} == @{$function->{overloads}}) {
2812             if ($function->{overloadIndex} > 1) {
2813                 GenerateOverloadedFunction($function, $interface);
2814             }
2815             GenerateFunctionCallback($function, $interface);
2816         }
2817
2818         if ($function->signature->name eq "item") {
2819             $indexer = $function->signature;
2820         }
2821
2822         if ($interfaceName eq "HTMLPropertiesCollection") {
2823             if ($function->signature->name eq "propertyNodeList") {
2824                 $namedPropertyGetter = $function->signature;
2825             }
2826         } elsif ($function->signature->name eq "namedItem") {
2827             $namedPropertyGetter = $function->signature;
2828         }
2829
2830         # If the function does not need domain security check, we need to
2831         # generate an access getter that returns different function objects
2832         # for different calling context.
2833         if ($interface->extendedAttributes->{"CheckSecurity"} && $function->signature->extendedAttributes->{"DoNotCheckSecurity"}) {
2834             if (!HasCustomMethod($function->signature->extendedAttributes) || $function->{overloadIndex} == 1) {
2835                 GenerateDomainSafeFunctionGetter($function, $interfaceName);
2836                 $needsDomainSafeFunctionSetter = 1;
2837             }
2838         }
2839
2840         # Separate out functions that are enabled per context so we can process them specially.
2841         if ($function->signature->extendedAttributes->{"V8EnabledPerContext"}) {
2842             push(@enabledPerContextFunctions, $function);
2843         } else {
2844             push(@normalFunctions, $function);
2845         }
2846     }
2847
2848     if ($needsDomainSafeFunctionSetter) {
2849         GenerateDomainSafeFunctionSetter($interfaceName);
2850     }
2851
2852     # Attributes
2853     my $attributes = $interface->attributes;
2854
2855     # For the DOMWindow interface we partition the attributes into the
2856     # ones that disallows shadowing and the rest.
2857     my @disallowsShadowing;
2858     # Also separate out attributes that are enabled at runtime so we can process them specially.
2859     my @enabledAtRuntimeAttributes;
2860     my @enabledPerContextAttributes;
2861     my @normalAttributes;
2862     foreach my $attribute (@$attributes) {
2863
2864         if ($interfaceName eq "DOMWindow" && $attribute->signature->extendedAttributes->{"V8Unforgeable"}) {
2865             push(@disallowsShadowing, $attribute);
2866         } elsif ($attribute->signature->extendedAttributes->{"V8EnabledAtRuntime"}) {
2867             push(@enabledAtRuntimeAttributes, $attribute);
2868         } elsif ($attribute->signature->extendedAttributes->{"V8EnabledPerContext"}) {
2869             push(@enabledPerContextAttributes, $attribute);
2870         } else {
2871             push(@normalAttributes, $attribute);
2872         }
2873     }
2874     $attributes = \@normalAttributes;
2875     # Put the attributes that disallow shadowing on the shadow object.
2876     if (@disallowsShadowing) {
2877         push(@implContent, "static const V8DOMConfiguration::BatchedAttribute shadowAttrs[] = {\n");
2878         GenerateBatchedAttributeData($interface, \@disallowsShadowing);
2879         push(@implContent, "};\n\n");
2880     }
2881
2882     my $has_attributes = 0;
2883     if (@$attributes) {
2884         $has_attributes = 1;
2885         push(@implContent, "static const V8DOMConfiguration::BatchedAttribute ${v8InterfaceName}Attrs[] = {\n");
2886         GenerateBatchedAttributeData($interface, $attributes);
2887         push(@implContent, "};\n\n");
2888     }
2889
2890     # Setup table of standard callback functions
2891     my $num_callbacks = 0;
2892     my $has_callbacks = 0;
2893     foreach my $function (@normalFunctions) {
2894         # Only one table entry is needed for overloaded methods:
2895         next if $function->{overloadIndex} > 1;
2896         # Don't put any nonstandard functions into this table:
2897         next if !IsStandardFunction($interface, $function);
2898         if (!$has_callbacks) {
2899             $has_callbacks = 1;
2900             push(@implContent, "static const V8DOMConfiguration::BatchedMethod ${v8InterfaceName}Methods[] = {\n");
2901         }
2902         my $name = $function->signature->name;
2903         my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature);
2904         push(@implContent, "#if ${conditionalString}\n") if $conditionalString;
2905         push(@implContent, <<END);
2906     {"$name", ${interfaceName}V8Internal::${name}MethodCallback},
2907 END
2908         push(@implContent, "#endif\n") if $conditionalString;
2909         $num_callbacks++;
2910     }
2911     push(@implContent, "};\n\n")  if $has_callbacks;
2912
2913     # Setup constants
2914     my $has_constants = 0;
2915     my @constantsEnabledAtRuntime;
2916     if (@{$interface->constants}) {
2917         $has_constants = 1;
2918         push(@implContent, "static const V8DOMConfiguration::BatchedConstant ${v8InterfaceName}Consts[] = {\n");
2919     }
2920     foreach my $constant (@{$interface->constants}) {
2921         my $name = $constant->name;
2922         my $value = $constant->value;
2923         my $attrExt = $constant->extendedAttributes;
2924         my $conditional = $attrExt->{"Conditional"};
2925         my $implementedBy = $attrExt->{"ImplementedBy"};
2926         if ($implementedBy) {
2927             AddToImplIncludes("${implementedBy}.h");
2928         }
2929         if ($attrExt->{"V8EnabledAtRuntime"}) {
2930             push(@constantsEnabledAtRuntime, $constant);
2931         } else {
2932             # FIXME: we need the static_cast here only because of one constant, NodeFilter.idl
2933             # defines "const unsigned long SHOW_ALL = 0xFFFFFFFF".  It would be better if we
2934             # handled this here, and converted it to a -1 constant in the c++ output.
2935             if ($conditional) {
2936                 my $conditionalString = $codeGenerator->GenerateConditionalStringFromAttributeValue($conditional);
2937                 push(@implContent, "#if ${conditionalString}\n");
2938             }
2939             push(@implContent, <<END);
2940     {"${name}", static_cast<signed int>($value)},
2941 END
2942             push(@implContent, "#endif\n") if $conditional;
2943         }
2944     }
2945     if ($has_constants) {
2946         push(@implContent, "};\n\n");
2947         push(@implContent, $codeGenerator->GenerateCompileTimeCheckForEnumsIfNeeded($interface));
2948     }
2949
2950     if (!HasCustomConstructor($interface)) {
2951         if ($interface->extendedAttributes->{"NamedConstructor"}) {
2952             GenerateNamedConstructor(@{$interface->constructors}[0], $interface);
2953         } elsif ($interface->extendedAttributes->{"Constructor"}) {
2954             GenerateConstructor($interface);
2955         } elsif ($codeGenerator->IsConstructorTemplate($interface, "Event")) {
2956             GenerateEventConstructor($interface);
2957         } elsif ($codeGenerator->IsConstructorTemplate($interface, "TypedArray")) {
2958             GenerateTypedArrayConstructor($interface);
2959         }
2960     }
2961     if (IsConstructable($interface)) {
2962         GenerateConstructorCallback($interface);
2963     }
2964
2965     push(@implContentInternals, "} // namespace ${interfaceName}V8Internal\n\n");
2966
2967     my $access_check = "";
2968     if ($interface->extendedAttributes->{"CheckSecurity"} && $interfaceName ne "DOMWindow") {
2969         $access_check = "instance->SetAccessCheckCallbacks(${interfaceName}V8Internal::namedSecurityCheck, ${interfaceName}V8Internal::indexedSecurityCheck, v8::External::New(&${v8InterfaceName}::info));";
2970     }
2971
2972     # For the DOMWindow interface, generate the shadow object template
2973     # configuration method.
2974     if ($interfaceName eq "DOMWindow") {
2975         push(@implContent, <<END);
2976 static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ, v8::Isolate* isolate)
2977 {
2978     V8DOMConfiguration::batchConfigureAttributes(templ, v8::Handle<v8::ObjectTemplate>(), shadowAttrs, WTF_ARRAY_LENGTH(shadowAttrs), isolate);
2979
2980     // Install a security handler with V8.
2981     templ->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheckCustom, V8DOMWindow::indexedSecurityCheckCustom, v8::External::New(&V8DOMWindow::info));
2982     templ->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
2983     return templ;
2984 }
2985 END
2986     }
2987
2988     if (!$parentClassTemplate) {
2989         $parentClassTemplate = "v8::Persistent<v8::FunctionTemplate>()";
2990     }
2991
2992     # Generate the template configuration method
2993     push(@implContent,  <<END);
2994 static v8::Persistent<v8::FunctionTemplate> Configure${v8InterfaceName}Template(v8::Persistent<v8::FunctionTemplate> desc, v8::Isolate* isolate, WrapperWorldType worldType)
2995 {
2996     desc->ReadOnlyPrototype();
2997
2998     v8::Local<v8::Signature> defaultSignature;
2999 END
3000     if ($interface->extendedAttributes->{"V8EnabledAtRuntime"}) {
3001         my $enable_function = GetRuntimeEnableFunctionName($interface);
3002         push(@implContent, <<END);
3003     if (!${enable_function}())
3004         defaultSignature = V8DOMConfiguration::configureTemplate(desc, \"\", $parentClassTemplate, ${v8InterfaceName}::internalFieldCount, 0, 0, 0, 0, isolate);
3005     else
3006 END
3007     }
3008     push(@implContent,  <<END);
3009     defaultSignature = V8DOMConfiguration::configureTemplate(desc, \"${visibleInterfaceName}\", $parentClassTemplate, ${v8InterfaceName}::internalFieldCount,
3010 END
3011     # Set up our attributes if we have them
3012     if ($has_attributes) {
3013         push(@implContent, <<END);
3014         ${v8InterfaceName}Attrs, WTF_ARRAY_LENGTH(${v8InterfaceName}Attrs),
3015 END
3016     } else {
3017         push(@implContent, <<END);
3018         0, 0,
3019 END
3020     }
3021
3022     if ($has_callbacks) {
3023         push(@implContent, <<END);
3024         ${v8InterfaceName}Methods, WTF_ARRAY_LENGTH(${v8InterfaceName}Methods), isolate);
3025 END
3026     } else {
3027         push(@implContent, <<END);
3028         0, 0, isolate);
3029 END
3030     }
3031
3032     AddToImplIncludes("wtf/UnusedParam.h");
3033     push(@implContent, <<END);
3034     UNUSED_PARAM(defaultSignature); // In some cases, it will not be used.
3035 END
3036
3037     if (IsConstructable($interface)) {
3038         my $conditionalString = $codeGenerator->GenerateConstructorConditionalString($interface);
3039         push(@implContent, "#if $conditionalString\n") if $conditionalString;
3040         push(@implContent, "    desc->SetCallHandler(${v8InterfaceName}::constructorCallback);\n");
3041         push(@implContent, "#endif // $conditionalString\n") if $conditionalString;
3042     }
3043
3044     if ($access_check or @enabledAtRuntimeAttributes or @normalFunctions or $has_constants) {
3045         push(@implContent,  <<END);
3046     v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
3047     v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
3048     UNUSED_PARAM(instance); // In some cases, it will not be used.
3049     UNUSED_PARAM(proto); // In some cases, it will not be used.
3050 END
3051     }
3052
3053     push(@implContent,  "    $access_check\n");
3054
3055     # Setup the enable-at-runtime attrs if we have them
3056     foreach my $runtime_attr (@enabledAtRuntimeAttributes) {
3057         my $enable_function = GetRuntimeEnableFunctionName($runtime_attr->signature);
3058         my $conditionalString = $codeGenerator->GenerateConditionalString($runtime_attr->signature);
3059         push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
3060         push(@implContent, "    if (${enable_function}()) {\n");
3061         push(@implContent, "        static const V8DOMConfiguration::BatchedAttribute attrData =\\\n");
3062         GenerateSingleBatchedAttribute($interfaceName, $runtime_attr, ";", "    ");
3063         push(@implContent, <<END);
3064         V8DOMConfiguration::configureAttribute(instance, proto, attrData, isolate);
3065     }
3066 END
3067         push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
3068     }
3069
3070     # Setup the enable-at-runtime constants if we have them
3071     foreach my $runtime_const (@constantsEnabledAtRuntime) {
3072         my $enable_function = GetRuntimeEnableFunctionName($runtime_const);
3073         my $conditionalString = $codeGenerator->GenerateConditionalString($runtime_const);
3074         my $name = $runtime_const->name;
3075         my $value = $runtime_const->value;
3076         push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
3077         push(@implContent, "    if (${enable_function}()) {\n");
3078         push(@implContent, <<END);
3079         static const V8DOMConfiguration::BatchedConstant constData = {"${name}", static_cast<signed int>(${value})};
3080         V8DOMConfiguration::batchConfigureConstants(desc, proto, &constData, 1, isolate);
3081 END
3082         push(@implContent, "    }\n");
3083         push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
3084     }
3085
3086     GenerateImplementationIndexer($interface, $indexer);
3087     GenerateImplementationNamedPropertyGetter($interface, $namedPropertyGetter);
3088     GenerateImplementationCustomCall($interface);
3089     GenerateImplementationMasqueradesAsUndefined($interface);
3090
3091     # Define our functions with Set() or SetAccessor()
3092     my $total_functions = 0;
3093     foreach my $function (@normalFunctions) {
3094         # Only one accessor is needed for overloaded methods:
3095         next if $function->{overloadIndex} > 1;
3096
3097         $total_functions++;
3098         next if IsStandardFunction($interface, $function);
3099         GenerateNonStandardFunction($interface, $function);
3100         $num_callbacks++;
3101     }
3102
3103     die "Wrong number of callbacks generated for $interfaceName ($num_callbacks, should be $total_functions)" if $num_callbacks != $total_functions;
3104
3105     if ($has_constants) {
3106         push(@implContent, <<END);
3107     V8DOMConfiguration::batchConfigureConstants(desc, proto, ${v8InterfaceName}Consts, WTF_ARRAY_LENGTH(${v8InterfaceName}Consts), isolate);
3108 END
3109     }
3110
3111     # Special cases
3112     if ($interfaceName eq "DOMWindow") {
3113         push(@implContent, <<END);
3114
3115     proto->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
3116     desc->SetHiddenPrototype(true);
3117     instance->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
3118     // Set access check callbacks, but turned off initially.
3119     // When a context is detached from a frame, turn on the access check.
3120     // Turning on checks also invalidates inline caches of the object.
3121     instance->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheckCustom, V8DOMWindow::indexedSecurityCheckCustom, v8::External::New(&V8DOMWindow::info), false);
3122 END
3123     }
3124     if ($interfaceName eq "HTMLDocument" or $interfaceName eq "DedicatedWorkerContext" or $interfaceName eq "SharedWorkerContext") {
3125         push(@implContent, <<END);
3126     desc->SetHiddenPrototype(true);
3127 END
3128     }
3129     if ($interfaceName eq "Location") {
3130         push(@implContent, <<END);
3131
3132     // For security reasons, these functions are on the instance instead
3133     // of on the prototype object to ensure that they cannot be overwritten.
3134     instance->SetAccessor(v8::String::NewSymbol("reload"), V8Location::reloadAttrGetterCustom, 0, v8Undefined(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
3135     instance->SetAccessor(v8::String::NewSymbol("replace"), V8Location::replaceAttrGetterCustom, 0, v8Undefined(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
3136     instance->SetAccessor(v8::String::NewSymbol("assign"), V8Location::assignAttrGetterCustom, 0, v8Undefined(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
3137 END
3138     }
3139
3140     push(@implContent, <<END);
3141
3142     // Custom toString template
3143     desc->Set(v8::String::NewSymbol("toString"), V8PerIsolateData::current()->toStringTemplate());
3144     return desc;
3145 }
3146
3147 v8::Persistent<v8::FunctionTemplate> ${v8InterfaceName}::GetRawTemplate(v8::Isolate* isolate)
3148 {
3149     V8PerIsolateData* data = V8PerIsolateData::from(isolate);
3150     V8PerIsolateData::TemplateMap::iterator result = data->rawTemplateMap().find(&info);
3151     if (result != data->rawTemplateMap().end())
3152         return result->value;
3153
3154     v8::HandleScope handleScope;
3155     v8::Persistent<v8::FunctionTemplate> templ = createRawTemplate(isolate);
3156     data->rawTemplateMap().add(&info, templ);
3157     return templ;
3158 }
3159
3160 v8::Persistent<v8::FunctionTemplate> ${v8InterfaceName}::GetTemplate(v8::Isolate* isolate, WrapperWorldType worldType)
3161 {
3162     V8PerIsolateData* data = V8PerIsolateData::from(isolate);
3163     V8PerIsolateData::TemplateMap::iterator result = data->templateMap().find(&info);
3164     if (result != data->templateMap().end())
3165         return result->value;
3166
3167     v8::HandleScope handleScope;
3168     v8::Persistent<v8::FunctionTemplate> templ =
3169         Configure${v8InterfaceName}Template(GetRawTemplate(isolate), isolate, worldType);
3170     data->templateMap().add(&info, templ);
3171     return templ;
3172 }
3173
3174 bool ${v8InterfaceName}::HasInstance(v8::Handle<v8::Value> value, v8::Isolate* isolate)
3175 {
3176     return GetRawTemplate(isolate)->HasInstance(value);
3177 }
3178
3179 END
3180
3181     if (@enabledPerContextAttributes) {
3182         push(@implContent, <<END);
3183 void ${v8InterfaceName}::installPerContextProperties(v8::Handle<v8::Object> instance, ${nativeType}* impl, v8::Isolate* isolate)
3184 {
3185     v8::Local<v8::Object> proto = v8::Local<v8::Object>::Cast(instance->GetPrototype());
3186     // When building QtWebkit with V8 this variable is unused when none of the features are enabled.
3187     UNUSED_PARAM(proto);
3188 END
3189
3190         # Setup the enable-by-settings attrs if we have them
3191         foreach my $runtimeAttr (@enabledPerContextAttributes) {
3192             my $enableFunction = GetContextEnableFunction($runtimeAttr->signature);
3193             my $conditionalString = $codeGenerator->GenerateConditionalString($runtimeAttr->signature);
3194             push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
3195 &