e38af4d1565dd9be5df4bf507f3f28f6dfc0143c
[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"} ? ", \"${interfaceName}\", 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     AddToImplIncludes("V8Document.h");
2183     push(@implContent, <<END);
2184     Document* document = currentDocument(BindingState::instance());
2185
2186     // Make sure the document is added to the DOM Node map. Otherwise, the ${interfaceName} instance
2187     // may end up being the only node in the map and get garbage-collected prematurely.
2188     toV8(document, args.Holder(), args.GetIsolate());
2189
2190 END
2191
2192     push(@implContent, GenerateArgumentsCountCheck($function, $interface));
2193
2194     if ($raisesExceptions) {
2195         AddToImplIncludes("ExceptionCode.h");
2196         push(@implContent, "\n");
2197         push(@implContent, "    ExceptionCode ec = 0;\n");
2198     }
2199
2200     my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersCheck($function, $interfaceName);
2201     push(@implContent, $parameterCheckString);
2202
2203     push(@beforeArgumentList, "document");
2204
2205     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) {
2206         push(@afterArgumentList, "ec");
2207     }
2208
2209     my @argumentList;
2210     my $index = 0;
2211     foreach my $parameter (@{$function->parameters}) {
2212         last if $index eq $paramIndex;
2213         if ($replacements{$parameter->name}) {
2214             push(@argumentList, $replacements{$parameter->name});
2215         } else {
2216             push(@argumentList, $parameter->name);
2217         }
2218         $index++;
2219     }
2220
2221     my $argumentString = join(", ", @beforeArgumentList, @argumentList, @afterArgumentList);
2222     push(@implContent, "\n");
2223     push(@implContent, "    RefPtr<${interfaceName}> impl = ${interfaceName}::createForJSConstructor(${argumentString});\n");
2224     push(@implContent, "    v8::Handle<v8::Object> wrapper = args.Holder();\n");
2225
2226     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) {
2227         push(@implContent, "    if (ec)\n");
2228         push(@implContent, "        goto fail;\n");
2229     }
2230
2231     push(@implContent, <<END);
2232
2233     V8DOMWrapper::associateObjectWithWrapper(impl.release(), &${v8InterfaceName}Constructor::info, wrapper, args.GetIsolate(), WrapperConfiguration::Dependent);
2234     return wrapper;
2235 END
2236
2237     if ($raisesExceptions) {
2238         push(@implContent, "    fail:\n");
2239         push(@implContent, "    return setDOMException(ec, args.GetIsolate());\n");
2240     }
2241
2242     push(@implContent, "}\n");
2243
2244     push(@implContent, <<END);
2245
2246 v8::Persistent<v8::FunctionTemplate> ${v8InterfaceName}Constructor::GetTemplate(v8::Isolate* isolate, WrapperWorldType worldType)
2247 {
2248     static v8::Persistent<v8::FunctionTemplate> cachedTemplate;
2249     if (!cachedTemplate.IsEmpty())
2250         return cachedTemplate;
2251
2252     v8::HandleScope scope;
2253     v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(${v8InterfaceName}ConstructorCallback);
2254
2255     v8::Local<v8::ObjectTemplate> instance = result->InstanceTemplate();
2256     instance->SetInternalFieldCount(${v8InterfaceName}::internalFieldCount);
2257     result->SetClassName(v8::String::NewSymbol("${interfaceName}"));
2258     result->Inherit(${v8InterfaceName}::GetTemplate(isolate, worldType));
2259
2260     cachedTemplate = v8::Persistent<v8::FunctionTemplate>::New(isolate, result);
2261     return cachedTemplate;
2262 }
2263
2264 END
2265 }
2266
2267 sub GenerateConstructorHeader
2268 {
2269     my $content = <<END;
2270     if (!args.IsConstructCall())
2271         return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate());
2272
2273     if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
2274         return args.Holder();
2275
2276 END
2277     return $content;
2278 }
2279
2280 sub GenerateBatchedAttributeData
2281 {
2282     my $interface = shift;
2283     my $attributes = shift;
2284     my $interfaceName = $interface->name;
2285
2286     foreach my $attribute (@$attributes) {
2287         my $conditionalString = $codeGenerator->GenerateConditionalString($attribute->signature);
2288         push(@implContent, "#if ${conditionalString}\n") if $conditionalString;
2289         GenerateSingleBatchedAttribute($interfaceName, $attribute, ",", "");
2290         push(@implContent, "#endif // ${conditionalString}\n") if $conditionalString;
2291     }
2292 }
2293
2294 sub GenerateSingleBatchedAttribute
2295 {
2296     my $interfaceName = shift;
2297     my $attribute = shift;
2298     my $delimiter = shift;
2299     my $indent = shift;
2300     my $attrName = $attribute->signature->name;
2301     my $attrExt = $attribute->signature->extendedAttributes;
2302
2303     my $accessControl = "v8::DEFAULT";
2304     if ($attrExt->{"DoNotCheckSecurityOnGetter"}) {
2305         $accessControl = "v8::ALL_CAN_READ";
2306     } elsif ($attrExt->{"DoNotCheckSecurityOnSetter"}) {
2307         $accessControl = "v8::ALL_CAN_WRITE";
2308     } elsif ($attrExt->{"DoNotCheckSecurity"}) {
2309         $accessControl = "v8::ALL_CAN_READ";
2310         if (!IsReadonly($attribute)) {
2311             $accessControl .= " | v8::ALL_CAN_WRITE";
2312         }
2313     }
2314     if ($attrExt->{"V8Unforgeable"}) {
2315         $accessControl .= " | v8::PROHIBITS_OVERWRITING";
2316     }
2317     $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";
2318
2319     my $customAccessor = HasCustomGetter($attrExt) || HasCustomSetter($attrExt) || "";
2320     if ($customAccessor eq "VALUE_IS_MISSING") {
2321         # use the naming convension, interface + (capitalize) attr name
2322         $customAccessor = $interfaceName . "::" . $attrName;
2323     }
2324
2325     my $getter;
2326     my $setter;
2327     my $propAttr = "v8::None";
2328
2329     # Check attributes.
2330     if ($attrExt->{"NotEnumerable"}) {
2331         $propAttr .= " | v8::DontEnum";
2332     }
2333     if ($attrExt->{"V8Unforgeable"}) {
2334         $propAttr .= " | v8::DontDelete";
2335     }
2336
2337     my $on_proto = "0 /* on instance */";
2338     my $data = "0 /* no data */";
2339
2340     # Constructor
2341     if ($attribute->signature->type =~ /Constructor$/) {
2342         my $constructorType = $attribute->signature->type;
2343         $constructorType =~ s/Constructor$//;
2344         # $constructorType ~= /Constructor$/ indicates that it is NamedConstructor.
2345         # We do not generate the header file for NamedConstructor of class XXXX,
2346         # since we generate the NamedConstructor declaration into the header file of class XXXX.
2347         if ($constructorType !~ /Constructor$/ || $attribute->signature->extendedAttributes->{"V8CustomConstructor"} || $attribute->signature->extendedAttributes->{"CustomConstructor"}) {
2348             AddToImplIncludes("V8${constructorType}.h", $attribute->signature->extendedAttributes->{"Conditional"});
2349         }
2350         $data = "&V8${constructorType}::info";
2351         $getter = "${interfaceName}V8Internal::${interfaceName}ConstructorGetter";
2352         $setter = "${interfaceName}V8Internal::${interfaceName}ReplaceableAttrSetterCallback";
2353     } else {
2354         # Default Getter and Setter
2355         $getter = "${interfaceName}V8Internal::${attrName}AttrGetterCallback";
2356         $setter = "${interfaceName}V8Internal::${attrName}AttrSetterCallback";
2357
2358         if (!HasCustomSetter($attrExt) && $attrExt->{"Replaceable"}) {
2359             $setter = "${interfaceName}V8Internal::${interfaceName}ReplaceableAttrSetterCallback";
2360         }
2361     }
2362
2363     # Read only attributes
2364     if (IsReadonly($attribute)) {
2365         $setter = "0";
2366     }
2367
2368     # An accessor can be installed on the proto
2369     if ($attrExt->{"V8OnProto"}) {
2370         $on_proto = "1 /* on proto */";
2371     }
2372
2373     my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
2374                       "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
2375
2376     push(@implContent, $indent . "    \/\/ $commentInfo\n");
2377     push(@implContent, $indent . "    {\"$attrName\", $getter, $setter, $data, $accessControl, static_cast<v8::PropertyAttribute>($propAttr), $on_proto}" . $delimiter . "\n");
2378 }
2379
2380 sub IsStandardFunction
2381 {
2382     my $interface = shift;
2383     my $function = shift;
2384
2385     my $interfaceName = $interface->name;
2386     my $attrExt = $function->signature->extendedAttributes;
2387     return 0 if $attrExt->{"V8Unforgeable"};
2388     return 0 if $function->isStatic;
2389     return 0 if $attrExt->{"V8EnabledAtRuntime"};
2390     return 0 if $attrExt->{"V8EnabledPerContext"};
2391     return 0 if RequiresCustomSignature($function);
2392     return 0 if $attrExt->{"V8DoNotCheckSignature"};
2393     return 0 if ($attrExt->{"DoNotCheckSecurity"} && ($interface->extendedAttributes->{"CheckSecurity"} || $interfaceName eq "DOMWindow"));
2394     return 0 if $attrExt->{"NotEnumerable"};
2395     return 0 if $attrExt->{"V8ReadOnly"};
2396     return 1;
2397 }
2398
2399 sub GenerateNonStandardFunction
2400 {
2401     my $interface = shift;
2402     my $function = shift;
2403
2404     my $interfaceName = $interface->name;
2405     my $attrExt = $function->signature->extendedAttributes;
2406     my $name = $function->signature->name;
2407
2408     my $property_attributes = "v8::DontDelete";
2409     if ($attrExt->{"NotEnumerable"}) {
2410         $property_attributes .= " | v8::DontEnum";
2411     }
2412     if ($attrExt->{"V8ReadOnly"}) {
2413         $property_attributes .= " | v8::ReadOnly";
2414     }
2415
2416     my $commentInfo = "Function '$name' (ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
2417
2418     my $template = "proto";
2419     if ($attrExt->{"V8Unforgeable"}) {
2420         $template = "instance";
2421     }
2422     if ($function->isStatic) {
2423         $template = "desc";
2424     }
2425
2426     my $conditional = "";
2427     if ($attrExt->{"V8EnabledAtRuntime"}) {
2428         # Only call Set()/SetAccessor() if this method should be enabled
2429         my $enable_function = GetRuntimeEnableFunctionName($function->signature);
2430         $conditional = "if (${enable_function}())\n        ";
2431     }
2432     if ($attrExt->{"V8EnabledPerContext"}) {
2433         # Only call Set()/SetAccessor() if this method should be enabled
2434         my $enable_function = GetContextEnableFunction($function->signature);
2435         $conditional = "if (${enable_function}(impl->document()))\n        ";
2436     }
2437
2438     if ($interface->extendedAttributes->{"CheckSecurity"} && $attrExt->{"DoNotCheckSecurity"}) {
2439         # Functions that are marked DoNotCheckSecurity are always readable but if they are changed
2440         # and then accessed on a different domain we do not return the underlying value but instead
2441         # return a new copy of the original function. This is achieved by storing the changed value
2442         # as hidden property.
2443         push(@implContent, <<END);
2444
2445     // $commentInfo
2446     ${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));
2447 END
2448         return;
2449     }
2450
2451     my $signature = "defaultSignature";
2452     if ($attrExt->{"V8DoNotCheckSignature"} || $function->isStatic) {
2453        $signature = "v8::Local<v8::Signature>()";
2454     }
2455
2456     if (RequiresCustomSignature($function)) {
2457         $signature = "${name}Signature";
2458         push(@implContent, "\n    // Custom Signature '$name'\n", CreateCustomSignature($function));
2459     }
2460
2461     if ($property_attributes eq "v8::DontDelete") {
2462         $property_attributes = "";
2463     } else {
2464         $property_attributes = ", static_cast<v8::PropertyAttribute>($property_attributes)";
2465     }
2466
2467     if ($template eq "proto" && $conditional eq "" && $signature eq "defaultSignature" && $property_attributes eq "") {
2468         die "This shouldn't happen: Intraface '$interfaceName' $commentInfo\n";
2469     }
2470
2471     my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature);
2472     push(@implContent, "#if ${conditionalString}\n") if $conditionalString;
2473     push(@implContent, "    ${conditional}$template->Set(v8::String::NewSymbol(\"$name\"), v8::FunctionTemplate::New(${interfaceName}V8Internal::${name}MethodCallback, v8Undefined(), ${signature})$property_attributes);\n");
2474     push(@implContent, "#endif // ${conditionalString}\n") if $conditionalString;
2475 }
2476
2477 sub GenerateImplementationIndexer
2478 {
2479     my $interface = shift;
2480     my $indexer = shift;
2481     my $interfaceName = $interface->name;
2482     my $v8InterfaceName = "V8$interfaceName";
2483
2484     # FIXME: Figure out what NumericIndexedGetter is really supposed to do. Right now, it's only set on WebGL-related files.
2485     my $hasCustomSetter = $interface->extendedAttributes->{"CustomIndexedSetter"} && !$interface->extendedAttributes->{"NumericIndexedGetter"};
2486     my $hasGetter = $interface->extendedAttributes->{"IndexedGetter"} || $interface->extendedAttributes->{"CustomGetOwnPropertySlot"};
2487
2488     # FIXME: Investigate and remove this nastinesss. In V8, named property handling and indexer handling are apparently decoupled,
2489     # which means that object[X] where X is a number doesn't reach named property indexer. So we need to provide
2490     # simplistic, mirrored indexer handling in addition to named property handling.
2491     my $isSpecialCase = exists $indexerSpecialCases{$interfaceName};
2492     if ($isSpecialCase) {
2493         $hasGetter = 1;
2494         if ($interface->extendedAttributes->{"CustomNamedSetter"}) {
2495             $hasCustomSetter = 1;
2496         }
2497     }
2498
2499     my $hasEnumerator = !$isSpecialCase && $codeGenerator->InheritsInterface($interface, "Node");
2500
2501     # FIXME: Find a way to not have to special-case HTMLOptionsCollection.
2502     if ($interfaceName eq "HTMLOptionsCollection") {
2503         $hasEnumerator = 1;
2504         $hasGetter = 1;
2505     }
2506
2507     if (!$hasGetter) {
2508         return;
2509     }
2510
2511     AddToImplIncludes("V8Collection.h");
2512
2513     if (!$indexer) {
2514         $indexer = $codeGenerator->FindSuperMethod($interface, "item");
2515     }
2516
2517     my $indexerType = $indexer ? $indexer->type : 0;
2518
2519     # FIXME: Remove this once toV8 helper methods are implemented (see https://bugs.webkit.org/show_bug.cgi?id=32563).
2520     if ($interfaceName eq "WebKitCSSKeyframesRule") {
2521         $indexerType = "WebKitCSSKeyframeRule";
2522     }
2523
2524     if ($indexerType && !$hasCustomSetter) {
2525         if ($indexerType eq "DOMString") {
2526             my $conversion = $indexer->extendedAttributes->{"TreatReturnedNullStringAs"};
2527             if ($conversion && $conversion eq "Null") {
2528                 push(@implContent, <<END);
2529     setCollectionStringOrUndefinedIndexedGetter<${interfaceName}>(desc);
2530 END
2531             } else {
2532                 push(@implContent, <<END);
2533     setCollectionStringIndexedGetter<${interfaceName}>(desc);
2534 END
2535             }
2536         } else {
2537             push(@implContent, <<END);
2538     setCollectionIndexedGetter<${interfaceName}, ${indexerType}>(desc);
2539 END
2540             # Include the header for this indexer type, because setCollectionIndexedGetter() requires toV8() for this type.
2541             AddToImplIncludes("V8${indexerType}.h");
2542         }
2543
2544         return;
2545     }
2546
2547     my $hasDeleter = $interface->extendedAttributes->{"CustomDeleteProperty"};
2548     my $setOn = "Instance";
2549
2550     # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
2551     # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
2552     # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
2553     # on the object.
2554     if ($interfaceName eq "DOMWindow") {
2555         $setOn = "Prototype";
2556         $hasDeleter = 0;
2557     }
2558
2559     push(@implContent, "    desc->${setOn}Template()->SetIndexedPropertyHandler(${v8InterfaceName}::indexedPropertyGetter");
2560     push(@implContent, $hasCustomSetter ? ", ${v8InterfaceName}::indexedPropertySetter" : ", 0");
2561     push(@implContent, ", 0"); # IndexedPropertyQuery -- not being used at the moment.
2562     push(@implContent, $hasDeleter ? ", ${v8InterfaceName}::indexedPropertyDeleter" : ", 0");
2563     push(@implContent, ", nodeCollectionIndexedPropertyEnumerator<${interfaceName}>") if $hasEnumerator;
2564     push(@implContent, ");\n");
2565 }
2566
2567 sub GenerateImplementationNamedPropertyGetter
2568 {
2569     my $interface = shift;
2570     my $namedPropertyGetter = shift;
2571     my $interfaceName = $interface->name;
2572     my $v8InterfaceName = "V8$interfaceName";
2573     my $hasCustomNamedGetter = $interface->extendedAttributes->{"CustomNamedGetter"} || $interface->extendedAttributes->{"CustomGetOwnPropertySlot"};
2574
2575     if ($interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
2576         $hasCustomNamedGetter = 1;
2577     }
2578
2579     if ($interfaceName eq "HTMLDocument") {
2580         $hasCustomNamedGetter = 0;
2581     }
2582
2583     my $hasGetter = $interface->extendedAttributes->{"NamedGetter"} || $hasCustomNamedGetter;
2584     if (!$hasGetter) {
2585         return;
2586     }
2587
2588     if (!$namedPropertyGetter) {
2589         $namedPropertyGetter = $codeGenerator->FindSuperMethod($interface, "namedItem");
2590     }
2591
2592     if ($namedPropertyGetter && $namedPropertyGetter->type ne "Node" && !$namedPropertyGetter->extendedAttributes->{"Custom"} && !$hasCustomNamedGetter) {
2593         AddToImplIncludes("V8Collection.h");
2594         my $type = $namedPropertyGetter->type;
2595         push(@implContent, <<END);
2596     setCollectionNamedGetter<${interfaceName}, ${type}>(desc);
2597 END
2598         return;
2599     }
2600
2601     my $hasCustomNamedSetter = $interface->extendedAttributes->{"CustomNamedSetter"};
2602     my $hasDeleter = $interface->extendedAttributes->{"CustomDeleteProperty"};
2603     my $hasEnumerator = $interface->extendedAttributes->{"CustomEnumerateProperty"};
2604     my $setOn = "Instance";
2605
2606     # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
2607     # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
2608     # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
2609     # on the object.
2610     if ($interfaceName eq "DOMWindow") {
2611         $setOn = "Prototype";
2612         $hasDeleter = 0;
2613         $hasEnumerator = 0;
2614     }
2615
2616     if ($interfaceName eq "HTMLPropertiesCollection") {
2617         push(@implContent, "    desc->${setOn}Template()->SetNamedPropertyHandler(V8HTMLCollection::namedPropertyGetter, ");
2618     } else {
2619         push(@implContent, "    desc->${setOn}Template()->SetNamedPropertyHandler(${v8InterfaceName}::namedPropertyGetter, ");
2620     }
2621     push(@implContent, $hasCustomNamedSetter ? "${v8InterfaceName}::namedPropertySetter, " : "0, ");
2622     # If there is a custom enumerator, there MUST be custom query to properly communicate property attributes.
2623     push(@implContent, $hasEnumerator ? "${v8InterfaceName}::namedPropertyQuery, " : "0, ");
2624     push(@implContent, $hasDeleter ? "${v8InterfaceName}::namedPropertyDeleter, " : "0, ");
2625     push(@implContent, $hasEnumerator ? "${v8InterfaceName}::namedPropertyEnumerator" : "0");
2626     push(@implContent, ");\n");
2627 }
2628
2629 sub GenerateImplementationCustomCall
2630 {
2631     my $interface = shift;
2632     my $interfaceName = $interface->name;
2633
2634     if ($interface->extendedAttributes->{"CustomCall"}) {
2635         push(@implContent, "    desc->InstanceTemplate()->SetCallAsFunctionHandler(V8${interfaceName}::callAsFunctionCallback);\n");
2636     }
2637 }
2638
2639 sub GenerateImplementationMasqueradesAsUndefined
2640 {
2641     my $interface = shift;
2642     if ($interface->extendedAttributes->{"MasqueradesAsUndefined"})
2643     {
2644         push(@implContent, "    desc->InstanceTemplate()->MarkAsUndetectable();\n");
2645     }
2646 }
2647
2648 sub GenerateImplementation
2649 {
2650     my $object = shift;
2651     my $interface = shift;
2652     my $interfaceName = $interface->name;
2653     my $visibleInterfaceName = $codeGenerator->GetVisibleInterfaceName($interface);
2654     my $v8InterfaceName = "V8$interfaceName";
2655     my $nativeType = GetNativeTypeForConversions($interface);
2656     my $vtableNameGnu = GetGnuVTableNameForInterface($interface);
2657     my $vtableRefGnu = GetGnuVTableRefForInterface($interface);
2658     my $vtableRefWin = GetWinVTableRefForInterface($interface);
2659
2660     # - Add default header template
2661     push(@implContentHeader, GenerateImplementationContentHeader($interface));
2662
2663     AddToImplIncludes("BindingState.h");
2664     AddToImplIncludes("ContextFeatures.h");
2665     AddToImplIncludes("RuntimeEnabledFeatures.h");
2666     AddToImplIncludes("V8Binding.h");
2667     AddToImplIncludes("V8DOMWrapper.h");
2668
2669     AddIncludesForType($interfaceName);
2670
2671     my $toActiveDOMObject = $codeGenerator->InheritsExtendedAttribute($interface, "ActiveDOMObject") ? "${v8InterfaceName}::toActiveDOMObject" : "0";
2672     my $toEventTarget = $codeGenerator->InheritsExtendedAttribute($interface, "EventTarget") ? "${v8InterfaceName}::toEventTarget" : "0";
2673     my $rootForGC = NeedsCustomOpaqueRootForGC($interface) ? "${v8InterfaceName}::opaqueRootForGC" : "0";
2674
2675     # Find the super descriptor.
2676     my $parentClass = "";
2677     my $parentClassTemplate = "";
2678     foreach (@{$interface->parents}) {
2679         my $parent = $_;
2680         AddToImplIncludes("V8${parent}.h");
2681         $parentClass = "V8" . $parent;
2682         $parentClassTemplate = $parentClass . "::GetTemplate(isolate, worldType)";
2683         last;
2684     }
2685
2686     push(@implContentInternals, <<END) if $vtableNameGnu;
2687 #if ENABLE(BINDING_INTEGRITY)
2688 #if defined(OS_WIN)
2689 #pragma warning(disable: 4483)
2690 extern "C" { extern void (*const ${vtableRefWin}[])(); }
2691 #else
2692 extern "C" { extern void* ${vtableNameGnu}[]; }
2693 #endif
2694 #endif // ENABLE(BINDING_INTEGRITY)
2695
2696 END
2697
2698     push(@implContentInternals, "namespace WebCore {\n\n");
2699
2700     push(@implContentInternals, <<END) if $vtableNameGnu;
2701 #if ENABLE(BINDING_INTEGRITY)
2702 // This checks if a DOM object that is about to be wrapped is valid.
2703 // Specifically, it checks that a vtable of the DOM object is equal to
2704 // a vtable of an expected class.
2705 // Due to a dangling pointer, the DOM object you are wrapping might be
2706 // already freed or realloced. If freed, the check will fail because
2707 // a free list pointer should be stored at the head of the DOM object.
2708 // If realloced, the check will fail because the vtable of the DOM object
2709 // differs from the expected vtable (unless the same class of DOM object
2710 // is realloced on the slot).
2711 inline void checkTypeOrDieTrying(${nativeType}* object)
2712 {
2713     void* actualVTablePointer = *(reinterpret_cast<void**>(object));
2714 #if defined(OS_WIN)
2715     void* expectedVTablePointer = reinterpret_cast<void*>(${vtableRefWin});
2716 #else
2717     void* expectedVTablePointer = ${vtableRefGnu};
2718 #endif
2719     if (actualVTablePointer != expectedVTablePointer)
2720         CRASH();
2721 }
2722 #endif // ENABLE(BINDING_INTEGRITY)
2723
2724 END
2725
2726
2727     my $parentClassInfo = $parentClass ? "&${parentClass}::info" : "0";
2728
2729     my $WrapperTypePrototype = $interface->isException ? "WrapperTypeErrorPrototype" : "WrapperTypeObjectPrototype";
2730
2731     push(@implContentInternals, "WrapperTypeInfo ${v8InterfaceName}::info = { ${v8InterfaceName}::GetTemplate, ${v8InterfaceName}::derefObject, $toActiveDOMObject, $toEventTarget, $rootForGC, ${v8InterfaceName}::installPerContextPrototypeProperties, $parentClassInfo, $WrapperTypePrototype };\n\n");
2732     push(@implContentInternals, "namespace ${interfaceName}V8Internal {\n\n");
2733
2734     push(@implContentInternals, "template <typename T> void V8_USE(T) { }\n\n");
2735
2736     my $hasConstructors = 0;
2737     my $hasReplaceable = 0;
2738
2739     # Generate property accessors for attributes.
2740     for (my $index = 0; $index < @{$interface->attributes}; $index++) {
2741         my $attribute = @{$interface->attributes}[$index];
2742         my $attrType = $attribute->signature->type;
2743         my $attrExt = $attribute->signature->extendedAttributes;
2744
2745         # Generate special code for the constructor attributes.
2746         if ($attrType =~ /Constructor$/) {
2747             if (!HasCustomGetter($attrExt)) {
2748                 $hasConstructors = 1;
2749             }
2750             next;
2751         }
2752
2753         if ($attrType eq "EventListener" && $interfaceName eq "DOMWindow") {
2754             $attrExt->{"V8OnProto"} = 1;
2755         }
2756
2757         if ($attrType eq "SerializedScriptValue") {
2758             AddToImplIncludes("SerializedScriptValue.h");
2759         }
2760
2761         GenerateNormalAttrGetter($attribute, $interface);
2762         GenerateNormalAttrGetterCallback($attribute, $interface);
2763
2764         if (!HasCustomSetter($attrExt) && $attrExt->{"Replaceable"}) {
2765             $hasReplaceable = 1;
2766         } elsif (!IsReadonly($attribute)) {
2767             GenerateNormalAttrSetter($attribute, $interface);
2768             GenerateNormalAttrSetterCallback($attribute, $interface);
2769         }
2770     }
2771
2772     if ($hasConstructors) {
2773         GenerateConstructorGetter($interface);
2774     }
2775
2776     if ($hasConstructors || $hasReplaceable) {
2777         GenerateReplaceableAttrSetter($interface);
2778         GenerateReplaceableAttrSetterCallback($interface);
2779     }
2780
2781     if (NeedsCustomOpaqueRootForGC($interface)) {
2782         GenerateOpaqueRootForGC($interface);
2783     }
2784
2785     if ($interface->extendedAttributes->{"CheckSecurity"} && $interface->name ne "DOMWindow") {
2786         GenerateSecurityCheckFunctions($interface);
2787     }
2788
2789     if ($interface->extendedAttributes->{"TypedArray"}) {
2790         my $viewType = GetTypeNameOfExternalTypedArray($interface);
2791         push(@implContent, <<END);
2792 v8::Handle<v8::Object> wrap($interfaceName* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
2793 {
2794     ASSERT(impl);
2795     v8::Handle<v8::Object> wrapper = ${v8InterfaceName}::createWrapper(impl, creationContext, isolate);
2796     if (!wrapper.IsEmpty())
2797         wrapper->SetIndexedPropertiesToExternalArrayData(impl->baseAddress(), $viewType, impl->length());
2798     return wrapper;
2799 }
2800
2801 END
2802     }
2803
2804     my $indexer;
2805     my $namedPropertyGetter;
2806     my @enabledPerContextFunctions;
2807     my @normalFunctions;
2808     my $needsDomainSafeFunctionSetter = 0;
2809     # Generate methods for functions.
2810     foreach my $function (@{$interface->functions}) {
2811         GenerateFunction($function, $interface);
2812         if ($function->{overloadIndex} == @{$function->{overloads}}) {
2813             if ($function->{overloadIndex} > 1) {
2814                 GenerateOverloadedFunction($function, $interface);
2815             }
2816             GenerateFunctionCallback($function, $interface);
2817         }
2818
2819         if ($function->signature->name eq "item") {
2820             $indexer = $function->signature;
2821         }
2822
2823         if ($interfaceName eq "HTMLPropertiesCollection") {
2824             if ($function->signature->name eq "propertyNodeList") {
2825                 $namedPropertyGetter = $function->signature;
2826             }
2827         } elsif ($function->signature->name eq "namedItem") {
2828             $namedPropertyGetter = $function->signature;
2829         }
2830
2831         # If the function does not need domain security check, we need to
2832         # generate an access getter that returns different function objects
2833         # for different calling context.
2834         if ($interface->extendedAttributes->{"CheckSecurity"} && $function->signature->extendedAttributes->{"DoNotCheckSecurity"}) {
2835             if (!HasCustomMethod($function->signature->extendedAttributes) || $function->{overloadIndex} == 1) {
2836                 GenerateDomainSafeFunctionGetter($function, $interfaceName);
2837                 $needsDomainSafeFunctionSetter = 1;
2838             }
2839         }
2840
2841         # Separate out functions that are enabled per context so we can process them specially.
2842         if ($function->signature->extendedAttributes->{"V8EnabledPerContext"}) {
2843             push(@enabledPerContextFunctions, $function);
2844         } else {
2845             push(@normalFunctions, $function);
2846         }
2847     }
2848
2849     if ($needsDomainSafeFunctionSetter) {
2850         GenerateDomainSafeFunctionSetter($interfaceName);
2851     }
2852
2853     # Attributes
2854     my $attributes = $interface->attributes;
2855
2856     # For the DOMWindow interface we partition the attributes into the
2857     # ones that disallows shadowing and the rest.
2858     my @disallowsShadowing;
2859     # Also separate out attributes that are enabled at runtime so we can process them specially.
2860     my @enabledAtRuntimeAttributes;
2861     my @enabledPerContextAttributes;
2862     my @normalAttributes;
2863     foreach my $attribute (@$attributes) {
2864
2865         if ($interfaceName eq "DOMWindow" && $attribute->signature->extendedAttributes->{"V8Unforgeable"}) {
2866             push(@disallowsShadowing, $attribute);
2867         } elsif ($attribute->signature->extendedAttributes->{"V8EnabledAtRuntime"}) {
2868             push(@enabledAtRuntimeAttributes, $attribute);
2869         } elsif ($attribute->signature->extendedAttributes->{"V8EnabledPerContext"}) {
2870             push(@enabledPerContextAttributes, $attribute);
2871         } else {
2872             push(@normalAttributes, $attribute);
2873         }
2874     }
2875     $attributes = \@normalAttributes;
2876     # Put the attributes that disallow shadowing on the shadow object.
2877     if (@disallowsShadowing) {
2878         push(@implContent, "static const V8DOMConfiguration::BatchedAttribute shadowAttrs[] = {\n");
2879         GenerateBatchedAttributeData($interface, \@disallowsShadowing);
2880         push(@implContent, "};\n\n");
2881     }
2882
2883     my $has_attributes = 0;
2884     if (@$attributes) {
2885         $has_attributes = 1;
2886         push(@implContent, "static const V8DOMConfiguration::BatchedAttribute ${v8InterfaceName}Attrs[] = {\n");
2887         GenerateBatchedAttributeData($interface, $attributes);
2888         push(@implContent, "};\n\n");
2889     }
2890
2891     # Setup table of standard callback functions
2892     my $num_callbacks = 0;
2893     my $has_callbacks = 0;
2894     foreach my $function (@normalFunctions) {
2895         # Only one table entry is needed for overloaded methods:
2896         next if $function->{overloadIndex} > 1;
2897         # Don't put any nonstandard functions into this table:
2898         next if !IsStandardFunction($interface, $function);
2899         if (!$has_callbacks) {
2900             $has_callbacks = 1;
2901             push(@implContent, "static const V8DOMConfiguration::BatchedMethod ${v8InterfaceName}Methods[] = {\n");
2902         }
2903         my $name = $function->signature->name;
2904         my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature);
2905         push(@implContent, "#if ${conditionalString}\n") if $conditionalString;
2906         push(@implContent, <<END);
2907     {"$name", ${interfaceName}V8Internal::${name}MethodCallback},
2908 END
2909         push(@implContent, "#endif\n") if $conditionalString;
2910         $num_callbacks++;
2911     }
2912     push(@implContent, "};\n\n")  if $has_callbacks;
2913
2914     # Setup constants
2915     my $has_constants = 0;
2916     my @constantsEnabledAtRuntime;
2917     if (@{$interface->constants}) {
2918         $has_constants = 1;
2919         push(@implContent, "static const V8DOMConfiguration::BatchedConstant ${v8InterfaceName}Consts[] = {\n");
2920     }
2921     foreach my $constant (@{$interface->constants}) {
2922         my $name = $constant->name;
2923         my $value = $constant->value;
2924         my $attrExt = $constant->extendedAttributes;
2925         my $conditional = $attrExt->{"Conditional"};
2926         my $implementedBy = $attrExt->{"ImplementedBy"};
2927         if ($implementedBy) {
2928             AddToImplIncludes("${implementedBy}.h");
2929         }
2930         if ($attrExt->{"V8EnabledAtRuntime"}) {
2931             push(@constantsEnabledAtRuntime, $constant);
2932         } else {
2933             if ($conditional) {
2934                 my $conditionalString = $codeGenerator->GenerateConditionalStringFromAttributeValue($conditional);
2935                 push(@implContent, "#if ${conditionalString}\n");
2936             }
2937             # If the value we're dealing with is a hex number, preprocess it into a signed integer
2938             # here, rather than running static_cast<signed int> in the generated code.
2939             if (substr($value, 0, 2) eq "0x") {
2940               $value = unpack('i', pack('I', hex($value)));
2941             }
2942             push(@implContent, <<END);
2943     {"${name}", $value},
2944 END
2945             push(@implContent, "#endif\n") if $conditional;
2946         }
2947     }
2948     if ($has_constants) {
2949         push(@implContent, "};\n\n");
2950         push(@implContent, $codeGenerator->GenerateCompileTimeCheckForEnumsIfNeeded($interface));
2951     }
2952
2953     if (!HasCustomConstructor($interface)) {
2954         if ($interface->extendedAttributes->{"NamedConstructor"}) {
2955             GenerateNamedConstructor(@{$interface->constructors}[0], $interface);
2956         } elsif ($interface->extendedAttributes->{"Constructor"}) {
2957             GenerateConstructor($interface);
2958         } elsif ($codeGenerator->IsConstructorTemplate($interface, "Event")) {
2959             GenerateEventConstructor($interface);
2960         } elsif ($codeGenerator->IsConstructorTemplate($interface, "TypedArray")) {
2961             GenerateTypedArrayConstructor($interface);
2962         }
2963     }
2964     if (IsConstructable($interface)) {
2965         GenerateConstructorCallback($interface);
2966     }
2967
2968     push(@implContentInternals, "} // namespace ${interfaceName}V8Internal\n\n");
2969
2970     my $access_check = "";
2971     if ($interface->extendedAttributes->{"CheckSecurity"} && $interfaceName ne "DOMWindow") {
2972         $access_check = "instance->SetAccessCheckCallbacks(${interfaceName}V8Internal::namedSecurityCheck, ${interfaceName}V8Internal::indexedSecurityCheck, v8::External::New(&${v8InterfaceName}::info));";
2973     }
2974
2975     # For the DOMWindow interface, generate the shadow object template
2976     # configuration method.
2977     if ($interfaceName eq "DOMWindow") {
2978         push(@implContent, <<END);
2979 static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ, v8::Isolate* isolate)
2980 {
2981     V8DOMConfiguration::batchConfigureAttributes(templ, v8::Handle<v8::ObjectTemplate>(), shadowAttrs, WTF_ARRAY_LENGTH(shadowAttrs), isolate);
2982
2983     // Install a security handler with V8.
2984     templ->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheckCustom, V8DOMWindow::indexedSecurityCheckCustom, v8::External::New(&V8DOMWindow::info));
2985     templ->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
2986     return templ;
2987 }
2988 END
2989     }
2990
2991     if (!$parentClassTemplate) {
2992         $parentClassTemplate = "v8::Persistent<v8::FunctionTemplate>()";
2993     }
2994
2995     # Generate the template configuration method
2996     push(@implContent,  <<END);
2997 static v8::Persistent<v8::FunctionTemplate> Configure${v8InterfaceName}Template(v8::Persistent<v8::FunctionTemplate> desc, v8::Isolate* isolate, WrapperWorldType worldType)
2998 {
2999     desc->ReadOnlyPrototype();
3000
3001     v8::Local<v8::Signature> defaultSignature;
3002 END
3003     if ($interface->extendedAttributes->{"V8EnabledAtRuntime"}) {
3004         my $enable_function = GetRuntimeEnableFunctionName($interface);
3005         push(@implContent, <<END);
3006     if (!${enable_function}())
3007         defaultSignature = V8DOMConfiguration::configureTemplate(desc, \"\", $parentClassTemplate, ${v8InterfaceName}::internalFieldCount, 0, 0, 0, 0, isolate);
3008     else
3009 END
3010     }
3011     push(@implContent,  <<END);
3012     defaultSignature = V8DOMConfiguration::configureTemplate(desc, \"${visibleInterfaceName}\", $parentClassTemplate, ${v8InterfaceName}::internalFieldCount,
3013 END
3014     # Set up our attributes if we have them
3015     if ($has_attributes) {
3016         push(@implContent, <<END);
3017         ${v8InterfaceName}Attrs, WTF_ARRAY_LENGTH(${v8InterfaceName}Attrs),
3018 END
3019     } else {
3020         push(@implContent, <<END);
3021         0, 0,
3022 END
3023     }
3024
3025     if ($has_callbacks) {
3026         push(@implContent, <<END);
3027         ${v8InterfaceName}Methods, WTF_ARRAY_LENGTH(${v8InterfaceName}Methods), isolate);
3028 END
3029     } else {
3030         push(@implContent, <<END);
3031         0, 0, isolate);
3032 END
3033     }
3034
3035     AddToImplIncludes("wtf/UnusedParam.h");
3036     push(@implContent, <<END);
3037     UNUSED_PARAM(defaultSignature); // In some cases, it will not be used.
3038 END
3039
3040     if (IsConstructable($interface)) {
3041         my $conditionalString = $codeGenerator->GenerateConstructorConditionalString($interface);
3042         push(@implContent, "#if $conditionalString\n") if $conditionalString;
3043         push(@implContent, "    desc->SetCallHandler(${v8InterfaceName}::constructorCallback);\n");
3044         push(@implContent, "#endif // $conditionalString\n") if $conditionalString;
3045     }
3046
3047     if ($access_check or @enabledAtRuntimeAttributes or @normalFunctions or $has_constants) {
3048         push(@implContent,  <<END);
3049     v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
3050     v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
3051     UNUSED_PARAM(instance); // In some cases, it will not be used.
3052     UNUSED_PARAM(proto); // In some cases, it will not be used.
3053 END
3054     }
3055
3056     push(@implContent,  "    $access_check\n");
3057
3058     # Setup the enable-at-runtime attrs if we have them
3059     foreach my $runtime_attr (@enabledAtRuntimeAttributes) {
3060         my $enable_function = GetRuntimeEnableFunctionName($runtime_attr->signature);
3061         my $conditionalString = $codeGenerator->GenerateConditionalString($runtime_attr->signature);
3062         push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
3063         push(@implContent, "    if (${enable_function}()) {\n");
3064         push(@implContent, "        static const V8DOMConfiguration::BatchedAttribute attrData =\\\n");
3065         GenerateSingleBatchedAttribute($interfaceName, $runtime_attr, ";", "    ");
3066         push(@implContent, <<END);
3067         V8DOMConfiguration::configureAttribute(instance, proto, attrData, isolate);
3068     }
3069 END
3070         push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
3071     }
3072
3073     # Setup the enable-at-runtime constants if we have them
3074     foreach my $runtime_const (@constantsEnabledAtRuntime) {
3075         my $enable_function = GetRuntimeEnableFunctionName($runtime_const);
3076         my $conditionalString = $codeGenerator->GenerateConditionalString($runtime_const);
3077         my $name = $runtime_const->name;
3078         my $value = $runtime_const->value;
3079         push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
3080         push(@implContent, "    if (${enable_function}()) {\n");
3081         push(@implContent, <<END);
3082         static const V8DOMConfiguration::BatchedConstant constData = {"${name}", static_cast<signed int>(${value})};
3083         V8DOMConfiguration::batchConfigureConstants(desc, proto, &constData, 1, isolate);
3084 END
3085         push(@implContent, "    }\n");
3086         push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
3087     }
3088
3089     GenerateImplementationIndexer($interface, $indexer);
3090     GenerateImplementationNamedPropertyGetter($interface, $namedPropertyGetter);
3091     GenerateImplementationCustomCall($interface);
3092     GenerateImplementationMasqueradesAsUndefined($interface);
3093
3094     # Define our functions with Set() or SetAccessor()
3095     my $total_functions = 0;
3096     foreach my $function (@normalFunctions) {
3097         # Only one accessor is needed for overloaded methods:
3098         next if $function->{overloadIndex} > 1;
3099
3100         $total_functions++;
3101         next if IsStandardFunction($interface, $function);
3102         GenerateNonStandardFunction($interface, $function);
3103         $num_callbacks++;
3104     }
3105
3106     die "Wrong number of callbacks generated for $interfaceName ($num_callbacks, should be $total_functions)" if $num_callbacks != $total_functions;
3107
3108     if ($has_constants) {
3109         push(@implContent, <<END);
3110     V8DOMConfiguration::batchConfigureConstants(desc, proto, ${v8InterfaceName}Consts, WTF_ARRAY_LENGTH(${v8InterfaceName}Consts), isolate);
3111 END
3112     }
3113
3114     # Special cases
3115     if ($interfaceName eq "DOMWindow") {
3116         push(@implContent, <<END);
3117
3118     proto->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
3119     desc->SetHiddenPrototype(true);
3120     instance->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
3121     // Set access check callbacks, but turned off initially.
3122     // When a context is detached from a frame, turn on the access check.
3123     // Turning on checks also invalidates inline caches of the object.
3124     instance->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheckCustom, V8DOMWindow::indexedSecurityCheckCustom, v8::External::New(&V8DOMWindow::info), false);
3125 END
3126     }
3127     if ($interfaceName eq "HTMLDocument" or $interfaceName eq "DedicatedWorkerContext" or $interfaceName eq "SharedWorkerContext") {
3128         push(@implContent, <<END);
3129     desc->SetHiddenPrototype(true);
3130 END
3131     }
3132     if ($interfaceName eq "Location") {
3133         push(@implContent, <<END);
3134
3135     // For security reasons, these functions are on the instance instead
3136     // of on the prototype object to ensure that they cannot be overwritten.
3137     instance->SetAccessor(v8::String::NewSymbol("reload"), V8Location::reloadAttrGetterCustom, 0, v8Undefined(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
3138     instance->SetAccessor(v8::String::NewSymbol("replace"), V8Location::replaceAttrGetterCustom, 0, v8Undefined(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
3139     instance->SetAccessor(v8::String::NewSymbol("assign"), V8Location::assignAttrGetterCustom, 0, v8Undefined(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
3140 END
3141     }
3142
3143     push(@implContent, <<END);
3144
3145     // Custom toString template
3146     desc->Set(v8::String::NewSymbol("toString"), V8PerIsolateData::current()->toStringTemplate());
3147     return desc;
3148 }
3149
3150 v8::Persistent<v8::FunctionTemplate> ${v8InterfaceName}::GetRawTemplate(v8::Isolate* isolate)
3151 {
3152     V8PerIsolateData* data = V8PerIsolateData::from(isolate);
3153     V8PerIsolateData::TemplateMap::iterator result = data->rawTemplateMap().find(&info);
3154     if (result != data->rawTemplateMap().end())
3155         return result->value;
3156
3157     v8::HandleScope handleScope;
3158     v8::Persistent<v8::FunctionTemplate> templ = createRawTemplate(isolate);
3159     data->rawTemplateMap().add(&info, templ);
3160     return templ;
3161 }
3162
3163 v8::Persistent<v8::FunctionTemplate> ${v8InterfaceName}::GetTemplate(v8::Isolate* isolate, WrapperWorldType worldType)
3164 {
3165     V8PerIsolateData* data = V8PerIsolateData::from(isolate);
3166     V8PerIsolateData::TemplateMap::iterator result = data->templateMap().find(&info);
3167     if (result != data->templateMap().end())
3168         return result->value;
3169
3170     v8::HandleScope handleScope;
3171     v8::Persistent<v8::FunctionTemplate> templ =
3172         Configure${v8InterfaceName}Template(GetRawTemplate(isolate), isolate, worldType);
3173     data->templateMap().add(&info, templ);
3174     return templ;
3175 }
3176
3177 bool ${v8InterfaceName}::HasInstance(v8::Handle<v8::Value> value, v8::Isolate* isolate)
3178 {
3179     return GetRawTemplate(isolate)->HasInstance(value);
3180 }
3181
3182 END
3183
3184     if (@enabledPerContextAttributes) {
3185         push(@implContent, <<END);
3186 void ${v8InterfaceName}::installPerContextProperties(v8::Handle<v8::Object> instance, ${nativeType}* impl, v8::Isolate* isolate)
3187 {
3188     v8::Local<v8::Object> proto = v8::Local<v8::Object>::Cast(instance->GetPrototype());
3189     // When building QtWebkit with V8 this variable is unused when none of the features are enabled.
3190     UNUSED_PARAM(proto);
3191 END
3192
3193         # Setup the enable-by-settings attrs if we have them
3194         foreach my $runtimeAttr (@enabledPerContextAttributes) {
3195             my $enableFunction = GetContextEnableFunction($runtimeAttr->signature);
3196             my $conditionalString = $codeGenerator->GenerateConditionalString($runtimeAttr->signature);
3197             push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
3198             push(@implContent, "    if (${enableFunction}(impl->document())) {\n");
3199             push(@implContent, "        static const V8DOMConfiguration::BatchedAttribute attrData =\\\n");
3200             GenerateSingleBatchedAttribute($interfaceName, $runtimeAttr, ";", "    ");
3201             push(@implContent, <<END);
3202         V8DOMConfiguration::configureAttribute(instance, proto, attrData, isolate);
3203 END
3204             push(@implContent, "    }\n");
3205             push(@implContent, "#endif // ${conditionalString}\n") if $conditionalString;
3206         }
3207         push(@implContent, <<END);
3208 }
3209
3210 END
3211     }
3212
3213     if (@enabledPerContextFunctions) {
3214         push(@implContent, <<END);
3215 void ${v8InterfaceName}::installPerContextPrototypeProperties(v8::Handle<v8::Object> proto, v8::Isolate* isolate)
3216 {
3217     UNUSED_PARAM(proto);
3218 END
3219         # Setup the enable-by-settings functions if we have them
3220         push(@implContent,  <<END);
3221     v8::Local<v8::Signature> defaultSignature = v8::Signature::New(GetTemplate(isolate, worldType(isolate)));
3222     UNUSED_PARAM(defaultSignature); // In some cases, it will not be used.
3223
3224     ScriptExecutionContext* context = toScriptExecutionContext(proto->CreationContext());
3225 END
3226
3227         foreach my $runtimeFunc (@enabledPerContextFunctions) {
3228             my $enableFunction = GetContextEnableFunction($runtimeFunc->signature);
3229             my $conditionalString = $codeGenerator->GenerateConditionalString($runtimeFunc->signature);
3230             push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
3231             push(@implContent, "    if (context && context->isDocument() && ${enableFunction}(static_cast<Document*>(context))) {\n");
3232             my $name = $runtimeFunc->signature->name;
3233             push(@implContent, <<END);
3234         proto->Set(v8::String::NewSymbol("${name}"), v8::FunctionTemplate::New(${interfaceName}V8Internal::${name}MethodCallback, v8Undefined(), defaultSignature)->GetFunction());
3235 END
3236             push(@implContent, "    }\n");
3237             push(@implContent, "#endif // ${conditionalString}\n") if $conditionalString;
3238         }
3239
3240         push(@implContent, <<END);
3241 }
3242
3243 END
3244     }
3245
3246     if ($codeGenerator->InheritsExtendedAttribute($interface, "ActiveDOMObject")) {
3247         # MessagePort is handled like an active dom object even though it doesn't inherit
3248         # from ActiveDOMObject, so don't try to cast it to ActiveDOMObject.
3249         my $returnValue = $interfaceName eq "MessagePort" ? "0" : "toNative(object)";
3250         push(@implContent, <<END);
3251 ActiveDOMObject* ${v8InterfaceName}::toActiveDOMObject(v8::Handle<v8::Object> object)
3252 {
3253     return $returnValue;
3254 }
3255
3256 END
3257     }
3258
3259     if ($codeGenerator->InheritsExtendedAttribute($interface, "EventTarget")) {
3260         push(@implContent, <<END);
3261 EventTarget* ${v8InterfaceName}::toEventTarget(v8::Handle<v8::Object> object)
3262 {
3263     return toNative(object);
3264 }
3265
3266 END
3267     }
3268
3269     if ($interfaceName eq "DOMWindow") {
3270         push(@implContent, <<END);
3271 v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate(v8::Isolate* isolate)
3272 {
3273     static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObjectCache;
3274     if (V8DOMWindowShadowObjectCache.IsEmpty()) {
3275         V8DOMWindowShadowObjectCache = v8::Persistent<v8::ObjectTemplate>::New(isolate, v8::ObjectTemplate::New());
3276         ConfigureShadowObjectTemplate(V8DOMWindowShadowObjectCache, isolate);
3277     }
3278     return V8DOMWindowShadowObjectCache;
3279 }
3280
3281 END
3282     }
3283
3284     GenerateToV8Converters($interface, $v8InterfaceName, $nativeType);
3285
3286     push(@implContent, <<END);
3287 void ${v8InterfaceName}::derefObject(void* object)
3288 {
3289     static_cast<${nativeType}*>(object)->deref();
3290 }
3291
3292 } // namespace WebCore
3293 END
3294
3295     my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
3296     push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
3297
3298     # We've already added the header for this file in implContentHeader, so remove
3299     # it from implIncludes to ensure we don't #include it twice.
3300     delete $implIncludes{"${v8InterfaceName}.h"};
3301 }
3302
3303 sub GenerateHeaderContentHeader
3304 {
3305     my $interface = shift;
3306     my $v8InterfaceName = "V8" . $interface->name;
3307     my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
3308
3309     my @headerContentHeader = split("\r", $headerTemplate);
3310
3311     push(@headerContentHeader, "\n#ifndef ${v8InterfaceName}" . "_h\n");
3312     push(@headerContentHeader, "#define ${v8InterfaceName}" . "_h\n\n");
3313     push(@headerContentHeader, "#if ${conditionalString}\n") if $conditionalString;
3314     return @headerContentHeader;
3315 }
3316
3317 sub GenerateImplementationContentHeader
3318 {
3319     my $interface = shift;
3320     my $v8InterfaceName = "V8" . $interface->name;
3321     my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
3322
3323     my @implContentHeader = split("\r", $headerTemplate);
3324
3325     push(@implContentHeader, "\n#include \"config.h\"\n");
3326     push(@implContentHeader, "#if ${conditionalString}\n") if $conditionalString;
3327     push(@implContentHeader, "#include \"${v8InterfaceName}.h\"\n\n");
3328     return @implContentHeader;
3329 }
3330
3331 sub GenerateCallbackHeader
3332 {
3333     my $object = shift;
3334     my $interface = shift;
3335
3336     my $interfaceName = $interface->name;
3337     my $v8InterfaceName = "V8$interfaceName";
3338
3339
3340     # - Add default header template
3341     push(@headerContent, GenerateHeaderContentHeader($interface));
3342
3343     my @unsortedIncludes = ();
3344     push(@unsortedIncludes, "#include \"ActiveDOMCallback.h\"");
3345     push(@unsortedIncludes, "#include \"$interfaceName.h\"");
3346     push(@unsortedIncludes, "#include \"ScopedPersistent.h\"");
3347     push(@unsortedIncludes, "#include \"WorldContextHandle.h\"");
3348     push(@unsortedIncludes, "#include <v8.h>");
3349     push(@unsortedIncludes, "#include <wtf/Forward.h>");
3350     push(@headerContent, join("\n", sort @unsortedIncludes));
3351     
3352     push(@headerContent, "\n\nnamespace WebCore {\n\n");
3353     push(@headerContent, "class ScriptExecutionContext;\n\n");
3354     push(@headerContent, "class $v8InterfaceName : public $interfaceName, public ActiveDOMCallback {\n");
3355
3356     push(@headerContent, <<END);
3357 public:
3358     static PassRefPtr<${v8InterfaceName}> create(v8::Handle<v8::Value> value, ScriptExecutionContext* context)
3359     {
3360         ASSERT(value->IsObject());
3361         ASSERT(context);
3362         return adoptRef(new ${v8InterfaceName}(v8::Handle<v8::Object>::Cast(value), context));
3363     }
3364
3365     virtual ~${v8InterfaceName}();
3366
3367 END
3368
3369     # Functions
3370     my $numFunctions = @{$interface->functions};
3371     if ($numFunctions > 0) {
3372         push(@headerContent, "    // Functions\n");
3373         foreach my $function (@{$interface->functions}) {
3374             my @params = @{$function->parameters};
3375             if (!$function->signature->extendedAttributes->{"Custom"} &&
3376                 !(GetNativeType($function->signature->type) eq "bool")) {
3377                     push(@headerContent, "    COMPILE_ASSERT(false)");
3378             }
3379
3380             push(@headerContent, "    virtual " . GetNativeTypeForCallbacks($function->signature->type) . " " . $function->signature->name . "(");
3381
3382             my @args = ();
3383             foreach my $param (@params) {
3384                 push(@args, GetNativeTypeForCallbacks($param->type) . " " . $param->name);
3385             }
3386             push(@headerContent, join(", ", @args));
3387             push(@headerContent, ");\n");
3388         }
3389     }
3390
3391     push(@headerContent, <<END);
3392
3393     virtual ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); }
3394
3395 private:
3396     ${v8InterfaceName}(v8::Handle<v8::Object>, ScriptExecutionContext*);
3397
3398     ScopedPersistent<v8::Object> m_callback;
3399     WorldContextHandle m_worldContext;
3400 };
3401
3402 END
3403
3404     push(@headerContent, "}\n\n");
3405     push(@headerContent, "#endif // $v8InterfaceName" . "_h\n\n");
3406
3407     my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
3408     push(@headerContent, "#endif // ${conditionalString}\n") if $conditionalString;
3409 }
3410
3411 sub GenerateCallbackImplementation
3412 {
3413     my $object = shift;
3414     my $interface = shift;
3415     my $interfaceName = $interface->name;
3416     my $v8InterfaceName = "V8$interfaceName";
3417
3418     # - Add default header template
3419     push(@implContentHeader, GenerateImplementationContentHeader($interface));
3420
3421     AddToImplIncludes("ScriptExecutionContext.h");
3422     AddToImplIncludes("V8Binding.h");
3423     AddToImplIncludes("V8Callback.h");
3424
3425     push(@implContent, "#include <wtf/Assertions.h>\n\n");
3426     push(@implContent, "namespace WebCore {\n\n");
3427     push(@implContent, <<END);
3428 ${v8InterfaceName}::${v8InterfaceName}(v8::Handle<v8::Object> callback, ScriptExecutionContext* context)
3429     : ActiveDOMCallback(context)
3430     , m_callback(callback)
3431     , m_worldContext(UseCurrentWorld)
3432 {
3433 }
3434
3435 ${v8InterfaceName}::~${v8InterfaceName}()
3436 {
3437 }
3438
3439 END
3440
3441     # Functions
3442     my $numFunctions = @{$interface->functions};
3443     if ($numFunctions > 0) {
3444         push(@implContent, "// Functions\n");
3445         foreach my $function (@{$interface->functions}) {
3446             my @params = @{$function->parameters};
3447             if ($function->signature->extendedAttributes->{"Custom"} ||
3448                 !(GetNativeTypeForCallbacks($function->signature->type) eq "bool")) {
3449                 next;
3450             }
3451
3452             AddIncludesForType($function->signature->type);
3453             push(@implContent, "\n" . GetNativeTypeForCallbacks($function->signature->type) . " ${v8InterfaceName}::" . $function->signature->name . "(");
3454
3455             my @args = ();
3456             my @argsCheck = ();
3457             my $thisType = $function->signature->extendedAttributes->{"PassThisToCallback"};
3458             foreach my $param (@params) {
3459                 my $paramName = $param->name;
3460                 AddIncludesForType($param->type);
3461                 push(@args, GetNativeTypeForCallbacks($param->type) . " " . $paramName);
3462                 if ($thisType and $thisType eq $param->type) {
3463                     push(@argsCheck, <<END);
3464     ASSERT(${paramName});
3465
3466 END
3467                 }
3468             }
3469             push(@implContent, join(", ", @args));
3470
3471             push(@implContent, ")\n");
3472             push(@implContent, "{\n");
3473             push(@implContent, @argsCheck) if @argsCheck;
3474             push(@implContent, "    if (!canInvokeCallback())\n");
3475             push(@implContent, "        return true;\n\n");
3476             push(@implContent, "    v8::HandleScope handleScope;\n\n");
3477             push(@implContent, "    v8::Handle<v8::Context> v8Context = toV8Context(scriptExecutionContext(), m_worldContext);\n");
3478             push(@implContent, "    if (v8Context.IsEmpty())\n");
3479             push(@implContent, "        return true;\n\n");
3480             push(@implContent, "    v8::Context::Scope scope(v8Context);\n\n");
3481
3482             @args = ();
3483             foreach my $param (@params) {
3484                 my $paramName = $param->name;
3485                 push(@implContent, "    v8::Handle<v8::Value> ${paramName}Handle = " . NativeToJSValue($param, $paramName, "v8::Handle<v8::Object>()", "v8Context->GetIsolate()") . ";\n");
3486                 push(@implContent, "    if (${paramName}Handle.IsEmpty()) {\n");
3487                 push(@implContent, "        if (!isScriptControllerTerminating())\n");
3488                 push(@implContent, "            CRASH();\n");
3489                 push(@implContent, "        return true;\n");
3490                 push(@implContent, "    }\n");
3491                 push(@args, "        ${paramName}Handle");
3492             }
3493
3494             if (scalar(@args) > 0) {
3495                 push(@implContent, "\n    v8::Handle<v8::Value> argv[] = {\n");
3496                 push(@implContent, join(",\n", @args));
3497                 push(@implContent, "\n    };\n\n");
3498             } else {
3499                 push(@implContent, "\n    v8::Handle<v8::Value> *argv = 0;\n\n");
3500             }
3501             push(@implContent, "    bool callbackReturnValue = false;\n");
3502             if ($thisType) {
3503                 foreach my $param (@params) {
3504                     next if $param->type ne $thisType;
3505                     my $paramName = $param->name;
3506                     push(@implContent, "    return !invokeCallback(m_callback.get(), v8::Handle<v8::Object>::Cast(${paramName}Handle), " . scalar(@params) . ", argv, callbackReturnValue, scriptExecutionContext());\n");
3507                     last;
3508                 }
3509             } else {
3510                 push(@implContent, "    return !invokeCallback(m_callback.get(), " . scalar(@params) . ", argv, callbackReturnValue, scriptExecutionContext());\n");
3511             }
3512             push(@implContent, "}\n");
3513         }
3514     }
3515
3516     push(@implContent, "\n} // namespace WebCore\n\n");
3517
3518     my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
3519     push(@implContent, "#endif // ${conditionalString}\n") if $conditionalString;
3520 }
3521
3522 sub BaseInterfaceName
3523 {
3524     my $interface = shift;
3525
3526     while (@{$interface->parents}) {
3527         $interface = $codeGenerator->ParseInterface(@{$interface->parents}[0], 1);
3528     }
3529
3530     return $interface->name;
3531 }
3532
3533 sub GenerateToV8Converters
3534 {
3535     my $interface = shift;
3536     my $v8InterfaceName = shift;
3537     my $nativeType = shift;
3538     my $interfaceName = $interface->name;
3539
3540     if ($interface->extendedAttributes->{"V8NoWrapperCache"} || $interface->extendedAttributes->{"SuppressToJSObject"}) {
3541         return;
3542     }
3543
3544     AddToImplIncludes("Frame.h");
3545
3546     my $createWrapperArgumentType = GetPassRefPtrType($nativeType);
3547     my $baseType = BaseInterfaceName($interface);
3548
3549     push(@implContent, <<END);
3550
3551 v8::Handle<v8::Object> ${v8InterfaceName}::createWrapper(${createWrapperArgumentType} impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
3552 {
3553     ASSERT(impl.get());
3554     ASSERT(DOMDataStore::getWrapper(impl.get(), isolate).IsEmpty());
3555 END
3556
3557     my $vtableNameGnu = GetGnuVTableNameForInterface($interface);
3558     push(@implContent, <<END) if $vtableNameGnu;
3559
3560 #if ENABLE(BINDING_INTEGRITY)
3561     checkTypeOrDieTrying(impl.get());
3562 #endif
3563 END
3564
3565     push(@implContent, <<END) if ($baseType ne $interfaceName);
3566     ASSERT(static_cast<void*>(static_cast<${baseType}*>(impl.get())) == static_cast<void*>(impl.get()));
3567 END
3568
3569     if ($codeGenerator->InheritsInterface($interface, "Document")) {
3570         push(@implContent, <<END);
3571     if (Frame* frame = impl->frame()) {
3572         if (frame->script()->initializeMainWorld()) {
3573             // initializeMainWorld may have created a wrapper for the object, retry from the start.
3574             v8::Handle<v8::Object> wrapper = DOMDataStore::getWrapper(impl.get(), isolate);
3575             if (!wrapper.IsEmpty())
3576                 return wrapper;
3577         }
3578     }
3579 END
3580     }
3581
3582     push(@implContent, <<END);
3583
3584     v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext, &info, impl.get(), isolate);
3585     if (UNLIKELY(wrapper.IsEmpty()))
3586         return wrapper;
3587
3588     installPerContextProperties(wrapper, impl.get(), isolate);
3589     V8DOMWrapper::associateObjectWithWrapper(impl, &info, wrapper, isolate, hasDependentLifetime ? WrapperConfiguration::Dependent : WrapperConfiguration::Independent);
3590     return wrapper;
3591 }
3592 END
3593 }
3594
3595 sub GenerateSecurityCheckFunctions
3596 {
3597     my $interface = shift;
3598     my $interfaceName = $interface->name;
3599     my $v8InterfaceName = "V8$interfaceName";
3600
3601     push(@implContentInternals, <<END);
3602 bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
3603 {
3604     $interfaceName* imp =  ${v8InterfaceName}::toNative(host);
3605     return BindingSecurity::shouldAllowAccessToFrame(BindingState::instance(), imp->frame(), DoNotReportSecurityError);
3606 }
3607
3608 bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
3609 {
3610     $interfaceName* imp =  ${v8InterfaceName}::toNative(host);
3611     return BindingSecurity::shouldAllowAccessToFrame(BindingState::instance(), imp->frame(), DoNotReportSecurityError);
3612 }
3613
3614 END
3615 }
3616
3617 sub GetNativeTypeForConversions
3618 {
3619     my $interface = shift;
3620     my $interfaceName = $interface->name;
3621     $interfaceName = $codeGenerator->GetSVGTypeNeedingTearOff($interfaceName) if $codeGenerator->IsSVGTypeNeedingTearOff($interfaceName);
3622     return $interfaceName;
3623 }
3624
3625 # See http://refspecs.linux-foundation.org/cxxabi-1.83.html.
3626 sub GetGnuVTableRefForInterface
3627 {
3628     my $interface = shift;
3629     my $vtableName = GetGnuVTableNameForInterface($interface);
3630     if (!$vtableName) {
3631         return "0";
3632     }
3633     my $typename = GetNativeTypeForConversions($interface);
3634     my $offset = GetGnuVTableOffsetForType($typename);
3635     return "&" . $vtableName . "[" . $offset . "]";
3636 }
3637
3638 sub GetGnuVTableNameForInterface
3639 {
3640     my $interface = shift;
3641     my $typename = GetNativeTypeForConversions($interface);
3642     my $templatePosition = index($typename, "<");
3643     return "" if $templatePosition != -1;
3644     return "" if GetImplementationLacksVTableForInterface($interface);
3645     return "" if GetV8SkipVTableValidationForInterface($interface);
3646     return "_ZTV" . GetGnuMangledNameForInterface($interface);
3647 }
3648
3649 sub GetGnuMangledNameForInterface
3650 {
3651     my $interface = shift;
3652     my $typename = GetNativeTypeForConversions($interface);
3653     my $templatePosition = index($typename, "<");
3654     if ($templatePosition != -1) {
3655         return "";
3656     }
3657     my $mangledType = length($typename) . $typename;
3658     my $namespace = GetNamespaceForInterface($interface);
3659     my $mangledNamespace =  "N" . length($namespace) . $namespace;
3660     return $mangledNamespace . $mangledType . "E";
3661 }
3662
3663 sub GetGnuVTableOffsetForType
3664 {
3665     my $typename = shift;
3666     if ($typename eq "SVGAElement"
3667         || $typename eq "SVGCircleElement"
3668         || $typename eq "SVGClipPathElement"
3669         || $typename eq "SVGDefsElement"
3670         || $typename eq "SVGEllipseElement"
3671         || $typename eq "SVGForeignObjectElement"
3672         || $typename eq "SVGGElement"
3673         || $typename eq "SVGImageElement"
3674         || $typename eq "SVGLineElement"
3675         || $typename eq "SVGPathElement"
3676         || $typename eq "SVGPolyElement"
3677         || $typename eq "SVGPolygonElement"
3678         || $typename eq "SVGPolylineElement"
3679         || $typename eq "SVGRectElement"
3680         || $typename eq "SVGSVGElement"
3681         || $typename eq "SVGStyledLocatableElement"
3682         || $typename eq "SVGStyledTransformableElement"
3683         || $typename eq "SVGSwitchElement"
3684         || $typename eq "SVGTextElement"
3685         || $typename eq "SVGTransformable"
3686         || $typename eq "SVGUseElement") {
3687         return "3";
3688     }
3689     return "2";
3690 }
3691
3692 # See http://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B_Name_Mangling.
3693 sub GetWinVTableRefForInterface
3694 {
3695     my $interface = shift;
3696     my $vtableName = GetWinVTableNameForInterface($interface);
3697     return 0 if !$vtableName;
3698     return "__identifier(\"" . $vtableName . "\")";
3699 }
3700
3701 sub GetWinVTableNameForInterface
3702 {
3703     my $interface = shift;
3704     my $typename = GetNativeTypeForConversions($interface);
3705     my $templatePosition = index($typename, "<");
3706     return "" if $templatePosition != -1;
3707     return "" if GetImplementationLacksVTableForInterface($interface);
3708     return "" if GetV8SkipVTableValidationForInterface($interface);
3709     return "??_7" . GetWinMangledNameForInterface($interface) . "6B@";
3710 }
3711
3712 sub GetWinMangledNameForInterface
3713 {
3714     my $interface = shift;