| OLD | NEW | 
|---|
|  | (Empty) | 
| 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 # Copyright (C) 2013 Samsung Electronics. All rights reserved. |  | 
| 12 # |  | 
| 13 # This library is free software; you can redistribute it and/or |  | 
| 14 # modify it under the terms of the GNU Library General Public |  | 
| 15 # License as published by the Free Software Foundation; either |  | 
| 16 # version 2 of the License, or (at your option) any later version. |  | 
| 17 # |  | 
| 18 # This library is distributed in the hope that it will be useful, |  | 
| 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of |  | 
| 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU |  | 
| 21 # Library General Public License for more details. |  | 
| 22 # |  | 
| 23 # You should have received a copy of the GNU Library General Public License |  | 
| 24 # along with this library; see the file COPYING.LIB.  If not, write to |  | 
| 25 # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |  | 
| 26 # Boston, MA 02111-1307, USA. |  | 
| 27 # |  | 
| 28 |  | 
| 29 package Block; |  | 
| 30 |  | 
| 31 # Sample code: |  | 
| 32 #   my $outer = new Block("Free Name 1", "namespace Foo {", "} // namespace Foo"
      ); |  | 
| 33 #   $outer->add("    void foo() {}"); |  | 
| 34 #   my $inner = new Block("Free Name 2", "namespace Bar {", "} // namespace Bar"
      ); |  | 
| 35 #   $inner->add("    void bar() {}"); |  | 
| 36 #   $outer->add($inner); |  | 
| 37 #   print $outer->toString(); |  | 
| 38 # |  | 
| 39 # Output code: |  | 
| 40 #   namespace Foo { |  | 
| 41 #       void foo() {} |  | 
| 42 #   namespace Bar { |  | 
| 43 #       void bar() {} |  | 
| 44 #   } // namespace Bar |  | 
| 45 #   } // namespace Foo |  | 
| 46 |  | 
| 47 sub new |  | 
| 48 { |  | 
| 49     my $package = shift; |  | 
| 50     my $name = shift || "Anonymous block"; |  | 
| 51     my $header = shift || ""; |  | 
| 52     my $footer = shift || ""; |  | 
| 53 |  | 
| 54     my $object = { |  | 
| 55         "name" => $name, |  | 
| 56         "header" => [$header], |  | 
| 57         "footer" => [$footer], |  | 
| 58         "contents" => [], |  | 
| 59     }; |  | 
| 60     bless $object, $package; |  | 
| 61     return $object; |  | 
| 62 } |  | 
| 63 |  | 
| 64 sub addHeader |  | 
| 65 { |  | 
| 66     my $object = shift; |  | 
| 67     my $header = shift || ""; |  | 
| 68 |  | 
| 69     push(@{$object->{header}}, $header); |  | 
| 70 } |  | 
| 71 |  | 
| 72 sub addFooter |  | 
| 73 { |  | 
| 74     my $object = shift; |  | 
| 75     my $footer = shift || ""; |  | 
| 76 |  | 
| 77     push(@{$object->{footer}}, $footer); |  | 
| 78 } |  | 
| 79 |  | 
| 80 sub add |  | 
| 81 { |  | 
| 82     my $object = shift; |  | 
| 83     my $content = shift || ""; |  | 
| 84 |  | 
| 85     push(@{$object->{contents}}, $content); |  | 
| 86 } |  | 
| 87 |  | 
| 88 sub toString |  | 
| 89 { |  | 
| 90     my $object = shift; |  | 
| 91 |  | 
| 92     my $header = join "", @{$object->{header}}; |  | 
| 93     my $footer = join "", @{$object->{footer}}; |  | 
| 94     my $code = ""; |  | 
| 95     $code .= "/* BEGIN " . $object->{name} . " */\n" if $verbose; |  | 
| 96     $code .=  $header . "\n" if $header; |  | 
| 97     for my $content (@{$object->{contents}}) { |  | 
| 98         if (ref($content) eq "Block") { |  | 
| 99             $code .= $content->toString(); |  | 
| 100         } else { |  | 
| 101             $code .= $content; |  | 
| 102         } |  | 
| 103     } |  | 
| 104     $code .=  $footer . "\n" if $footer; |  | 
| 105     $code .= "/* END " . $object->{name} . " */\n" if $verbose; |  | 
| 106     return $code; |  | 
| 107 } |  | 
| 108 |  | 
| 109 |  | 
| 110 package deprecated_code_generator_v8; |  | 
| 111 |  | 
| 112 use strict; |  | 
| 113 use Cwd; |  | 
| 114 use File::Basename; |  | 
| 115 use File::Find; |  | 
| 116 use File::Spec; |  | 
| 117 |  | 
| 118 my $idlDocument; |  | 
| 119 my $idlDirectories; |  | 
| 120 my $preprocessor; |  | 
| 121 my $verbose; |  | 
| 122 my $interfaceIdlFiles; |  | 
| 123 my $writeFileOnlyIfChanged; |  | 
| 124 my $sourceRoot; |  | 
| 125 |  | 
| 126 # Cache of IDL file pathnames. |  | 
| 127 my $idlFiles; |  | 
| 128 my $cachedInterfaces = {}; |  | 
| 129 |  | 
| 130 my %implIncludes = (); |  | 
| 131 my %headerIncludes = (); |  | 
| 132 |  | 
| 133 # Header code structure: |  | 
| 134 # Root                    ... Copyright, include duplication check |  | 
| 135 #   Conditional           ... #if FEATURE ... #endif  (to be removed soon) |  | 
| 136 #     Includes |  | 
| 137 #     NameSpaceWebCore |  | 
| 138 #       Class |  | 
| 139 #         ClassPublic |  | 
| 140 #         ClassPrivate |  | 
| 141 my %header; |  | 
| 142 |  | 
| 143 # Implementation code structure: |  | 
| 144 # Root                    ... Copyright |  | 
| 145 #   Conditional           ... #if FEATURE ... #endif  (to be removed soon) |  | 
| 146 #     Includes |  | 
| 147 #     NameSpaceWebCore |  | 
| 148 #     NameSpaceInternal   ... namespace ${implClassName}V8Internal in case of no
      n-callback |  | 
| 149 my %implementation; |  | 
| 150 |  | 
| 151 # Promise is not yet in the Web IDL spec but is going to be speced |  | 
| 152 # as primitive types in the future. |  | 
| 153 # Since V8 dosn't provide Promise primitive object currently, |  | 
| 154 # primitiveTypeHash doesn't contain Promise. |  | 
| 155 my %primitiveTypeHash = ("boolean" => 1, |  | 
| 156                          "void" => 1, |  | 
| 157                          "Date" => 1, |  | 
| 158                          "byte" => 1, |  | 
| 159                          "octet" => 1, |  | 
| 160                          "short" => 1, |  | 
| 161                          "long" => 1, |  | 
| 162                          "long long" => 1, |  | 
| 163                          "unsigned short" => 1, |  | 
| 164                          "unsigned long" => 1, |  | 
| 165                          "unsigned long long" => 1, |  | 
| 166                          "float" => 1, |  | 
| 167                          "double" => 1, |  | 
| 168                         ); |  | 
| 169 |  | 
| 170 my %nonWrapperTypes = ("CompareHow" => 1, |  | 
| 171                        "DOMTimeStamp" => 1, |  | 
| 172                        "Dictionary" => 1, |  | 
| 173                        "EventListener" => 1, |  | 
| 174                        "EventHandler" => 1, |  | 
| 175                        "MediaQueryListListener" => 1, |  | 
| 176                        "NodeFilter" => 1, |  | 
| 177                        "SerializedScriptValue" => 1, |  | 
| 178                        "any" => 1, |  | 
| 179                       ); |  | 
| 180 |  | 
| 181 my %typedArrayHash = ("ArrayBuffer" => [], |  | 
| 182                       "ArrayBufferView" => [], |  | 
| 183                       "Uint8Array" => ["unsigned char", "v8::kExternalUnsignedBy
      teArray"], |  | 
| 184                       "Uint8ClampedArray" => ["unsigned char", "v8::kExternalPix
      elArray"], |  | 
| 185                       "Uint16Array" => ["unsigned short", "v8::kExternalUnsigned
      ShortArray"], |  | 
| 186                       "Uint32Array" => ["unsigned int", "v8::kExternalUnsignedIn
      tArray"], |  | 
| 187                       "Int8Array" => ["signed char", "v8::kExternalByteArray"], |  | 
| 188                       "Int16Array" => ["short", "v8::kExternalShortArray"], |  | 
| 189                       "Int32Array" => ["int", "v8::kExternalIntArray"], |  | 
| 190                       "Float32Array" => ["float", "v8::kExternalFloatArray"], |  | 
| 191                       "Float64Array" => ["double", "v8::kExternalDoubleArray"], |  | 
| 192                      ); |  | 
| 193 |  | 
| 194 my %callbackFunctionTypeHash = (); |  | 
| 195 |  | 
| 196 my %enumTypeHash = (); |  | 
| 197 |  | 
| 198 my %svgAttributesInHTMLHash = ("class" => 1, "id" => 1, "onabort" => 1, "onclick
      " => 1, |  | 
| 199                                "onerror" => 1, "onload" => 1, "onmousedown" => 1
      , |  | 
| 200                                "onmouseenter" => 1, "onmouseleave" => 1, |  | 
| 201                                "onmousemove" => 1, "onmouseout" => 1, "onmouseov
      er" => 1, |  | 
| 202                                "onmouseup" => 1, "onresize" => 1, "onscroll" => 
      1, |  | 
| 203                                "onunload" => 1); |  | 
| 204 |  | 
| 205 my %svgTypeNeedingTearOff = ( |  | 
| 206     "SVGAngle" => "SVGPropertyTearOff<SVGAngle>", |  | 
| 207     "SVGLength" => "SVGPropertyTearOff<SVGLength>", |  | 
| 208     "SVGLengthList" => "SVGListPropertyTearOff<SVGLengthList>", |  | 
| 209     "SVGMatrix" => "SVGPropertyTearOff<SVGMatrix>", |  | 
| 210     "SVGNumber" => "SVGPropertyTearOff<SVGNumber>", |  | 
| 211     "SVGNumberList" => "SVGListPropertyTearOff<SVGNumberList>", |  | 
| 212     "SVGPathSegList" => "SVGPathSegListPropertyTearOff", |  | 
| 213     "SVGPoint" => "SVGPropertyTearOff<SVGPoint>", |  | 
| 214     "SVGPointList" => "SVGListPropertyTearOff<SVGPointList>", |  | 
| 215     "SVGPreserveAspectRatio" => "SVGPropertyTearOff<SVGPreserveAspectRatio>", |  | 
| 216     "SVGRect" => "SVGPropertyTearOff<SVGRect>", |  | 
| 217     "SVGStringList" => "SVGStaticListPropertyTearOff<SVGStringList>", |  | 
| 218     "SVGTransform" => "SVGPropertyTearOff<SVGTransform>", |  | 
| 219     "SVGTransformList" => "SVGTransformListPropertyTearOff" |  | 
| 220 ); |  | 
| 221 |  | 
| 222 my %svgTypeWithWritablePropertiesNeedingTearOff = ( |  | 
| 223     "SVGPoint" => 1, |  | 
| 224     "SVGMatrix" => 1 |  | 
| 225 ); |  | 
| 226 |  | 
| 227 # Default .h template |  | 
| 228 my $headerTemplate = <<EOF; |  | 
| 229 /* |  | 
| 230     This file is part of the Blink open source project. |  | 
| 231     This file has been auto-generated by CodeGeneratorV8.pm. DO NOT MODIFY! |  | 
| 232 |  | 
| 233     This library is free software; you can redistribute it and/or |  | 
| 234     modify it under the terms of the GNU Library General Public |  | 
| 235     License as published by the Free Software Foundation; either |  | 
| 236     version 2 of the License, or (at your option) any later version. |  | 
| 237 |  | 
| 238     This library is distributed in the hope that it will be useful, |  | 
| 239     but WITHOUT ANY WARRANTY; without even the implied warranty of |  | 
| 240     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU |  | 
| 241     Library General Public License for more details. |  | 
| 242 |  | 
| 243     You should have received a copy of the GNU Library General Public License |  | 
| 244     along with this library; see the file COPYING.LIB.  If not, write to |  | 
| 245     the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |  | 
| 246     Boston, MA 02111-1307, USA. |  | 
| 247 */ |  | 
| 248 EOF |  | 
| 249 |  | 
| 250 sub new |  | 
| 251 { |  | 
| 252     my $object = shift; |  | 
| 253     my $reference = { }; |  | 
| 254 |  | 
| 255     $idlDocument = shift; |  | 
| 256     $idlDirectories = shift; |  | 
| 257     $preprocessor = shift; |  | 
| 258     $verbose = shift; |  | 
| 259     $interfaceIdlFiles = shift; |  | 
| 260     $writeFileOnlyIfChanged = shift; |  | 
| 261 |  | 
| 262     $sourceRoot = dirname(dirname(dirname(Cwd::abs_path($0)))); |  | 
| 263 |  | 
| 264     bless($reference, $object); |  | 
| 265     return $reference; |  | 
| 266 } |  | 
| 267 |  | 
| 268 |  | 
| 269 sub IDLFileForInterface |  | 
| 270 { |  | 
| 271     my $interfaceName = shift; |  | 
| 272 |  | 
| 273     unless ($idlFiles) { |  | 
| 274         my @directories = map { $_ = "$sourceRoot/$_" if -d "$sourceRoot/$_"; $_
       } @$idlDirectories; |  | 
| 275         push(@directories, "."); |  | 
| 276 |  | 
| 277         $idlFiles = { }; |  | 
| 278         foreach my $idlFile (@$interfaceIdlFiles) { |  | 
| 279             $idlFiles->{fileparse(basename($idlFile), ".idl")} = $idlFile; |  | 
| 280         } |  | 
| 281 |  | 
| 282         my $wanted = sub { |  | 
| 283             $idlFiles->{$1} = $File::Find::name if /^([A-Z].*)\.idl$/; |  | 
| 284             $File::Find::prune = 1 if /^\../; |  | 
| 285         }; |  | 
| 286         find($wanted, @directories); |  | 
| 287     } |  | 
| 288 |  | 
| 289     return $idlFiles->{$interfaceName}; |  | 
| 290 } |  | 
| 291 |  | 
| 292 sub ParseInterface |  | 
| 293 { |  | 
| 294     my $interfaceName = shift; |  | 
| 295 |  | 
| 296     if (exists $cachedInterfaces->{$interfaceName}) { |  | 
| 297         return $cachedInterfaces->{$interfaceName}; |  | 
| 298     } |  | 
| 299 |  | 
| 300     # Step #1: Find the IDL file associated with 'interface' |  | 
| 301     my $filename = IDLFileForInterface($interfaceName) |  | 
| 302       or die("Could NOT find IDL file for interface \"$interfaceName\" $!\n"); |  | 
| 303 |  | 
| 304     print "  |  |>  Parsing parent IDL \"$filename\" for interface \"$interfaceN
      ame\"\n" if $verbose; |  | 
| 305 |  | 
| 306     # Step #2: Parse the found IDL file (in quiet mode). |  | 
| 307     my $parser = deprecated_idl_parser->new(1); |  | 
| 308     my $document = $parser->Parse($filename, $preprocessor); |  | 
| 309 |  | 
| 310     foreach my $interface (@{$document->interfaces}) { |  | 
| 311         if ($interface->name eq $interfaceName or $interface->isPartial) { |  | 
| 312             $cachedInterfaces->{$interfaceName} = $interface; |  | 
| 313             return $interface; |  | 
| 314         } |  | 
| 315     } |  | 
| 316 |  | 
| 317     die("Could NOT find interface definition for $interfaceName in $filename"); |  | 
| 318 } |  | 
| 319 |  | 
| 320 sub GenerateInterface |  | 
| 321 { |  | 
| 322     my $object = shift; |  | 
| 323     my $interface = shift; |  | 
| 324 |  | 
| 325     %callbackFunctionTypeHash = map { $_->name => $_ } @{$idlDocument->callbackF
      unctions}; |  | 
| 326     %enumTypeHash = map { $_->name => $_->values } @{$idlDocument->enumerations}
      ; |  | 
| 327     my $v8ClassName = GetV8ClassName($interface); |  | 
| 328     my $defineName = $v8ClassName . "_h"; |  | 
| 329     my $internalNamespace = GetImplName($interface) . "V8Internal"; |  | 
| 330 |  | 
| 331     my $conditionalString = GenerateConditionalString($interface); |  | 
| 332     my $conditionalIf = ""; |  | 
| 333     my $conditionalEndif = ""; |  | 
| 334     if ($conditionalString) { |  | 
| 335         $conditionalIf = "#if ${conditionalString}"; |  | 
| 336         $conditionalEndif = "#endif // ${conditionalString}"; |  | 
| 337     } |  | 
| 338 |  | 
| 339     $header{root} = new Block("ROOT", "", ""); |  | 
| 340     # FIXME: newlines should be generated by Block::toString(). |  | 
| 341     $header{conditional} = new Block("Conditional", "$conditionalIf", $condition
      alEndif ? "$conditionalEndif\n" : ""); |  | 
| 342     $header{includes} = new Block("Includes", "", ""); |  | 
| 343     $header{nameSpaceWebCore} = new Block("Namespace WebCore", "\nnamespace WebC
      ore {\n", "}\n"); |  | 
| 344     $header{class} = new Block("Class definition", "", ""); |  | 
| 345     $header{classPublic} = new Block("Class public:", "public:", ""); |  | 
| 346     $header{classPrivate} = new Block("Class private:", "private:", ""); |  | 
| 347 |  | 
| 348     $header{root}->add($header{conditional}); |  | 
| 349     $header{conditional}->add($header{includes}); |  | 
| 350     $header{conditional}->add($header{nameSpaceWebCore}); |  | 
| 351     $header{nameSpaceWebCore}->add($header{class}); |  | 
| 352     $header{class}->add($header{classPublic}); |  | 
| 353     $header{class}->add($header{classPrivate}); |  | 
| 354 |  | 
| 355     # - Add default header template |  | 
| 356     $header{root}->addHeader($headerTemplate . "\n"); |  | 
| 357     $header{root}->addHeader("#ifndef $defineName\n#define $defineName\n"); |  | 
| 358     $header{root}->addFooter("#endif // $defineName"); |  | 
| 359 |  | 
| 360     $implementation{root} = new Block("ROOT", "", ""); |  | 
| 361     $conditionalEndif = "\n$conditionalEndif" if !$interface->isCallback and $co
      nditionalEndif; |  | 
| 362     $implementation{conditional} = new Block("Conditional", $conditionalIf, $con
      ditionalEndif); |  | 
| 363     $implementation{includes} = new Block("Includes", "", ""); |  | 
| 364 |  | 
| 365     # FIXME: newlines should be generated by Block::toString(). |  | 
| 366     my $nameSpaceWebCoreBegin = "namespace WebCore {\n"; |  | 
| 367     my $nameSpaceWebCoreEnd = "} // namespace WebCore"; |  | 
| 368     $nameSpaceWebCoreBegin = "$nameSpaceWebCoreBegin\n" if !$interface->isCallba
      ck; |  | 
| 369     $nameSpaceWebCoreEnd = "\n$nameSpaceWebCoreEnd\n" if $interface->isCallback; |  | 
| 370     $implementation{nameSpaceWebCore} = new Block("Namespace WebCore", $nameSpac
      eWebCoreBegin, $nameSpaceWebCoreEnd); |  | 
| 371     $implementation{nameSpaceInternal} = new Block("Internal namespace", "namesp
      ace $internalNamespace {\n", "} // namespace $internalNamespace\n"); |  | 
| 372 |  | 
| 373     $implementation{root}->add($implementation{conditional}); |  | 
| 374     $implementation{conditional}->add($implementation{includes}); |  | 
| 375     $implementation{conditional}->add($implementation{nameSpaceWebCore}); |  | 
| 376     if (!$interface->isCallback) { |  | 
| 377         $implementation{nameSpaceWebCore}->add($implementation{nameSpaceInternal
      }); |  | 
| 378     } |  | 
| 379 |  | 
| 380     # - Add default header template |  | 
| 381     $implementation{root}->addHeader($headerTemplate); |  | 
| 382     $implementation{root}->addHeader("\n#include \"config.h\""); |  | 
| 383     $implementation{includes}->add("#include \"${v8ClassName}.h\"\n\n"); |  | 
| 384 |  | 
| 385     # Start actual generation |  | 
| 386     if ($interface->isCallback) { |  | 
| 387         $object->GenerateCallbackHeader($interface); |  | 
| 388         $object->GenerateCallbackImplementation($interface); |  | 
| 389     } else { |  | 
| 390         $object->GenerateHeader($interface); |  | 
| 391         $object->GenerateImplementation($interface); |  | 
| 392     } |  | 
| 393 } |  | 
| 394 |  | 
| 395 sub AddToImplIncludes |  | 
| 396 { |  | 
| 397     my $header = shift; |  | 
| 398     $implIncludes{$header} = 1; |  | 
| 399 } |  | 
| 400 |  | 
| 401 sub AddToHeaderIncludes |  | 
| 402 { |  | 
| 403     my @includes = @_; |  | 
| 404 |  | 
| 405     for my $include (@includes) { |  | 
| 406         $headerIncludes{$include} = 1; |  | 
| 407     } |  | 
| 408 } |  | 
| 409 |  | 
| 410 sub SkipIncludeHeader |  | 
| 411 { |  | 
| 412     my $type = shift; |  | 
| 413 |  | 
| 414     return 1 if IsPrimitiveType($type); |  | 
| 415     return 1 if IsEnumType($type); |  | 
| 416     return 1 if IsCallbackFunctionType($type); |  | 
| 417     return 1 if $type eq "DOMString"; |  | 
| 418     return 0; |  | 
| 419 } |  | 
| 420 |  | 
| 421 sub AddIncludesForType |  | 
| 422 { |  | 
| 423     my $type = shift; |  | 
| 424 |  | 
| 425     return if SkipIncludeHeader($type); |  | 
| 426 |  | 
| 427     # Default includes |  | 
| 428     if ($type eq "EventListener" or $type eq "EventHandler") { |  | 
| 429         AddToImplIncludes("core/dom/EventListener.h"); |  | 
| 430     } elsif ($type eq "SerializedScriptValue") { |  | 
| 431         AddToImplIncludes("bindings/v8/SerializedScriptValue.h"); |  | 
| 432     } elsif ($type eq "any" || IsCallbackFunctionType($type)) { |  | 
| 433         AddToImplIncludes("bindings/v8/ScriptValue.h"); |  | 
| 434     } elsif ($type eq "Promise") { |  | 
| 435         AddToImplIncludes("bindings/v8/ScriptPromise.h"); |  | 
| 436     } elsif (IsTypedArrayType($type)) { |  | 
| 437         AddToImplIncludes("bindings/v8/custom/V8${type}Custom.h"); |  | 
| 438     } else { |  | 
| 439         AddToImplIncludes("V8${type}.h"); |  | 
| 440     } |  | 
| 441 } |  | 
| 442 |  | 
| 443 sub HeaderFilesForInterface |  | 
| 444 { |  | 
| 445     my $interfaceName = shift; |  | 
| 446     my $implClassName = shift; |  | 
| 447 |  | 
| 448     my @includes = (); |  | 
| 449     if (IsTypedArrayType($interfaceName)) { |  | 
| 450         push(@includes, "wtf/${interfaceName}.h"); |  | 
| 451     } elsif (!SkipIncludeHeader($interfaceName)) { |  | 
| 452         my $idlFilename = Cwd::abs_path(IDLFileForInterface($interfaceName)) or 
      die("Could NOT find IDL file for interface \"$interfaceName\" $!\n"); |  | 
| 453         my $idlRelPath = File::Spec->abs2rel($idlFilename, $sourceRoot); |  | 
| 454         push(@includes, dirname($idlRelPath) . "/" . $implClassName . ".h"); |  | 
| 455     } |  | 
| 456     return @includes; |  | 
| 457 } |  | 
| 458 |  | 
| 459 sub NeedsOpaqueRootForGC |  | 
| 460 { |  | 
| 461     my $interface = shift; |  | 
| 462     return $interface->extendedAttributes->{"GenerateIsReachable"} || $interface
      ->extendedAttributes->{"CustomIsReachable"}; |  | 
| 463 } |  | 
| 464 |  | 
| 465 sub GenerateOpaqueRootForGC |  | 
| 466 { |  | 
| 467     my $interface = shift; |  | 
| 468     my $implClassName = GetImplName($interface); |  | 
| 469     my $v8ClassName = GetV8ClassName($interface); |  | 
| 470 |  | 
| 471     if ($interface->extendedAttributes->{"CustomIsReachable"}) { |  | 
| 472         return; |  | 
| 473     } |  | 
| 474 |  | 
| 475     my $code = <<END; |  | 
| 476 void* ${v8ClassName}::opaqueRootForGC(void* object, v8::Isolate* isolate) |  | 
| 477 { |  | 
| 478     ${implClassName}* impl = fromInternalPointer(object); |  | 
| 479 END |  | 
| 480     my $isReachableMethod = $interface->extendedAttributes->{"GenerateIsReachabl
      e"}; |  | 
| 481     if ($isReachableMethod) { |  | 
| 482         AddToImplIncludes("bindings/v8/V8GCController.h"); |  | 
| 483         AddToImplIncludes("core/dom/Element.h"); |  | 
| 484         $code .= <<END; |  | 
| 485     if (Node* owner = impl->${isReachableMethod}()) |  | 
| 486         return V8GCController::opaqueRootForGC(owner, isolate); |  | 
| 487 END |  | 
| 488     } |  | 
| 489 |  | 
| 490     $code .= <<END; |  | 
| 491     return object; |  | 
| 492 } |  | 
| 493 |  | 
| 494 END |  | 
| 495     $implementation{nameSpaceWebCore}->add($code); |  | 
| 496 } |  | 
| 497 |  | 
| 498 sub GetSVGPropertyTypes |  | 
| 499 { |  | 
| 500     my $implType = shift; |  | 
| 501 |  | 
| 502     my $svgPropertyType; |  | 
| 503     my $svgListPropertyType; |  | 
| 504     my $svgNativeType; |  | 
| 505 |  | 
| 506     return ($svgPropertyType, $svgListPropertyType, $svgNativeType) if not $impl
      Type =~ /SVG/; |  | 
| 507 |  | 
| 508     $svgNativeType = GetSVGTypeNeedingTearOff($implType); |  | 
| 509     return ($svgPropertyType, $svgListPropertyType, $svgNativeType) if not $svgN
      ativeType; |  | 
| 510 |  | 
| 511     # Append space to avoid compilation errors when using  PassRefPtr<$svgNative
      Type> |  | 
| 512     $svgNativeType = "$svgNativeType "; |  | 
| 513 |  | 
| 514     my $svgWrappedNativeType = GetSVGWrappedTypeNeedingTearOff($implType); |  | 
| 515     if ($svgNativeType =~ /SVGPropertyTearOff/) { |  | 
| 516         $svgPropertyType = $svgWrappedNativeType; |  | 
| 517         AddToHeaderIncludes("core/svg/properties/SVGAnimatedPropertyTearOff.h"); |  | 
| 518     } elsif ($svgNativeType =~ /SVGListPropertyTearOff/ or $svgNativeType =~ /SV
      GStaticListPropertyTearOff/ or $svgNativeType =~ /SVGTransformListPropertyTearOf
      f/) { |  | 
| 519         $svgListPropertyType = $svgWrappedNativeType; |  | 
| 520         AddToHeaderIncludes("core/svg/properties/SVGAnimatedListPropertyTearOff.
      h"); |  | 
| 521     } elsif ($svgNativeType =~ /SVGPathSegListPropertyTearOff/) { |  | 
| 522         $svgListPropertyType = $svgWrappedNativeType; |  | 
| 523         AddToHeaderIncludes("core/svg/properties/SVGPathSegListPropertyTearOff.h
      "); |  | 
| 524     } |  | 
| 525 |  | 
| 526     return ($svgPropertyType, $svgListPropertyType, $svgNativeType); |  | 
| 527 } |  | 
| 528 |  | 
| 529 sub GetIndexedGetterFunction |  | 
| 530 { |  | 
| 531     my $interface = shift; |  | 
| 532 |  | 
| 533     # FIXME: Expose indexed getter of CSSMixFunctionValue by removing this speci
      al case |  | 
| 534     # because CSSValueList(which is parent of CSSMixFunctionValue) has indexed p
      roperty getter. |  | 
| 535     if ($interface->name eq "CSSMixFunctionValue") { |  | 
| 536         return 0; |  | 
| 537     } |  | 
| 538 |  | 
| 539     return GetSpecialAccessorFunctionForType($interface, "getter", "unsigned lon
      g", 1); |  | 
| 540 } |  | 
| 541 |  | 
| 542 sub GetIndexedSetterFunction |  | 
| 543 { |  | 
| 544     my $interface = shift; |  | 
| 545 |  | 
| 546     return GetSpecialAccessorFunctionForType($interface, "setter", "unsigned lon
      g", 2); |  | 
| 547 } |  | 
| 548 |  | 
| 549 sub GetIndexedDeleterFunction |  | 
| 550 { |  | 
| 551     my $interface = shift; |  | 
| 552 |  | 
| 553     return GetSpecialAccessorFunctionForType($interface, "deleter", "unsigned lo
      ng", 1); |  | 
| 554 } |  | 
| 555 |  | 
| 556 sub GetNamedGetterFunction |  | 
| 557 { |  | 
| 558     my $interface = shift; |  | 
| 559     return GetSpecialAccessorFunctionForType($interface, "getter", "DOMString", 
      1); |  | 
| 560 } |  | 
| 561 |  | 
| 562 sub GetNamedSetterFunction |  | 
| 563 { |  | 
| 564     my $interface = shift; |  | 
| 565     return GetSpecialAccessorFunctionForType($interface, "setter", "DOMString", 
      2); |  | 
| 566 } |  | 
| 567 |  | 
| 568 sub GetNamedDeleterFunction |  | 
| 569 { |  | 
| 570     my $interface = shift; |  | 
| 571     return GetSpecialAccessorFunctionForType($interface, "deleter", "DOMString",
       1); |  | 
| 572 } |  | 
| 573 |  | 
| 574 sub GetSpecialAccessorFunctionForType |  | 
| 575 { |  | 
| 576     my $interface = shift; |  | 
| 577     my $special = shift; |  | 
| 578     my $firstParameterType = shift; |  | 
| 579     my $numberOfParameters = shift; |  | 
| 580 |  | 
| 581     foreach my $function (@{$interface->functions}) { |  | 
| 582         my $specials = $function->specials; |  | 
| 583         my $specialExists = grep { $_ eq $special } @$specials; |  | 
| 584         my $parameters = $function->parameters; |  | 
| 585         if ($specialExists and scalar(@$parameters) == $numberOfParameters and $
      parameters->[0]->type eq $firstParameterType) { |  | 
| 586             return $function; |  | 
| 587         } |  | 
| 588     } |  | 
| 589 |  | 
| 590     return 0; |  | 
| 591 } |  | 
| 592 |  | 
| 593 sub GenerateHeader |  | 
| 594 { |  | 
| 595     my $object = shift; |  | 
| 596     my $interface = shift; |  | 
| 597 |  | 
| 598     my $interfaceName = $interface->name; |  | 
| 599     my $implClassName = GetImplName($interface); |  | 
| 600     my $v8ClassName = GetV8ClassName($interface); |  | 
| 601 |  | 
| 602     LinkOverloadedFunctions($interface); |  | 
| 603 |  | 
| 604     # Ensure the IsDOMNodeType function is in sync. |  | 
| 605     die("IsDOMNodeType is out of date with respect to $interfaceName") if IsDOMN
      odeType($interfaceName) != InheritsInterface($interface, "Node"); |  | 
| 606 |  | 
| 607     my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGProperty
      Types($interfaceName); |  | 
| 608 |  | 
| 609     my $parentInterface = $interface->parent; |  | 
| 610     AddToHeaderIncludes("V8${parentInterface}.h") if $parentInterface; |  | 
| 611     AddToHeaderIncludes("bindings/v8/WrapperTypeInfo.h"); |  | 
| 612     AddToHeaderIncludes("bindings/v8/V8Binding.h"); |  | 
| 613     AddToHeaderIncludes("bindings/v8/V8DOMWrapper.h"); |  | 
| 614     AddToHeaderIncludes(HeaderFilesForInterface($interfaceName, $implClassName))
      ; |  | 
| 615     foreach my $headerInclude (sort keys(%headerIncludes)) { |  | 
| 616         $header{includes}->add("#include \"${headerInclude}\"\n"); |  | 
| 617     } |  | 
| 618 |  | 
| 619     $header{nameSpaceWebCore}->addHeader("\ntemplate<typename PropertyType> clas
      s SVGPropertyTearOff;\n") if $svgPropertyType; |  | 
| 620     if ($svgNativeType) { |  | 
| 621         if ($svgNativeType =~ /SVGStaticListPropertyTearOff/) { |  | 
| 622             $header{nameSpaceWebCore}->addHeader("\ntemplate<typename PropertyTy
      pe> class SVGStaticListPropertyTearOff;\n"); |  | 
| 623         } else { |  | 
| 624             $header{nameSpaceWebCore}->addHeader("\ntemplate<typename PropertyTy
      pe> class SVGListPropertyTearOff;\n"); |  | 
| 625         } |  | 
| 626     } |  | 
| 627 |  | 
| 628     $header{nameSpaceWebCore}->addHeader("\nclass Dictionary;") if IsConstructor
      Template($interface, "Event"); |  | 
| 629 |  | 
| 630     my $nativeType = GetNativeTypeForConversions($interface); |  | 
| 631     if ($interface->extendedAttributes->{"NamedConstructor"}) { |  | 
| 632         $header{nameSpaceWebCore}->addHeader(<<END); |  | 
| 633 |  | 
| 634 class V8${nativeType}Constructor { |  | 
| 635 public: |  | 
| 636     static v8::Handle<v8::FunctionTemplate> GetTemplate(v8::Isolate*, WrapperWor
      ldType); |  | 
| 637     static WrapperTypeInfo info; |  | 
| 638 }; |  | 
| 639 END |  | 
| 640     } |  | 
| 641 |  | 
| 642     $header{class}->addHeader("class $v8ClassName {"); |  | 
| 643     $header{class}->addFooter("};"); |  | 
| 644 |  | 
| 645     $header{classPublic}->add(<<END); |  | 
| 646     static bool HasInstance(v8::Handle<v8::Value>, v8::Isolate*, WrapperWorldTyp
      e); |  | 
| 647     static bool HasInstanceInAnyWorld(v8::Handle<v8::Value>, v8::Isolate*); |  | 
| 648     static v8::Handle<v8::FunctionTemplate> GetTemplate(v8::Isolate*, WrapperWor
      ldType); |  | 
| 649     static ${nativeType}* toNative(v8::Handle<v8::Object> object) |  | 
| 650     { |  | 
| 651         return fromInternalPointer(object->GetAlignedPointerFromInternalField(v8
      DOMWrapperObjectIndex)); |  | 
| 652     } |  | 
| 653     static void derefObject(void*); |  | 
| 654     static WrapperTypeInfo info; |  | 
| 655 END |  | 
| 656 |  | 
| 657     if (NeedsOpaqueRootForGC($interface)) { |  | 
| 658         $header{classPublic}->add("    static void* opaqueRootForGC(void*, v8::I
      solate*);\n"); |  | 
| 659     } |  | 
| 660 |  | 
| 661     if (InheritsExtendedAttribute($interface, "ActiveDOMObject")) { |  | 
| 662         $header{classPublic}->add("    static ActiveDOMObject* toActiveDOMObject
      (v8::Handle<v8::Object>);\n"); |  | 
| 663     } |  | 
| 664 |  | 
| 665     if (InheritsInterface($interface, "EventTarget")) { |  | 
| 666         $header{classPublic}->add("    static EventTarget* toEventTarget(v8::Han
      dle<v8::Object>);\n"); |  | 
| 667     } |  | 
| 668 |  | 
| 669     if ($interfaceName eq "Window") { |  | 
| 670         $header{classPublic}->add(<<END); |  | 
| 671     static v8::Handle<v8::ObjectTemplate> GetShadowObjectTemplate(v8::Isolate*, 
      WrapperWorldType); |  | 
| 672 END |  | 
| 673     } |  | 
| 674 |  | 
| 675     my @enabledPerContextFunctions; |  | 
| 676     foreach my $function (@{$interface->functions}) { |  | 
| 677         my $name = $function->name; |  | 
| 678         next if $name eq ""; |  | 
| 679         my $attrExt = $function->extendedAttributes; |  | 
| 680 |  | 
| 681         if (HasCustomMethod($attrExt) && $function->{overloadIndex} == 1) { |  | 
| 682             my $conditionalString = GenerateConditionalString($function); |  | 
| 683             $header{classPublic}->add("#if ${conditionalString}\n") if $conditio
      nalString; |  | 
| 684             $header{classPublic}->add(<<END); |  | 
| 685     static void ${name}MethodCustom(const v8::FunctionCallbackInfo<v8::Value>&); |  | 
| 686 END |  | 
| 687             $header{classPublic}->add("#endif // ${conditionalString}\n") if $co
      nditionalString; |  | 
| 688         } |  | 
| 689         if ($attrExt->{"EnabledPerContext"}) { |  | 
| 690             push(@enabledPerContextFunctions, $function); |  | 
| 691         } |  | 
| 692     } |  | 
| 693 |  | 
| 694     if (IsConstructable($interface)) { |  | 
| 695         $header{classPublic}->add("    static void constructorCallback(const v8:
      :FunctionCallbackInfo<v8::Value>&);\n"); |  | 
| 696 END |  | 
| 697     } |  | 
| 698     if (HasCustomConstructor($interface)) { |  | 
| 699         $header{classPublic}->add("    static void constructorCustom(const v8::F
      unctionCallbackInfo<v8::Value>&);\n"); |  | 
| 700     } |  | 
| 701 |  | 
| 702     my @enabledPerContextAttributes; |  | 
| 703     foreach my $attribute (@{$interface->attributes}) { |  | 
| 704         my $name = $attribute->name; |  | 
| 705         my $attrExt = $attribute->extendedAttributes; |  | 
| 706         my $conditionalString = GenerateConditionalString($attribute); |  | 
| 707         if (HasCustomGetter($attrExt) && !$attrExt->{"ImplementedBy"}) { |  | 
| 708             $header{classPublic}->add("#if ${conditionalString}\n") if $conditio
      nalString; |  | 
| 709             $header{classPublic}->add(<<END); |  | 
| 710     static void ${name}AttributeGetterCustom(v8::Local<v8::String> name, const v
      8::PropertyCallbackInfo<v8::Value>&); |  | 
| 711 END |  | 
| 712             $header{classPublic}->add("#endif // ${conditionalString}\n") if $co
      nditionalString; |  | 
| 713         } |  | 
| 714         if (HasCustomSetter($attrExt) && !$attrExt->{"ImplementedBy"}) { |  | 
| 715             $header{classPublic}->add("#if ${conditionalString}\n") if $conditio
      nalString; |  | 
| 716             $header{classPublic}->add(<<END); |  | 
| 717     static void ${name}AttributeSetterCustom(v8::Local<v8::String> name, v8::Loc
      al<v8::Value>, const v8::PropertyCallbackInfo<void>&); |  | 
| 718 END |  | 
| 719             $header{classPublic}->add("#endif // ${conditionalString}\n") if $co
      nditionalString; |  | 
| 720         } |  | 
| 721         if ($attrExt->{"EnabledPerContext"}) { |  | 
| 722             push(@enabledPerContextAttributes, $attribute); |  | 
| 723         } |  | 
| 724     } |  | 
| 725 |  | 
| 726     GenerateHeaderNamedAndIndexedPropertyAccessors($interface); |  | 
| 727     GenerateHeaderLegacyCall($interface); |  | 
| 728     GenerateHeaderCustomInternalFieldIndices($interface); |  | 
| 729 |  | 
| 730     my $toWrappedType; |  | 
| 731     my $fromWrappedType; |  | 
| 732     if ($interface->parent) { |  | 
| 733         my $v8ParentClassName = "V8" . $interface->parent; |  | 
| 734         $toWrappedType = "${v8ParentClassName}::toInternalPointer(impl)"; |  | 
| 735         $fromWrappedType = "static_cast<${nativeType}*>(${v8ParentClassName}::fr
      omInternalPointer(object))"; |  | 
| 736     } else { |  | 
| 737         $toWrappedType = "impl"; |  | 
| 738         $fromWrappedType = "static_cast<${nativeType}*>(object)"; |  | 
| 739     } |  | 
| 740 |  | 
| 741     $header{classPublic}->add(<<END); |  | 
| 742     static inline void* toInternalPointer(${nativeType}* impl) |  | 
| 743     { |  | 
| 744         return $toWrappedType; |  | 
| 745     } |  | 
| 746 |  | 
| 747     static inline ${nativeType}* fromInternalPointer(void* object) |  | 
| 748     { |  | 
| 749         return $fromWrappedType; |  | 
| 750     } |  | 
| 751 END |  | 
| 752 |  | 
| 753     if ($interface->name eq "Window") { |  | 
| 754         $header{classPublic}->add(<<END); |  | 
| 755     static bool namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v
      8::Value> key, v8::AccessType, v8::Local<v8::Value> data); |  | 
| 756     static bool indexedSecurityCheckCustom(v8::Local<v8::Object> host, uint32_t 
      index, v8::AccessType, v8::Local<v8::Value> data); |  | 
| 757 END |  | 
| 758     } |  | 
| 759 |  | 
| 760     if (@enabledPerContextAttributes) { |  | 
| 761         $header{classPublic}->add(<<END); |  | 
| 762     static void installPerContextProperties(v8::Handle<v8::Object>, ${nativeType
      }*, v8::Isolate*); |  | 
| 763 END |  | 
| 764     } else { |  | 
| 765         $header{classPublic}->add(<<END); |  | 
| 766     static void installPerContextProperties(v8::Handle<v8::Object>, ${nativeType
      }*, v8::Isolate*) { } |  | 
| 767 END |  | 
| 768     } |  | 
| 769 |  | 
| 770     if (@enabledPerContextFunctions) { |  | 
| 771         $header{classPublic}->add(<<END); |  | 
| 772     static void installPerContextPrototypeProperties(v8::Handle<v8::Object>, v8:
      :Isolate*); |  | 
| 773 END |  | 
| 774     } else { |  | 
| 775         $header{classPublic}->add(<<END); |  | 
| 776     static void installPerContextPrototypeProperties(v8::Handle<v8::Object>, v8:
      :Isolate*) { } |  | 
| 777 END |  | 
| 778     } |  | 
| 779 |  | 
| 780     if ($interfaceName eq "HTMLElement") { |  | 
| 781         $header{classPublic}->add(<<END); |  | 
| 782     friend v8::Handle<v8::Object> createV8HTMLWrapper(HTMLElement*, v8::Handle<v
      8::Object> creationContext, v8::Isolate*); |  | 
| 783     friend v8::Handle<v8::Object> createV8HTMLDirectWrapper(HTMLElement*, v8::Ha
      ndle<v8::Object> creationContext, v8::Isolate*); |  | 
| 784 END |  | 
| 785     } elsif ($interfaceName eq "SVGElement") { |  | 
| 786         $header{classPublic}->add(<<END); |  | 
| 787     friend v8::Handle<v8::Object> createV8SVGWrapper(SVGElement*, v8::Handle<v8:
      :Object> creationContext, v8::Isolate*); |  | 
| 788     friend v8::Handle<v8::Object> createV8SVGDirectWrapper(SVGElement*, v8::Hand
      le<v8::Object> creationContext, v8::Isolate*); |  | 
| 789     friend v8::Handle<v8::Object> createV8SVGFallbackWrapper(SVGElement*, v8::Ha
      ndle<v8::Object> creationContext, v8::Isolate*); |  | 
| 790 END |  | 
| 791     } elsif ($interfaceName eq "HTMLUnknownElement") { |  | 
| 792         $header{classPublic}->add(<<END); |  | 
| 793     friend v8::Handle<v8::Object> createV8HTMLFallbackWrapper(HTMLUnknownElement
      *, v8::Handle<v8::Object> creationContext, v8::Isolate*); |  | 
| 794 END |  | 
| 795     } elsif ($interfaceName eq "Element") { |  | 
| 796         $header{classPublic}->add(<<END); |  | 
| 797     // This is a performance optimization hack. See V8Element::wrap. |  | 
| 798     friend v8::Handle<v8::Object> wrap(Node*, v8::Handle<v8::Object> creationCon
      text, v8::Isolate*); |  | 
| 799 END |  | 
| 800     } |  | 
| 801     $header{classPublic}->add("\n");  # blank line to separate classPrivate |  | 
| 802 |  | 
| 803     my $noToV8 = $interface->extendedAttributes->{"DoNotGenerateToV8"}; |  | 
| 804     my $noWrap = $interface->extendedAttributes->{"DoNotGenerateWrap"} || $noToV
      8; |  | 
| 805     if (!$noWrap) { |  | 
| 806         my $createWrapperArgumentType = GetPassRefPtrType($nativeType); |  | 
| 807         $header{classPrivate}->add(<<END); |  | 
| 808     friend v8::Handle<v8::Object> wrap(${nativeType}*, v8::Handle<v8::Object> cr
      eationContext, v8::Isolate*); |  | 
| 809     static v8::Handle<v8::Object> createWrapper(${createWrapperArgumentType}, v8
      ::Handle<v8::Object> creationContext, v8::Isolate*); |  | 
| 810 END |  | 
| 811     } |  | 
| 812 |  | 
| 813     $header{nameSpaceWebCore}->add(<<END); |  | 
| 814 |  | 
| 815 template<> |  | 
| 816 class WrapperTypeTraits<${nativeType} > { |  | 
| 817 public: |  | 
| 818     static WrapperTypeInfo* info() { return &${v8ClassName}::info; } |  | 
| 819 }; |  | 
| 820 END |  | 
| 821 |  | 
| 822     my $customWrap = $interface->extendedAttributes->{"CustomToV8"} || $svgNativ
      eType; |  | 
| 823     if ($noToV8) { |  | 
| 824         die "Can't suppress toV8 for subclass\n" if $interface->parent; |  | 
| 825     } elsif ($noWrap) { |  | 
| 826         die "Must have custom toV8\n" if !$customWrap; |  | 
| 827         $header{nameSpaceWebCore}->add(<<END); |  | 
| 828 class ${nativeType}; |  | 
| 829 v8::Handle<v8::Value> toV8(${nativeType}*, v8::Handle<v8::Object> creationContex
      t, v8::Isolate*); |  | 
| 830 |  | 
| 831 template<class CallbackInfo> |  | 
| 832 inline void v8SetReturnValue(const CallbackInfo& callbackInfo, ${nativeType}* im
      pl, v8::Handle<v8::Object> creationContext) |  | 
| 833 { |  | 
| 834     v8SetReturnValue(callbackInfo, toV8(impl, creationContext, callbackInfo.GetI
      solate())); |  | 
| 835 } |  | 
| 836 |  | 
| 837 template<class CallbackInfo> |  | 
| 838 inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo, ${nat
      iveType}* impl, v8::Handle<v8::Object> creationContext) |  | 
| 839 { |  | 
| 840      v8SetReturnValue(callbackInfo, toV8(impl, creationContext, callbackInfo.Get
      Isolate())); |  | 
| 841 } |  | 
| 842 |  | 
| 843 template<class CallbackInfo, class Wrappable> |  | 
| 844 inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo, ${nativeType}
      * impl, Wrappable*) |  | 
| 845 { |  | 
| 846      v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackIn
      fo.GetIsolate())); |  | 
| 847 } |  | 
| 848 |  | 
| 849 END |  | 
| 850     } else { |  | 
| 851 |  | 
| 852         my $createWrapperCall = $customWrap ? "${v8ClassName}::wrap" : "${v8Clas
      sName}::createWrapper"; |  | 
| 853 |  | 
| 854         if ($customWrap) { |  | 
| 855             $header{nameSpaceWebCore}->add(<<END); |  | 
| 856 |  | 
| 857 v8::Handle<v8::Object> wrap(${nativeType}* impl, v8::Handle<v8::Object> creation
      Context, v8::Isolate*); |  | 
| 858 END |  | 
| 859         } else { |  | 
| 860             $header{nameSpaceWebCore}->add(<<END); |  | 
| 861 |  | 
| 862 inline v8::Handle<v8::Object> wrap(${nativeType}* impl, v8::Handle<v8::Object> c
      reationContext, v8::Isolate* isolate) |  | 
| 863 { |  | 
| 864     ASSERT(impl); |  | 
| 865     ASSERT(!DOMDataStore::containsWrapper<${v8ClassName}>(impl, isolate)); |  | 
| 866     return $createWrapperCall(impl, creationContext, isolate); |  | 
| 867 } |  | 
| 868 END |  | 
| 869         } |  | 
| 870 |  | 
| 871         $header{nameSpaceWebCore}->add(<<END); |  | 
| 872 |  | 
| 873 inline v8::Handle<v8::Value> toV8(${nativeType}* impl, v8::Handle<v8::Object> cr
      eationContext, v8::Isolate* isolate) |  | 
| 874 { |  | 
| 875     if (UNLIKELY(!impl)) |  | 
| 876         return v8NullWithCheck(isolate); |  | 
| 877     v8::Handle<v8::Value> wrapper = DOMDataStore::getWrapper<${v8ClassName}>(imp
      l, isolate); |  | 
| 878     if (!wrapper.IsEmpty()) |  | 
| 879         return wrapper; |  | 
| 880     return wrap(impl, creationContext, isolate); |  | 
| 881 } |  | 
| 882 |  | 
| 883 template<typename CallbackInfo> |  | 
| 884 inline void v8SetReturnValue(const CallbackInfo& callbackInfo, ${nativeType}* im
      pl, v8::Handle<v8::Object> creationContext) |  | 
| 885 { |  | 
| 886     if (UNLIKELY(!impl)) { |  | 
| 887         v8SetReturnValueNull(callbackInfo); |  | 
| 888         return; |  | 
| 889     } |  | 
| 890     if (DOMDataStore::setReturnValueFromWrapper<${v8ClassName}>(callbackInfo.Get
      ReturnValue(), impl)) |  | 
| 891         return; |  | 
| 892     v8::Handle<v8::Object> wrapper = wrap(impl, creationContext, callbackInfo.Ge
      tIsolate()); |  | 
| 893     v8SetReturnValue(callbackInfo, wrapper); |  | 
| 894 } |  | 
| 895 |  | 
| 896 template<typename CallbackInfo> |  | 
| 897 inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo, ${nat
      iveType}* impl, v8::Handle<v8::Object> creationContext) |  | 
| 898 { |  | 
| 899     ASSERT(worldType(callbackInfo.GetIsolate()) == MainWorld); |  | 
| 900     if (UNLIKELY(!impl)) { |  | 
| 901         v8SetReturnValueNull(callbackInfo); |  | 
| 902         return; |  | 
| 903     } |  | 
| 904     if (DOMDataStore::setReturnValueFromWrapperForMainWorld<${v8ClassName}>(call
      backInfo.GetReturnValue(), impl)) |  | 
| 905         return; |  | 
| 906     v8::Handle<v8::Value> wrapper = wrap(impl, creationContext, callbackInfo.Get
      Isolate()); |  | 
| 907     v8SetReturnValue(callbackInfo, wrapper); |  | 
| 908 } |  | 
| 909 |  | 
| 910 template<class CallbackInfo, class Wrappable> |  | 
| 911 inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo, ${nativeType}
      * impl, Wrappable* wrappable) |  | 
| 912 { |  | 
| 913     if (UNLIKELY(!impl)) { |  | 
| 914         v8SetReturnValueNull(callbackInfo); |  | 
| 915         return; |  | 
| 916     } |  | 
| 917     if (DOMDataStore::setReturnValueFromWrapperFast<${v8ClassName}>(callbackInfo
      .GetReturnValue(), impl, callbackInfo.Holder(), wrappable)) |  | 
| 918         return; |  | 
| 919     v8::Handle<v8::Object> wrapper = wrap(impl, callbackInfo.Holder(), callbackI
      nfo.GetIsolate()); |  | 
| 920     v8SetReturnValue(callbackInfo, wrapper); |  | 
| 921 } |  | 
| 922 END |  | 
| 923     } |  | 
| 924 |  | 
| 925     $header{nameSpaceWebCore}->add(<<END); |  | 
| 926 |  | 
| 927 inline v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl, v8::Handle<v8
      ::Object> creationContext, v8::Isolate* isolate) |  | 
| 928 { |  | 
| 929     return toV8(impl.get(), creationContext, isolate); |  | 
| 930 } |  | 
| 931 |  | 
| 932 template<class CallbackInfo> |  | 
| 933 inline void v8SetReturnValue(const CallbackInfo& callbackInfo, PassRefPtr<${nati
      veType} > impl, v8::Handle<v8::Object> creationContext) |  | 
| 934 { |  | 
| 935     v8SetReturnValue(callbackInfo, impl.get(), creationContext); |  | 
| 936 } |  | 
| 937 |  | 
| 938 template<class CallbackInfo> |  | 
| 939 inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo, PassR
      efPtr<${nativeType} > impl, v8::Handle<v8::Object> creationContext) |  | 
| 940 { |  | 
| 941     v8SetReturnValueForMainWorld(callbackInfo, impl.get(), creationContext); |  | 
| 942 } |  | 
| 943 |  | 
| 944 template<class CallbackInfo, class Wrappable> |  | 
| 945 inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo, PassRefPtr<${
      nativeType} > impl, Wrappable* wrappable) |  | 
| 946 { |  | 
| 947     v8SetReturnValueFast(callbackInfo, impl.get(), wrappable); |  | 
| 948 } |  | 
| 949 |  | 
| 950 END |  | 
| 951 |  | 
| 952     if (IsConstructorTemplate($interface, "Event")) { |  | 
| 953         $header{nameSpaceWebCore}->add("bool fill${implClassName}Init(${implClas
      sName}Init&, const Dictionary&);\n\n"); |  | 
| 954     } |  | 
| 955 } |  | 
| 956 |  | 
| 957 sub GetInternalFields |  | 
| 958 { |  | 
| 959     my $interface = shift; |  | 
| 960 |  | 
| 961     my @customInternalFields = (); |  | 
| 962     # Event listeners on DOM nodes are explicitly supported in the GC controller
      . |  | 
| 963     if (!InheritsInterface($interface, "Node") && |  | 
| 964         InheritsInterface($interface, "EventTarget")) { |  | 
| 965         push(@customInternalFields, "eventListenerCacheIndex"); |  | 
| 966     } |  | 
| 967     return @customInternalFields; |  | 
| 968 } |  | 
| 969 |  | 
| 970 sub GenerateHeaderCustomInternalFieldIndices |  | 
| 971 { |  | 
| 972     my $interface = shift; |  | 
| 973     my @customInternalFields = GetInternalFields($interface); |  | 
| 974     my $customFieldCounter = 0; |  | 
| 975     foreach my $customInternalField (@customInternalFields) { |  | 
| 976         $header{classPublic}->add(<<END); |  | 
| 977     static const int ${customInternalField} = v8DefaultWrapperInternalFieldCount
       + ${customFieldCounter}; |  | 
| 978 END |  | 
| 979         $customFieldCounter++; |  | 
| 980     } |  | 
| 981     $header{classPublic}->add(<<END); |  | 
| 982     static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + $
      {customFieldCounter}; |  | 
| 983 END |  | 
| 984 } |  | 
| 985 |  | 
| 986 sub GenerateHeaderNamedAndIndexedPropertyAccessors |  | 
| 987 { |  | 
| 988     my $interface = shift; |  | 
| 989 |  | 
| 990     my $indexedGetterFunction = GetIndexedGetterFunction($interface); |  | 
| 991     my $hasCustomIndexedGetter = $indexedGetterFunction && $indexedGetterFunctio
      n->extendedAttributes->{"Custom"}; |  | 
| 992 |  | 
| 993     my $indexedSetterFunction = GetIndexedSetterFunction($interface); |  | 
| 994     my $hasCustomIndexedSetter = $indexedSetterFunction && $indexedSetterFunctio
      n->extendedAttributes->{"Custom"}; |  | 
| 995 |  | 
| 996     my $indexedDeleterFunction = GetIndexedDeleterFunction($interface); |  | 
| 997     my $hasCustomIndexedDeleters = $indexedDeleterFunction && $indexedDeleterFun
      ction->extendedAttributes->{"Custom"}; |  | 
| 998 |  | 
| 999     my $namedGetterFunction = GetNamedGetterFunction($interface); |  | 
| 1000     my $hasCustomNamedGetter = $namedGetterFunction && $namedGetterFunction->ext
      endedAttributes->{"Custom"}; |  | 
| 1001 |  | 
| 1002     my $namedSetterFunction = GetNamedSetterFunction($interface); |  | 
| 1003     my $hasCustomNamedSetter = $namedSetterFunction && $namedSetterFunction->ext
      endedAttributes->{"Custom"}; |  | 
| 1004 |  | 
| 1005     my $namedDeleterFunction = GetNamedDeleterFunction($interface); |  | 
| 1006     my $hasCustomNamedDeleter = $namedDeleterFunction && $namedDeleterFunction->
      extendedAttributes->{"Custom"}; |  | 
| 1007 |  | 
| 1008     my $namedEnumeratorFunction = $namedGetterFunction && !$namedGetterFunction-
      >extendedAttributes->{"NotEnumerable"}; |  | 
| 1009     my $hasCustomNamedEnumerator = $namedGetterFunction && $namedGetterFunction-
      >extendedAttributes->{"CustomEnumerateProperty"}; |  | 
| 1010 |  | 
| 1011     if ($hasCustomIndexedGetter) { |  | 
| 1012         $header{classPublic}->add("    static void indexedPropertyGetterCustom(u
      int32_t, const v8::PropertyCallbackInfo<v8::Value>&);\n"); |  | 
| 1013     } |  | 
| 1014 |  | 
| 1015     if ($hasCustomIndexedSetter) { |  | 
| 1016         $header{classPublic}->add("    static void indexedPropertySetterCustom(u
      int32_t, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Value>&);\n"); |  | 
| 1017     } |  | 
| 1018 |  | 
| 1019     if ($hasCustomIndexedDeleters) { |  | 
| 1020         $header{classPublic}->add("    static void indexedPropertyDeleterCustom(
      uint32_t, const v8::PropertyCallbackInfo<v8::Boolean>&);\n"); |  | 
| 1021     } |  | 
| 1022 |  | 
| 1023     if ($hasCustomNamedGetter) { |  | 
| 1024         $header{classPublic}->add("    static void namedPropertyGetterCustom(v8:
      :Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>&);\n"); |  | 
| 1025     } |  | 
| 1026 |  | 
| 1027     if ($hasCustomNamedSetter) { |  | 
| 1028         $header{classPublic}->add("    static void namedPropertySetterCustom(v8:
      :Local<v8::String>, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Val
      ue>&);\n"); |  | 
| 1029     } |  | 
| 1030 |  | 
| 1031     if ($hasCustomNamedDeleter) { |  | 
| 1032         $header{classPublic}->add("    static void namedPropertyDeleterCustom(v8
      ::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Boolean>&);\n"); |  | 
| 1033     } |  | 
| 1034 |  | 
| 1035     if ($hasCustomNamedEnumerator) { |  | 
| 1036         $header{classPublic}->add("    static void namedPropertyEnumeratorCustom
      (const v8::PropertyCallbackInfo<v8::Array>&);\n"); |  | 
| 1037         $header{classPublic}->add("    static void namedPropertyQueryCustom(v8::
      Local<v8::String>, const v8::PropertyCallbackInfo<v8::Integer>&);\n"); |  | 
| 1038     } |  | 
| 1039 } |  | 
| 1040 |  | 
| 1041 sub GenerateHeaderLegacyCall |  | 
| 1042 { |  | 
| 1043     my $interface = shift; |  | 
| 1044 |  | 
| 1045     if ($interface->extendedAttributes->{"CustomLegacyCall"}) { |  | 
| 1046         $header{classPublic}->add("    static void legacyCallCustom(const v8::Fu
      nctionCallbackInfo<v8::Value>&);\n"); |  | 
| 1047     } |  | 
| 1048 } |  | 
| 1049 |  | 
| 1050 sub HasActivityLogging |  | 
| 1051 { |  | 
| 1052     my $forMainWorldSuffix = shift; |  | 
| 1053     my $attrExt = shift; |  | 
| 1054     my $access = shift; |  | 
| 1055 |  | 
| 1056     if (!$attrExt->{"ActivityLog"}) { |  | 
| 1057         return 0; |  | 
| 1058     } |  | 
| 1059     my $logAllAccess = ($attrExt->{"ActivityLog"} =~ /^Access/); |  | 
| 1060     my $logGetter = ($attrExt->{"ActivityLog"} =~ /^Getter/); |  | 
| 1061     my $logSetter = ($attrExt->{"ActivityLog"} =~ /^Setter/); |  | 
| 1062     my $logOnlyIsolatedWorlds = ($attrExt->{"ActivityLog"} =~ /ForIsolatedWorlds
      $/); |  | 
| 1063 |  | 
| 1064     if ($logOnlyIsolatedWorlds && $forMainWorldSuffix eq "ForMainWorld") { |  | 
| 1065         return 0; |  | 
| 1066     } |  | 
| 1067     return $logAllAccess || ($logGetter && $access eq "Getter") || ($logSetter &
      & $access eq "Setter"); |  | 
| 1068 } |  | 
| 1069 |  | 
| 1070 sub IsConstructable |  | 
| 1071 { |  | 
| 1072     my $interface = shift; |  | 
| 1073 |  | 
| 1074     return $interface->extendedAttributes->{"CustomConstructor"} || $interface->
      extendedAttributes->{"Constructor"} || $interface->extendedAttributes->{"Constru
      ctorTemplate"}; |  | 
| 1075 } |  | 
| 1076 |  | 
| 1077 sub HasCustomConstructor |  | 
| 1078 { |  | 
| 1079     my $interface = shift; |  | 
| 1080 |  | 
| 1081     return $interface->extendedAttributes->{"CustomConstructor"}; |  | 
| 1082 } |  | 
| 1083 |  | 
| 1084 sub HasCustomGetter |  | 
| 1085 { |  | 
| 1086     my $attrExt = shift; |  | 
| 1087     return $attrExt->{"Custom"} || $attrExt->{"CustomGetter"}; |  | 
| 1088 } |  | 
| 1089 |  | 
| 1090 sub HasCustomSetter |  | 
| 1091 { |  | 
| 1092     my $attrExt = shift; |  | 
| 1093     return $attrExt->{"Custom"} || $attrExt->{"CustomSetter"}; |  | 
| 1094 } |  | 
| 1095 |  | 
| 1096 sub HasCustomMethod |  | 
| 1097 { |  | 
| 1098     my $attrExt = shift; |  | 
| 1099     return $attrExt->{"Custom"}; |  | 
| 1100 } |  | 
| 1101 |  | 
| 1102 sub IsReadonly |  | 
| 1103 { |  | 
| 1104     my $attribute = shift; |  | 
| 1105     my $attrExt = $attribute->extendedAttributes; |  | 
| 1106     return $attribute->isReadOnly && !$attrExt->{"Replaceable"}; |  | 
| 1107 } |  | 
| 1108 |  | 
| 1109 sub GetV8ClassName |  | 
| 1110 { |  | 
| 1111     my $interface = shift; |  | 
| 1112     return "V8" . $interface->name; |  | 
| 1113 } |  | 
| 1114 |  | 
| 1115 sub GetImplName |  | 
| 1116 { |  | 
| 1117     my $interfaceOrAttributeOrFunction = shift; |  | 
| 1118     return $interfaceOrAttributeOrFunction->extendedAttributes->{"ImplementedAs"
      } || $interfaceOrAttributeOrFunction->name; |  | 
| 1119 } |  | 
| 1120 |  | 
| 1121 sub GetImplNameFromImplementedBy |  | 
| 1122 { |  | 
| 1123     my $implementedBy = shift; |  | 
| 1124 |  | 
| 1125     my $interface = ParseInterface($implementedBy); |  | 
| 1126 |  | 
| 1127     return $interface->extendedAttributes->{"ImplementedAs"} || $implementedBy; |  | 
| 1128 } |  | 
| 1129 |  | 
| 1130 sub GenerateDomainSafeFunctionGetter |  | 
| 1131 { |  | 
| 1132     my $function = shift; |  | 
| 1133     my $interface = shift; |  | 
| 1134 |  | 
| 1135     my $implClassName = GetImplName($interface); |  | 
| 1136     my $v8ClassName = GetV8ClassName($interface); |  | 
| 1137     my $funcName = $function->name; |  | 
| 1138 |  | 
| 1139     my $functionLength = GetFunctionLength($function); |  | 
| 1140     my $signature = "v8::Signature::New(V8PerIsolateData::from(info.GetIsolate()
      )->rawTemplate(&" . $v8ClassName . "::info, currentWorldType))"; |  | 
| 1141     if ($function->extendedAttributes->{"DoNotCheckSignature"}) { |  | 
| 1142         $signature = "v8::Local<v8::Signature>()"; |  | 
| 1143     } |  | 
| 1144 |  | 
| 1145     my $newTemplateParams = "${implClassName}V8Internal::${funcName}MethodCallba
      ck, v8Undefined(), $signature"; |  | 
| 1146 |  | 
| 1147     AddToImplIncludes("bindings/v8/BindingSecurity.h"); |  | 
| 1148     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 1149 static void ${funcName}AttributeGetter(v8::Local<v8::String> name, const v8::Pro
      pertyCallbackInfo<v8::Value>& info) |  | 
| 1150 { |  | 
| 1151     // This is only for getting a unique pointer which we can pass to privateTem
      plate. |  | 
| 1152     static const char* privateTemplateUniqueKey = "${funcName}PrivateTemplate"; |  | 
| 1153     WrapperWorldType currentWorldType = worldType(info.GetIsolate()); |  | 
| 1154     V8PerIsolateData* data = V8PerIsolateData::from(info.GetIsolate()); |  | 
| 1155     v8::Handle<v8::FunctionTemplate> privateTemplate = data->privateTemplate(cur
      rentWorldType, &privateTemplateUniqueKey, $newTemplateParams, $functionLength); |  | 
| 1156 |  | 
| 1157     v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(${
      v8ClassName}::GetTemplate(info.GetIsolate(), currentWorldType)); |  | 
| 1158     if (holder.IsEmpty()) { |  | 
| 1159         // can only reach here by 'object.__proto__.func', and it should passed |  | 
| 1160         // domain security check already |  | 
| 1161         v8SetReturnValue(info, privateTemplate->GetFunction()); |  | 
| 1162         return; |  | 
| 1163     } |  | 
| 1164     ${implClassName}* imp = ${v8ClassName}::toNative(holder); |  | 
| 1165     if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame(), DoNotReportSecu
      rityError)) { |  | 
| 1166         static const char* sharedTemplateUniqueKey = "${funcName}SharedTemplate"
      ; |  | 
| 1167         v8::Handle<v8::FunctionTemplate> sharedTemplate = data->privateTemplate(
      currentWorldType, &sharedTemplateUniqueKey, $newTemplateParams, $functionLength)
      ; |  | 
| 1168         v8SetReturnValue(info, sharedTemplate->GetFunction()); |  | 
| 1169         return; |  | 
| 1170     } |  | 
| 1171 |  | 
| 1172     v8::Local<v8::Value> hiddenValue = info.This()->GetHiddenValue(name); |  | 
| 1173     if (!hiddenValue.IsEmpty()) { |  | 
| 1174         v8SetReturnValue(info, hiddenValue); |  | 
| 1175         return; |  | 
| 1176     } |  | 
| 1177 |  | 
| 1178     v8SetReturnValue(info, privateTemplate->GetFunction()); |  | 
| 1179 } |  | 
| 1180 |  | 
| 1181 END |  | 
| 1182     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 1183 static void ${funcName}AttributeGetterCallback(v8::Local<v8::String> name, const
       v8::PropertyCallbackInfo<v8::Value>& info) |  | 
| 1184 { |  | 
| 1185     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMGetter"); |  | 
| 1186     ${implClassName}V8Internal::${funcName}AttributeGetter(name, info); |  | 
| 1187     TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution"); |  | 
| 1188 } |  | 
| 1189 |  | 
| 1190 END |  | 
| 1191 } |  | 
| 1192 |  | 
| 1193 sub GenerateDomainSafeFunctionSetter |  | 
| 1194 { |  | 
| 1195     my $interface = shift; |  | 
| 1196 |  | 
| 1197     my $implClassName = GetImplName($interface); |  | 
| 1198     my $v8ClassName = GetV8ClassName($interface); |  | 
| 1199 |  | 
| 1200     AddToImplIncludes("bindings/v8/BindingSecurity.h"); |  | 
| 1201     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 1202 static void ${implClassName}DomainSafeFunctionSetter(v8::Local<v8::String> name,
       v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info) |  | 
| 1203 { |  | 
| 1204     v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(${
      v8ClassName}::GetTemplate(info.GetIsolate(), worldType(info.GetIsolate()))); |  | 
| 1205     if (holder.IsEmpty()) |  | 
| 1206         return; |  | 
| 1207     ${implClassName}* imp = ${v8ClassName}::toNative(holder); |  | 
| 1208     if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame())) |  | 
| 1209         return; |  | 
| 1210 |  | 
| 1211     info.This()->SetHiddenValue(name, value); |  | 
| 1212 } |  | 
| 1213 |  | 
| 1214 END |  | 
| 1215 } |  | 
| 1216 |  | 
| 1217 sub GenerateConstructorGetter |  | 
| 1218 { |  | 
| 1219     my $interface = shift; |  | 
| 1220     my $implClassName = GetImplName($interface); |  | 
| 1221 |  | 
| 1222     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 1223 static void ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const 
      v8::PropertyCallbackInfo<v8::Value>& info) |  | 
| 1224 { |  | 
| 1225     v8::Handle<v8::Value> data = info.Data(); |  | 
| 1226     ASSERT(data->IsExternal()); |  | 
| 1227     V8PerContextData* perContextData = V8PerContextData::from(info.Holder()->Cre
      ationContext()); |  | 
| 1228     if (!perContextData) |  | 
| 1229         return; |  | 
| 1230     v8SetReturnValue(info, perContextData->constructorForType(WrapperTypeInfo::u
      nwrap(data))); |  | 
| 1231 } |  | 
| 1232 END |  | 
| 1233 } |  | 
| 1234 |  | 
| 1235 sub GenerateFeatureObservation |  | 
| 1236 { |  | 
| 1237     my $measureAs = shift; |  | 
| 1238 |  | 
| 1239     if ($measureAs) { |  | 
| 1240         AddToImplIncludes("core/page/UseCounter.h"); |  | 
| 1241         return "    UseCounter::count(activeDOMWindow(), UseCounter::${measureAs
      });\n"; |  | 
| 1242     } |  | 
| 1243 |  | 
| 1244     return ""; |  | 
| 1245 } |  | 
| 1246 |  | 
| 1247 sub GenerateDeprecationNotification |  | 
| 1248 { |  | 
| 1249     my $deprecateAs = shift; |  | 
| 1250     if ($deprecateAs) { |  | 
| 1251         AddToImplIncludes("core/page/PageConsole.h"); |  | 
| 1252         AddToImplIncludes("core/page/UseCounter.h"); |  | 
| 1253         return "    UseCounter::countDeprecation(activeScriptExecutionContext(),
       UseCounter::${deprecateAs});\n"; |  | 
| 1254     } |  | 
| 1255     return ""; |  | 
| 1256 } |  | 
| 1257 |  | 
| 1258 sub GenerateActivityLogging |  | 
| 1259 { |  | 
| 1260     my $accessType = shift; |  | 
| 1261     my $interface = shift; |  | 
| 1262     my $propertyName = shift; |  | 
| 1263 |  | 
| 1264     my $interfaceName = $interface->name; |  | 
| 1265 |  | 
| 1266     AddToImplIncludes("bindings/v8/V8Binding.h"); |  | 
| 1267     AddToImplIncludes("bindings/v8/V8DOMActivityLogger.h"); |  | 
| 1268     AddToImplIncludes("wtf/Vector.h"); |  | 
| 1269 |  | 
| 1270     my $code = ""; |  | 
| 1271     if ($accessType eq "Method") { |  | 
| 1272         $code .= <<END; |  | 
| 1273     V8PerContextData* contextData = V8PerContextData::from(args.GetIsolate()->Ge
      tCurrentContext()); |  | 
| 1274     if (contextData && contextData->activityLogger()) { |  | 
| 1275         Vector<v8::Handle<v8::Value> > loggerArgs = toVectorOfArguments(args); |  | 
| 1276         contextData->activityLogger()->log("${interfaceName}.${propertyName}", a
      rgs.Length(), loggerArgs.data(), "${accessType}"); |  | 
| 1277     } |  | 
| 1278 END |  | 
| 1279     } elsif ($accessType eq "Setter") { |  | 
| 1280         $code .= <<END; |  | 
| 1281     V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->Ge
      tCurrentContext()); |  | 
| 1282     if (contextData && contextData->activityLogger()) { |  | 
| 1283         v8::Handle<v8::Value> loggerArg[] = { value }; |  | 
| 1284         contextData->activityLogger()->log("${interfaceName}.${propertyName}", 1
      , &loggerArg[0], "${accessType}"); |  | 
| 1285     } |  | 
| 1286 END |  | 
| 1287     } elsif ($accessType eq "Getter") { |  | 
| 1288         $code .= <<END; |  | 
| 1289     V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->Ge
      tCurrentContext()); |  | 
| 1290     if (contextData && contextData->activityLogger()) |  | 
| 1291         contextData->activityLogger()->log("${interfaceName}.${propertyName}", 0
      , 0, "${accessType}"); |  | 
| 1292 END |  | 
| 1293     } else { |  | 
| 1294         die "Unrecognized activity logging access type"; |  | 
| 1295     } |  | 
| 1296 |  | 
| 1297     return $code; |  | 
| 1298 } |  | 
| 1299 |  | 
| 1300 sub GenerateNormalAttributeGetterCallback |  | 
| 1301 { |  | 
| 1302     my $attribute = shift; |  | 
| 1303     my $interface = shift; |  | 
| 1304     my $forMainWorldSuffix = shift; |  | 
| 1305 |  | 
| 1306     my $implClassName = GetImplName($interface); |  | 
| 1307     my $v8ClassName = GetV8ClassName($interface); |  | 
| 1308     my $attrExt = $attribute->extendedAttributes; |  | 
| 1309     my $attrName = $attribute->name; |  | 
| 1310 |  | 
| 1311     my $conditionalString = GenerateConditionalString($attribute); |  | 
| 1312     my $code = ""; |  | 
| 1313     $code .= "#if ${conditionalString}\n\n" if $conditionalString; |  | 
| 1314 |  | 
| 1315     $code .= "static void ${attrName}AttributeGetterCallback${forMainWorldSuffix
      }(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)\n
      "; |  | 
| 1316     $code .= "{\n"; |  | 
| 1317     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMGetter\");\n"; |  | 
| 1318     $code .= GenerateFeatureObservation($attrExt->{"MeasureAs"}); |  | 
| 1319     $code .= GenerateDeprecationNotification($attrExt->{"DeprecateAs"}); |  | 
| 1320     if (HasActivityLogging($forMainWorldSuffix, $attrExt, "Getter")) { |  | 
| 1321         $code .= GenerateActivityLogging("Getter", $interface, "${attrName}"); |  | 
| 1322     } |  | 
| 1323     if (HasCustomGetter($attrExt)) { |  | 
| 1324         $code .= "    ${v8ClassName}::${attrName}AttributeGetterCustom(name, inf
      o);\n"; |  | 
| 1325     } else { |  | 
| 1326         $code .= "    ${implClassName}V8Internal::${attrName}AttributeGetter${fo
      rMainWorldSuffix}(name, info);\n"; |  | 
| 1327     } |  | 
| 1328     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |  | 
| 1329     $code .= "}\n\n"; |  | 
| 1330     $code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |  | 
| 1331 |  | 
| 1332     $implementation{nameSpaceInternal}->add($code); |  | 
| 1333 } |  | 
| 1334 |  | 
| 1335 sub GetCachedAttribute |  | 
| 1336 { |  | 
| 1337     my $attribute = shift; |  | 
| 1338     my $attrExt = $attribute->extendedAttributes; |  | 
| 1339     if (($attribute->type eq "any" || $attribute->type eq "SerializedScriptValue
      ") && $attrExt->{"CachedAttribute"}) { |  | 
| 1340         return $attrExt->{"CachedAttribute"}; |  | 
| 1341     } |  | 
| 1342     return ""; |  | 
| 1343 } |  | 
| 1344 |  | 
| 1345 sub GenerateNormalAttributeGetter |  | 
| 1346 { |  | 
| 1347     my $attribute = shift; |  | 
| 1348     my $interface = shift; |  | 
| 1349     my $forMainWorldSuffix = shift; |  | 
| 1350 |  | 
| 1351     my $interfaceName = $interface->name; |  | 
| 1352     my $implClassName = GetImplName($interface); |  | 
| 1353     my $v8ClassName = GetV8ClassName($interface); |  | 
| 1354     my $attrExt = $attribute->extendedAttributes; |  | 
| 1355     my $attrName = $attribute->name; |  | 
| 1356     my $attrType = $attribute->type; |  | 
| 1357     my $attrCached = GetCachedAttribute($attribute); |  | 
| 1358 |  | 
| 1359     if (HasCustomGetter($attrExt)) { |  | 
| 1360         return; |  | 
| 1361     } |  | 
| 1362 |  | 
| 1363     AssertNotSequenceType($attrType); |  | 
| 1364     my $nativeType = GetNativeType($attribute->type, $attribute->extendedAttribu
      tes, ""); |  | 
| 1365     my $svgNativeType = GetSVGTypeNeedingTearOff($interfaceName); |  | 
| 1366 |  | 
| 1367     my $conditionalString = GenerateConditionalString($attribute); |  | 
| 1368     my $code = ""; |  | 
| 1369     $code .= "#if ${conditionalString}\n\n" if $conditionalString; |  | 
| 1370     $code .= <<END; |  | 
| 1371 static void ${attrName}AttributeGetter${forMainWorldSuffix}(v8::Local<v8::String
      > name, const v8::PropertyCallbackInfo<v8::Value>& info) |  | 
| 1372 { |  | 
| 1373 END |  | 
| 1374     if ($svgNativeType) { |  | 
| 1375         my $svgWrappedNativeType = GetSVGWrappedTypeNeedingTearOff($interfaceNam
      e); |  | 
| 1376         if ($svgWrappedNativeType =~ /List/) { |  | 
| 1377             $code .= <<END; |  | 
| 1378     $svgNativeType* imp = ${v8ClassName}::toNative(info.Holder()); |  | 
| 1379 END |  | 
| 1380         } else { |  | 
| 1381             $code .= <<END; |  | 
| 1382     $svgNativeType* wrapper = ${v8ClassName}::toNative(info.Holder()); |  | 
| 1383     $svgWrappedNativeType& impInstance = wrapper->propertyReference(); |  | 
| 1384     $svgWrappedNativeType* imp = &impInstance; |  | 
| 1385 END |  | 
| 1386         } |  | 
| 1387     } elsif ($attrExt->{"OnProto"} || $attrExt->{"Unforgeable"}) { |  | 
| 1388         if ($interfaceName eq "Window") { |  | 
| 1389             $code .= <<END; |  | 
| 1390     v8::Handle<v8::Object> holder = info.Holder(); |  | 
| 1391 END |  | 
| 1392         } else { |  | 
| 1393             # perform lookup first |  | 
| 1394             $code .= <<END; |  | 
| 1395     v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(${
      v8ClassName}::GetTemplate(info.GetIsolate(), worldType(info.GetIsolate()))); |  | 
| 1396     if (holder.IsEmpty()) |  | 
| 1397         return; |  | 
| 1398 END |  | 
| 1399         } |  | 
| 1400         $code .= <<END; |  | 
| 1401     ${implClassName}* imp = ${v8ClassName}::toNative(holder); |  | 
| 1402 END |  | 
| 1403     } else { |  | 
| 1404         my $reflect = $attribute->extendedAttributes->{"Reflect"}; |  | 
| 1405         my $url = $attribute->extendedAttributes->{"URL"}; |  | 
| 1406         if ($reflect && !$url && InheritsInterface($interface, "Node") && $attrT
      ype eq "DOMString") { |  | 
| 1407             # Generate super-compact call for regular attribute getter: |  | 
| 1408             my ($functionName, @arguments) = GetterExpression($interfaceName, $a
      ttribute); |  | 
| 1409             $code .= "    Element* imp = V8Element::toNative(info.Holder());\n"; |  | 
| 1410             $code .= "    v8SetReturnValueString(info, imp->${functionName}(" . 
      join(", ", @arguments) . "), info.GetIsolate());\n"; |  | 
| 1411             $code .= "    return;\n"; |  | 
| 1412             $code .= "}\n\n"; |  | 
| 1413             $code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |  | 
| 1414             $implementation{nameSpaceInternal}->add($code); |  | 
| 1415             return; |  | 
| 1416             # Skip the rest of the function! |  | 
| 1417         } |  | 
| 1418         my $imp = 0; |  | 
| 1419         if ($attrCached) { |  | 
| 1420             $imp = 1; |  | 
| 1421             $code .= <<END; |  | 
| 1422     v8::Handle<v8::String> propertyName = v8::String::NewSymbol("${attrName}"); |  | 
| 1423     v8::Handle<v8::Value> value; |  | 
| 1424     ${implClassName}* imp = ${v8ClassName}::toNative(info.Holder()); |  | 
| 1425     if (!imp->$attrCached()) { |  | 
| 1426         value = info.Holder()->GetHiddenValue(propertyName); |  | 
| 1427         if (!value.IsEmpty()) { |  | 
| 1428             v8SetReturnValue(info, value); |  | 
| 1429             return; |  | 
| 1430         } |  | 
| 1431     } |  | 
| 1432 END |  | 
| 1433         } |  | 
| 1434         if (!$attribute->isStatic && !$imp) { |  | 
| 1435             $code .= <<END; |  | 
| 1436     ${implClassName}* imp = ${v8ClassName}::toNative(info.Holder()); |  | 
| 1437 END |  | 
| 1438         } |  | 
| 1439     } |  | 
| 1440 |  | 
| 1441     # Generate security checks if necessary |  | 
| 1442     if ($attribute->extendedAttributes->{"CheckSecurityForNode"}) { |  | 
| 1443         AddToImplIncludes("bindings/v8/BindingSecurity.h"); |  | 
| 1444         $code .= "    if (!BindingSecurity::shouldAllowAccessToNode(imp->" . Get
      ImplName($attribute) . "())) {\n"; |  | 
| 1445         $code .= "        v8SetReturnValueNull(info);\n"; |  | 
| 1446         $code .= "        return;\n"; |  | 
| 1447         $code .= "    }\n"; |  | 
| 1448     } |  | 
| 1449 |  | 
| 1450     my $useExceptions = 1 if $attribute->extendedAttributes->{"GetterRaisesExcep
      tion"} ||  $attribute->extendedAttributes->{"RaisesException"}; |  | 
| 1451     my $isNullable = $attribute->isNullable; |  | 
| 1452     if ($useExceptions) { |  | 
| 1453         AddToImplIncludes("bindings/v8/ExceptionMessages.h"); |  | 
| 1454         AddToImplIncludes("bindings/v8/ExceptionState.h"); |  | 
| 1455         $code .= "    ExceptionState es(info.GetIsolate());\n"; |  | 
| 1456     } |  | 
| 1457 |  | 
| 1458     if ($isNullable) { |  | 
| 1459         $code .= "    bool isNull = false;\n"; |  | 
| 1460     } |  | 
| 1461 |  | 
| 1462     my $returnType = $attribute->type; |  | 
| 1463     my $getterString; |  | 
| 1464 |  | 
| 1465     my ($functionName, @arguments) = GetterExpression($interfaceName, $attribute
      ); |  | 
| 1466     push(@arguments, "isNull") if $isNullable; |  | 
| 1467     push(@arguments, "es") if $useExceptions; |  | 
| 1468     if ($attribute->extendedAttributes->{"ImplementedBy"}) { |  | 
| 1469         my $implementedBy = $attribute->extendedAttributes->{"ImplementedBy"}; |  | 
| 1470         my $implementedByImplName = GetImplNameFromImplementedBy($implementedBy)
      ; |  | 
| 1471         AddToImplIncludes(HeaderFilesForInterface($implementedBy, $implementedBy
      ImplName)); |  | 
| 1472         unshift(@arguments, "imp") if !$attribute->isStatic; |  | 
| 1473         $functionName = "${implementedByImplName}::${functionName}"; |  | 
| 1474     } elsif ($attribute->isStatic) { |  | 
| 1475         $functionName = "${implClassName}::${functionName}"; |  | 
| 1476     } else { |  | 
| 1477         $functionName = "imp->${functionName}"; |  | 
| 1478     } |  | 
| 1479     my ($arg, $subCode) = GenerateCallWith($attribute->extendedAttributes->{"Cal
      lWith"}, "    ", 0); |  | 
| 1480     $code .= $subCode; |  | 
| 1481     unshift(@arguments, @$arg); |  | 
| 1482     $getterString = "${functionName}(" . join(", ", @arguments) . ")"; |  | 
| 1483 |  | 
| 1484     my $expression; |  | 
| 1485     if ($attribute->type eq "EventHandler" && $interface->name eq "Window") { |  | 
| 1486         $code .= "    if (!imp->document())\n"; |  | 
| 1487         $code .= "        return;\n"; |  | 
| 1488     } |  | 
| 1489 |  | 
| 1490     if ($useExceptions || $isNullable) { |  | 
| 1491         if ($nativeType =~ /^V8StringResource/) { |  | 
| 1492             $code .= "    " . ConvertToV8StringResource($attribute, $nativeType,
       "v", $getterString) . ";\n"; |  | 
| 1493         } else { |  | 
| 1494             $code .= "    $nativeType v = $getterString;\n"; |  | 
| 1495         } |  | 
| 1496 |  | 
| 1497         if ($isNullable) { |  | 
| 1498             $code .= "    if (isNull) {\n"; |  | 
| 1499             $code .= "        v8SetReturnValueNull(info);\n"; |  | 
| 1500             $code .= "        return;\n"; |  | 
| 1501             $code .= "    }\n"; |  | 
| 1502         } |  | 
| 1503 |  | 
| 1504         if ($useExceptions) { |  | 
| 1505             if ($useExceptions) { |  | 
| 1506                 $code .= "    if (UNLIKELY(es.throwIfNeeded()))\n"; |  | 
| 1507                 $code .= "        return;\n"; |  | 
| 1508             } |  | 
| 1509 |  | 
| 1510             if (ExtendedAttributeContains($attribute->extendedAttributes->{"Call
      With"}, "ScriptState")) { |  | 
| 1511                 $code .= "    if (state.hadException()) {\n"; |  | 
| 1512                 $code .= "        throwError(state.exception(), info.GetIsolate(
      ));\n"; |  | 
| 1513                 $code .= "        return;\n"; |  | 
| 1514                 $code .= "    }\n"; |  | 
| 1515             } |  | 
| 1516         } |  | 
| 1517 |  | 
| 1518         $expression = "v"; |  | 
| 1519         $expression .= ".release()" if (IsRefPtrType($returnType)); |  | 
| 1520     } else { |  | 
| 1521         # Can inline the function call into the return statement to avoid overhe
      ad of using a Ref<> temporary |  | 
| 1522         $expression = $getterString; |  | 
| 1523         # Fix amigious conversion problem, by casting to the base type first ($g
      etterString returns a type that inherits from SVGAnimatedEnumeration, not the ba
      se class directly). |  | 
| 1524         $expression = "static_pointer_cast<SVGAnimatedEnumeration>($expression)"
       if $returnType eq "SVGAnimatedEnumeration"; |  | 
| 1525     } |  | 
| 1526 |  | 
| 1527     if (ShouldKeepAttributeAlive($interface, $attribute, $returnType)) { |  | 
| 1528         my $arrayType = GetArrayType($returnType); |  | 
| 1529         if ($arrayType) { |  | 
| 1530             AddIncludeForType("V8$arrayType.h"); |  | 
| 1531             $code .= "    v8SetReturnValue(info, v8Array(${getterString}, info.G
      etIsolate()));\n"; |  | 
| 1532             $code .= "    return;\n"; |  | 
| 1533             $code .= "}\n\n"; |  | 
| 1534             $implementation{nameSpaceInternal}->add($code); |  | 
| 1535             return; |  | 
| 1536         } |  | 
| 1537 |  | 
| 1538         AddIncludesForType($returnType); |  | 
| 1539         AddToImplIncludes("bindings/v8/V8HiddenPropertyName.h"); |  | 
| 1540         # Check for a wrapper in the wrapper cache. If there is one, we know tha
      t a hidden reference has already |  | 
| 1541         # been created. If we don't find a wrapper, we create both a wrapper and
       a hidden reference. |  | 
| 1542         my $nativeReturnType = GetNativeType($returnType); |  | 
| 1543         my $v8ReturnType = "V8" . $returnType; |  | 
| 1544         $code .= "    $nativeReturnType result = ${getterString};\n"; |  | 
| 1545         if ($forMainWorldSuffix) { |  | 
| 1546             $code .= "    if (result.get() && DOMDataStore::setReturnValueFromWr
      apper${forMainWorldSuffix}<${v8ReturnType}>(info.GetReturnValue(), result.get())
      )\n"; |  | 
| 1547         } else { |  | 
| 1548             $code .= "    if (result.get() && DOMDataStore::setReturnValueFromWr
      apper<${v8ReturnType}>(info.GetReturnValue(), result.get()))\n"; |  | 
| 1549         } |  | 
| 1550         $code .= "        return;\n"; |  | 
| 1551         $code .= "    v8::Handle<v8::Value> wrapper = toV8(result.get(), info.Ho
      lder(), info.GetIsolate());\n"; |  | 
| 1552         $code .= "    if (!wrapper.IsEmpty()) {\n"; |  | 
| 1553         $code .= "        V8HiddenPropertyName::setNamedHiddenReference(info.Hol
      der(), \"${attrName}\", wrapper);\n"; |  | 
| 1554         $code .= "        v8SetReturnValue(info, wrapper);\n"; |  | 
| 1555         $code .= "    }\n"; |  | 
| 1556         $code .= "    return;\n"; |  | 
| 1557         $code .= "}\n\n"; |  | 
| 1558         $code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |  | 
| 1559         $implementation{nameSpaceInternal}->add($code); |  | 
| 1560         return; |  | 
| 1561     } |  | 
| 1562 |  | 
| 1563     if ((IsSVGAnimatedType($interfaceName) or $interfaceName eq "SVGViewSpec") a
      nd IsSVGTypeNeedingTearOff($attrType)) { |  | 
| 1564         AddToImplIncludes("V8$attrType.h"); |  | 
| 1565         my $svgNativeType = GetSVGTypeNeedingTearOff($attrType); |  | 
| 1566         # Convert from abstract SVGProperty to real type, so the right toJS() me
      thod can be invoked. |  | 
| 1567         if ($forMainWorldSuffix eq "ForMainWorld") { |  | 
| 1568             $code .= "    v8SetReturnValueForMainWorld(info, static_cast<$svgNat
      iveType*>($expression), info.Holder());\n"; |  | 
| 1569         } else { |  | 
| 1570             $code .= "    v8SetReturnValueFast(info, static_cast<$svgNativeType*
      >($expression), imp);\n"; |  | 
| 1571         } |  | 
| 1572         $code .= "    return;\n"; |  | 
| 1573     } elsif (IsSVGTypeNeedingTearOff($attrType) and not $interfaceName =~ /List$
      /) { |  | 
| 1574         AddToImplIncludes("V8$attrType.h"); |  | 
| 1575         AddToImplIncludes("core/svg/properties/SVGPropertyTearOff.h"); |  | 
| 1576         my $tearOffType = GetSVGTypeNeedingTearOff($attrType); |  | 
| 1577         my $wrappedValue; |  | 
| 1578         if (IsSVGTypeWithWritablePropertiesNeedingTearOff($attrType) and not def
      ined $attribute->extendedAttributes->{"Immutable"}) { |  | 
| 1579             my $getter = $expression; |  | 
| 1580             $getter =~ s/imp->//; |  | 
| 1581             $getter =~ s/\(\)//; |  | 
| 1582 |  | 
| 1583             my $updateMethod = "&${implClassName}::update" . FirstLetterToUpperC
      ase($getter); |  | 
| 1584 |  | 
| 1585             my $selfIsTearOffType = IsSVGTypeNeedingTearOff($interfaceName); |  | 
| 1586             if ($selfIsTearOffType) { |  | 
| 1587                 AddToImplIncludes("core/svg/properties/SVGMatrixTearOff.h"); |  | 
| 1588                 # FIXME: Don't create a new one everytime we access the matrix p
      roperty. This means, e.g, === won't work. |  | 
| 1589                 $wrappedValue = "WTF::getPtr(SVGMatrixTearOff::create(wrapper, $
      expression))"; |  | 
| 1590             } else { |  | 
| 1591                 AddToImplIncludes("core/svg/properties/SVGStaticPropertyTearOff.
      h"); |  | 
| 1592                 $tearOffType =~ s/SVGPropertyTearOff</SVGStaticPropertyTearOff<$
      implClassName, /; |  | 
| 1593 |  | 
| 1594                 $wrappedValue = "WTF::getPtr(${tearOffType}::create(imp, $expres
      sion, $updateMethod))"; |  | 
| 1595             } |  | 
| 1596         } elsif ($tearOffType =~ /SVGStaticListPropertyTearOff/) { |  | 
| 1597                 $wrappedValue = "WTF::getPtr(${tearOffType}::create(imp, $expres
      sion))"; |  | 
| 1598         } elsif ($tearOffType =~ /SVG(Point|PathSeg)List/) { |  | 
| 1599                 $wrappedValue = "WTF::getPtr($expression)"; |  | 
| 1600         } else { |  | 
| 1601                 $wrappedValue = "WTF::getPtr(${tearOffType}::create($expression)
      )"; |  | 
| 1602         } |  | 
| 1603         if ($forMainWorldSuffix eq "ForMainWorld") { |  | 
| 1604             $code .= "    v8SetReturnValueForMainWorld(info, $wrappedValue, info
      .Holder());\n"; |  | 
| 1605         } else { |  | 
| 1606             $code .= "    v8SetReturnValueFast(info, $wrappedValue, imp);\n"; |  | 
| 1607         } |  | 
| 1608         $code .= "    return;\n"; |  | 
| 1609     } elsif ($attrCached) { |  | 
| 1610         if ($attribute->type eq "SerializedScriptValue") { |  | 
| 1611             $code .= "    RefPtr<SerializedScriptValue> serialized = $getterStri
      ng;\n"; |  | 
| 1612             $code .= "    value = serialized ? serialized->deserialize() : v8::H
      andle<v8::Value>(v8::Null(info.GetIsolate()));\n"; |  | 
| 1613         } else { |  | 
| 1614             $code .= "    value = $getterString.v8Value();\n"; |  | 
| 1615         } |  | 
| 1616         $code .= <<END; |  | 
| 1617     info.Holder()->SetHiddenValue(propertyName, value); |  | 
| 1618     v8SetReturnValue(info, value); |  | 
| 1619     return; |  | 
| 1620 END |  | 
| 1621     } elsif ($attribute->type eq "EventHandler") { |  | 
| 1622         AddToImplIncludes("bindings/v8/V8AbstractEventListener.h"); |  | 
| 1623         my $getterFunc = ToMethodName($attribute->name); |  | 
| 1624         # FIXME: Pass the main world ID for main-world-only getters. |  | 
| 1625         $code .= "    EventListener* listener = imp->${getterFunc}(isolatedWorld
      ForIsolate(info.GetIsolate()));\n"; |  | 
| 1626         $code .= "    v8SetReturnValue(info, listener ? v8::Handle<v8::Value>(V8
      AbstractEventListener::cast(listener)->getListenerObject(imp->scriptExecutionCon
      text())) : v8::Handle<v8::Value>(v8::Null(info.GetIsolate())));\n"; |  | 
| 1627         $code .= "    return;\n"; |  | 
| 1628     } else { |  | 
| 1629         my $nativeValue = NativeToJSValue($attribute->type, $attribute->extended
      Attributes, $expression, "    ", "", "info.Holder()", "info.GetIsolate()", "info
      ", "imp", $forMainWorldSuffix, "return"); |  | 
| 1630         $code .= "${nativeValue}\n"; |  | 
| 1631         $code .= "    return;\n"; |  | 
| 1632     } |  | 
| 1633 |  | 
| 1634     $code .= "}\n\n";  # end of getter |  | 
| 1635     $code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |  | 
| 1636     $implementation{nameSpaceInternal}->add($code); |  | 
| 1637 } |  | 
| 1638 |  | 
| 1639 sub ShouldKeepAttributeAlive |  | 
| 1640 { |  | 
| 1641     my ($interface, $attribute, $returnType) = @_; |  | 
| 1642     my $attrName = $attribute->name; |  | 
| 1643 |  | 
| 1644     return 1 if $attribute->extendedAttributes->{"KeepAttributeAliveForGC"}; |  | 
| 1645 |  | 
| 1646     # Basically, for readonly or replaceable attributes, we have to guarantee |  | 
| 1647     # that JS wrappers don't get garbage-collected prematually when their |  | 
| 1648     # lifetime is strongly tied to their owner. |  | 
| 1649     return 0 if !IsWrapperType($returnType); |  | 
| 1650     return 0 if !IsReadonly($attribute) && !$attribute->extendedAttributes->{"Re
      placeable"}; |  | 
| 1651 |  | 
| 1652     # However, there are a couple of exceptions. |  | 
| 1653 |  | 
| 1654     # Node lifetime is managed by object grouping. |  | 
| 1655     return 0 if InheritsInterface($interface, "Node"); |  | 
| 1656     return 0 if IsDOMNodeType($returnType); |  | 
| 1657 |  | 
| 1658     # To avoid adding a reference to itself. |  | 
| 1659     # FIXME: Introduce [DoNotKeepAttributeAliveForGC] and remove this hack |  | 
| 1660     # depending on the attribute name. |  | 
| 1661     return 0 if $attrName eq "self"; |  | 
| 1662 |  | 
| 1663     # FIXME: Remove these hard-coded hacks. |  | 
| 1664     return 0 if $returnType eq "EventTarget"; |  | 
| 1665     return 0 if $returnType eq "SerializedScriptValue"; |  | 
| 1666     return 0 if $returnType eq "Window"; |  | 
| 1667     return 0 if $returnType =~ /SVG/; |  | 
| 1668     return 0 if $returnType =~ /HTML/; |  | 
| 1669 |  | 
| 1670     return 1; |  | 
| 1671 } |  | 
| 1672 |  | 
| 1673 sub GenerateReplaceableAttributeSetterCallback |  | 
| 1674 { |  | 
| 1675     my $interface = shift; |  | 
| 1676     my $implClassName = GetImplName($interface); |  | 
| 1677 |  | 
| 1678     my $code = ""; |  | 
| 1679     $code .= "static void ${implClassName}ReplaceableAttributeSetterCallback(v8:
      :Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackI
      nfo<void>& info)\n"; |  | 
| 1680     $code .= "{\n"; |  | 
| 1681     $code .= GenerateFeatureObservation($interface->extendedAttributes->{"Measur
      eAs"}); |  | 
| 1682     $code .= GenerateDeprecationNotification($interface->extendedAttributes->{"D
      eprecateAs"}); |  | 
| 1683     $code .= GenerateCustomElementInvocationScopeIfNeeded($interface->extendedAt
      tributes); |  | 
| 1684     if (HasActivityLogging("", $interface->extendedAttributes, "Setter")) { |  | 
| 1685          die "IDL error: ActivityLog attribute cannot exist on a ReplacableAttri
      buteSetterCallback"; |  | 
| 1686     } |  | 
| 1687     $code .= "    ${implClassName}V8Internal::${implClassName}ReplaceableAttribu
      teSetter(name, value, info);\n"; |  | 
| 1688     $code .= "}\n\n"; |  | 
| 1689     $implementation{nameSpaceInternal}->add($code); |  | 
| 1690 } |  | 
| 1691 |  | 
| 1692 sub GenerateReplaceableAttributeSetter |  | 
| 1693 { |  | 
| 1694     my $interface = shift; |  | 
| 1695 |  | 
| 1696     my $implClassName = GetImplName($interface); |  | 
| 1697     my $v8ClassName = GetV8ClassName($interface); |  | 
| 1698 |  | 
| 1699     my $code = ""; |  | 
| 1700     $code .= <<END; |  | 
| 1701 static void ${implClassName}ReplaceableAttributeSetter(v8::Local<v8::String> nam
      e, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info) |  | 
| 1702 { |  | 
| 1703 END |  | 
| 1704     if ($interface->extendedAttributes->{"CheckSecurity"}) { |  | 
| 1705         AddToImplIncludes("bindings/v8/BindingSecurity.h"); |  | 
| 1706         $code .= <<END; |  | 
| 1707     ${implClassName}* imp = ${v8ClassName}::toNative(info.Holder()); |  | 
| 1708     if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame())) |  | 
| 1709         return; |  | 
| 1710 END |  | 
| 1711     } |  | 
| 1712 |  | 
| 1713     $code .= <<END; |  | 
| 1714     info.This()->ForceSet(name, value); |  | 
| 1715 } |  | 
| 1716 |  | 
| 1717 END |  | 
| 1718     $implementation{nameSpaceInternal}->add($code); |  | 
| 1719 } |  | 
| 1720 |  | 
| 1721 sub GenerateCustomElementInvocationScopeIfNeeded |  | 
| 1722 { |  | 
| 1723     my $code = ""; |  | 
| 1724     my $ext = shift; |  | 
| 1725     my $annotation = $ext->{"CustomElementCallbacks"} || ""; |  | 
| 1726 |  | 
| 1727     if ($annotation eq "None") { |  | 
| 1728         # Explicit CustomElementCallbacks=None overrides any other |  | 
| 1729         # heuristic. |  | 
| 1730         return $code; |  | 
| 1731     } |  | 
| 1732 |  | 
| 1733     if ($annotation eq "Enable" or $ext->{"Reflect"}) { |  | 
| 1734         AddToImplIncludes("core/dom/CustomElementCallbackDispatcher.h"); |  | 
| 1735         $code .= <<END; |  | 
| 1736     CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope; |  | 
| 1737 END |  | 
| 1738     } |  | 
| 1739     return $code; |  | 
| 1740 } |  | 
| 1741 |  | 
| 1742 sub GenerateNormalAttributeSetterCallback |  | 
| 1743 { |  | 
| 1744     my $attribute = shift; |  | 
| 1745     my $interface = shift; |  | 
| 1746     my $forMainWorldSuffix = shift; |  | 
| 1747 |  | 
| 1748     my $implClassName = GetImplName($interface); |  | 
| 1749     my $v8ClassName = GetV8ClassName($interface); |  | 
| 1750     my $attrExt = $attribute->extendedAttributes; |  | 
| 1751     my $attrName = $attribute->name; |  | 
| 1752 |  | 
| 1753     my $conditionalString = GenerateConditionalString($attribute); |  | 
| 1754     my $code = ""; |  | 
| 1755     $code .= "#if ${conditionalString}\n\n" if $conditionalString; |  | 
| 1756 |  | 
| 1757     $code .= "static void ${attrName}AttributeSetterCallback${forMainWorldSuffix
      }(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCall
      backInfo<void>& info)\n"; |  | 
| 1758     $code .= "{\n"; |  | 
| 1759     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMSetter\");\n"; |  | 
| 1760     $code .= GenerateFeatureObservation($attrExt->{"MeasureAs"}); |  | 
| 1761     $code .= GenerateDeprecationNotification($attrExt->{"DeprecateAs"}); |  | 
| 1762     if (HasActivityLogging($forMainWorldSuffix, $attrExt, "Setter")) { |  | 
| 1763         $code .= GenerateActivityLogging("Setter", $interface, "${attrName}"); |  | 
| 1764     } |  | 
| 1765     $code .= GenerateCustomElementInvocationScopeIfNeeded($attrExt); |  | 
| 1766     if (HasCustomSetter($attrExt)) { |  | 
| 1767         $code .= "    ${v8ClassName}::${attrName}AttributeSetterCustom(name, val
      ue, info);\n"; |  | 
| 1768     } else { |  | 
| 1769         $code .= "    ${implClassName}V8Internal::${attrName}AttributeSetter${fo
      rMainWorldSuffix}(name, value, info);\n"; |  | 
| 1770     } |  | 
| 1771     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |  | 
| 1772     $code .= "}\n\n"; |  | 
| 1773     $code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |  | 
| 1774     $implementation{nameSpaceInternal}->add($code); |  | 
| 1775 } |  | 
| 1776 |  | 
| 1777 sub GenerateNormalAttributeSetter |  | 
| 1778 { |  | 
| 1779     my $attribute = shift; |  | 
| 1780     my $interface = shift; |  | 
| 1781     my $forMainWorldSuffix = shift; |  | 
| 1782 |  | 
| 1783     my $interfaceName = $interface->name; |  | 
| 1784     my $implClassName = GetImplName($interface); |  | 
| 1785     my $v8ClassName = GetV8ClassName($interface); |  | 
| 1786     my $attrName = $attribute->name; |  | 
| 1787     my $attrExt = $attribute->extendedAttributes; |  | 
| 1788     my $attrType = $attribute->type; |  | 
| 1789     my $attrCached = GetCachedAttribute($attribute); |  | 
| 1790 |  | 
| 1791     if (HasCustomSetter($attrExt)) { |  | 
| 1792         return; |  | 
| 1793     } |  | 
| 1794 |  | 
| 1795     my $conditionalString = GenerateConditionalString($attribute); |  | 
| 1796     my $code = ""; |  | 
| 1797     $code .= "#if ${conditionalString}\n\n" if $conditionalString; |  | 
| 1798     $code .= "static void ${attrName}AttributeSetter${forMainWorldSuffix}(v8::Lo
      cal<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo
      <void>& info)\n"; |  | 
| 1799     $code .= "{\n"; |  | 
| 1800 |  | 
| 1801     # If the "StrictTypeChecking" extended attribute is present, and the attribu
      te's type is an |  | 
| 1802     # interface type, then if the incoming value does not implement that interfa
      ce, a TypeError is |  | 
| 1803     # thrown rather than silently passing NULL to the C++ code. |  | 
| 1804     # Per the Web IDL and ECMAScript specifications, incoming values can always 
      be converted to both |  | 
| 1805     # strings and numbers, so do not throw TypeError if the attribute is of thes
      e types. |  | 
| 1806     if ($attribute->extendedAttributes->{"StrictTypeChecking"}) { |  | 
| 1807         my $argType = $attribute->type; |  | 
| 1808         if (IsWrapperType($argType)) { |  | 
| 1809             $code .= "    if (!isUndefinedOrNull(value) && !V8${argType}::HasIns
      tance(value, info.GetIsolate(), worldType(info.GetIsolate()))) {\n"; |  | 
| 1810             $code .= "        throwTypeError(info.GetIsolate());\n"; |  | 
| 1811             $code .= "        return;\n"; |  | 
| 1812             $code .= "    }\n"; |  | 
| 1813         } |  | 
| 1814     } |  | 
| 1815 |  | 
| 1816     my $svgNativeType = GetSVGTypeNeedingTearOff($interfaceName); |  | 
| 1817     if ($svgNativeType) { |  | 
| 1818         my $svgWrappedNativeType = GetSVGWrappedTypeNeedingTearOff($interfaceNam
      e); |  | 
| 1819         if ($svgWrappedNativeType =~ /List$/) { |  | 
| 1820             $code .= <<END; |  | 
| 1821     $svgNativeType* imp = ${v8ClassName}::toNative(info.Holder()); |  | 
| 1822 END |  | 
| 1823         } else { |  | 
| 1824             AddToImplIncludes("bindings/v8/ExceptionMessages.h"); |  | 
| 1825             AddToImplIncludes("bindings/v8/ExceptionState.h"); |  | 
| 1826             $code .= "    $svgNativeType* wrapper = ${v8ClassName}::toNative(inf
      o.Holder());\n"; |  | 
| 1827             $code .= "    if (wrapper->isReadOnly()) {\n"; |  | 
| 1828             $code .= "        setDOMException(NoModificationAllowedError, info.G
      etIsolate());\n"; |  | 
| 1829             $code .= "        return;\n"; |  | 
| 1830             $code .= "    }\n"; |  | 
| 1831             $code .= "    $svgWrappedNativeType& impInstance = wrapper->property
      Reference();\n"; |  | 
| 1832             $code .= "    $svgWrappedNativeType* imp = &impInstance;\n"; |  | 
| 1833         } |  | 
| 1834     } elsif ($attrExt->{"OnProto"}) { |  | 
| 1835         $code .= <<END; |  | 
| 1836     ${implClassName}* imp = ${v8ClassName}::toNative(info.Holder()); |  | 
| 1837 END |  | 
| 1838     } else { |  | 
| 1839         my $reflect = $attribute->extendedAttributes->{"Reflect"}; |  | 
| 1840         if ($reflect && InheritsInterface($interface, "Node") && $attrType eq "D
      OMString") { |  | 
| 1841             # Generate super-compact call for regular attribute setter: |  | 
| 1842             my $contentAttributeName = $reflect eq "VALUE_IS_MISSING" ? lc $attr
      Name : $reflect; |  | 
| 1843             my $namespace = NamespaceForAttributeName($interfaceName, $contentAt
      tributeName); |  | 
| 1844             AddToImplIncludes("${namespace}.h"); |  | 
| 1845             $code .= "    Element* imp = V8Element::toNative(info.Holder());\n"; |  | 
| 1846             $code .= "    V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<
      WithNullCheck>, stringResource, value);\n"; |  | 
| 1847             # Attr (not Attribute) used in content attributes |  | 
| 1848             $code .= "    imp->setAttribute(${namespace}::${contentAttributeName
      }Attr, stringResource);\n"; |  | 
| 1849             $code .= "}\n\n"; |  | 
| 1850             $code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |  | 
| 1851             $implementation{nameSpaceInternal}->add($code); |  | 
| 1852             return; |  | 
| 1853             # Skip the rest of the function! |  | 
| 1854         } |  | 
| 1855 |  | 
| 1856         if (!$attribute->isStatic) { |  | 
| 1857             $code .= <<END; |  | 
| 1858     ${implClassName}* imp = ${v8ClassName}::toNative(info.Holder()); |  | 
| 1859 END |  | 
| 1860         } |  | 
| 1861     } |  | 
| 1862 |  | 
| 1863     my $nativeType = GetNativeType($attribute->type, $attribute->extendedAttribu
      tes, "parameter"); |  | 
| 1864     if ($attribute->type eq "EventHandler") { |  | 
| 1865         if ($interface->name eq "Window") { |  | 
| 1866             $code .= "    if (!imp->document())\n"; |  | 
| 1867             $code .= "        return;\n"; |  | 
| 1868         } |  | 
| 1869     } else { |  | 
| 1870         $code .= JSValueToNativeStatement($attribute->type, $attribute->extended
      Attributes, "value", "v", "    ", "info.GetIsolate()"); |  | 
| 1871     } |  | 
| 1872 |  | 
| 1873     if (IsEnumType($attrType)) { |  | 
| 1874         # setter ignores invalid enumeration values |  | 
| 1875         my @enumValues = ValidEnumValues($attrType); |  | 
| 1876         my @validEqualities = (); |  | 
| 1877         foreach my $enumValue (@enumValues) { |  | 
| 1878             push(@validEqualities, "string == \"$enumValue\""); |  | 
| 1879         } |  | 
| 1880         my $enumValidationExpression = join(" || ", @validEqualities); |  | 
| 1881         $code .= <<END; |  | 
| 1882     String string = v; |  | 
| 1883     if (!($enumValidationExpression)) |  | 
| 1884         return; |  | 
| 1885 END |  | 
| 1886     } |  | 
| 1887 |  | 
| 1888     my $expression = "v"; |  | 
| 1889     my $returnType = $attribute->type; |  | 
| 1890     if (IsRefPtrType($returnType) && !GetArrayType($returnType)) { |  | 
| 1891         $expression = "WTF::getPtr(" . $expression . ")"; |  | 
| 1892     } |  | 
| 1893 |  | 
| 1894     $code .= GenerateCustomElementInvocationScopeIfNeeded($attribute->extendedAt
      tributes); |  | 
| 1895 |  | 
| 1896     my $useExceptions = 1 if $attribute->extendedAttributes->{"SetterRaisesExcep
      tion"} ||  $attribute->extendedAttributes->{"RaisesException"}; |  | 
| 1897 |  | 
| 1898     if ($useExceptions) { |  | 
| 1899         AddToImplIncludes("bindings/v8/ExceptionMessages.h"); |  | 
| 1900         AddToImplIncludes("bindings/v8/ExceptionState.h"); |  | 
| 1901         $code .= "    ExceptionState es(info.GetIsolate());\n"; |  | 
| 1902     } |  | 
| 1903 |  | 
| 1904     if ($attribute->type eq "EventHandler") { |  | 
| 1905         my $implSetterFunctionName = FirstLetterToUpperCase($attrName); |  | 
| 1906         AddToImplIncludes("bindings/v8/V8AbstractEventListener.h"); |  | 
| 1907         # Non callable input should be treated as null |  | 
| 1908         $code .= "    if (!value->IsNull() && !value->IsFunction())\n"; |  | 
| 1909         $code .= "        value = v8::Null(info.GetIsolate());\n"; |  | 
| 1910         if (!InheritsInterface($interface, "Node")) { |  | 
| 1911             my $attrImplName = GetImplName($attribute); |  | 
| 1912             $code .= "    transferHiddenDependency(info.Holder(), imp->${attrImp
      lName}(isolatedWorldForIsolate(info.GetIsolate())), value, ${v8ClassName}::event
      ListenerCacheIndex, info.GetIsolate());\n"; |  | 
| 1913         } |  | 
| 1914         AddToImplIncludes("bindings/v8/V8EventListenerList.h"); |  | 
| 1915         if (($interfaceName eq "Window" or $interfaceName eq "WorkerGlobalScope"
      ) and $attribute->name eq "onerror") { |  | 
| 1916             AddToImplIncludes("bindings/v8/V8ErrorHandler.h"); |  | 
| 1917             $code .= "    imp->set$implSetterFunctionName(V8EventListenerList::f
      indOrCreateWrapper<V8ErrorHandler>(value, true), isolatedWorldForIsolate(info.Ge
      tIsolate()));\n"; |  | 
| 1918         } else { |  | 
| 1919             $code .= "    imp->set$implSetterFunctionName(V8EventListenerList::g
      etEventListener(value, true, ListenerFindOrCreate), isolatedWorldForIsolate(info
      .GetIsolate()));\n"; |  | 
| 1920         } |  | 
| 1921     } else { |  | 
| 1922         my ($functionName, @arguments) = SetterExpression($interfaceName, $attri
      bute); |  | 
| 1923         push(@arguments, $expression); |  | 
| 1924         push(@arguments, "es") if $useExceptions; |  | 
| 1925         if ($attribute->extendedAttributes->{"ImplementedBy"}) { |  | 
| 1926             my $implementedBy = $attribute->extendedAttributes->{"ImplementedBy"
      }; |  | 
| 1927             my $implementedByImplName = GetImplNameFromImplementedBy($implemente
      dBy); |  | 
| 1928             AddToImplIncludes(HeaderFilesForInterface($implementedBy, $implement
      edByImplName)); |  | 
| 1929             unshift(@arguments, "imp") if !$attribute->isStatic; |  | 
| 1930             $functionName = "${implementedByImplName}::${functionName}"; |  | 
| 1931         } elsif ($attribute->isStatic) { |  | 
| 1932             $functionName = "${implClassName}::${functionName}"; |  | 
| 1933         } else { |  | 
| 1934             $functionName = "imp->${functionName}"; |  | 
| 1935         } |  | 
| 1936         my ($arg, $subCode) = GenerateCallWith($attribute->extendedAttributes->{
      "SetterCallWith"} || $attribute->extendedAttributes->{"CallWith"}, "    ", 1); |  | 
| 1937         $code .= $subCode; |  | 
| 1938         unshift(@arguments, @$arg); |  | 
| 1939         $code .= "    ${functionName}(" . join(", ", @arguments) . ");\n"; |  | 
| 1940     } |  | 
| 1941 |  | 
| 1942     if ($useExceptions) { |  | 
| 1943         $code .= "    es.throwIfNeeded();\n"; |  | 
| 1944     } |  | 
| 1945 |  | 
| 1946     if (ExtendedAttributeContains($attribute->extendedAttributes->{"CallWith"}, 
      "ScriptState")) { |  | 
| 1947         $code .= "    if (state.hadException())\n"; |  | 
| 1948         $code .= "        throwError(state.exception(), info.GetIsolate());\n"; |  | 
| 1949     } |  | 
| 1950 |  | 
| 1951     if ($svgNativeType) { |  | 
| 1952         if ($useExceptions) { |  | 
| 1953             $code .= "    if (!es.hadException())\n"; |  | 
| 1954             $code .= "        wrapper->commitChange();\n"; |  | 
| 1955         } else { |  | 
| 1956             $code .= "    wrapper->commitChange();\n"; |  | 
| 1957         } |  | 
| 1958     } |  | 
| 1959 |  | 
| 1960     if ($attrCached) { |  | 
| 1961         $code .= <<END; |  | 
| 1962     info.Holder()->DeleteHiddenValue(v8::String::NewSymbol("${attrName}")); // I
      nvalidate the cached value. |  | 
| 1963 END |  | 
| 1964     } |  | 
| 1965 |  | 
| 1966     $code .= "    return;\n"; |  | 
| 1967     $code .= "}\n\n";  # end of setter |  | 
| 1968     $code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |  | 
| 1969     $implementation{nameSpaceInternal}->add($code); |  | 
| 1970 } |  | 
| 1971 |  | 
| 1972 sub GenerateParametersCheckExpression |  | 
| 1973 { |  | 
| 1974     my $numParameters = shift; |  | 
| 1975     my $function = shift; |  | 
| 1976 |  | 
| 1977     my @andExpression = (); |  | 
| 1978     push(@andExpression, "args.Length() == $numParameters"); |  | 
| 1979     my $parameterIndex = 0; |  | 
| 1980     foreach my $parameter (@{$function->parameters}) { |  | 
| 1981         last if $parameterIndex >= $numParameters; |  | 
| 1982         my $value = "args[$parameterIndex]"; |  | 
| 1983         my $type = $parameter->type; |  | 
| 1984 |  | 
| 1985         # Only DOMString or wrapper types are checked. |  | 
| 1986         # For DOMString with StrictTypeChecking only Null, Undefined and Object |  | 
| 1987         # are accepted for compatibility. Otherwise, no restrictions are made to |  | 
| 1988         # match the non-overloaded behavior. |  | 
| 1989         # FIXME: Implement WebIDL overload resolution algorithm. |  | 
| 1990         if ($type eq "DOMString") { |  | 
| 1991             if ($parameter->extendedAttributes->{"StrictTypeChecking"}) { |  | 
| 1992                 push(@andExpression, "(${value}->IsNull() || ${value}->IsUndefin
      ed() || ${value}->IsString() || ${value}->IsObject())"); |  | 
| 1993             } |  | 
| 1994         } elsif (IsCallbackInterface($parameter->type)) { |  | 
| 1995             # For Callbacks only checks if the value is null or object. |  | 
| 1996             push(@andExpression, "(${value}->IsNull() || ${value}->IsFunction())
      "); |  | 
| 1997         } elsif (GetArrayOrSequenceType($type)) { |  | 
| 1998             if ($parameter->isNullable) { |  | 
| 1999                 push(@andExpression, "(${value}->IsNull() || ${value}->IsArray()
      )"); |  | 
| 2000             } else { |  | 
| 2001                 push(@andExpression, "(${value}->IsArray())"); |  | 
| 2002             } |  | 
| 2003         } elsif (IsWrapperType($type)) { |  | 
| 2004             if ($parameter->isNullable) { |  | 
| 2005                 push(@andExpression, "(${value}->IsNull() || V8${type}::HasInsta
      nce($value, args.GetIsolate(), worldType(args.GetIsolate())))"); |  | 
| 2006             } else { |  | 
| 2007                 push(@andExpression, "(V8${type}::HasInstance($value, args.GetIs
      olate(), worldType(args.GetIsolate())))"); |  | 
| 2008             } |  | 
| 2009         } |  | 
| 2010 |  | 
| 2011         $parameterIndex++; |  | 
| 2012     } |  | 
| 2013     my $res = join(" && ", @andExpression); |  | 
| 2014     $res = "($res)" if @andExpression > 1; |  | 
| 2015     return $res; |  | 
| 2016 } |  | 
| 2017 |  | 
| 2018 # As per Web IDL specification, the length of a function Object is |  | 
| 2019 # its number of mandatory parameters. |  | 
| 2020 sub GetFunctionLength |  | 
| 2021 { |  | 
| 2022     my $function = shift; |  | 
| 2023 |  | 
| 2024     my $numMandatoryParams = 0; |  | 
| 2025     foreach my $parameter (@{$function->parameters}) { |  | 
| 2026         # Abort as soon as we find the first optional parameter as no mandatory |  | 
| 2027         # parameter can follow an optional one. |  | 
| 2028         last if $parameter->isOptional; |  | 
| 2029         $numMandatoryParams++; |  | 
| 2030     } |  | 
| 2031     return $numMandatoryParams; |  | 
| 2032 } |  | 
| 2033 |  | 
| 2034 sub GenerateFunctionParametersCheck |  | 
| 2035 { |  | 
| 2036     my $function = shift; |  | 
| 2037 |  | 
| 2038     my @orExpression = (); |  | 
| 2039     my $numParameters = 0; |  | 
| 2040     my $hasVariadic = 0; |  | 
| 2041     my $numMandatoryParams = @{$function->parameters}; |  | 
| 2042     foreach my $parameter (@{$function->parameters}) { |  | 
| 2043         if ($parameter->isOptional) { |  | 
| 2044             push(@orExpression, GenerateParametersCheckExpression($numParameters
      , $function)); |  | 
| 2045             $numMandatoryParams--; |  | 
| 2046         } |  | 
| 2047         if ($parameter->isVariadic) { |  | 
| 2048             $hasVariadic = 1; |  | 
| 2049             last; |  | 
| 2050         } |  | 
| 2051         $numParameters++; |  | 
| 2052     } |  | 
| 2053     if (!$hasVariadic) { |  | 
| 2054         push(@orExpression, GenerateParametersCheckExpression($numParameters, $f
      unction)); |  | 
| 2055     } |  | 
| 2056     return ($numMandatoryParams, join(" || ", @orExpression)); |  | 
| 2057 } |  | 
| 2058 |  | 
| 2059 sub GenerateOverloadedFunction |  | 
| 2060 { |  | 
| 2061     my $function = shift; |  | 
| 2062     my $interface = shift; |  | 
| 2063     my $forMainWorldSuffix = shift; |  | 
| 2064 |  | 
| 2065     # Generate code for choosing the correct overload to call. Overloads are |  | 
| 2066     # chosen based on the total number of arguments passed and the type of |  | 
| 2067     # values passed in non-primitive argument slots. When more than a single |  | 
| 2068     # overload is applicable, precedence is given according to the order of |  | 
| 2069     # declaration in the IDL. |  | 
| 2070 |  | 
| 2071     my $name = $function->name; |  | 
| 2072     my $implClassName = GetImplName($interface); |  | 
| 2073 |  | 
| 2074     my $conditionalString = GenerateConditionalString($function); |  | 
| 2075     my $leastNumMandatoryParams = 255; |  | 
| 2076     my $code = ""; |  | 
| 2077     $code .= "#if ${conditionalString}\n\n" if $conditionalString; |  | 
| 2078     $code .= <<END; |  | 
| 2079 static void ${name}Method${forMainWorldSuffix}(const v8::FunctionCallbackInfo<v8
      ::Value>& args) |  | 
| 2080 { |  | 
| 2081 END |  | 
| 2082     $code .= GenerateFeatureObservation($function->extendedAttributes->{"Measure
      As"}); |  | 
| 2083     $code .= GenerateDeprecationNotification($function->extendedAttributes->{"De
      precateAs"}); |  | 
| 2084 |  | 
| 2085     foreach my $overload (@{$function->{overloads}}) { |  | 
| 2086         my ($numMandatoryParams, $parametersCheck) = GenerateFunctionParametersC
      heck($overload); |  | 
| 2087         $leastNumMandatoryParams = $numMandatoryParams if ($numMandatoryParams <
       $leastNumMandatoryParams); |  | 
| 2088         $code .= "    if ($parametersCheck) {\n"; |  | 
| 2089         my $overloadedIndexString = $overload->{overloadIndex}; |  | 
| 2090         $code .= "        ${name}${overloadedIndexString}Method${forMainWorldSuf
      fix}(args);\n"; |  | 
| 2091         $code .= "        return;\n"; |  | 
| 2092         $code .= "    }\n"; |  | 
| 2093     } |  | 
| 2094     if ($leastNumMandatoryParams >= 1) { |  | 
| 2095         $code .= "    if (UNLIKELY(args.Length() < $leastNumMandatoryParams)) {\
      n"; |  | 
| 2096         $code .= "        throwTypeError(ExceptionMessages::failedToExecute(\"$n
      ame\", \"$implClassName\", ExceptionMessages::notEnoughArguments($leastNumMandat
      oryParams, args.Length())), args.GetIsolate());\n"; |  | 
| 2097         $code .= "        return;\n"; |  | 
| 2098         $code .= "    }\n"; |  | 
| 2099     } |  | 
| 2100     $code .= <<END; |  | 
| 2101     throwTypeError(args.GetIsolate()); |  | 
| 2102 END |  | 
| 2103     $code .= "}\n\n"; |  | 
| 2104     $code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |  | 
| 2105     $implementation{nameSpaceInternal}->add($code); |  | 
| 2106 } |  | 
| 2107 |  | 
| 2108 sub GenerateFunctionCallback |  | 
| 2109 { |  | 
| 2110     my $function = shift; |  | 
| 2111     my $interface = shift; |  | 
| 2112     my $forMainWorldSuffix = shift; |  | 
| 2113 |  | 
| 2114     my $implClassName = GetImplName($interface); |  | 
| 2115     my $v8ClassName = GetV8ClassName($interface); |  | 
| 2116     my $name = $function->name; |  | 
| 2117 |  | 
| 2118     if ($name eq "") { |  | 
| 2119         return; |  | 
| 2120     } |  | 
| 2121 |  | 
| 2122     my $conditionalString = GenerateConditionalString($function); |  | 
| 2123     my $code = ""; |  | 
| 2124     $code .= "#if ${conditionalString}\n\n" if $conditionalString; |  | 
| 2125     $code .= <<END; |  | 
| 2126 static void ${name}MethodCallback${forMainWorldSuffix}(const v8::FunctionCallbac
      kInfo<v8::Value>& args) |  | 
| 2127 { |  | 
| 2128 END |  | 
| 2129     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMMethod\");\n"; |  | 
| 2130     $code .= GenerateFeatureObservation($function->extendedAttributes->{"Measure
      As"}); |  | 
| 2131     $code .= GenerateDeprecationNotification($function->extendedAttributes->{"De
      precateAs"}); |  | 
| 2132     if (HasActivityLogging($forMainWorldSuffix, $function->extendedAttributes, "
      Access")) { |  | 
| 2133         $code .= GenerateActivityLogging("Method", $interface, "${name}"); |  | 
| 2134     } |  | 
| 2135     if (HasCustomMethod($function->extendedAttributes)) { |  | 
| 2136         $code .= "    ${v8ClassName}::${name}MethodCustom(args);\n"; |  | 
| 2137     } else { |  | 
| 2138         $code .= "    ${implClassName}V8Internal::${name}Method${forMainWorldSuf
      fix}(args);\n"; |  | 
| 2139     } |  | 
| 2140     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |  | 
| 2141     $code .= "}\n\n"; |  | 
| 2142     $code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |  | 
| 2143     $implementation{nameSpaceInternal}->add($code); |  | 
| 2144 } |  | 
| 2145 |  | 
| 2146 sub GenerateFunction |  | 
| 2147 { |  | 
| 2148     my $function = shift; |  | 
| 2149     my $interface = shift; |  | 
| 2150     my $forMainWorldSuffix = shift; |  | 
| 2151 |  | 
| 2152     my $interfaceName = $interface->name; |  | 
| 2153     my $implClassName = GetImplName($interface); |  | 
| 2154     my $v8ClassName = GetV8ClassName($interface); |  | 
| 2155     my $name = $function->name; |  | 
| 2156     my $implName = GetImplName($function); |  | 
| 2157     my $funcExt = $function->extendedAttributes; |  | 
| 2158 |  | 
| 2159     if (HasCustomMethod($funcExt) || $name eq "") { |  | 
| 2160         return; |  | 
| 2161     } |  | 
| 2162 |  | 
| 2163     if (@{$function->{overloads}} > 1) { |  | 
| 2164         # Append a number to an overloaded method's name to make it unique: |  | 
| 2165         $name = $name . $function->{overloadIndex}; |  | 
| 2166     } |  | 
| 2167 |  | 
| 2168     my $conditionalString = GenerateConditionalString($function); |  | 
| 2169     my $code = ""; |  | 
| 2170     $code .= "#if ${conditionalString}\n\n" if $conditionalString; |  | 
| 2171     $code .= "static void ${name}Method${forMainWorldSuffix}(const v8::FunctionC
      allbackInfo<v8::Value>& args)\n"; |  | 
| 2172     $code .= "{\n"; |  | 
| 2173 |  | 
| 2174     if ($name eq "addEventListener" || $name eq "removeEventListener") { |  | 
| 2175         my $lookupType = ($name eq "addEventListener") ? "OrCreate" : "Only"; |  | 
| 2176         my $passRefPtrHandling = ($name eq "addEventListener") ? "" : ".get()"; |  | 
| 2177         my $hiddenDependencyAction = ($name eq "addEventListener") ? "create" : 
      "remove"; |  | 
| 2178 |  | 
| 2179         AddToImplIncludes("bindings/v8/BindingSecurity.h"); |  | 
| 2180         AddToImplIncludes("bindings/v8/V8EventListenerList.h"); |  | 
| 2181         AddToImplIncludes("core/page/DOMWindow.h"); |  | 
| 2182         $code .= <<END; |  | 
| 2183     EventTarget* impl = ${v8ClassName}::toNative(args.Holder()); |  | 
| 2184     if (DOMWindow* window = impl->toDOMWindow()) { |  | 
| 2185         if (!BindingSecurity::shouldAllowAccessToFrame(window->frame())) |  | 
| 2186             return; |  | 
| 2187 |  | 
| 2188         if (!window->document()) |  | 
| 2189             return; |  | 
| 2190     } |  | 
| 2191 |  | 
| 2192     RefPtr<EventListener> listener = V8EventListenerList::getEventListener(args[
      1], false, ListenerFind${lookupType}); |  | 
| 2193     if (listener) { |  | 
| 2194         V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, st
      ringResource, args[0]); |  | 
| 2195         impl->${implName}(stringResource, listener${passRefPtrHandling}, args[2]
      ->BooleanValue()); |  | 
| 2196         if (!impl->toNode()) |  | 
| 2197             ${hiddenDependencyAction}HiddenDependency(args.Holder(), args[1], ${
      v8ClassName}::eventListenerCacheIndex, args.GetIsolate()); |  | 
| 2198     } |  | 
| 2199 } |  | 
| 2200 |  | 
| 2201 END |  | 
| 2202         $code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |  | 
| 2203         $implementation{nameSpaceInternal}->add($code); |  | 
| 2204         return; |  | 
| 2205     } |  | 
| 2206 |  | 
| 2207     $code .= GenerateArgumentsCountCheck($function, $interface); |  | 
| 2208 |  | 
| 2209     if ($name eq "set" and IsConstructorTemplate($interface, "TypedArray")) { |  | 
| 2210         AddToImplIncludes("bindings/v8/custom/V8ArrayBufferViewCustom.h"); |  | 
| 2211         $code .= <<END; |  | 
| 2212     setWebGLArrayHelper<$implClassName, ${v8ClassName}>(args); |  | 
| 2213 } |  | 
| 2214 |  | 
| 2215 END |  | 
| 2216         $implementation{nameSpaceInternal}->add($code); |  | 
| 2217         return; |  | 
| 2218     } |  | 
| 2219 |  | 
| 2220     my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGProperty
      Types($interfaceName); |  | 
| 2221 |  | 
| 2222     if ($svgNativeType) { |  | 
| 2223         my $nativeClassName = GetNativeType($interfaceName); |  | 
| 2224         if ($interfaceName =~ /List$/) { |  | 
| 2225             $code .= "    $nativeClassName imp = ${v8ClassName}::toNative(args.H
      older());\n"; |  | 
| 2226         } else { |  | 
| 2227             AddToImplIncludes("bindings/v8/ExceptionMessages.h"); |  | 
| 2228             AddToImplIncludes("bindings/v8/ExceptionState.h"); |  | 
| 2229             AddToImplIncludes("core/dom/ExceptionCode.h"); |  | 
| 2230             $code .= "    $nativeClassName wrapper = ${v8ClassName}::toNative(ar
      gs.Holder());\n"; |  | 
| 2231             $code .= "    if (wrapper->isReadOnly()) {\n"; |  | 
| 2232             $code .= "        setDOMException(NoModificationAllowedError, args.G
      etIsolate());\n"; |  | 
| 2233             $code .= "        return;\n"; |  | 
| 2234             $code .= "    }\n"; |  | 
| 2235             my $svgWrappedNativeType = GetSVGWrappedTypeNeedingTearOff($interfac
      eName); |  | 
| 2236             $code .= "    $svgWrappedNativeType& impInstance = wrapper->property
      Reference();\n"; |  | 
| 2237             $code .= "    $svgWrappedNativeType* imp = &impInstance;\n"; |  | 
| 2238         } |  | 
| 2239     } elsif (!$function->isStatic) { |  | 
| 2240         $code .= <<END; |  | 
| 2241     ${implClassName}* imp = ${v8ClassName}::toNative(args.Holder()); |  | 
| 2242 END |  | 
| 2243     } |  | 
| 2244 |  | 
| 2245     $code .= GenerateCustomElementInvocationScopeIfNeeded($funcExt); |  | 
| 2246 |  | 
| 2247     # Check domain security if needed |  | 
| 2248     if ($interface->extendedAttributes->{"CheckSecurity"} && !$function->extende
      dAttributes->{"DoNotCheckSecurity"}) { |  | 
| 2249         # We have not find real use cases yet. |  | 
| 2250         AddToImplIncludes("bindings/v8/BindingSecurity.h"); |  | 
| 2251         $code .= <<END; |  | 
| 2252     if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame())) |  | 
| 2253         return; |  | 
| 2254 END |  | 
| 2255     } |  | 
| 2256 |  | 
| 2257     my $raisesExceptions = $function->extendedAttributes->{"RaisesException"}; |  | 
| 2258     if ($raisesExceptions) { |  | 
| 2259         AddToImplIncludes("bindings/v8/ExceptionMessages.h"); |  | 
| 2260         AddToImplIncludes("bindings/v8/ExceptionState.h"); |  | 
| 2261         $code .= "    ExceptionState es(args.GetIsolate());\n"; |  | 
| 2262     } |  | 
| 2263 |  | 
| 2264     if ($function->extendedAttributes->{"CheckSecurityForNode"}) { |  | 
| 2265         AddToImplIncludes("bindings/v8/BindingSecurity.h"); |  | 
| 2266         $code .= "    if (!BindingSecurity::shouldAllowAccessToNode(imp->" . Get
      ImplName($function) . "(es))) {\n"; |  | 
| 2267         $code .= "        v8SetReturnValueNull(args);\n"; |  | 
| 2268         $code .= "        return;\n"; |  | 
| 2269         $code .= "    }\n"; |  | 
| 2270 END |  | 
| 2271     } |  | 
| 2272 |  | 
| 2273     my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersC
      heck($function, $interface, $forMainWorldSuffix); |  | 
| 2274     $code .= $parameterCheckString; |  | 
| 2275 |  | 
| 2276     # Build the function call string. |  | 
| 2277     $code .= GenerateFunctionCallString($function, $paramIndex, "    ", $interfa
      ce, $forMainWorldSuffix, %replacements); |  | 
| 2278     $code .= "}\n\n"; |  | 
| 2279     $code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |  | 
| 2280     $implementation{nameSpaceInternal}->add($code); |  | 
| 2281 } |  | 
| 2282 |  | 
| 2283 sub GenerateCallWith |  | 
| 2284 { |  | 
| 2285     my $callWith = shift; |  | 
| 2286     return ([], "") unless $callWith; |  | 
| 2287     my $indent = shift; |  | 
| 2288     my $returnVoid = shift; |  | 
| 2289     my $function = shift; |  | 
| 2290     my $code = ""; |  | 
| 2291 |  | 
| 2292     my @callWithArgs; |  | 
| 2293     if (ExtendedAttributeContains($callWith, "ScriptState")) { |  | 
| 2294         $code .= $indent . "ScriptState* currentState = ScriptState::current();\
      n"; |  | 
| 2295         $code .= $indent . "if (!currentState)\n"; |  | 
| 2296         $code .= $indent . "    return" . ($returnVoid ? "" : " v8Undefined()") 
      . ";\n"; |  | 
| 2297         $code .= $indent . "ScriptState& state = *currentState;\n"; |  | 
| 2298         push(@callWithArgs, "&state"); |  | 
| 2299     } |  | 
| 2300     if (ExtendedAttributeContains($callWith, "ScriptExecutionContext")) { |  | 
| 2301         $code .= $indent . "ScriptExecutionContext* scriptContext = getScriptExe
      cutionContext();\n"; |  | 
| 2302         push(@callWithArgs, "scriptContext"); |  | 
| 2303     } |  | 
| 2304     if ($function and ExtendedAttributeContains($callWith, "ScriptArguments")) { |  | 
| 2305         $code .= $indent . "RefPtr<ScriptArguments> scriptArguments(createScript
      Arguments(args, " . @{$function->parameters} . "));\n"; |  | 
| 2306         push(@callWithArgs, "scriptArguments.release()"); |  | 
| 2307         AddToImplIncludes("bindings/v8/ScriptCallStackFactory.h"); |  | 
| 2308         AddToImplIncludes("core/inspector/ScriptArguments.h"); |  | 
| 2309     } |  | 
| 2310     if (ExtendedAttributeContains($callWith, "ActiveWindow")) { |  | 
| 2311         push(@callWithArgs, "activeDOMWindow()"); |  | 
| 2312     } |  | 
| 2313     if (ExtendedAttributeContains($callWith, "FirstWindow")) { |  | 
| 2314         push(@callWithArgs, "firstDOMWindow()"); |  | 
| 2315     } |  | 
| 2316     return ([@callWithArgs], $code); |  | 
| 2317 } |  | 
| 2318 |  | 
| 2319 sub GenerateArgumentsCountCheck |  | 
| 2320 { |  | 
| 2321     my $function = shift; |  | 
| 2322     my $interface = shift; |  | 
| 2323 |  | 
| 2324     my $functionName = $function->name; |  | 
| 2325     my $implClassName = GetImplName($interface); |  | 
| 2326 |  | 
| 2327     my $numMandatoryParams = 0; |  | 
| 2328     my $allowNonOptional = 1; |  | 
| 2329     foreach my $param (@{$function->parameters}) { |  | 
| 2330         if ($param->isOptional or $param->isVariadic) { |  | 
| 2331             $allowNonOptional = 0; |  | 
| 2332         } else { |  | 
| 2333             die "An argument must not be declared to be optional unless all subs
      equent arguments to the operation are also optional." if !$allowNonOptional; |  | 
| 2334             $numMandatoryParams++; |  | 
| 2335         } |  | 
| 2336     } |  | 
| 2337 |  | 
| 2338     my $argumentsCountCheckString = ""; |  | 
| 2339     if ($numMandatoryParams >= 1) { |  | 
| 2340         $argumentsCountCheckString .= "    if (UNLIKELY(args.Length() < $numMand
      atoryParams)) {\n"; |  | 
| 2341         $argumentsCountCheckString .= "        throwTypeError(ExceptionMessages:
      :failedToExecute(\"$functionName\", \"$implClassName\", ExceptionMessages::notEn
      oughArguments($numMandatoryParams, args.Length())), args.GetIsolate());\n"; |  | 
| 2342         $argumentsCountCheckString .= "        return;\n"; |  | 
| 2343         $argumentsCountCheckString .= "    }\n"; |  | 
| 2344     } |  | 
| 2345     return $argumentsCountCheckString; |  | 
| 2346 } |  | 
| 2347 |  | 
| 2348 sub GenerateParametersCheck |  | 
| 2349 { |  | 
| 2350     my $function = shift; |  | 
| 2351     my $interface = shift; |  | 
| 2352     my $forMainWorldSuffix = shift; |  | 
| 2353     my $style = shift || "new"; |  | 
| 2354 |  | 
| 2355     my $parameterCheckString = ""; |  | 
| 2356     my $paramIndex = 0; |  | 
| 2357     my %replacements = (); |  | 
| 2358 |  | 
| 2359     foreach my $parameter (@{$function->parameters}) { |  | 
| 2360         my $nativeType = GetNativeType($parameter->type, $parameter->extendedAtt
      ributes, "parameter"); |  | 
| 2361 |  | 
| 2362         # Optional arguments without [Default=...] should generate an early call
       with fewer arguments. |  | 
| 2363         # Optional arguments with [Optional=...] should not generate the early c
      all. |  | 
| 2364         # Optional Dictionary arguments always considered to have default of emp
      ty dictionary. |  | 
| 2365         if ($parameter->isOptional && !$parameter->extendedAttributes->{"Default
      "} && $nativeType ne "Dictionary" && !IsCallbackInterface($parameter->type)) { |  | 
| 2366             $parameterCheckString .= "    if (UNLIKELY(args.Length() <= $paramIn
      dex))"; |  | 
| 2367             my $functionCall = GenerateFunctionCallString($function, $paramIndex
      , "    " x 2, $interface, $forMainWorldSuffix, %replacements); |  | 
| 2368             my $multiLine = ($functionCall =~ tr/\n//) > 1; |  | 
| 2369             $parameterCheckString .= $multiLine ? " {\n" : "\n"; |  | 
| 2370             $parameterCheckString .= $functionCall; |  | 
| 2371             $parameterCheckString .= $multiLine ? "    }\n" : "\n"; |  | 
| 2372         } |  | 
| 2373 |  | 
| 2374         my $parameterName = $parameter->name; |  | 
| 2375         AddToImplIncludes("bindings/v8/ExceptionMessages.h"); |  | 
| 2376         AddToImplIncludes("bindings/v8/ExceptionState.h"); |  | 
| 2377         if (IsCallbackInterface($parameter->type)) { |  | 
| 2378             my $v8ClassName = "V8" . $parameter->type; |  | 
| 2379             AddToImplIncludes("$v8ClassName.h"); |  | 
| 2380             if ($parameter->isOptional) { |  | 
| 2381                 $parameterCheckString .= "    RefPtr<" . $parameter->type . "> $
      parameterName;\n"; |  | 
| 2382                 $parameterCheckString .= "    if (args.Length() > $paramIndex &&
       !args[$paramIndex]->IsNull() && !args[$paramIndex]->IsUndefined()) {\n"; |  | 
| 2383                 $parameterCheckString .= "        if (!args[$paramIndex]->IsFunc
      tion()) {\n"; |  | 
| 2384                 $parameterCheckString .= "            throwTypeError(args.GetIso
      late());\n"; |  | 
| 2385                 $parameterCheckString .= "            return;\n"; |  | 
| 2386                 $parameterCheckString .= "        }\n"; |  | 
| 2387                 $parameterCheckString .= "        $parameterName = ${v8ClassName
      }::create(args[$paramIndex], getScriptExecutionContext());\n"; |  | 
| 2388                 $parameterCheckString .= "    }\n"; |  | 
| 2389             } else { |  | 
| 2390                 $parameterCheckString .= "    if (args.Length() <= $paramIndex |
      | "; |  | 
| 2391                 if ($parameter->isNullable) { |  | 
| 2392                     $parameterCheckString .= "!(args[$paramIndex]->IsFunction() 
      || args[$paramIndex]->IsNull())"; |  | 
| 2393                 } else { |  | 
| 2394                     $parameterCheckString .= "!args[$paramIndex]->IsFunction()"; |  | 
| 2395                 } |  | 
| 2396                 $parameterCheckString .= ") {\n"; |  | 
| 2397                 $parameterCheckString .= "        throwTypeError(args.GetIsolate
      ());\n"; |  | 
| 2398                 $parameterCheckString .= "        return;\n"; |  | 
| 2399                 $parameterCheckString .= "    }\n"; |  | 
| 2400                 $parameterCheckString .= "    RefPtr<" . $parameter->type . "> $
      parameterName = "; |  | 
| 2401                 $parameterCheckString .= "args[$paramIndex]->IsNull() ? 0 : " if
       $parameter->isNullable; |  | 
| 2402                 $parameterCheckString .= "${v8ClassName}::create(args[$paramInde
      x], getScriptExecutionContext());\n"; |  | 
| 2403             } |  | 
| 2404         } elsif ($parameter->extendedAttributes->{"Clamp"}) { |  | 
| 2405                 my $nativeValue = "${parameterName}NativeValue"; |  | 
| 2406                 my $paramType = $parameter->type; |  | 
| 2407                 $parameterCheckString .= "    $paramType $parameterName = 0;\n"; |  | 
| 2408                 $parameterCheckString .= "    V8TRYCATCH_VOID(double, $nativeVal
      ue, args[$paramIndex]->NumberValue());\n"; |  | 
| 2409                 $parameterCheckString .= "    if (!std::isnan($nativeValue))\n"; |  | 
| 2410                 $parameterCheckString .= "        $parameterName = clampTo<$para
      mType>($nativeValue);\n"; |  | 
| 2411         } elsif ($parameter->type eq "SerializedScriptValue") { |  | 
| 2412             AddToImplIncludes("bindings/v8/SerializedScriptValue.h"); |  | 
| 2413             $parameterCheckString .= "    bool ${parameterName}DidThrow = false;
      \n"; |  | 
| 2414             $parameterCheckString .= "    $nativeType $parameterName = Serialize
      dScriptValue::create(args[$paramIndex], 0, 0, ${parameterName}DidThrow, args.Get
      Isolate());\n"; |  | 
| 2415             $parameterCheckString .= "    if (${parameterName}DidThrow)\n"; |  | 
| 2416             $parameterCheckString .= "        return;\n"; |  | 
| 2417         } elsif ($parameter->isVariadic) { |  | 
| 2418             my $nativeElementType = GetNativeType($parameter->type); |  | 
| 2419             if ($nativeElementType =~ />$/) { |  | 
| 2420                 $nativeElementType .= " "; |  | 
| 2421             } |  | 
| 2422 |  | 
| 2423             my $argType = $parameter->type; |  | 
| 2424             if (IsWrapperType($argType)) { |  | 
| 2425                 $parameterCheckString .= "    Vector<$nativeElementType> $parame
      terName;\n"; |  | 
| 2426                 $parameterCheckString .= "    for (int i = $paramIndex; i < args
      .Length(); ++i) {\n"; |  | 
| 2427                 $parameterCheckString .= "        if (!V8${argType}::HasInstance
      (args[i], args.GetIsolate(), worldType(args.GetIsolate()))) {\n"; |  | 
| 2428                 $parameterCheckString .= "            throwTypeError(args.GetIso
      late());\n"; |  | 
| 2429                 $parameterCheckString .= "            return;\n"; |  | 
| 2430                 $parameterCheckString .= "        }\n"; |  | 
| 2431                 $parameterCheckString .= "        $parameterName.append(V8${argT
      ype}::toNative(v8::Handle<v8::Object>::Cast(args[i])));\n"; |  | 
| 2432                 $parameterCheckString .= "    }\n"; |  | 
| 2433             } else { |  | 
| 2434                 $parameterCheckString .= "    V8TRYCATCH_VOID(Vector<$nativeElem
      entType>, $parameterName, toNativeArguments<$nativeElementType>(args, $paramInde
      x));\n"; |  | 
| 2435             } |  | 
| 2436         } elsif ($nativeType =~ /^V8StringResource/) { |  | 
| 2437             my $default = defined $parameter->extendedAttributes->{"Default"} ? 
      $parameter->extendedAttributes->{"Default"} : ""; |  | 
| 2438             my $jsValue = $parameter->isOptional && $default eq "NullString" ? "
      argumentOrNull(args, $paramIndex)" : "args[$paramIndex]"; |  | 
| 2439             $parameterCheckString .= JSValueToNativeStatement($parameter->type, 
      $parameter->extendedAttributes, $jsValue, $parameterName, "    ", "args.GetIsola
      te()"); |  | 
| 2440             if (IsEnumType($parameter->type)) { |  | 
| 2441                 my @enumValues = ValidEnumValues($parameter->type); |  | 
| 2442                 my @validEqualities = (); |  | 
| 2443                 foreach my $enumValue (@enumValues) { |  | 
| 2444                     push(@validEqualities, "string == \"$enumValue\""); |  | 
| 2445                 } |  | 
| 2446                 my $enumValidationExpression = join(" || ", @validEqualities); |  | 
| 2447                 $parameterCheckString .=  "    String string = $parameterName;\n
      "; |  | 
| 2448                 $parameterCheckString .= "    if (!($enumValidationExpression)) 
      {\n"; |  | 
| 2449                 $parameterCheckString .= "        throwTypeError(args.GetIsolate
      ());\n"; |  | 
| 2450                 $parameterCheckString .= "        return;\n"; |  | 
| 2451                 $parameterCheckString .= "    }\n"; |  | 
| 2452             } |  | 
| 2453         } else { |  | 
| 2454             # If the "StrictTypeChecking" extended attribute is present, and the
       argument's type is an |  | 
| 2455             # interface type, then if the incoming value does not implement that
       interface, a TypeError |  | 
| 2456             # is thrown rather than silently passing NULL to the C++ code. |  | 
| 2457             # Per the Web IDL and ECMAScript specifications, incoming values can
       always be converted |  | 
| 2458             # to both strings and numbers, so do not throw TypeError if the argu
      ment is of these |  | 
| 2459             # types. |  | 
| 2460             if ($function->extendedAttributes->{"StrictTypeChecking"}) { |  | 
| 2461                 my $argValue = "args[$paramIndex]"; |  | 
| 2462                 my $argType = $parameter->type; |  | 
| 2463                 if (IsWrapperType($argType)) { |  | 
| 2464                     $parameterCheckString .= "    if (args.Length() > $paramInde
      x && !isUndefinedOrNull($argValue) && !V8${argType}::HasInstance($argValue, args
      .GetIsolate(), worldType(args.GetIsolate()))) {\n"; |  | 
| 2465                     $parameterCheckString .= "        throwTypeError(args.GetIso
      late());\n"; |  | 
| 2466                     $parameterCheckString .= "        return;\n"; |  | 
| 2467                     $parameterCheckString .= "    }\n"; |  | 
| 2468                 } |  | 
| 2469             } |  | 
| 2470             my $default = defined $parameter->extendedAttributes->{"Default"} ? 
      $parameter->extendedAttributes->{"Default"} : ""; |  | 
| 2471             my $jsValue = $parameter->isOptional && $default eq "NullString" ? "
      argumentOrNull(args, $paramIndex)" : "args[$paramIndex]"; |  | 
| 2472             $parameterCheckString .= JSValueToNativeStatement($parameter->type, 
      $parameter->extendedAttributes, $jsValue, $parameterName, "    ", "args.GetIsola
      te()"); |  | 
| 2473             if ($nativeType eq 'Dictionary' or $nativeType eq 'ScriptPromise') { |  | 
| 2474                 $parameterCheckString .= "    if (!$parameterName.isUndefinedOrN
      ull() && !$parameterName.isObject()) {\n"; |  | 
| 2475                 $parameterCheckString .= "        throwTypeError(\"Not an object
      .\", args.GetIsolate());\n"; |  | 
| 2476                 $parameterCheckString .= "        return;\n"; |  | 
| 2477                 $parameterCheckString .= "    }\n"; |  | 
| 2478             } |  | 
| 2479         } |  | 
| 2480 |  | 
| 2481         $paramIndex++; |  | 
| 2482     } |  | 
| 2483     return ($parameterCheckString, $paramIndex, %replacements); |  | 
| 2484 } |  | 
| 2485 |  | 
| 2486 sub GenerateOverloadedConstructorCallback |  | 
| 2487 { |  | 
| 2488     my $interface = shift; |  | 
| 2489     my $implClassName = GetImplName($interface); |  | 
| 2490 |  | 
| 2491     my $code = ""; |  | 
| 2492     $code .= <<END; |  | 
| 2493 static void constructor(const v8::FunctionCallbackInfo<v8::Value>& args) |  | 
| 2494 { |  | 
| 2495 END |  | 
| 2496     my $leastNumMandatoryParams = 255; |  | 
| 2497     foreach my $constructor (@{$interface->constructors}) { |  | 
| 2498         my $name = "constructor" . $constructor->overloadedIndex; |  | 
| 2499         my ($numMandatoryParams, $parametersCheck) = GenerateFunctionParametersC
      heck($constructor); |  | 
| 2500         $leastNumMandatoryParams = $numMandatoryParams if ($numMandatoryParams <
       $leastNumMandatoryParams); |  | 
| 2501         $code .= "    if ($parametersCheck) {\n"; |  | 
| 2502         $code .= "        ${implClassName}V8Internal::${name}(args);\n"; |  | 
| 2503         $code .= "        return;\n"; |  | 
| 2504         $code .= "    }\n"; |  | 
| 2505     } |  | 
| 2506     if ($leastNumMandatoryParams >= 1) { |  | 
| 2507         AddToImplIncludes("bindings/v8/ExceptionMessages.h"); |  | 
| 2508         $code .= "    if (UNLIKELY(args.Length() < $leastNumMandatoryParams)) {\
      n"; |  | 
| 2509 |  | 
| 2510         $code .= "        throwTypeError(ExceptionMessages::failedToConstruct(\"
      $implClassName\", ExceptionMessages::notEnoughArguments($leastNumMandatoryParams
      , args.Length())), args.GetIsolate());\n"; |  | 
| 2511         $code .= "        return;\n"; |  | 
| 2512         $code .= "    }\n"; |  | 
| 2513     } |  | 
| 2514     $code .= <<END; |  | 
| 2515     throwTypeError(args.GetIsolate()); |  | 
| 2516     return; |  | 
| 2517 END |  | 
| 2518     $code .= "}\n\n"; |  | 
| 2519     $implementation{nameSpaceInternal}->add($code); |  | 
| 2520 } |  | 
| 2521 |  | 
| 2522 sub GenerateSingleConstructorCallback |  | 
| 2523 { |  | 
| 2524     my $interface = shift; |  | 
| 2525     my $function = shift; |  | 
| 2526 |  | 
| 2527     my $implClassName = GetImplName($interface); |  | 
| 2528     my $v8ClassName = GetV8ClassName($interface); |  | 
| 2529     my $overloadedIndexString = ""; |  | 
| 2530     if ($function->overloadedIndex > 0) { |  | 
| 2531         $overloadedIndexString .= $function->overloadedIndex; |  | 
| 2532     } |  | 
| 2533 |  | 
| 2534     my $raisesExceptions = $function->extendedAttributes->{"RaisesException"}; |  | 
| 2535     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) { |  | 
| 2536         $raisesExceptions = 1; |  | 
| 2537     } |  | 
| 2538 |  | 
| 2539     my @beforeArgumentList; |  | 
| 2540     my @afterArgumentList; |  | 
| 2541     my $code = ""; |  | 
| 2542     $code .= <<END; |  | 
| 2543 static void constructor${overloadedIndexString}(const v8::FunctionCallbackInfo<v
      8::Value>& args) |  | 
| 2544 { |  | 
| 2545 END |  | 
| 2546 |  | 
| 2547     if ($function->overloadedIndex == 0) { |  | 
| 2548         $code .= GenerateArgumentsCountCheck($function, $interface); |  | 
| 2549     } |  | 
| 2550 |  | 
| 2551     if ($raisesExceptions) { |  | 
| 2552         AddToImplIncludes("bindings/v8/ExceptionMessages.h"); |  | 
| 2553         AddToImplIncludes("bindings/v8/ExceptionState.h"); |  | 
| 2554         $code .= "    ExceptionState es(args.GetIsolate());\n"; |  | 
| 2555     } |  | 
| 2556 |  | 
| 2557     # FIXME: Currently [Constructor(...)] does not yet support optional argument
      s without [Default=...] |  | 
| 2558     my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersC
      heck($function, $interface, ""); |  | 
| 2559     $code .= $parameterCheckString; |  | 
| 2560 |  | 
| 2561     if ($interface->extendedAttributes->{"ConstructorCallWith"}) { |  | 
| 2562         if ($interface->extendedAttributes->{"ConstructorCallWith"} eq "ScriptEx
      ecutionContext") { |  | 
| 2563             push(@beforeArgumentList, "context"); |  | 
| 2564             $code .= "\n"; |  | 
| 2565             $code .= "    ScriptExecutionContext* context = getScriptExecutionCo
      ntext();"; |  | 
| 2566         } elsif ($interface->extendedAttributes->{"ConstructorCallWith"} eq "Doc
      ument") { |  | 
| 2567             push(@beforeArgumentList, "document"); |  | 
| 2568             $code .= "\n"; |  | 
| 2569             $code .= "    Document& document = *toDocument(getScriptExecutionCon
      text());"; |  | 
| 2570         } |  | 
| 2571     } |  | 
| 2572 |  | 
| 2573     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) { |  | 
| 2574         push(@afterArgumentList, "es"); |  | 
| 2575     } |  | 
| 2576 |  | 
| 2577     my @argumentList; |  | 
| 2578     my $index = 0; |  | 
| 2579     foreach my $parameter (@{$function->parameters}) { |  | 
| 2580         last if $index eq $paramIndex; |  | 
| 2581         if ($replacements{$parameter->name}) { |  | 
| 2582             push(@argumentList, $replacements{$parameter->name}); |  | 
| 2583         } else { |  | 
| 2584             push(@argumentList, $parameter->name); |  | 
| 2585         } |  | 
| 2586         $index++; |  | 
| 2587     } |  | 
| 2588 |  | 
| 2589     my $argumentString = join(", ", @beforeArgumentList, @argumentList, @afterAr
      gumentList); |  | 
| 2590     $code .= "\n"; |  | 
| 2591     $code .= "    RefPtr<${implClassName}> impl = ${implClassName}::create(${arg
      umentString});\n"; |  | 
| 2592     $code .= "    v8::Handle<v8::Object> wrapper = args.Holder();\n"; |  | 
| 2593 |  | 
| 2594     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) { |  | 
| 2595         $code .= "    if (es.throwIfNeeded())\n"; |  | 
| 2596         $code .= "        return;\n"; |  | 
| 2597     } |  | 
| 2598 |  | 
| 2599     $code .= <<END; |  | 
| 2600 |  | 
| 2601     V8DOMWrapper::associateObjectWithWrapper<${v8ClassName}>(impl.release(), &${
      v8ClassName}::info, wrapper, args.GetIsolate(), WrapperConfiguration::Dependent)
      ; |  | 
| 2602     args.GetReturnValue().Set(wrapper); |  | 
| 2603 } |  | 
| 2604 |  | 
| 2605 END |  | 
| 2606     $implementation{nameSpaceInternal}->add($code); |  | 
| 2607 } |  | 
| 2608 |  | 
| 2609 # The Web IDL specification states that Interface objects for interfaces MUST ha
      ve a property named |  | 
| 2610 # "length" that returns the length of the shortest argument list of the entries 
      in the effective |  | 
| 2611 # overload set for constructors. In other words, use the lowest number of mandat
      ory arguments among |  | 
| 2612 # all constructors. |  | 
| 2613 sub GetInterfaceLength |  | 
| 2614 { |  | 
| 2615     my $interface = shift; |  | 
| 2616 |  | 
| 2617     my $leastConstructorLength = 0; |  | 
| 2618     if (IsConstructorTemplate($interface, "Event") || IsConstructorTemplate($int
      erface, "TypedArray")) { |  | 
| 2619         $leastConstructorLength = 1; |  | 
| 2620     } elsif ($interface->extendedAttributes->{"Constructor"} || $interface->exte
      ndedAttributes->{"CustomConstructor"}) { |  | 
| 2621         my @constructors = @{$interface->constructors}; |  | 
| 2622         my @customConstructors = @{$interface->customConstructors}; |  | 
| 2623         $leastConstructorLength = 255; |  | 
| 2624         foreach my $constructor (@constructors, @customConstructors) { |  | 
| 2625             my $constructorLength = GetFunctionLength($constructor); |  | 
| 2626             $leastConstructorLength = $constructorLength if ($constructorLength 
      < $leastConstructorLength); |  | 
| 2627         } |  | 
| 2628     } |  | 
| 2629 |  | 
| 2630     return $leastConstructorLength; |  | 
| 2631 } |  | 
| 2632 |  | 
| 2633 sub GenerateConstructorCallback |  | 
| 2634 { |  | 
| 2635     my $interface = shift; |  | 
| 2636 |  | 
| 2637     my $implClassName = GetImplName($interface); |  | 
| 2638     my $v8ClassName = GetV8ClassName($interface); |  | 
| 2639     my $code = ""; |  | 
| 2640     $code .= "void ${v8ClassName}::constructorCallback(const v8::FunctionCallbac
      kInfo<v8::Value>& args)\n"; |  | 
| 2641     $code .= "{\n"; |  | 
| 2642     $code .= "    TRACE_EVENT_SCOPED_SAMPLING_STATE(\"Blink\", \"DOMConstructor\
      ");\n"; |  | 
| 2643     $code .= GenerateFeatureObservation($interface->extendedAttributes->{"Measur
      eAs"}); |  | 
| 2644     $code .= GenerateDeprecationNotification($interface->extendedAttributes->{"D
      eprecateAs"}); |  | 
| 2645     $code .= GenerateConstructorHeader(); |  | 
| 2646     if (HasCustomConstructor($interface)) { |  | 
| 2647         $code .= "    ${v8ClassName}::constructorCustom(args);\n"; |  | 
| 2648     } else { |  | 
| 2649         $code .= "    ${implClassName}V8Internal::constructor(args);\n"; |  | 
| 2650     } |  | 
| 2651     $code .= "}\n\n"; |  | 
| 2652     $implementation{nameSpaceWebCore}->add($code); |  | 
| 2653 } |  | 
| 2654 |  | 
| 2655 sub GenerateConstructor |  | 
| 2656 { |  | 
| 2657     my $interface = shift; |  | 
| 2658 |  | 
| 2659     if (@{$interface->constructors} == 1) { |  | 
| 2660         GenerateSingleConstructorCallback($interface, @{$interface->constructors
      }[0]); |  | 
| 2661     } else { |  | 
| 2662         foreach my $constructor (@{$interface->constructors}) { |  | 
| 2663             GenerateSingleConstructorCallback($interface, $constructor); |  | 
| 2664         } |  | 
| 2665         GenerateOverloadedConstructorCallback($interface); |  | 
| 2666     } |  | 
| 2667 } |  | 
| 2668 |  | 
| 2669 sub GenerateEventConstructor |  | 
| 2670 { |  | 
| 2671     my $interface = shift; |  | 
| 2672     my $implClassName = GetImplName($interface); |  | 
| 2673     my $v8ClassName = GetV8ClassName($interface); |  | 
| 2674 |  | 
| 2675     my @anyAttributeNames; |  | 
| 2676     my @serializableAnyAttributeNames; |  | 
| 2677     foreach my $attribute (@{$interface->attributes}) { |  | 
| 2678         if ($attribute->type eq "any") { |  | 
| 2679             push(@anyAttributeNames, $attribute->name); |  | 
| 2680             if (!$attribute->extendedAttributes->{"Unserializable"}) { |  | 
| 2681                 push(@serializableAnyAttributeNames, $attribute->name); |  | 
| 2682             } |  | 
| 2683         } |  | 
| 2684     } |  | 
| 2685 |  | 
| 2686     AddToImplIncludes("bindings/v8/Dictionary.h"); |  | 
| 2687     AddToImplIncludes("bindings/v8/ExceptionMessages.h"); |  | 
| 2688     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 2689 static void constructor(const v8::FunctionCallbackInfo<v8::Value>& args) |  | 
| 2690 { |  | 
| 2691     if (args.Length() < 1) { |  | 
| 2692         throwTypeError(ExceptionMessages::failedToConstruct("$implClassName", "A
      n event name must be provided."), args.GetIsolate()); |  | 
| 2693         return; |  | 
| 2694     } |  | 
| 2695 |  | 
| 2696     V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, args[0]); |  | 
| 2697 END |  | 
| 2698 |  | 
| 2699     foreach my $attrName (@anyAttributeNames) { |  | 
| 2700         $implementation{nameSpaceInternal}->add("    v8::Local<v8::Value> ${attr
      Name};\n"); |  | 
| 2701     } |  | 
| 2702 |  | 
| 2703     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 2704     ${implClassName}Init eventInit; |  | 
| 2705     if (args.Length() >= 2) { |  | 
| 2706         V8TRYCATCH_VOID(Dictionary, options, Dictionary(args[1], args.GetIsolate
      ())); |  | 
| 2707         if (!fill${implClassName}Init(eventInit, options)) |  | 
| 2708             return; |  | 
| 2709 END |  | 
| 2710 |  | 
| 2711     # Store 'any'-typed properties on the wrapper to avoid leaking them between 
      isolated worlds. |  | 
| 2712     foreach my $attrName (@anyAttributeNames) { |  | 
| 2713         $implementation{nameSpaceInternal}->add(<<END); |  | 
| 2714         options.get("${attrName}", ${attrName}); |  | 
| 2715         if (!${attrName}.IsEmpty()) |  | 
| 2716             args.Holder()->SetHiddenValue(V8HiddenPropertyName::${attrName}(), $
      {attrName}); |  | 
| 2717 END |  | 
| 2718     } |  | 
| 2719 |  | 
| 2720     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 2721     } |  | 
| 2722 |  | 
| 2723     RefPtr<${implClassName}> event = ${implClassName}::create(type, eventInit); |  | 
| 2724 END |  | 
| 2725 |  | 
| 2726     if (@serializableAnyAttributeNames) { |  | 
| 2727         # If we're in an isolated world, create a SerializedScriptValue and stor
      e it in the event for |  | 
| 2728         # later cloning if the property is accessed from another world. |  | 
| 2729         # The main world case is handled lazily (in Custom code). |  | 
| 2730         $implementation{nameSpaceInternal}->add("    if (isolatedWorldForIsolate
      (args.GetIsolate())) {\n"); |  | 
| 2731         foreach my $attrName (@serializableAnyAttributeNames) { |  | 
| 2732             my $setter = "setSerialized" . FirstLetterToUpperCase($attrName); |  | 
| 2733             $implementation{nameSpaceInternal}->add(<<END); |  | 
| 2734         if (!${attrName}.IsEmpty()) |  | 
| 2735             event->${setter}(SerializedScriptValue::createAndSwallowExceptions($
      {attrName}, args.GetIsolate())); |  | 
| 2736 END |  | 
| 2737         } |  | 
| 2738         $implementation{nameSpaceInternal}->add("    }\n\n"); |  | 
| 2739     } |  | 
| 2740 |  | 
| 2741     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 2742     v8::Handle<v8::Object> wrapper = args.Holder(); |  | 
| 2743     V8DOMWrapper::associateObjectWithWrapper<${v8ClassName}>(event.release(), &$
      {v8ClassName}::info, wrapper, args.GetIsolate(), WrapperConfiguration::Dependent
      ); |  | 
| 2744     v8SetReturnValue(args, wrapper); |  | 
| 2745 } |  | 
| 2746 END |  | 
| 2747 |  | 
| 2748     my $code = ""; |  | 
| 2749     $code .= <<END; |  | 
| 2750 bool fill${implClassName}Init(${implClassName}Init& eventInit, const Dictionary&
       options) |  | 
| 2751 { |  | 
| 2752 END |  | 
| 2753 |  | 
| 2754     if ($interface->parent) { |  | 
| 2755         my $interfaceBase = $interface->parent; |  | 
| 2756         $code .= <<END; |  | 
| 2757     if (!fill${interfaceBase}Init(eventInit, options)) |  | 
| 2758         return false; |  | 
| 2759 |  | 
| 2760 END |  | 
| 2761     } |  | 
| 2762 |  | 
| 2763     foreach my $attribute (@{$interface->attributes}) { |  | 
| 2764         if ($attribute->extendedAttributes->{"InitializedByEventConstructor"}) { |  | 
| 2765             if ($attribute->type ne "any") { |  | 
| 2766                 my $attributeName = $attribute->name; |  | 
| 2767                 my $attributeImplName = GetImplName($attribute); |  | 
| 2768                 my $deprecation = $attribute->extendedAttributes->{"DeprecateAs"
      }; |  | 
| 2769                 my $dictionaryGetter = "options.get(\"$attributeName\", eventIni
      t.$attributeImplName)"; |  | 
| 2770                 if ($attribute->extendedAttributes->{"DeprecateAs"}) { |  | 
| 2771                     $code .= "    if ($dictionaryGetter)\n"; |  | 
| 2772                     $code .= "    " . GenerateDeprecationNotification($attribute
      ->extendedAttributes->{"DeprecateAs"}); |  | 
| 2773                 } else { |  | 
| 2774                     $code .= "    $dictionaryGetter;\n"; |  | 
| 2775                 } |  | 
| 2776             } |  | 
| 2777         } |  | 
| 2778     } |  | 
| 2779 |  | 
| 2780     $code .= <<END; |  | 
| 2781     return true; |  | 
| 2782 } |  | 
| 2783 |  | 
| 2784 END |  | 
| 2785     $implementation{nameSpaceWebCore}->add($code); |  | 
| 2786 } |  | 
| 2787 |  | 
| 2788 sub GenerateNamedConstructor |  | 
| 2789 { |  | 
| 2790     my $function = shift; |  | 
| 2791     my $interface = shift; |  | 
| 2792 |  | 
| 2793     my $implClassName = GetImplName($interface); |  | 
| 2794     my $v8ClassName = GetV8ClassName($interface); |  | 
| 2795     my $raisesExceptions = $function->extendedAttributes->{"RaisesException"}; |  | 
| 2796     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) { |  | 
| 2797         $raisesExceptions = 1; |  | 
| 2798     } |  | 
| 2799 |  | 
| 2800     my $maybeObserveFeature = GenerateFeatureObservation($function->extendedAttr
      ibutes->{"MeasureAs"}); |  | 
| 2801     my $maybeDeprecateFeature = GenerateDeprecationNotification($function->exten
      dedAttributes->{"DeprecateAs"}); |  | 
| 2802 |  | 
| 2803     my @beforeArgumentList; |  | 
| 2804     my @afterArgumentList; |  | 
| 2805 |  | 
| 2806     my $toActiveDOMObject = "0"; |  | 
| 2807     if (InheritsExtendedAttribute($interface, "ActiveDOMObject")) { |  | 
| 2808         $toActiveDOMObject = "${v8ClassName}::toActiveDOMObject"; |  | 
| 2809     } |  | 
| 2810 |  | 
| 2811     my $toEventTarget = "0"; |  | 
| 2812     if (InheritsInterface($interface, "EventTarget")) { |  | 
| 2813         $toEventTarget = "${v8ClassName}::toEventTarget"; |  | 
| 2814     } |  | 
| 2815 |  | 
| 2816     $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 2817 WrapperTypeInfo ${v8ClassName}Constructor::info = { ${v8ClassName}Constructor::G
      etTemplate, ${v8ClassName}::derefObject, $toActiveDOMObject, $toEventTarget, 0, 
      ${v8ClassName}::installPerContextPrototypeProperties, 0, WrapperTypeObjectProtot
      ype }; |  | 
| 2818 |  | 
| 2819 END |  | 
| 2820 |  | 
| 2821     my $code = ""; |  | 
| 2822     $code .= <<END; |  | 
| 2823 static void ${v8ClassName}ConstructorCallback(const v8::FunctionCallbackInfo<v8:
      :Value>& args) |  | 
| 2824 { |  | 
| 2825 END |  | 
| 2826     $code .= $maybeObserveFeature if $maybeObserveFeature; |  | 
| 2827     $code .= $maybeDeprecateFeature if $maybeDeprecateFeature; |  | 
| 2828     $code .= GenerateConstructorHeader(); |  | 
| 2829     AddToImplIncludes("V8Document.h"); |  | 
| 2830     $code .= <<END; |  | 
| 2831     Document* document = currentDocument(); |  | 
| 2832     ASSERT(document); |  | 
| 2833 |  | 
| 2834     // Make sure the document is added to the DOM Node map. Otherwise, the ${imp
      lClassName} instance |  | 
| 2835     // may end up being the only node in the map and get garbage-collected prema
      turely. |  | 
| 2836     toV8(document, args.Holder(), args.GetIsolate()); |  | 
| 2837 |  | 
| 2838 END |  | 
| 2839 |  | 
| 2840     $code .= GenerateArgumentsCountCheck($function, $interface); |  | 
| 2841 |  | 
| 2842     if ($raisesExceptions) { |  | 
| 2843         AddToImplIncludes("bindings/v8/ExceptionMessages.h"); |  | 
| 2844         AddToImplIncludes("bindings/v8/ExceptionState.h"); |  | 
| 2845         $code .= "    ExceptionState es(args.GetIsolate());\n"; |  | 
| 2846     } |  | 
| 2847 |  | 
| 2848     my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersC
      heck($function, $interface); |  | 
| 2849     $code .= $parameterCheckString; |  | 
| 2850 |  | 
| 2851     push(@beforeArgumentList, "*document"); |  | 
| 2852 |  | 
| 2853     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) { |  | 
| 2854         push(@afterArgumentList, "es"); |  | 
| 2855     } |  | 
| 2856 |  | 
| 2857     my @argumentList; |  | 
| 2858     my $index = 0; |  | 
| 2859     foreach my $parameter (@{$function->parameters}) { |  | 
| 2860         last if $index eq $paramIndex; |  | 
| 2861         if ($replacements{$parameter->name}) { |  | 
| 2862             push(@argumentList, $replacements{$parameter->name}); |  | 
| 2863         } else { |  | 
| 2864             push(@argumentList, $parameter->name); |  | 
| 2865         } |  | 
| 2866         $index++; |  | 
| 2867     } |  | 
| 2868 |  | 
| 2869     my $argumentString = join(", ", @beforeArgumentList, @argumentList, @afterAr
      gumentList); |  | 
| 2870     $code .= "\n"; |  | 
| 2871     $code .= "    RefPtr<${implClassName}> impl = ${implClassName}::createForJSC
      onstructor(${argumentString});\n"; |  | 
| 2872     $code .= "    v8::Handle<v8::Object> wrapper = args.Holder();\n"; |  | 
| 2873 |  | 
| 2874     if ($interface->extendedAttributes->{"ConstructorRaisesException"}) { |  | 
| 2875         $code .= "    if (es.throwIfNeeded())\n"; |  | 
| 2876         $code .= "        return;\n"; |  | 
| 2877     } |  | 
| 2878 |  | 
| 2879     $code .= <<END; |  | 
| 2880 |  | 
| 2881     V8DOMWrapper::associateObjectWithWrapper<${v8ClassName}>(impl.release(), &${
      v8ClassName}Constructor::info, wrapper, args.GetIsolate(), WrapperConfiguration:
      :Dependent); |  | 
| 2882     args.GetReturnValue().Set(wrapper); |  | 
| 2883 } |  | 
| 2884 |  | 
| 2885 END |  | 
| 2886     $implementation{nameSpaceWebCore}->add($code); |  | 
| 2887 |  | 
| 2888     $code = <<END; |  | 
| 2889 v8::Handle<v8::FunctionTemplate> ${v8ClassName}Constructor::GetTemplate(v8::Isol
      ate* isolate, WrapperWorldType currentWorldType) |  | 
| 2890 { |  | 
| 2891     // This is only for getting a unique pointer which we can pass to privateTem
      plate. |  | 
| 2892     static const char* privateTemplateUniqueKey = "${v8ClassName}Constructor::Ge
      tTemplatePrivateTemplate"; |  | 
| 2893     V8PerIsolateData* data = V8PerIsolateData::from(isolate); |  | 
| 2894     v8::Handle<v8::FunctionTemplate> result = data->privateTemplateIfExists(curr
      entWorldType, &privateTemplateUniqueKey); |  | 
| 2895     if (!result.IsEmpty()) |  | 
| 2896         return result; |  | 
| 2897 |  | 
| 2898     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink\", \"BuildDOMTemplate"); |  | 
| 2899     v8::HandleScope scope(isolate); |  | 
| 2900     result = v8::FunctionTemplate::New(${v8ClassName}ConstructorCallback); |  | 
| 2901 |  | 
| 2902     v8::Local<v8::ObjectTemplate> instance = result->InstanceTemplate(); |  | 
| 2903     instance->SetInternalFieldCount(${v8ClassName}::internalFieldCount); |  | 
| 2904     result->SetClassName(v8::String::NewSymbol("${implClassName}")); |  | 
| 2905     result->Inherit(${v8ClassName}::GetTemplate(isolate, currentWorldType)); |  | 
| 2906     data->setPrivateTemplate(currentWorldType, &privateTemplateUniqueKey, result
      ); |  | 
| 2907 |  | 
| 2908     return scope.Close(result); |  | 
| 2909 } |  | 
| 2910 |  | 
| 2911 END |  | 
| 2912     $implementation{nameSpaceWebCore}->add($code); |  | 
| 2913 } |  | 
| 2914 |  | 
| 2915 sub GenerateConstructorHeader |  | 
| 2916 { |  | 
| 2917     AddToImplIncludes("bindings/v8/V8ObjectConstructor.h"); |  | 
| 2918     my $content = <<END; |  | 
| 2919     if (!args.IsConstructCall()) { |  | 
| 2920         throwTypeError("DOM object constructor cannot be called as a function.",
       args.GetIsolate()); |  | 
| 2921         return; |  | 
| 2922     } |  | 
| 2923 |  | 
| 2924     if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) { |  | 
| 2925         args.GetReturnValue().Set(args.Holder()); |  | 
| 2926         return; |  | 
| 2927     } |  | 
| 2928 |  | 
| 2929 END |  | 
| 2930     return $content; |  | 
| 2931 } |  | 
| 2932 |  | 
| 2933 sub GenerateAttributeConfigurationArray |  | 
| 2934 { |  | 
| 2935     my $interface = shift; |  | 
| 2936     my $attributes = shift; |  | 
| 2937     my $code = ""; |  | 
| 2938 |  | 
| 2939     foreach my $attribute (@$attributes) { |  | 
| 2940         my $conditionalString = GenerateConditionalString($attribute); |  | 
| 2941         my $subCode = ""; |  | 
| 2942         $subCode .= "#if ${conditionalString}\n" if $conditionalString; |  | 
| 2943         $subCode .= GenerateAttributeConfiguration($interface, $attribute, ",", 
      ""); |  | 
| 2944         $subCode .= "#endif // ${conditionalString}\n" if $conditionalString; |  | 
| 2945         $code .= $subCode; |  | 
| 2946     } |  | 
| 2947     return $code; |  | 
| 2948 } |  | 
| 2949 |  | 
| 2950 sub GenerateAttributeConfiguration |  | 
| 2951 { |  | 
| 2952     my $interface = shift; |  | 
| 2953     my $attribute = shift; |  | 
| 2954     my $delimiter = shift; |  | 
| 2955     my $indent = shift; |  | 
| 2956     my $code = ""; |  | 
| 2957     my $attrName = $attribute->name; |  | 
| 2958     my $attrExt = $attribute->extendedAttributes; |  | 
| 2959     my $implClassName = GetImplName($interface); |  | 
| 2960 |  | 
| 2961     my $accessControl = "v8::DEFAULT"; |  | 
| 2962     if ($attrExt->{"DoNotCheckSecurityOnGetter"}) { |  | 
| 2963         $accessControl = "v8::ALL_CAN_READ"; |  | 
| 2964     } elsif ($attrExt->{"DoNotCheckSecurityOnSetter"}) { |  | 
| 2965         $accessControl = "v8::ALL_CAN_WRITE"; |  | 
| 2966     } elsif ($attrExt->{"DoNotCheckSecurity"}) { |  | 
| 2967         $accessControl = "v8::ALL_CAN_READ"; |  | 
| 2968         if (!IsReadonly($attribute)) { |  | 
| 2969             $accessControl .= " | v8::ALL_CAN_WRITE"; |  | 
| 2970         } |  | 
| 2971     } |  | 
| 2972     if ($attrExt->{"Unforgeable"}) { |  | 
| 2973         $accessControl .= " | v8::PROHIBITS_OVERWRITING"; |  | 
| 2974     } |  | 
| 2975     $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")"; |  | 
| 2976 |  | 
| 2977     my $customAccessor = HasCustomGetter($attrExt) || HasCustomSetter($attrExt) 
      || ""; |  | 
| 2978     if ($customAccessor eq "VALUE_IS_MISSING") { |  | 
| 2979         # use the naming convension, interface + (capitalize) attr name |  | 
| 2980         $customAccessor = $implClassName . "::" . $attrName; |  | 
| 2981     } |  | 
| 2982 |  | 
| 2983     my $getter; |  | 
| 2984     my $setter; |  | 
| 2985     my $getterForMainWorld; |  | 
| 2986     my $setterForMainWorld; |  | 
| 2987     my $propAttribute = "v8::None"; |  | 
| 2988 |  | 
| 2989     my $isConstructor = ($attribute->type =~ /Constructor$/); |  | 
| 2990 |  | 
| 2991     # Check attributes. |  | 
| 2992     # As per Web IDL specification, constructor properties on the ECMAScript glo
      bal object should be |  | 
| 2993     # configurable and should not be enumerable. |  | 
| 2994     if ($attrExt->{"NotEnumerable"} || $isConstructor) { |  | 
| 2995         $propAttribute .= " | v8::DontEnum"; |  | 
| 2996     } |  | 
| 2997     if ($attrExt->{"Unforgeable"} && !$isConstructor) { |  | 
| 2998         $propAttribute .= " | v8::DontDelete"; |  | 
| 2999     } |  | 
| 3000 |  | 
| 3001     my $on_proto = "0 /* on instance */"; |  | 
| 3002     my $data = "0";  # no data |  | 
| 3003 |  | 
| 3004     # Constructor |  | 
| 3005     if ($isConstructor) { |  | 
| 3006         my $constructorType = $attribute->type; |  | 
| 3007         $constructorType =~ s/Constructor$//; |  | 
| 3008         # $constructorType ~= /Constructor$/ indicates that it is NamedConstruct
      or. |  | 
| 3009         # We do not generate the header file for NamedConstructor of class XXXX, |  | 
| 3010         # since we generate the NamedConstructor declaration into the header fil
      e of class XXXX. |  | 
| 3011         if ($constructorType !~ /Constructor$/ || $attribute->extendedAttributes
      ->{"CustomConstructor"}) { |  | 
| 3012             AddToImplIncludes("V8${constructorType}.h"); |  | 
| 3013         } |  | 
| 3014         $data = "&V8${constructorType}::info"; |  | 
| 3015         $getter = "${implClassName}V8Internal::${implClassName}ConstructorGetter
      "; |  | 
| 3016         $setter = "${implClassName}V8Internal::${implClassName}ReplaceableAttrib
      uteSetterCallback"; |  | 
| 3017         $getterForMainWorld = "0"; |  | 
| 3018         $setterForMainWorld = "0"; |  | 
| 3019     } else { |  | 
| 3020         # Default Getter and Setter |  | 
| 3021         $getter = "${implClassName}V8Internal::${attrName}AttributeGetterCallbac
      k"; |  | 
| 3022         $setter = "${implClassName}V8Internal::${attrName}AttributeSetterCallbac
      k"; |  | 
| 3023         $getterForMainWorld = "${getter}ForMainWorld"; |  | 
| 3024         $setterForMainWorld = "${setter}ForMainWorld"; |  | 
| 3025 |  | 
| 3026         if (!HasCustomSetter($attrExt) && $attrExt->{"Replaceable"}) { |  | 
| 3027             $setter = "${implClassName}V8Internal::${implClassName}ReplaceableAt
      tributeSetterCallback"; |  | 
| 3028             $setterForMainWorld = "0"; |  | 
| 3029         } |  | 
| 3030     } |  | 
| 3031 |  | 
| 3032     # Read only attributes |  | 
| 3033     if (IsReadonly($attribute)) { |  | 
| 3034         $setter = "0"; |  | 
| 3035         $setterForMainWorld = "0"; |  | 
| 3036     } |  | 
| 3037 |  | 
| 3038     # An accessor can be installed on the proto |  | 
| 3039     if ($attrExt->{"OnProto"}) { |  | 
| 3040         $on_proto = "1 /* on proto */"; |  | 
| 3041     } |  | 
| 3042 |  | 
| 3043     if (!$attrExt->{"PerWorldBindings"}) { |  | 
| 3044       $getterForMainWorld = "0"; |  | 
| 3045       $setterForMainWorld = "0"; |  | 
| 3046     } |  | 
| 3047 |  | 
| 3048     $code .= $indent . "    {\"$attrName\", $getter, $setter, $getterForMainWorl
      d, $setterForMainWorld, $data, $accessControl, static_cast<v8::PropertyAttribute
      >($propAttribute), $on_proto}" . $delimiter . "\n"; |  | 
| 3049     return $code; |  | 
| 3050 } |  | 
| 3051 |  | 
| 3052 sub IsStandardFunction |  | 
| 3053 { |  | 
| 3054     my $interface = shift; |  | 
| 3055     my $function = shift; |  | 
| 3056 |  | 
| 3057     my $interfaceName = $interface->name; |  | 
| 3058     my $attrExt = $function->extendedAttributes; |  | 
| 3059     return 0 if $attrExt->{"Unforgeable"}; |  | 
| 3060     return 0 if $function->isStatic; |  | 
| 3061     return 0 if $attrExt->{"EnabledAtRuntime"}; |  | 
| 3062     return 0 if $attrExt->{"EnabledPerContext"}; |  | 
| 3063     return 0 if RequiresCustomSignature($function); |  | 
| 3064     return 0 if $attrExt->{"DoNotCheckSignature"}; |  | 
| 3065     return 0 if ($attrExt->{"DoNotCheckSecurity"} && ($interface->extendedAttrib
      utes->{"CheckSecurity"} || $interfaceName eq "Window")); |  | 
| 3066     return 0 if $attrExt->{"NotEnumerable"}; |  | 
| 3067     return 0 if $attrExt->{"ReadOnly"}; |  | 
| 3068     return 1; |  | 
| 3069 } |  | 
| 3070 |  | 
| 3071 sub GenerateNonStandardFunction |  | 
| 3072 { |  | 
| 3073     my $interface = shift; |  | 
| 3074     my $function = shift; |  | 
| 3075     my $code = ""; |  | 
| 3076 |  | 
| 3077     my $implClassName = GetImplName($interface); |  | 
| 3078     my $attrExt = $function->extendedAttributes; |  | 
| 3079     my $name = $function->name; |  | 
| 3080 |  | 
| 3081     my $property_attributes = "v8::DontDelete"; |  | 
| 3082     if ($attrExt->{"NotEnumerable"}) { |  | 
| 3083         $property_attributes .= " | v8::DontEnum"; |  | 
| 3084     } |  | 
| 3085     if ($attrExt->{"ReadOnly"}) { |  | 
| 3086         $property_attributes .= " | v8::ReadOnly"; |  | 
| 3087     } |  | 
| 3088 |  | 
| 3089     my $commentInfo = "Function '$name' (Extended Attributes: '" . join(' ', key
      s(%{$attrExt})) . "')"; |  | 
| 3090 |  | 
| 3091     my $template = "proto"; |  | 
| 3092     if ($attrExt->{"Unforgeable"}) { |  | 
| 3093         $template = "instance"; |  | 
| 3094     } |  | 
| 3095     if ($function->isStatic) { |  | 
| 3096         $template = "desc"; |  | 
| 3097     } |  | 
| 3098 |  | 
| 3099     my $conditional = ""; |  | 
| 3100     if ($attrExt->{"EnabledAtRuntime"}) { |  | 
| 3101         # Only call Set()/SetAccessor() if this method should be enabled |  | 
| 3102         my $enable_function = GetRuntimeEnableFunctionName($function); |  | 
| 3103         $conditional = "if (${enable_function}())\n        "; |  | 
| 3104     } |  | 
| 3105     if ($attrExt->{"EnabledPerContext"}) { |  | 
| 3106         # Only call Set()/SetAccessor() if this method should be enabled |  | 
| 3107         my $enable_function = GetContextEnableFunction($function); |  | 
| 3108         $conditional = "if (${enable_function}(impl->document()))\n        "; |  | 
| 3109     } |  | 
| 3110 |  | 
| 3111     if ($interface->extendedAttributes->{"CheckSecurity"} && $attrExt->{"DoNotCh
      eckSecurity"}) { |  | 
| 3112         my $setter = $attrExt->{"ReadOnly"} ? "0" : "${implClassName}V8Internal:
      :${implClassName}DomainSafeFunctionSetter"; |  | 
| 3113         # Functions that are marked DoNotCheckSecurity are always readable but i
      f they are changed |  | 
| 3114         # and then accessed on a different domain we do not return the underlyin
      g value but instead |  | 
| 3115         # return a new copy of the original function. This is achieved by storin
      g the changed value |  | 
| 3116         # as hidden property. |  | 
| 3117         $code .= <<END; |  | 
| 3118 |  | 
| 3119     // $commentInfo |  | 
| 3120     ${conditional}$template->SetAccessor(v8::String::NewSymbol("$name"), ${implC
      lassName}V8Internal::${name}AttributeGetterCallback, ${setter}, v8Undefined(), v
      8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>($property_attributes)); |  | 
| 3121 END |  | 
| 3122         return $code; |  | 
| 3123     } |  | 
| 3124 |  | 
| 3125     my $signature = "defaultSignature"; |  | 
| 3126     if ($attrExt->{"DoNotCheckSignature"} || $function->isStatic) { |  | 
| 3127        $signature = "v8::Local<v8::Signature>()"; |  | 
| 3128     } |  | 
| 3129 |  | 
| 3130     my $conditionalString = GenerateConditionalString($function); |  | 
| 3131     $code .= "#if ${conditionalString}\n" if $conditionalString; |  | 
| 3132     if (RequiresCustomSignature($function)) { |  | 
| 3133         $signature = "${name}Signature"; |  | 
| 3134         $code .= "\n    // Custom Signature '$name'\n" . CreateCustomSignature($
      function); |  | 
| 3135     } |  | 
| 3136 |  | 
| 3137     if ($property_attributes eq "v8::DontDelete") { |  | 
| 3138         $property_attributes = ""; |  | 
| 3139     } else { |  | 
| 3140         $property_attributes = ", static_cast<v8::PropertyAttribute>($property_a
      ttributes)"; |  | 
| 3141     } |  | 
| 3142 |  | 
| 3143     if ($template eq "proto" && $conditional eq "" && $signature eq "defaultSign
      ature" && $property_attributes eq "") { |  | 
| 3144         die "This shouldn't happen: Class '$implClassName' $commentInfo\n"; |  | 
| 3145     } |  | 
| 3146 |  | 
| 3147     my $functionLength = GetFunctionLength($function); |  | 
| 3148 |  | 
| 3149     if ($function->extendedAttributes->{"PerWorldBindings"}) { |  | 
| 3150         $code .= "    if (currentWorldType == MainWorld) {\n"; |  | 
| 3151         $code .= "        ${conditional}$template->Set(v8::String::NewSymbol(\"$
      name\"), v8::FunctionTemplate::New(${implClassName}V8Internal::${name}MethodCall
      backForMainWorld, v8Undefined(), ${signature}, $functionLength)$property_attribu
      tes);\n"; |  | 
| 3152         $code .= "    } else {\n"; |  | 
| 3153         $code .= "        ${conditional}$template->Set(v8::String::NewSymbol(\"$
      name\"), v8::FunctionTemplate::New(${implClassName}V8Internal::${name}MethodCall
      back, v8Undefined(), ${signature}, $functionLength)$property_attributes);\n"; |  | 
| 3154         $code .= "    }\n"; |  | 
| 3155     } else { |  | 
| 3156         $code .= "    ${conditional}$template->Set(v8::String::NewSymbol(\"$name
      \"), v8::FunctionTemplate::New(${implClassName}V8Internal::${name}MethodCallback
      , v8Undefined(), ${signature}, $functionLength)$property_attributes);\n"; |  | 
| 3157     } |  | 
| 3158     $code .= "#endif // ${conditionalString}\n" if $conditionalString; |  | 
| 3159     return $code; |  | 
| 3160 } |  | 
| 3161 |  | 
| 3162 sub GenerateIsNullExpression |  | 
| 3163 { |  | 
| 3164     my $type = shift; |  | 
| 3165     my $variableName = shift; |  | 
| 3166     if (IsUnionType($type)) { |  | 
| 3167         my $types = $type->unionMemberTypes; |  | 
| 3168         my @expression = (); |  | 
| 3169         for my $i (0 .. scalar(@$types)-1) { |  | 
| 3170             my $unionMemberType = $types->[$i]; |  | 
| 3171             my $unionMemberVariable = $variableName . $i; |  | 
| 3172             my $isNull = GenerateIsNullExpression($unionMemberType, $unionMember
      Variable); |  | 
| 3173             push @expression, $isNull; |  | 
| 3174         } |  | 
| 3175         return join " && ", @expression; |  | 
| 3176     } |  | 
| 3177     if (IsRefPtrType($type)) { |  | 
| 3178         return "!${variableName}"; |  | 
| 3179     } elsif ($type eq "DOMString") { |  | 
| 3180         return "${variableName}.isNull()"; |  | 
| 3181     } elsif ($type eq "Promise") { |  | 
| 3182         return "${variableName}.isNull()"; |  | 
| 3183     } else { |  | 
| 3184         return ""; |  | 
| 3185     } |  | 
| 3186 } |  | 
| 3187 |  | 
| 3188 sub GenerateIfElseStatement |  | 
| 3189 { |  | 
| 3190     my $type = shift; |  | 
| 3191     my $outputVariableName = shift; |  | 
| 3192     my $conditions = shift; |  | 
| 3193     my $statements = shift; |  | 
| 3194 |  | 
| 3195     my $code = ""; |  | 
| 3196     if (@$conditions == 1) { |  | 
| 3197         $code .= "    ${type} ${outputVariableName} = " . $statements->[0] . "\n
      "; |  | 
| 3198     } else { |  | 
| 3199         $code .= "    ${type} ${outputVariableName};\n"; |  | 
| 3200         for my $i (0 .. @$conditions - 1) { |  | 
| 3201             my $token = "else if"; |  | 
| 3202             $token = "if" if $i == 0; |  | 
| 3203             $token = "else" if $i == @$conditions - 1; |  | 
| 3204             $code .= "    ${token}"; |  | 
| 3205             $code .= " (" . $conditions->[$i] . ")" if $conditions->[$i]; |  | 
| 3206             $code .= "\n"; |  | 
| 3207             $code .= "        ${outputVariableName} = " . $statements->[$i] . "\
      n"; |  | 
| 3208         } |  | 
| 3209     } |  | 
| 3210     return $code; |  | 
| 3211 } |  | 
| 3212 |  | 
| 3213 sub GenerateImplementationIndexedPropertyAccessors |  | 
| 3214 { |  | 
| 3215     my $interface = shift; |  | 
| 3216     my $interfaceName = $interface->name; |  | 
| 3217     my $implClassName = GetImplName($interface); |  | 
| 3218     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3219 |  | 
| 3220     my $indexedGetterFunction = GetIndexedGetterFunction($interface); |  | 
| 3221     if ($indexedGetterFunction) { |  | 
| 3222         my $hasCustomIndexedGetter = $indexedGetterFunction->extendedAttributes-
      >{"Custom"}; |  | 
| 3223         if (!$hasCustomIndexedGetter) { |  | 
| 3224             GenerateImplementationIndexedPropertyGetter($interface, $indexedGett
      erFunction); |  | 
| 3225         } |  | 
| 3226         GenerateImplementationIndexedPropertyGetterCallback($interface, $hasCust
      omIndexedGetter); |  | 
| 3227     } |  | 
| 3228 |  | 
| 3229     my $indexedSetterFunction = GetIndexedSetterFunction($interface); |  | 
| 3230     if ($indexedSetterFunction) { |  | 
| 3231         my $hasCustomIndexedSetter = $indexedSetterFunction->extendedAttributes-
      >{"Custom"}; |  | 
| 3232         if (!$hasCustomIndexedSetter) { |  | 
| 3233             GenerateImplementationIndexedPropertySetter($interface, $indexedSett
      erFunction); |  | 
| 3234         } |  | 
| 3235         GenerateImplementationIndexedPropertySetterCallback($interface, $hasCust
      omIndexedSetter); |  | 
| 3236     } |  | 
| 3237 |  | 
| 3238     my $indexedDeleterFunction = GetIndexedDeleterFunction($interface); |  | 
| 3239     if ($indexedDeleterFunction) { |  | 
| 3240         my $hasCustomIndexedDeleter = $indexedDeleterFunction->extendedAttribute
      s->{"Custom"}; |  | 
| 3241         if (!$hasCustomIndexedDeleter) { |  | 
| 3242             GenerateImplementationIndexedPropertyDeleter($interface, $indexedDel
      eterFunction); |  | 
| 3243         } |  | 
| 3244         GenerateImplementationIndexedPropertyDeleterCallback($interface, $hasCus
      tomIndexedDeleter); |  | 
| 3245     } |  | 
| 3246 |  | 
| 3247     my $indexedEnumeratorFunction = $indexedGetterFunction; |  | 
| 3248     $indexedEnumeratorFunction = 0 if $indexedGetterFunction && $indexedGetterFu
      nction->extendedAttributes->{"NotEnumerable"}; |  | 
| 3249 |  | 
| 3250     my $indexedQueryFunction = 0; |  | 
| 3251     # If there is an enumerator, there MUST be a query method to properly commun
      icate property attributes. |  | 
| 3252     my $hasQuery = $indexedQueryFunction || $indexedEnumeratorFunction; |  | 
| 3253 |  | 
| 3254     my $setOn = "Instance"; |  | 
| 3255 |  | 
| 3256     # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallba
      cks) and it's used on Window |  | 
| 3257     # instead of deleters or enumerators. In addition, the getter should be set 
      on prototype template, to |  | 
| 3258     # get implementation straight out of the Window prototype regardless of what
       prototype is actually set |  | 
| 3259     # on the object. |  | 
| 3260     if ($interfaceName eq "Window") { |  | 
| 3261         $setOn = "Prototype"; |  | 
| 3262     } |  | 
| 3263 |  | 
| 3264     my $code = ""; |  | 
| 3265     if ($indexedGetterFunction || $indexedSetterFunction || $indexedDeleterFunct
      ion || $indexedEnumeratorFunction || $hasQuery) { |  | 
| 3266         $code .= "    desc->${setOn}Template()->SetIndexedPropertyHandler(${impl
      ClassName}V8Internal::indexedPropertyGetterCallback"; |  | 
| 3267         $code .= $indexedSetterFunction ? ", ${implClassName}V8Internal::indexed
      PropertySetterCallback" : ", 0"; |  | 
| 3268         $code .= ", 0"; # IndexedPropertyQuery -- not being used at the moment. |  | 
| 3269         $code .= $indexedDeleterFunction ? ", ${implClassName}V8Internal::indexe
      dPropertyDeleterCallback" : ", 0"; |  | 
| 3270         $code .= $indexedEnumeratorFunction ? ", indexedPropertyEnumerator<${imp
      lClassName}>" : ", 0"; |  | 
| 3271         $code .= ");\n"; |  | 
| 3272     } |  | 
| 3273 |  | 
| 3274     return $code; |  | 
| 3275 } |  | 
| 3276 |  | 
| 3277 sub GenerateImplementationIndexedPropertyGetter |  | 
| 3278 { |  | 
| 3279     my $interface = shift; |  | 
| 3280     my $indexedGetterFunction = shift; |  | 
| 3281     my $implClassName = GetImplName($interface); |  | 
| 3282     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3283     my $methodName = GetImplName($indexedGetterFunction); |  | 
| 3284 |  | 
| 3285     my $returnType = $indexedGetterFunction->type; |  | 
| 3286     my $nativeType = GetNativeType($returnType); |  | 
| 3287     my $nativeValue = "element"; |  | 
| 3288     $nativeValue .= ".release()" if (IsRefPtrType($returnType)); |  | 
| 3289     my $isNull = GenerateIsNullExpression($returnType, "element"); |  | 
| 3290     my $returnJSValueCode = NativeToJSValue($indexedGetterFunction->type, $index
      edGetterFunction->extendedAttributes, $nativeValue, "    ", "", "info.Holder()",
       "info.GetIsolate()", "info", "collection", "", "return"); |  | 
| 3291     my $raisesExceptions = $indexedGetterFunction->extendedAttributes->{"RaisesE
      xception"}; |  | 
| 3292     my $methodCallCode = GenerateMethodCall($returnType, "element", "collection-
      >${methodName}", "index", $raisesExceptions); |  | 
| 3293     my $getterCode = "static void indexedPropertyGetter(uint32_t index, const v8
      ::PropertyCallbackInfo<v8::Value>& info)\n"; |  | 
| 3294     $getterCode .= "{\n"; |  | 
| 3295     $getterCode .= "    ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder()));\n"
      ; |  | 
| 3296     $getterCode .= "    ${implClassName}* collection = ${v8ClassName}::toNative(
      info.Holder());\n"; |  | 
| 3297     if ($raisesExceptions) { |  | 
| 3298         $getterCode .= "    ExceptionState es(info.GetIsolate());\n"; |  | 
| 3299     } |  | 
| 3300     $getterCode .= $methodCallCode . "\n"; |  | 
| 3301     if ($raisesExceptions) { |  | 
| 3302         $getterCode .= "    if (es.throwIfNeeded())\n"; |  | 
| 3303         $getterCode .= "        return;\n"; |  | 
| 3304     } |  | 
| 3305     if (IsUnionType($returnType)) { |  | 
| 3306         $getterCode .= "${returnJSValueCode}\n"; |  | 
| 3307         $getterCode .= "    return;\n"; |  | 
| 3308     } else { |  | 
| 3309         $getterCode .= "    if (${isNull})\n"; |  | 
| 3310         $getterCode .= "        return;\n"; |  | 
| 3311         $getterCode .= $returnJSValueCode . "\n"; |  | 
| 3312     } |  | 
| 3313     $getterCode .= "}\n\n"; |  | 
| 3314     $implementation{nameSpaceInternal}->add($getterCode); |  | 
| 3315 } |  | 
| 3316 |  | 
| 3317 sub GenerateImplementationIndexedPropertyGetterCallback |  | 
| 3318 { |  | 
| 3319     my $interface = shift; |  | 
| 3320     my $hasCustom = shift; |  | 
| 3321     my $implClassName = GetImplName($interface); |  | 
| 3322     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3323 |  | 
| 3324     my $code = "static void indexedPropertyGetterCallback(uint32_t index, const 
      v8::PropertyCallbackInfo<v8::Value>& info)\n"; |  | 
| 3325     $code .= "{\n"; |  | 
| 3326     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMIndexedProperty
      \");\n"; |  | 
| 3327     if ($hasCustom) { |  | 
| 3328         $code .= "    ${v8ClassName}::indexedPropertyGetterCustom(index, info);\
      n"; |  | 
| 3329     } else { |  | 
| 3330         $code .= "    ${implClassName}V8Internal::indexedPropertyGetter(index, i
      nfo);\n"; |  | 
| 3331     } |  | 
| 3332     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |  | 
| 3333     $code .= "}\n\n"; |  | 
| 3334     $implementation{nameSpaceInternal}->add($code); |  | 
| 3335 } |  | 
| 3336 |  | 
| 3337 sub GenerateImplementationIndexedPropertySetterCallback |  | 
| 3338 { |  | 
| 3339     my $interface = shift; |  | 
| 3340     my $hasCustom = shift; |  | 
| 3341     my $implClassName = GetImplName($interface); |  | 
| 3342     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3343 |  | 
| 3344     my $code = "static void indexedPropertySetterCallback(uint32_t index, v8::Lo
      cal<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)\n"; |  | 
| 3345     $code .= "{\n"; |  | 
| 3346     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMIndexedProperty
      \");\n"; |  | 
| 3347     if ($hasCustom) { |  | 
| 3348         $code .= "    ${v8ClassName}::indexedPropertySetterCustom(index, value, 
      info);\n"; |  | 
| 3349     } else { |  | 
| 3350         $code .= "    ${implClassName}V8Internal::indexedPropertySetter(index, v
      alue, info);\n"; |  | 
| 3351     } |  | 
| 3352     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |  | 
| 3353     $code .= "}\n\n"; |  | 
| 3354     $implementation{nameSpaceInternal}->add($code); |  | 
| 3355 } |  | 
| 3356 |  | 
| 3357 sub GenerateImplementationIndexedPropertyDeleterCallback |  | 
| 3358 { |  | 
| 3359     my $interface = shift; |  | 
| 3360     my $hasCustom = shift; |  | 
| 3361     my $implClassName = GetImplName($interface); |  | 
| 3362     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3363 |  | 
| 3364     my $code = "static void indexedPropertyDeleterCallback(uint32_t index, const
       v8::PropertyCallbackInfo<v8::Boolean>& info)\n"; |  | 
| 3365     $code .= "{\n"; |  | 
| 3366     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMIndexedProperty
      \");\n"; |  | 
| 3367     if ($hasCustom) { |  | 
| 3368         $code .= "    ${v8ClassName}::indexedPropertyDeleterCustom(index, info);
      \n"; |  | 
| 3369     } else { |  | 
| 3370         $code .= "    ${implClassName}V8Internal::indexedPropertyDeleter(index, 
      info);\n"; |  | 
| 3371     } |  | 
| 3372     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |  | 
| 3373     $code .= "}\n\n"; |  | 
| 3374     $implementation{nameSpaceInternal}->add($code); |  | 
| 3375 } |  | 
| 3376 |  | 
| 3377 sub GenerateImplementationIndexedPropertySetter |  | 
| 3378 { |  | 
| 3379     my $interface = shift; |  | 
| 3380     my $indexedSetterFunction = shift; |  | 
| 3381     my $implClassName = GetImplName($interface); |  | 
| 3382     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3383     my $methodName = GetImplName($indexedSetterFunction); |  | 
| 3384 |  | 
| 3385     my $type = $indexedSetterFunction->parameters->[1]->type; |  | 
| 3386     my $raisesExceptions = $indexedSetterFunction->extendedAttributes->{"RaisesE
      xception"}; |  | 
| 3387     my $treatNullAs = $indexedSetterFunction->parameters->[1]->extendedAttribute
      s->{"TreatNullAs"}; |  | 
| 3388     my $treatUndefinedAs = $indexedSetterFunction->parameters->[1]->extendedAttr
      ibutes->{"TreatUndefinedAs"}; |  | 
| 3389     my $code = "static void indexedPropertySetter(uint32_t index, v8::Local<v8::
      Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)\n"; |  | 
| 3390     $code .= "{\n"; |  | 
| 3391     $code .= "    ${implClassName}* collection = ${v8ClassName}::toNative(info.H
      older());\n"; |  | 
| 3392     $code .= JSValueToNativeStatement($indexedSetterFunction->parameters->[1]->t
      ype, $indexedSetterFunction->extendedAttributes, "value", "propertyValue", "    
      ", "info.GetIsolate()"); |  | 
| 3393 |  | 
| 3394     my $extraArguments = ""; |  | 
| 3395     if ($raisesExceptions) { |  | 
| 3396         $code .= "    ExceptionState es(info.GetIsolate());\n"; |  | 
| 3397         $extraArguments = ", es"; |  | 
| 3398     } |  | 
| 3399     my @conditions = (); |  | 
| 3400     my @statements = (); |  | 
| 3401     if ($treatNullAs && $treatNullAs ne "NullString") { |  | 
| 3402         push @conditions, "value->IsNull()"; |  | 
| 3403         push @statements, "collection->${treatNullAs}(index$extraArguments);"; |  | 
| 3404     } |  | 
| 3405     if ($treatUndefinedAs && $treatUndefinedAs ne "NullString") { |  | 
| 3406         push @conditions, "value->IsUndefined()"; |  | 
| 3407         push @statements, "collection->${treatUndefinedAs}(index$extraArguments)
      ;"; |  | 
| 3408     } |  | 
| 3409     push @conditions, ""; |  | 
| 3410     push @statements, "collection->${methodName}(index, propertyValue$extraArgum
      ents);"; |  | 
| 3411     $code .= GenerateIfElseStatement("bool", "result", \@conditions, \@statement
      s); |  | 
| 3412 |  | 
| 3413     $code .= "    if (!result)\n"; |  | 
| 3414     $code .= "        return;\n"; |  | 
| 3415     if ($raisesExceptions) { |  | 
| 3416         $code .= "    if (es.throwIfNeeded())\n"; |  | 
| 3417         $code .= "        return;\n"; |  | 
| 3418     } |  | 
| 3419     $code .= "    v8SetReturnValue(info, value);\n"; |  | 
| 3420     $code .= "}\n\n"; |  | 
| 3421     $implementation{nameSpaceInternal}->add($code); |  | 
| 3422 } |  | 
| 3423 |  | 
| 3424 sub GenerateImplementationNamedPropertyAccessors |  | 
| 3425 { |  | 
| 3426     my $interface = shift; |  | 
| 3427 |  | 
| 3428     my $interfaceName = $interface->name; |  | 
| 3429     my $implClassName = GetImplName($interface); |  | 
| 3430     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3431 |  | 
| 3432     my $namedGetterFunction = GetNamedGetterFunction($interface); |  | 
| 3433     if ($namedGetterFunction) { |  | 
| 3434         my $hasCustomNamedGetter = $namedGetterFunction->extendedAttributes->{"C
      ustom"}; |  | 
| 3435         if (!$hasCustomNamedGetter) { |  | 
| 3436             GenerateImplementationNamedPropertyGetter($interface, $namedGetterFu
      nction); |  | 
| 3437         } |  | 
| 3438         GenerateImplementationNamedPropertyGetterCallback($interface, $hasCustom
      NamedGetter); |  | 
| 3439     } |  | 
| 3440 |  | 
| 3441     my $namedSetterFunction = GetNamedSetterFunction($interface); |  | 
| 3442     if ($namedSetterFunction) { |  | 
| 3443         my $hasCustomNamedSetter = $namedSetterFunction->extendedAttributes->{"C
      ustom"}; |  | 
| 3444         if (!$hasCustomNamedSetter) { |  | 
| 3445             GenerateImplementationNamedPropertySetter($interface, $namedSetterFu
      nction); |  | 
| 3446         } |  | 
| 3447         GenerateImplementationNamedPropertySetterCallback($interface, $hasCustom
      NamedSetter); |  | 
| 3448     } |  | 
| 3449 |  | 
| 3450     my $namedDeleterFunction = GetNamedDeleterFunction($interface); |  | 
| 3451     if ($namedDeleterFunction) { |  | 
| 3452         my $hasCustomNamedDeleter = $namedDeleterFunction->extendedAttributes->{
      "Custom"}; |  | 
| 3453         if (!$hasCustomNamedDeleter) { |  | 
| 3454             GenerateImplementationNamedPropertyDeleter($interface, $namedDeleter
      Function); |  | 
| 3455         } |  | 
| 3456         GenerateImplementationNamedPropertyDeleterCallback($interface, $hasCusto
      mNamedDeleter); |  | 
| 3457     } |  | 
| 3458 |  | 
| 3459     my $namedEnumeratorFunction = $namedGetterFunction && !$namedGetterFunction-
      >extendedAttributes->{"NotEnumerable"}; |  | 
| 3460     if ($namedEnumeratorFunction) { |  | 
| 3461         my $hasCustomNamedEnumerator = $namedGetterFunction->extendedAttributes-
      >{"CustomEnumerateProperty"}; |  | 
| 3462         if (!$hasCustomNamedEnumerator) { |  | 
| 3463             GenerateImplementationNamedPropertyEnumerator($interface); |  | 
| 3464             GenerateImplementationNamedPropertyQuery($interface); |  | 
| 3465         } |  | 
| 3466         GenerateImplementationNamedPropertyEnumeratorCallback($interface, $hasCu
      stomNamedEnumerator); |  | 
| 3467         GenerateImplementationNamedPropertyQueryCallback($interface, $hasCustomN
      amedEnumerator); |  | 
| 3468     } |  | 
| 3469 |  | 
| 3470     my $subCode = ""; |  | 
| 3471     if ($namedGetterFunction || $namedSetterFunction || $namedDeleterFunction ||
       $namedEnumeratorFunction) { |  | 
| 3472         my $setOn = "Instance"; |  | 
| 3473 |  | 
| 3474         # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCa
      llbacks) and it's used on Window |  | 
| 3475         # instead of deleters or enumerators. In addition, the getter should be 
      set on prototype template, to |  | 
| 3476         # get implementation straight out of the Window prototype regardless of 
      what prototype is actually set |  | 
| 3477         # on the object. |  | 
| 3478         if ($interfaceName eq "Window") { |  | 
| 3479             $setOn = "Prototype"; |  | 
| 3480         } |  | 
| 3481 |  | 
| 3482         $subCode .= "    desc->${setOn}Template()->SetNamedPropertyHandler("; |  | 
| 3483         $subCode .= $namedGetterFunction ? "${implClassName}V8Internal::namedPro
      pertyGetterCallback, " : "0, "; |  | 
| 3484         $subCode .= $namedSetterFunction ? "${implClassName}V8Internal::namedPro
      pertySetterCallback, " : "0, "; |  | 
| 3485         $subCode .= $namedEnumeratorFunction ? "${implClassName}V8Internal::name
      dPropertyQueryCallback, " : "0, "; |  | 
| 3486         $subCode .= $namedDeleterFunction ? "${implClassName}V8Internal::namedPr
      opertyDeleterCallback, " : "0, "; |  | 
| 3487         $subCode .= $namedEnumeratorFunction ? "${implClassName}V8Internal::name
      dPropertyEnumeratorCallback" : "0"; |  | 
| 3488         $subCode .= ");\n"; |  | 
| 3489     } |  | 
| 3490 |  | 
| 3491     return $subCode; |  | 
| 3492 } |  | 
| 3493 |  | 
| 3494 sub GenerateImplementationNamedPropertyGetterCallback |  | 
| 3495 { |  | 
| 3496     my $interface = shift; |  | 
| 3497     my $hasCustom = shift; |  | 
| 3498     my $implClassName = GetImplName($interface); |  | 
| 3499     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3500 |  | 
| 3501     my $code = "static void namedPropertyGetterCallback(v8::Local<v8::String> na
      me, const v8::PropertyCallbackInfo<v8::Value>& info)\n"; |  | 
| 3502     $code .= "{\n"; |  | 
| 3503     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMNamedProperty\"
      );\n"; |  | 
| 3504     if ($hasCustom) { |  | 
| 3505         $code .= "    ${v8ClassName}::namedPropertyGetterCustom(name, info);\n"; |  | 
| 3506     } else { |  | 
| 3507         $code .= "    ${implClassName}V8Internal::namedPropertyGetter(name, info
      );\n"; |  | 
| 3508     } |  | 
| 3509     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |  | 
| 3510     $code .= "}\n\n"; |  | 
| 3511     $implementation{nameSpaceInternal}->add($code); |  | 
| 3512 } |  | 
| 3513 |  | 
| 3514 sub GenerateImplementationNamedPropertySetterCallback |  | 
| 3515 { |  | 
| 3516     my $interface = shift; |  | 
| 3517     my $hasCustom = shift; |  | 
| 3518     my $implClassName = GetImplName($interface); |  | 
| 3519     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3520 |  | 
| 3521     my $code = "static void namedPropertySetterCallback(v8::Local<v8::String> na
      me, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
      \n"; |  | 
| 3522     $code .= "{\n"; |  | 
| 3523     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMNamedProperty\"
      );\n"; |  | 
| 3524     if ($hasCustom) { |  | 
| 3525         $code .= "    ${v8ClassName}::namedPropertySetterCustom(name, value, inf
      o);\n"; |  | 
| 3526     } else { |  | 
| 3527         $code .= "    ${implClassName}V8Internal::namedPropertySetter(name, valu
      e, info);\n"; |  | 
| 3528     } |  | 
| 3529     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |  | 
| 3530     $code .= "}\n\n"; |  | 
| 3531     $implementation{nameSpaceInternal}->add($code); |  | 
| 3532 } |  | 
| 3533 |  | 
| 3534 sub GenerateImplementationNamedPropertyDeleterCallback |  | 
| 3535 { |  | 
| 3536     my $interface = shift; |  | 
| 3537     my $hasCustom = shift; |  | 
| 3538     my $implClassName = GetImplName($interface); |  | 
| 3539     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3540 |  | 
| 3541     my $code = "static void namedPropertyDeleterCallback(v8::Local<v8::String> n
      ame, const v8::PropertyCallbackInfo<v8::Boolean>& info)\n"; |  | 
| 3542     $code .= "{\n"; |  | 
| 3543     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMNamedProperty\"
      );\n"; |  | 
| 3544     if ($hasCustom) { |  | 
| 3545         $code .= "    ${v8ClassName}::namedPropertyDeleterCustom(name, info);\n"
      ; |  | 
| 3546     } else { |  | 
| 3547         $code .= "    ${implClassName}V8Internal::namedPropertyDeleter(name, inf
      o);\n"; |  | 
| 3548     } |  | 
| 3549     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |  | 
| 3550     $code .= "}\n\n"; |  | 
| 3551     $implementation{nameSpaceInternal}->add($code); |  | 
| 3552 } |  | 
| 3553 |  | 
| 3554 sub GenerateImplementationNamedPropertyEnumeratorCallback |  | 
| 3555 { |  | 
| 3556     my $interface = shift; |  | 
| 3557     my $hasCustom = shift; |  | 
| 3558     my $implClassName = GetImplName($interface); |  | 
| 3559     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3560 |  | 
| 3561     my $code = "static void namedPropertyEnumeratorCallback(const v8::PropertyCa
      llbackInfo<v8::Array>& info)\n"; |  | 
| 3562     $code .= "{\n"; |  | 
| 3563     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMNamedProperty\"
      );\n"; |  | 
| 3564     if ($hasCustom) { |  | 
| 3565         $code .= "    ${v8ClassName}::namedPropertyEnumeratorCustom(info);\n"; |  | 
| 3566     } else { |  | 
| 3567         $code .= "    ${implClassName}V8Internal::namedPropertyEnumerator(info);
      \n"; |  | 
| 3568     } |  | 
| 3569     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |  | 
| 3570     $code .= "}\n\n"; |  | 
| 3571     $implementation{nameSpaceInternal}->add($code); |  | 
| 3572 } |  | 
| 3573 |  | 
| 3574 sub GenerateImplementationNamedPropertyQueryCallback |  | 
| 3575 { |  | 
| 3576     my $interface = shift; |  | 
| 3577     my $hasCustom = shift; |  | 
| 3578     my $implClassName = GetImplName($interface); |  | 
| 3579     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3580 |  | 
| 3581     my $code = "static void namedPropertyQueryCallback(v8::Local<v8::String> nam
      e, const v8::PropertyCallbackInfo<v8::Integer>& info)\n"; |  | 
| 3582     $code .= "{\n"; |  | 
| 3583     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMNamedProperty\"
      );\n"; |  | 
| 3584     if ($hasCustom) { |  | 
| 3585         $code .= "    ${v8ClassName}::namedPropertyQueryCustom(name, info);\n"; |  | 
| 3586     } else { |  | 
| 3587         $code .= "    ${implClassName}V8Internal::namedPropertyQuery(name, info)
      ;\n"; |  | 
| 3588     } |  | 
| 3589     $code .= "    TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |  | 
| 3590     $code .= "}\n\n"; |  | 
| 3591     $implementation{nameSpaceInternal}->add($code); |  | 
| 3592 } |  | 
| 3593 |  | 
| 3594 sub GenerateMethodCall |  | 
| 3595 { |  | 
| 3596     my $returnType = shift; # string or UnionType |  | 
| 3597     my $returnName = shift; |  | 
| 3598     my $functionExpression = shift; |  | 
| 3599     my $firstArgument = shift; |  | 
| 3600     my $raisesExceptions = shift; |  | 
| 3601 |  | 
| 3602     my @arguments = (); |  | 
| 3603     push @arguments, $firstArgument; |  | 
| 3604     if ($raisesExceptions) { |  | 
| 3605         push @arguments, "es"; |  | 
| 3606     } |  | 
| 3607 |  | 
| 3608     if (IsUnionType($returnType)) { |  | 
| 3609         my $code = ""; |  | 
| 3610         my @extraArguments = (); |  | 
| 3611         for my $i (0..scalar(@{$returnType->unionMemberTypes})-1) { |  | 
| 3612             my $unionMemberType = $returnType->unionMemberTypes->[$i]; |  | 
| 3613             my $nativeType = GetNativeType($unionMemberType); |  | 
| 3614             my $unionMemberVariable = $returnName . $i; |  | 
| 3615             my $unionMemberEnabledVariable = $returnName . $i . "Enabled"; |  | 
| 3616             $code .= "    bool ${unionMemberEnabledVariable} = false;\n"; |  | 
| 3617             $code .= "    ${nativeType} ${unionMemberVariable};\n"; |  | 
| 3618             push @extraArguments, $unionMemberEnabledVariable; |  | 
| 3619             push @extraArguments, $unionMemberVariable; |  | 
| 3620         } |  | 
| 3621         push @arguments, @extraArguments; |  | 
| 3622         $code .= "    ${functionExpression}(" . (join ", ", @arguments) . ");"; |  | 
| 3623         return $code; |  | 
| 3624     } else { |  | 
| 3625         my $nativeType = GetNativeType($returnType); |  | 
| 3626         return "    ${nativeType} element = ${functionExpression}(" . (join ", "
      , @arguments) . ");" |  | 
| 3627     } |  | 
| 3628 } |  | 
| 3629 |  | 
| 3630 sub GenerateImplementationNamedPropertyGetter |  | 
| 3631 { |  | 
| 3632     my $interface = shift; |  | 
| 3633     my $namedGetterFunction = shift; |  | 
| 3634     my $implClassName = GetImplName($interface); |  | 
| 3635     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3636     my $methodName = GetImplName($namedGetterFunction); |  | 
| 3637 |  | 
| 3638     my $returnType = $namedGetterFunction->type; |  | 
| 3639     my $isNull = GenerateIsNullExpression($returnType, "element"); |  | 
| 3640     my $nativeValue = "element"; |  | 
| 3641     $nativeValue .= ".release()" if (IsRefPtrType($returnType)); |  | 
| 3642     my $returnJSValueCode = NativeToJSValue($namedGetterFunction->type, $namedGe
      tterFunction->extendedAttributes, $nativeValue, "    ", "", "info.Holder()", "in
      fo.GetIsolate()", "info", "collection", "", "return"); |  | 
| 3643     my $raisesExceptions = $namedGetterFunction->extendedAttributes->{"RaisesExc
      eption"}; |  | 
| 3644     my $methodCallCode = GenerateMethodCall($returnType, "element", "collection-
      >${methodName}", "propertyName", $raisesExceptions); |  | 
| 3645 |  | 
| 3646     my $code = "static void namedPropertyGetter(v8::Local<v8::String> name, cons
      t v8::PropertyCallbackInfo<v8::Value>& info)\n"; |  | 
| 3647     $code .= "{\n"; |  | 
| 3648     if (!$namedGetterFunction->extendedAttributes->{"OverrideBuiltins"}) { |  | 
| 3649         $code .= "    if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(n
      ame).IsEmpty())\n"; |  | 
| 3650         $code .= "        return;\n"; |  | 
| 3651         $code .= "    if (info.Holder()->HasRealNamedCallbackProperty(name))\n"; |  | 
| 3652         $code .= "        return;\n"; |  | 
| 3653         $code .= "    if (info.Holder()->HasRealNamedProperty(name))\n"; |  | 
| 3654         $code .= "        return;\n"; |  | 
| 3655     } |  | 
| 3656     $code .= "\n"; |  | 
| 3657     $code .= "    ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder()));\n"; |  | 
| 3658     $code .= "    ${implClassName}* collection = ${v8ClassName}::toNative(info.H
      older());\n"; |  | 
| 3659     $code .= "    AtomicString propertyName = toWebCoreAtomicString(name);\n"; |  | 
| 3660     if ($raisesExceptions) { |  | 
| 3661         $code .= "    ExceptionState es(info.GetIsolate());\n"; |  | 
| 3662     } |  | 
| 3663     $code .= $methodCallCode . "\n"; |  | 
| 3664     if ($raisesExceptions) { |  | 
| 3665         $code .= "    if (es.throwIfNeeded())\n"; |  | 
| 3666         $code .= "        return;\n"; |  | 
| 3667     } |  | 
| 3668     if (IsUnionType($returnType)) { |  | 
| 3669         $code .= "${returnJSValueCode}\n"; |  | 
| 3670         $code .= "    return;\n"; |  | 
| 3671     } else { |  | 
| 3672         $code .= "    if (${isNull})\n"; |  | 
| 3673         $code .= "        return;\n"; |  | 
| 3674         $code .= $returnJSValueCode . "\n"; |  | 
| 3675     } |  | 
| 3676     $code .= "}\n\n"; |  | 
| 3677     $implementation{nameSpaceInternal}->add($code); |  | 
| 3678 } |  | 
| 3679 |  | 
| 3680 sub GenerateImplementationNamedPropertySetter |  | 
| 3681 { |  | 
| 3682     my $interface = shift; |  | 
| 3683     my $namedSetterFunction = shift; |  | 
| 3684     my $implClassName = GetImplName($interface); |  | 
| 3685     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3686     my $methodName = GetImplName($namedSetterFunction); |  | 
| 3687 |  | 
| 3688     my $raisesExceptions = $namedSetterFunction->extendedAttributes->{"RaisesExc
      eption"}; |  | 
| 3689     my $treatNullAs = $namedSetterFunction->parameters->[1]->extendedAttributes-
      >{"TreatNullAs"}; |  | 
| 3690     my $treatUndefinedAs = $namedSetterFunction->parameters->[1]->extendedAttrib
      utes->{"TreatUndefinedAs"}; |  | 
| 3691 |  | 
| 3692     my $code = "static void namedPropertySetter(v8::Local<v8::String> name, v8::
      Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)\n"; |  | 
| 3693     $code .= "{\n"; |  | 
| 3694     if (!$namedSetterFunction->extendedAttributes->{"OverrideBuiltins"}) { |  | 
| 3695         $code .= "    if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(n
      ame).IsEmpty())\n"; |  | 
| 3696         $code .= "        return;\n"; |  | 
| 3697         $code .= "    if (info.Holder()->HasRealNamedCallbackProperty(name))\n"; |  | 
| 3698         $code .= "        return;\n"; |  | 
| 3699         $code .= "    if (info.Holder()->HasRealNamedProperty(name))\n"; |  | 
| 3700         $code .= "        return;\n"; |  | 
| 3701     } |  | 
| 3702     $code .= "    ${implClassName}* collection = ${v8ClassName}::toNative(info.H
      older());\n"; |  | 
| 3703     $code .= JSValueToNativeStatement($namedSetterFunction->parameters->[0]->typ
      e, $namedSetterFunction->extendedAttributes, "name", "propertyName", "    ", "in
      fo.GetIsolate()"); |  | 
| 3704     $code .= JSValueToNativeStatement($namedSetterFunction->parameters->[1]->typ
      e, $namedSetterFunction->extendedAttributes, "value", "propertyValue", "    ", "
      info.GetIsolate()"); |  | 
| 3705     my $extraArguments = ""; |  | 
| 3706     if ($raisesExceptions) { |  | 
| 3707         $code .= "    ExceptionState es(info.GetIsolate());\n"; |  | 
| 3708         $extraArguments = ", es"; |  | 
| 3709     } |  | 
| 3710 |  | 
| 3711     my @conditions = (); |  | 
| 3712     my @statements = (); |  | 
| 3713     if ($treatNullAs && $treatNullAs ne "NullString") { |  | 
| 3714         push @conditions, "value->IsNull()"; |  | 
| 3715         push @statements, "collection->${treatNullAs}(propertyName$extraArgument
      s);"; |  | 
| 3716     } |  | 
| 3717     if ($treatUndefinedAs && $treatUndefinedAs ne "NullString") { |  | 
| 3718         push @conditions, "value->IsUndefined()"; |  | 
| 3719         push @statements, "collection->${treatUndefinedAs}(propertyName$extraArg
      uments);"; |  | 
| 3720     } |  | 
| 3721     push @conditions, ""; |  | 
| 3722     push @statements, "collection->${methodName}(propertyName, propertyValue$ext
      raArguments);"; |  | 
| 3723     $code .= GenerateIfElseStatement("bool", "result", \@conditions, \@statement
      s); |  | 
| 3724 |  | 
| 3725     $code .= "    if (!result)\n"; |  | 
| 3726     $code .= "        return;\n"; |  | 
| 3727     if ($raisesExceptions) { |  | 
| 3728         $code .= "    if (es.throwIfNeeded())\n"; |  | 
| 3729         $code .= "        return;\n"; |  | 
| 3730     } |  | 
| 3731     $code .= "    v8SetReturnValue(info, value);\n"; |  | 
| 3732     $code .= "}\n\n"; |  | 
| 3733     $implementation{nameSpaceInternal}->add($code); |  | 
| 3734 } |  | 
| 3735 |  | 
| 3736 sub GenerateImplementationIndexedPropertyDeleter |  | 
| 3737 { |  | 
| 3738     my $interface = shift; |  | 
| 3739     my $indexedDeleterFunction = shift; |  | 
| 3740     my $implClassName = GetImplName($interface); |  | 
| 3741     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3742     my $methodName = GetImplName($indexedDeleterFunction); |  | 
| 3743 |  | 
| 3744     my $raisesExceptions = $indexedDeleterFunction->extendedAttributes->{"Raises
      Exception"}; |  | 
| 3745 |  | 
| 3746     my $code = "static void indexedPropertyDeleter(unsigned index, const v8::Pro
      pertyCallbackInfo<v8::Boolean>& info)\n"; |  | 
| 3747     $code .= "{\n"; |  | 
| 3748     $code .= "    ${implClassName}* collection = ${v8ClassName}::toNative(info.H
      older());\n"; |  | 
| 3749     my $extraArguments = ""; |  | 
| 3750     if ($raisesExceptions) { |  | 
| 3751         $code .= "    ExceptionState es(info.GetIsolate());\n"; |  | 
| 3752         $extraArguments = ", es"; |  | 
| 3753     } |  | 
| 3754     $code .= "    bool result = collection->${methodName}(index$extraArguments);
      \n"; |  | 
| 3755     if ($raisesExceptions) { |  | 
| 3756         $code .= "    if (es.throwIfNeeded())\n"; |  | 
| 3757         $code .= "        return;\n"; |  | 
| 3758     } |  | 
| 3759     $code .= "    return v8SetReturnValueBool(info, result);\n"; |  | 
| 3760     $code .= "}\n\n"; |  | 
| 3761     $implementation{nameSpaceInternal}->add($code); |  | 
| 3762 } |  | 
| 3763 |  | 
| 3764 sub GenerateImplementationNamedPropertyDeleter |  | 
| 3765 { |  | 
| 3766     my $interface = shift; |  | 
| 3767     my $namedDeleterFunction = shift; |  | 
| 3768     my $implClassName = GetImplName($interface); |  | 
| 3769     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3770     my $methodName = GetImplName($namedDeleterFunction); |  | 
| 3771 |  | 
| 3772     my $raisesExceptions = $namedDeleterFunction->extendedAttributes->{"RaisesEx
      ception"}; |  | 
| 3773 |  | 
| 3774     my $code = "static void namedPropertyDeleter(v8::Local<v8::String> name, con
      st v8::PropertyCallbackInfo<v8::Boolean>& info)\n"; |  | 
| 3775     $code .= "{\n"; |  | 
| 3776     $code .= "    ${implClassName}* collection = ${v8ClassName}::toNative(info.H
      older());\n"; |  | 
| 3777     $code .= "    AtomicString propertyName = toWebCoreAtomicString(name);\n"; |  | 
| 3778     my $extraArguments = ""; |  | 
| 3779     if ($raisesExceptions) { |  | 
| 3780         $code .= "    ExceptionState es(info.GetIsolate());\n"; |  | 
| 3781         $extraArguments = ", es"; |  | 
| 3782     } |  | 
| 3783     $code .= "    bool result = collection->${methodName}(propertyName$extraArgu
      ments);\n"; |  | 
| 3784     if ($raisesExceptions) { |  | 
| 3785         $code .= "    if (es.throwIfNeeded())\n"; |  | 
| 3786         $code .= "        return;\n"; |  | 
| 3787     } |  | 
| 3788     $code .= "    return v8SetReturnValueBool(info, result);\n"; |  | 
| 3789     $code .= "}\n\n"; |  | 
| 3790     $implementation{nameSpaceInternal}->add($code); |  | 
| 3791 } |  | 
| 3792 |  | 
| 3793 sub GenerateImplementationNamedPropertyEnumerator |  | 
| 3794 { |  | 
| 3795     my $interface = shift; |  | 
| 3796     my $implClassName = GetImplName($interface); |  | 
| 3797     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3798 |  | 
| 3799     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 3800 static void namedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& i
      nfo) |  | 
| 3801 { |  | 
| 3802     ExceptionState es(info.GetIsolate()); |  | 
| 3803     ${implClassName}* collection = ${v8ClassName}::toNative(info.Holder()); |  | 
| 3804     Vector<String> names; |  | 
| 3805     collection->namedPropertyEnumerator(names, es); |  | 
| 3806     if (es.throwIfNeeded()) |  | 
| 3807         return; |  | 
| 3808     v8::Handle<v8::Array> v8names = v8::Array::New(names.size()); |  | 
| 3809     for (size_t i = 0; i < names.size(); ++i) |  | 
| 3810         v8names->Set(v8::Integer::New(i, info.GetIsolate()), v8String(names[i], 
      info.GetIsolate())); |  | 
| 3811     v8SetReturnValue(info, v8names); |  | 
| 3812 } |  | 
| 3813 |  | 
| 3814 END |  | 
| 3815 } |  | 
| 3816 |  | 
| 3817 sub GenerateImplementationNamedPropertyQuery |  | 
| 3818 { |  | 
| 3819     my $interface = shift; |  | 
| 3820     my $implClassName = GetImplName($interface); |  | 
| 3821     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3822 |  | 
| 3823     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 3824 static void namedPropertyQuery(v8::Local<v8::String> name, const v8::PropertyCal
      lbackInfo<v8::Integer>& info) |  | 
| 3825 { |  | 
| 3826     ${implClassName}* collection = ${v8ClassName}::toNative(info.Holder()); |  | 
| 3827     AtomicString propertyName = toWebCoreAtomicString(name); |  | 
| 3828     ExceptionState es(info.GetIsolate()); |  | 
| 3829     bool result = collection->namedPropertyQuery(propertyName, es); |  | 
| 3830     if (es.throwIfNeeded()) |  | 
| 3831         return; |  | 
| 3832     if (!result) |  | 
| 3833         return; |  | 
| 3834     v8SetReturnValueInt(info, v8::None); |  | 
| 3835 } |  | 
| 3836 |  | 
| 3837 END |  | 
| 3838 } |  | 
| 3839 |  | 
| 3840 sub GenerateImplementationLegacyCall |  | 
| 3841 { |  | 
| 3842     my $interface = shift; |  | 
| 3843     my $code = ""; |  | 
| 3844 |  | 
| 3845     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3846 |  | 
| 3847     if ($interface->extendedAttributes->{"CustomLegacyCall"}) { |  | 
| 3848         $code .= "    desc->InstanceTemplate()->SetCallAsFunctionHandler(${v8Cla
      ssName}::legacyCallCustom);\n"; |  | 
| 3849     } |  | 
| 3850     return $code; |  | 
| 3851 } |  | 
| 3852 |  | 
| 3853 sub GenerateImplementationMasqueradesAsUndefined |  | 
| 3854 { |  | 
| 3855     my $interface = shift; |  | 
| 3856     my $code = ""; |  | 
| 3857 |  | 
| 3858     if ($interface->extendedAttributes->{"MasqueradesAsUndefined"}) |  | 
| 3859     { |  | 
| 3860         $code .= "    desc->InstanceTemplate()->MarkAsUndetectable();\n"; |  | 
| 3861     } |  | 
| 3862     return $code; |  | 
| 3863 } |  | 
| 3864 |  | 
| 3865 sub GenerateImplementation |  | 
| 3866 { |  | 
| 3867     my $object = shift; |  | 
| 3868     my $interface = shift; |  | 
| 3869     my $interfaceName = $interface->name; |  | 
| 3870     my $implClassName = GetImplName($interface); |  | 
| 3871     my $v8ClassName = GetV8ClassName($interface); |  | 
| 3872     my $nativeType = GetNativeTypeForConversions($interface); |  | 
| 3873 |  | 
| 3874     AddToImplIncludes("bindings/v8/V8Binding.h"); |  | 
| 3875     AddToImplIncludes("bindings/v8/V8DOMWrapper.h"); |  | 
| 3876     AddToImplIncludes("core/dom/ContextFeatures.h"); |  | 
| 3877     AddToImplIncludes("core/dom/Document.h"); |  | 
| 3878     AddToImplIncludes("RuntimeEnabledFeatures.h"); |  | 
| 3879     AddToImplIncludes("core/platform/chromium/TraceEvent.h"); |  | 
| 3880 |  | 
| 3881     AddIncludesForType($interfaceName); |  | 
| 3882 |  | 
| 3883     my $toActiveDOMObject = InheritsExtendedAttribute($interface, "ActiveDOMObje
      ct") ? "${v8ClassName}::toActiveDOMObject" : "0"; |  | 
| 3884     my $toEventTarget = InheritsInterface($interface, "EventTarget") ? "${v8Clas
      sName}::toEventTarget" : "0"; |  | 
| 3885     my $rootForGC = NeedsOpaqueRootForGC($interface) ? "${v8ClassName}::opaqueRo
      otForGC" : "0"; |  | 
| 3886 |  | 
| 3887     # Find the super descriptor. |  | 
| 3888     my $parentClass = ""; |  | 
| 3889     my $parentClassTemplate = ""; |  | 
| 3890     if ($interface->parent) { |  | 
| 3891         my $parent = $interface->parent; |  | 
| 3892         AddToImplIncludes("V8${parent}.h"); |  | 
| 3893         $parentClass = "V8" . $parent; |  | 
| 3894         $parentClassTemplate = $parentClass . "::GetTemplate(isolate, currentWor
      ldType)"; |  | 
| 3895     } |  | 
| 3896 |  | 
| 3897     my $parentClassInfo = $parentClass ? "&${parentClass}::info" : "0"; |  | 
| 3898     my $WrapperTypePrototype = $interface->isException ? "WrapperTypeErrorProtot
      ype" : "WrapperTypeObjectPrototype"; |  | 
| 3899 |  | 
| 3900     if (!IsSVGTypeNeedingTearOff($interfaceName)) { |  | 
| 3901         my $code = <<END; |  | 
| 3902 static void initializeScriptWrappableForInterface(${implClassName}* object) |  | 
| 3903 { |  | 
| 3904     if (ScriptWrappable::wrapperCanBeStoredInObject(object)) |  | 
| 3905         ScriptWrappable::setTypeInfoInObject(object, &${v8ClassName}::info); |  | 
| 3906     else |  | 
| 3907         ASSERT_NOT_REACHED(); |  | 
| 3908 } |  | 
| 3909 |  | 
| 3910 } // namespace WebCore |  | 
| 3911 |  | 
| 3912 // In ScriptWrappable::init, the use of a local function declaration has an issu
      e on Windows: |  | 
| 3913 // the local declaration does not pick up the surrounding namespace. Therefore, 
      we provide this function |  | 
| 3914 // in the global namespace. |  | 
| 3915 // (More info on the MSVC bug here: http://connect.microsoft.com/VisualStudio/fe
      edback/details/664619/the-namespace-of-local-function-declarations-in-c) |  | 
| 3916 END |  | 
| 3917 |  | 
| 3918     if (GetNamespaceForInterface($interface) eq "WebCore") { |  | 
| 3919         $code .= "void webCoreInitializeScriptWrappableForInterface(WebCore::${i
      mplClassName}* object)\n"; |  | 
| 3920     } else { |  | 
| 3921         $code .= "void webCoreInitializeScriptWrappableForInterface(${implClassN
      ame}* object)\n"; |  | 
| 3922     } |  | 
| 3923 |  | 
| 3924     $code .= <<END; |  | 
| 3925 { |  | 
| 3926     WebCore::initializeScriptWrappableForInterface(object); |  | 
| 3927 } |  | 
| 3928 |  | 
| 3929 namespace WebCore { |  | 
| 3930 END |  | 
| 3931         $implementation{nameSpaceWebCore}->addHeader($code); |  | 
| 3932     } |  | 
| 3933 |  | 
| 3934     my $code = "WrapperTypeInfo ${v8ClassName}::info = { ${v8ClassName}::GetTemp
      late, ${v8ClassName}::derefObject, $toActiveDOMObject, $toEventTarget, "; |  | 
| 3935     $code .= "$rootForGC, ${v8ClassName}::installPerContextPrototypeProperties, 
      $parentClassInfo, $WrapperTypePrototype };\n"; |  | 
| 3936     $implementation{nameSpaceWebCore}->addHeader($code); |  | 
| 3937 |  | 
| 3938     $implementation{nameSpaceInternal}->add("template <typename T> void V8_USE(T
      ) { }\n\n"); |  | 
| 3939 |  | 
| 3940     my $hasConstructors = 0; |  | 
| 3941     my $hasReplaceable = 0; |  | 
| 3942 |  | 
| 3943     # Generate property accessors for attributes. |  | 
| 3944     for (my $index = 0; $index < @{$interface->attributes}; $index++) { |  | 
| 3945         my $attribute = @{$interface->attributes}[$index]; |  | 
| 3946         my $attrType = $attribute->type; |  | 
| 3947         my $attrExt = $attribute->extendedAttributes; |  | 
| 3948 |  | 
| 3949         # Generate special code for the constructor attributes. |  | 
| 3950         if ($attrType =~ /Constructor$/) { |  | 
| 3951             if (!HasCustomGetter($attrExt)) { |  | 
| 3952                 $hasConstructors = 1; |  | 
| 3953             } |  | 
| 3954             next; |  | 
| 3955         } |  | 
| 3956 |  | 
| 3957         if ($attrType eq "EventHandler" && $interfaceName eq "Window") { |  | 
| 3958             $attrExt->{"OnProto"} = 1; |  | 
| 3959         } |  | 
| 3960 |  | 
| 3961         if ($attrType eq "SerializedScriptValue") { |  | 
| 3962             AddToImplIncludes("bindings/v8/SerializedScriptValue.h"); |  | 
| 3963         } |  | 
| 3964 |  | 
| 3965         GenerateNormalAttributeGetter($attribute, $interface, ""); |  | 
| 3966         GenerateNormalAttributeGetterCallback($attribute, $interface, ""); |  | 
| 3967         if ($attrExt->{"PerWorldBindings"}) { |  | 
| 3968             GenerateNormalAttributeGetter($attribute, $interface, "ForMainWorld"
      ); |  | 
| 3969             GenerateNormalAttributeGetterCallback($attribute, $interface, "ForMa
      inWorld"); |  | 
| 3970         } |  | 
| 3971         if (!HasCustomSetter($attrExt) && $attrExt->{"Replaceable"}) { |  | 
| 3972             $hasReplaceable = 1; |  | 
| 3973         } elsif (!IsReadonly($attribute)) { |  | 
| 3974             GenerateNormalAttributeSetter($attribute, $interface, ""); |  | 
| 3975             GenerateNormalAttributeSetterCallback($attribute, $interface, ""); |  | 
| 3976             if ($attrExt->{"PerWorldBindings"}) { |  | 
| 3977               GenerateNormalAttributeSetter($attribute, $interface, "ForMainWorl
      d"); |  | 
| 3978               GenerateNormalAttributeSetterCallback($attribute, $interface, "For
      MainWorld"); |  | 
| 3979             } |  | 
| 3980         } |  | 
| 3981     } |  | 
| 3982 |  | 
| 3983     if ($hasConstructors) { |  | 
| 3984         GenerateConstructorGetter($interface); |  | 
| 3985     } |  | 
| 3986 |  | 
| 3987     if ($hasConstructors || $hasReplaceable) { |  | 
| 3988         GenerateReplaceableAttributeSetter($interface); |  | 
| 3989         GenerateReplaceableAttributeSetterCallback($interface); |  | 
| 3990     } |  | 
| 3991 |  | 
| 3992     if (NeedsOpaqueRootForGC($interface)) { |  | 
| 3993         GenerateOpaqueRootForGC($interface); |  | 
| 3994     } |  | 
| 3995 |  | 
| 3996     if ($interface->extendedAttributes->{"CheckSecurity"} && $interface->name ne
       "Window") { |  | 
| 3997         GenerateSecurityCheckFunctions($interface); |  | 
| 3998     } |  | 
| 3999 |  | 
| 4000     if (IsConstructorTemplate($interface, "TypedArray")) { |  | 
| 4001         my ($nativeType, $arrayType) = GetNativeTypeOfTypedArray($interface); |  | 
| 4002         $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4003 v8::Handle<v8::Object> wrap($implClassName* impl, v8::Handle<v8::Object> creatio
      nContext, v8::Isolate* isolate) |  | 
| 4004 { |  | 
| 4005     ASSERT(impl); |  | 
| 4006     v8::Handle<v8::Object> wrapper = ${v8ClassName}::createWrapper(impl, creatio
      nContext, isolate); |  | 
| 4007     if (!wrapper.IsEmpty()) |  | 
| 4008         wrapper->SetIndexedPropertiesToExternalArrayData(impl->baseAddress(), $a
      rrayType, impl->length()); |  | 
| 4009     return wrapper; |  | 
| 4010 } |  | 
| 4011 |  | 
| 4012 END |  | 
| 4013     } |  | 
| 4014 |  | 
| 4015     # Add strong reference from TearOff to SVGElement, so that SVGElement would 
      never get GC-ed while the TearOff is alive. We do this in V8-side to avoid circu
      lar reference on Blink side. |  | 
| 4016     my $svgNativeType = GetSVGTypeNeedingTearOff($interface->name); |  | 
| 4017     if ($svgNativeType) { |  | 
| 4018         # below include needed for SVGPathSegListPropertyTearOff |  | 
| 4019         AddToImplIncludes("V8SVGPathElement.h"); |  | 
| 4020         $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4021 v8::Handle<v8::Object> wrap($svgNativeType* impl, v8::Handle<v8::Object> creatio
      nContext, v8::Isolate* isolate) |  | 
| 4022 { |  | 
| 4023     ASSERT(impl); |  | 
| 4024     ASSERT(!DOMDataStore::containsWrapper<${v8ClassName}>(impl, isolate)); |  | 
| 4025     v8::Handle<v8::Object> wrapper = ${v8ClassName}::createWrapper(impl, creatio
      nContext, isolate); |  | 
| 4026     if (impl->contextElement()) |  | 
| 4027         V8HiddenPropertyName::setNamedHiddenReference(wrapper, "contextElement",
       toV8(impl->contextElement(), creationContext, isolate)); |  | 
| 4028     return wrapper; |  | 
| 4029 } |  | 
| 4030 |  | 
| 4031 END |  | 
| 4032     } |  | 
| 4033 |  | 
| 4034     my @enabledPerContextFunctions; |  | 
| 4035     my @normalFunctions; |  | 
| 4036     my $needsDomainSafeFunctionSetter = 0; |  | 
| 4037     # Generate methods for functions. |  | 
| 4038     foreach my $function (@{$interface->functions}) { |  | 
| 4039         next if $function->name eq ""; |  | 
| 4040         GenerateFunction($function, $interface, ""); |  | 
| 4041         if ($function->extendedAttributes->{"PerWorldBindings"}) { |  | 
| 4042             GenerateFunction($function, $interface, "ForMainWorld"); |  | 
| 4043         } |  | 
| 4044         if ($function->{overloadIndex} == @{$function->{overloads}}) { |  | 
| 4045             if ($function->{overloadIndex} > 1) { |  | 
| 4046                 GenerateOverloadedFunction($function, $interface, ""); |  | 
| 4047                 if ($function->extendedAttributes->{"PerWorldBindings"}) { |  | 
| 4048                     GenerateOverloadedFunction($function, $interface, "ForMainWo
      rld"); |  | 
| 4049                 } |  | 
| 4050             } |  | 
| 4051             GenerateFunctionCallback($function, $interface, ""); |  | 
| 4052             if ($function->extendedAttributes->{"PerWorldBindings"}) { |  | 
| 4053                 GenerateFunctionCallback($function, $interface, "ForMainWorld"); |  | 
| 4054             } |  | 
| 4055         } |  | 
| 4056 |  | 
| 4057         # If the function does not need domain security check, we need to |  | 
| 4058         # generate an access getter that returns different function objects |  | 
| 4059         # for different calling context. |  | 
| 4060         if ($interface->extendedAttributes->{"CheckSecurity"} && $function->exte
      ndedAttributes->{"DoNotCheckSecurity"}) { |  | 
| 4061             if (!HasCustomMethod($function->extendedAttributes) || $function->{o
      verloadIndex} == 1) { |  | 
| 4062                 GenerateDomainSafeFunctionGetter($function, $interface); |  | 
| 4063                 if (!$function->extendedAttributes->{"ReadOnly"}) { |  | 
| 4064                     $needsDomainSafeFunctionSetter = 1; |  | 
| 4065                 } |  | 
| 4066             } |  | 
| 4067         } |  | 
| 4068 |  | 
| 4069         # Separate out functions that are enabled per context so we can process 
      them specially. |  | 
| 4070         if ($function->extendedAttributes->{"EnabledPerContext"}) { |  | 
| 4071             push(@enabledPerContextFunctions, $function); |  | 
| 4072         } else { |  | 
| 4073             push(@normalFunctions, $function); |  | 
| 4074         } |  | 
| 4075     } |  | 
| 4076 |  | 
| 4077     if ($needsDomainSafeFunctionSetter) { |  | 
| 4078         GenerateDomainSafeFunctionSetter($interface); |  | 
| 4079     } |  | 
| 4080 |  | 
| 4081     # Attributes |  | 
| 4082     my $attributes = $interface->attributes; |  | 
| 4083 |  | 
| 4084     # For the Window interface we partition the attributes into the |  | 
| 4085     # ones that disallows shadowing and the rest. |  | 
| 4086     my @disallowsShadowing; |  | 
| 4087     # Also separate out attributes that are enabled at runtime so we can process
       them specially. |  | 
| 4088     my @enabledAtRuntimeAttributes; |  | 
| 4089     my @enabledPerContextAttributes; |  | 
| 4090     my @normalAttributes; |  | 
| 4091     foreach my $attribute (@$attributes) { |  | 
| 4092 |  | 
| 4093         if ($interfaceName eq "Window" && $attribute->extendedAttributes->{"Unfo
      rgeable"}) { |  | 
| 4094             push(@disallowsShadowing, $attribute); |  | 
| 4095         } elsif ($attribute->extendedAttributes->{"EnabledAtRuntime"} || $attrib
      ute->extendedAttributes->{"EnabledPerContext"}) { |  | 
| 4096             if ($attribute->extendedAttributes->{"EnabledPerContext"}) { |  | 
| 4097                 push(@enabledPerContextAttributes, $attribute); |  | 
| 4098             } |  | 
| 4099             if ($attribute->extendedAttributes->{"EnabledAtRuntime"}) { |  | 
| 4100                 push(@enabledAtRuntimeAttributes, $attribute); |  | 
| 4101             } |  | 
| 4102         } else { |  | 
| 4103             push(@normalAttributes, $attribute); |  | 
| 4104         } |  | 
| 4105     } |  | 
| 4106     AddToImplIncludes("bindings/v8/V8DOMConfiguration.h"); |  | 
| 4107     $attributes = \@normalAttributes; |  | 
| 4108     # Put the attributes that disallow shadowing on the shadow object. |  | 
| 4109     if (@disallowsShadowing) { |  | 
| 4110         my $code = ""; |  | 
| 4111         $code .= "static const V8DOMConfiguration::AttributeConfiguration shadow
      Attributes[] = {\n"; |  | 
| 4112         $code .= GenerateAttributeConfigurationArray($interface, \@disallowsShad
      owing); |  | 
| 4113         $code .= "};\n\n"; |  | 
| 4114         $implementation{nameSpaceWebCore}->add($code); |  | 
| 4115     } |  | 
| 4116 |  | 
| 4117     my $has_attributes = 0; |  | 
| 4118     if (@$attributes) { |  | 
| 4119         $has_attributes = 1; |  | 
| 4120         my $code = ""; |  | 
| 4121         $code .= "static const V8DOMConfiguration::AttributeConfiguration ${v8Cl
      assName}Attributes[] = {\n"; |  | 
| 4122         $code .= GenerateAttributeConfigurationArray($interface, $attributes); |  | 
| 4123         $code .= "};\n\n"; |  | 
| 4124         $implementation{nameSpaceWebCore}->add($code); |  | 
| 4125     } |  | 
| 4126 |  | 
| 4127     # Setup table of standard callback functions |  | 
| 4128     my $num_callbacks = 0; |  | 
| 4129     my $has_callbacks = 0; |  | 
| 4130     $code = ""; |  | 
| 4131     foreach my $function (@normalFunctions) { |  | 
| 4132         # Only one table entry is needed for overloaded methods: |  | 
| 4133         next if $function->{overloadIndex} > 1; |  | 
| 4134         # Don't put any nonstandard functions into this table: |  | 
| 4135         next if !IsStandardFunction($interface, $function); |  | 
| 4136         next if $function->name eq ""; |  | 
| 4137         if (!$has_callbacks) { |  | 
| 4138             $has_callbacks = 1; |  | 
| 4139             $code .= "static const V8DOMConfiguration::MethodConfiguration ${v8C
      lassName}Methods[] = {\n"; |  | 
| 4140         } |  | 
| 4141         my $name = $function->name; |  | 
| 4142         my $methodForMainWorld = "0"; |  | 
| 4143         if ($function->extendedAttributes->{"PerWorldBindings"}) { |  | 
| 4144             $methodForMainWorld = "${implClassName}V8Internal::${name}MethodCall
      backForMainWorld"; |  | 
| 4145         } |  | 
| 4146         my $functionLength = GetFunctionLength($function); |  | 
| 4147         my $conditionalString = GenerateConditionalString($function); |  | 
| 4148         $code .= "#if ${conditionalString}\n" if $conditionalString; |  | 
| 4149         $code .= <<END; |  | 
| 4150     {"$name", ${implClassName}V8Internal::${name}MethodCallback, ${methodForMain
      World}, ${functionLength}}, |  | 
| 4151 END |  | 
| 4152         $code .= "#endif // ${conditionalString}\n" if $conditionalString; |  | 
| 4153         $num_callbacks++; |  | 
| 4154     } |  | 
| 4155     $code .= "};\n\n"  if $has_callbacks; |  | 
| 4156     $implementation{nameSpaceWebCore}->add($code); |  | 
| 4157 |  | 
| 4158     my $has_constants = 0; |  | 
| 4159     if (@{$interface->constants}) { |  | 
| 4160         $has_constants = 1; |  | 
| 4161     } |  | 
| 4162 |  | 
| 4163     if (!HasCustomConstructor($interface)) { |  | 
| 4164         if ($interface->extendedAttributes->{"NamedConstructor"}) { |  | 
| 4165             GenerateNamedConstructor(@{$interface->constructors}[0], $interface)
      ; |  | 
| 4166         } elsif ($interface->extendedAttributes->{"Constructor"}) { |  | 
| 4167             GenerateConstructor($interface); |  | 
| 4168         } elsif (IsConstructorTemplate($interface, "Event")) { |  | 
| 4169             GenerateEventConstructor($interface); |  | 
| 4170         } |  | 
| 4171     } |  | 
| 4172     if (IsConstructable($interface)) { |  | 
| 4173         GenerateConstructorCallback($interface); |  | 
| 4174     } |  | 
| 4175 |  | 
| 4176     my $access_check = ""; |  | 
| 4177     if ($interface->extendedAttributes->{"CheckSecurity"} && $interfaceName ne "
      Window") { |  | 
| 4178         $access_check = "instance->SetAccessCheckCallbacks(${implClassName}V8Int
      ernal::namedSecurityCheck, ${implClassName}V8Internal::indexedSecurityCheck, v8:
      :External::New(&${v8ClassName}::info));"; |  | 
| 4179     } |  | 
| 4180 |  | 
| 4181     # For the Window interface, generate the shadow object template |  | 
| 4182     # configuration method. |  | 
| 4183     if ($interfaceName eq "Window") { |  | 
| 4184         $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4185 static void ConfigureShadowObjectTemplate(v8::Handle<v8::ObjectTemplate> templ, 
      v8::Isolate* isolate, WrapperWorldType currentWorldType) |  | 
| 4186 { |  | 
| 4187     V8DOMConfiguration::installAttributes(templ, v8::Handle<v8::ObjectTemplate>(
      ), shadowAttributes, WTF_ARRAY_LENGTH(shadowAttributes), isolate, currentWorldTy
      pe); |  | 
| 4188 |  | 
| 4189     // Install a security handler with V8. |  | 
| 4190     templ->SetAccessCheckCallbacks(V8Window::namedSecurityCheckCustom, V8Window:
      :indexedSecurityCheckCustom, v8::External::New(&V8Window::info)); |  | 
| 4191     templ->SetInternalFieldCount(V8Window::internalFieldCount); |  | 
| 4192 } |  | 
| 4193 END |  | 
| 4194     } |  | 
| 4195 |  | 
| 4196     if (!$parentClassTemplate) { |  | 
| 4197         $parentClassTemplate = "v8::Local<v8::FunctionTemplate>()"; |  | 
| 4198     } |  | 
| 4199 |  | 
| 4200     # Generate the template configuration method |  | 
| 4201     $code =  <<END; |  | 
| 4202 static v8::Handle<v8::FunctionTemplate> Configure${v8ClassName}Template(v8::Hand
      le<v8::FunctionTemplate> desc, v8::Isolate* isolate, WrapperWorldType currentWor
      ldType) |  | 
| 4203 { |  | 
| 4204     desc->ReadOnlyPrototype(); |  | 
| 4205 |  | 
| 4206     v8::Local<v8::Signature> defaultSignature; |  | 
| 4207 END |  | 
| 4208     if ($interface->extendedAttributes->{"EnabledAtRuntime"}) { |  | 
| 4209         my $enable_function = GetRuntimeEnableFunctionName($interface); |  | 
| 4210         $code .= <<END; |  | 
| 4211     if (!${enable_function}()) |  | 
| 4212         defaultSignature = V8DOMConfiguration::installDOMClassTemplate(desc, \"\
      ", $parentClassTemplate, ${v8ClassName}::internalFieldCount, 0, 0, 0, 0, isolate
      , currentWorldType); |  | 
| 4213     else |  | 
| 4214 END |  | 
| 4215     } |  | 
| 4216     $code .=  <<END; |  | 
| 4217     defaultSignature = V8DOMConfiguration::installDOMClassTemplate(desc, \"${int
      erfaceName}\", $parentClassTemplate, ${v8ClassName}::internalFieldCount, |  | 
| 4218 END |  | 
| 4219     # Set up our attributes if we have them |  | 
| 4220     if ($has_attributes) { |  | 
| 4221         $code .= <<END; |  | 
| 4222         ${v8ClassName}Attributes, WTF_ARRAY_LENGTH(${v8ClassName}Attributes), |  | 
| 4223 END |  | 
| 4224     } else { |  | 
| 4225         $code .= <<END; |  | 
| 4226         0, 0, |  | 
| 4227 END |  | 
| 4228     } |  | 
| 4229 |  | 
| 4230     if ($has_callbacks) { |  | 
| 4231         $code .= <<END; |  | 
| 4232         ${v8ClassName}Methods, WTF_ARRAY_LENGTH(${v8ClassName}Methods), isolate,
       currentWorldType); |  | 
| 4233 END |  | 
| 4234     } else { |  | 
| 4235         $code .= <<END; |  | 
| 4236         0, 0, isolate, currentWorldType); |  | 
| 4237 END |  | 
| 4238     } |  | 
| 4239 |  | 
| 4240     AddToImplIncludes("wtf/UnusedParam.h"); |  | 
| 4241     $code .= <<END; |  | 
| 4242     UNUSED_PARAM(defaultSignature); |  | 
| 4243 END |  | 
| 4244 |  | 
| 4245     if (IsConstructable($interface)) { |  | 
| 4246         $code .= "    desc->SetCallHandler(${v8ClassName}::constructorCallback);
      \n"; |  | 
| 4247         my $interfaceLength = GetInterfaceLength($interface); |  | 
| 4248         $code .= "    desc->SetLength(${interfaceLength});\n"; |  | 
| 4249     } |  | 
| 4250 |  | 
| 4251     if ($access_check or @enabledAtRuntimeAttributes or @normalFunctions or $has
      _constants) { |  | 
| 4252         $code .=  <<END; |  | 
| 4253     v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate(); |  | 
| 4254     v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate(); |  | 
| 4255     UNUSED_PARAM(instance); |  | 
| 4256     UNUSED_PARAM(proto); |  | 
| 4257 END |  | 
| 4258     } |  | 
| 4259 |  | 
| 4260     if ($access_check) { |  | 
| 4261         $code .=  "    $access_check\n"; |  | 
| 4262     } |  | 
| 4263 |  | 
| 4264     # Setup the enable-at-runtime attributes if we have them |  | 
| 4265     foreach my $runtime_attr (@enabledAtRuntimeAttributes) { |  | 
| 4266         next if grep { $_ eq $runtime_attr } @enabledPerContextAttributes; |  | 
| 4267         my $enable_function = GetRuntimeEnableFunctionName($runtime_attr); |  | 
| 4268         my $conditionalString = GenerateConditionalString($runtime_attr); |  | 
| 4269         $code .= "\n#if ${conditionalString}\n" if $conditionalString; |  | 
| 4270         $code .= "    if (${enable_function}()) {\n"; |  | 
| 4271         $code .= "        static const V8DOMConfiguration::AttributeConfiguratio
      n attributeConfiguration =\\\n"; |  | 
| 4272         $code .= GenerateAttributeConfiguration($interface, $runtime_attr, ";", 
      "    "); |  | 
| 4273         $code .= <<END; |  | 
| 4274         V8DOMConfiguration::installAttribute(instance, proto, attributeConfigura
      tion, isolate, currentWorldType); |  | 
| 4275     } |  | 
| 4276 END |  | 
| 4277         $code .= "\n#endif // ${conditionalString}\n" if $conditionalString; |  | 
| 4278     } |  | 
| 4279 |  | 
| 4280     my @constantsEnabledAtRuntime; |  | 
| 4281     if ($has_constants) { |  | 
| 4282         $code .= "    static const V8DOMConfiguration::ConstantConfiguration ${v
      8ClassName}Constants[] = {\n"; |  | 
| 4283         foreach my $constant (@{$interface->constants}) { |  | 
| 4284             my $name = $constant->name; |  | 
| 4285             my $value = $constant->value; |  | 
| 4286             my $attrExt = $constant->extendedAttributes; |  | 
| 4287             my $implementedBy = $attrExt->{"ImplementedBy"}; |  | 
| 4288             if ($implementedBy) { |  | 
| 4289                 my $implementedByImplName = GetImplNameFromImplementedBy($implem
      entedBy); |  | 
| 4290                 AddToImplIncludes(HeaderFilesForInterface($implementedBy, $imple
      mentedByImplName)); |  | 
| 4291             } |  | 
| 4292             if ($attrExt->{"EnabledAtRuntime"}) { |  | 
| 4293                 push(@constantsEnabledAtRuntime, $constant); |  | 
| 4294             } else { |  | 
| 4295                 $code .= <<END; |  | 
| 4296         {"${name}", $value}, |  | 
| 4297 END |  | 
| 4298             } |  | 
| 4299         } |  | 
| 4300         $code .= "    };\n"; |  | 
| 4301         $code .= <<END; |  | 
| 4302     V8DOMConfiguration::installConstants(desc, proto, ${v8ClassName}Constants, W
      TF_ARRAY_LENGTH(${v8ClassName}Constants), isolate); |  | 
| 4303 END |  | 
| 4304         # Setup the enable-at-runtime constants if we have them |  | 
| 4305         foreach my $runtime_const (@constantsEnabledAtRuntime) { |  | 
| 4306             my $enable_function = GetRuntimeEnableFunctionName($runtime_const); |  | 
| 4307             my $name = $runtime_const->name; |  | 
| 4308             my $value = $runtime_const->value; |  | 
| 4309             $code .= "    if (${enable_function}()) {\n"; |  | 
| 4310             $code .= <<END; |  | 
| 4311         static const V8DOMConfiguration::ConstantConfiguration constantConfigura
      tion = {"${name}", static_cast<signed int>(${value})}; |  | 
| 4312         V8DOMConfiguration::installConstants(desc, proto, &constantConfiguration
      , 1, isolate); |  | 
| 4313 END |  | 
| 4314             $code .= "    }\n"; |  | 
| 4315         } |  | 
| 4316         $code .= join "", GenerateCompileTimeCheckForEnumsIfNeeded($interface); |  | 
| 4317     } |  | 
| 4318 |  | 
| 4319     $code .= GenerateImplementationIndexedPropertyAccessors($interface); |  | 
| 4320     $code .= GenerateImplementationNamedPropertyAccessors($interface); |  | 
| 4321     $code .= GenerateImplementationLegacyCall($interface); |  | 
| 4322     $code .= GenerateImplementationMasqueradesAsUndefined($interface); |  | 
| 4323 |  | 
| 4324     # Define our functions with Set() or SetAccessor() |  | 
| 4325     my $total_functions = 0; |  | 
| 4326     foreach my $function (@normalFunctions) { |  | 
| 4327         # Only one accessor is needed for overloaded methods: |  | 
| 4328         next if $function->{overloadIndex} > 1; |  | 
| 4329         next if $function->name eq ""; |  | 
| 4330 |  | 
| 4331         $total_functions++; |  | 
| 4332         next if IsStandardFunction($interface, $function); |  | 
| 4333         $code .= GenerateNonStandardFunction($interface, $function); |  | 
| 4334         $num_callbacks++; |  | 
| 4335     } |  | 
| 4336 |  | 
| 4337     die "Wrong number of callbacks generated for $interfaceName ($num_callbacks,
       should be $total_functions)" if $num_callbacks != $total_functions; |  | 
| 4338 |  | 
| 4339     # Special cases |  | 
| 4340     if ($interfaceName eq "Window") { |  | 
| 4341         $code .= <<END; |  | 
| 4342 |  | 
| 4343     proto->SetInternalFieldCount(V8Window::internalFieldCount); |  | 
| 4344     desc->SetHiddenPrototype(true); |  | 
| 4345     instance->SetInternalFieldCount(V8Window::internalFieldCount); |  | 
| 4346     // Set access check callbacks, but turned off initially. |  | 
| 4347     // When a context is detached from a frame, turn on the access check. |  | 
| 4348     // Turning on checks also invalidates inline caches of the object. |  | 
| 4349     instance->SetAccessCheckCallbacks(V8Window::namedSecurityCheckCustom, V8Wind
      ow::indexedSecurityCheckCustom, v8::External::New(&V8Window::info), false); |  | 
| 4350 END |  | 
| 4351     } |  | 
| 4352     if ($interfaceName eq "HTMLDocument" or $interfaceName eq "DedicatedWorkerGl
      obalScope" or $interfaceName eq "SharedWorkerGlobalScope") { |  | 
| 4353         $code .= <<END; |  | 
| 4354     desc->SetHiddenPrototype(true); |  | 
| 4355 END |  | 
| 4356     } |  | 
| 4357 |  | 
| 4358     $code .= <<END; |  | 
| 4359 |  | 
| 4360     // Custom toString template |  | 
| 4361     desc->Set(v8::String::NewSymbol("toString"), V8PerIsolateData::current()->to
      StringTemplate()); |  | 
| 4362     return desc; |  | 
| 4363 } |  | 
| 4364 |  | 
| 4365 END |  | 
| 4366     $implementation{nameSpaceWebCore}->add($code); |  | 
| 4367 |  | 
| 4368     $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4369 v8::Handle<v8::FunctionTemplate> ${v8ClassName}::GetTemplate(v8::Isolate* isolat
      e, WrapperWorldType currentWorldType) |  | 
| 4370 { |  | 
| 4371     V8PerIsolateData* data = V8PerIsolateData::from(isolate); |  | 
| 4372     V8PerIsolateData::TemplateMap::iterator result = data->templateMap(currentWo
      rldType).find(&info); |  | 
| 4373     if (result != data->templateMap(currentWorldType).end()) |  | 
| 4374         return result->value.newLocal(isolate); |  | 
| 4375 |  | 
| 4376     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate"); |  | 
| 4377     v8::HandleScope handleScope(isolate); |  | 
| 4378     v8::Handle<v8::FunctionTemplate> templ = |  | 
| 4379         Configure${v8ClassName}Template(data->rawTemplate(&info, currentWorldTyp
      e), isolate, currentWorldType); |  | 
| 4380     data->templateMap(currentWorldType).add(&info, UnsafePersistent<v8::Function
      Template>(isolate, templ)); |  | 
| 4381     return handleScope.Close(templ); |  | 
| 4382 } |  | 
| 4383 |  | 
| 4384 END |  | 
| 4385     $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4386 bool ${v8ClassName}::HasInstance(v8::Handle<v8::Value> value, v8::Isolate* isola
      te, WrapperWorldType currentWorldType) |  | 
| 4387 { |  | 
| 4388     return V8PerIsolateData::from(isolate)->hasInstance(&info, value, currentWor
      ldType); |  | 
| 4389 } |  | 
| 4390 |  | 
| 4391 END |  | 
| 4392     $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4393 bool ${v8ClassName}::HasInstanceInAnyWorld(v8::Handle<v8::Value> value, v8::Isol
      ate* isolate) |  | 
| 4394 { |  | 
| 4395     return V8PerIsolateData::from(isolate)->hasInstance(&info, value, MainWorld) |  | 
| 4396         || V8PerIsolateData::from(isolate)->hasInstance(&info, value, IsolatedWo
      rld) |  | 
| 4397         || V8PerIsolateData::from(isolate)->hasInstance(&info, value, WorkerWorl
      d); |  | 
| 4398 } |  | 
| 4399 |  | 
| 4400 END |  | 
| 4401 |  | 
| 4402     if (@enabledPerContextAttributes) { |  | 
| 4403         my $code = ""; |  | 
| 4404         $code .= <<END; |  | 
| 4405 void ${v8ClassName}::installPerContextProperties(v8::Handle<v8::Object> instance
      , ${nativeType}* impl, v8::Isolate* isolate) |  | 
| 4406 { |  | 
| 4407     v8::Local<v8::Object> proto = v8::Local<v8::Object>::Cast(instance->GetProto
      type()); |  | 
| 4408 END |  | 
| 4409 |  | 
| 4410         # Setup the enable-by-settings attributes if we have them |  | 
| 4411         foreach my $runtimeAttribute (@enabledPerContextAttributes) { |  | 
| 4412             my $enableFunction = GetContextEnableFunction($runtimeAttribute); |  | 
| 4413             my $conditionalString = GenerateConditionalString($runtimeAttribute)
      ; |  | 
| 4414             $code .= "\n#if ${conditionalString}\n" if $conditionalString; |  | 
| 4415             if (grep { $_ eq $runtimeAttribute } @enabledAtRuntimeAttributes) { |  | 
| 4416                 my $runtimeEnableFunction = GetRuntimeEnableFunctionName($runtim
      eAttribute); |  | 
| 4417                 $code .= "    if (${enableFunction}(impl->document()) && ${runti
      meEnableFunction}()) {\n"; |  | 
| 4418             } else { |  | 
| 4419                 $code .= "    if (${enableFunction}(impl->document())) {\n"; |  | 
| 4420             } |  | 
| 4421 |  | 
| 4422             $code .= "        static const V8DOMConfiguration::AttributeConfigur
      ation    attributeConfiguration =\\\n"; |  | 
| 4423             $code .= GenerateAttributeConfiguration($interface, $runtimeAttribut
      e, ";", "    "); |  | 
| 4424             $code .= <<END; |  | 
| 4425         V8DOMConfiguration::installAttribute(instance, proto, attributeConfigura
      tion, isolate); |  | 
| 4426 END |  | 
| 4427             $code .= "    }\n"; |  | 
| 4428             $code .= "#endif // ${conditionalString}\n" if $conditionalString; |  | 
| 4429         } |  | 
| 4430         $code .= <<END; |  | 
| 4431 } |  | 
| 4432 |  | 
| 4433 END |  | 
| 4434         $implementation{nameSpaceWebCore}->add($code); |  | 
| 4435     } |  | 
| 4436 |  | 
| 4437     if (@enabledPerContextFunctions) { |  | 
| 4438         my $code = ""; |  | 
| 4439         $code .= <<END; |  | 
| 4440 void ${v8ClassName}::installPerContextPrototypeProperties(v8::Handle<v8::Object>
       proto, v8::Isolate* isolate) |  | 
| 4441 { |  | 
| 4442     UNUSED_PARAM(proto); |  | 
| 4443 END |  | 
| 4444         # Setup the enable-by-settings functions if we have them |  | 
| 4445         $code .=  <<END; |  | 
| 4446     v8::Local<v8::Signature> defaultSignature = v8::Signature::New(GetTemplate(i
      solate, worldType(isolate))); |  | 
| 4447     UNUSED_PARAM(defaultSignature); |  | 
| 4448 |  | 
| 4449     ScriptExecutionContext* context = toScriptExecutionContext(proto->CreationCo
      ntext()); |  | 
| 4450 END |  | 
| 4451 |  | 
| 4452         foreach my $runtimeFunc (@enabledPerContextFunctions) { |  | 
| 4453             my $enableFunction = GetContextEnableFunction($runtimeFunc); |  | 
| 4454             my $functionLength = GetFunctionLength($runtimeFunc); |  | 
| 4455             my $conditionalString = GenerateConditionalString($runtimeFunc); |  | 
| 4456             $code .= "\n#if ${conditionalString}\n" if $conditionalString; |  | 
| 4457             $code .= "    if (context && context->isDocument() && ${enableFuncti
      on}(toDocument(context)))\n"; |  | 
| 4458             my $name = $runtimeFunc->name; |  | 
| 4459             $code .= <<END; |  | 
| 4460         proto->Set(v8::String::NewSymbol("${name}"), v8::FunctionTemplate::New($
      {implClassName}V8Internal::${name}MethodCallback, v8Undefined(), defaultSignatur
      e, $functionLength)->GetFunction()); |  | 
| 4461 END |  | 
| 4462             $code .= "#endif // ${conditionalString}\n" if $conditionalString; |  | 
| 4463         } |  | 
| 4464 |  | 
| 4465         $code .= <<END; |  | 
| 4466 } |  | 
| 4467 |  | 
| 4468 END |  | 
| 4469         $implementation{nameSpaceWebCore}->add($code); |  | 
| 4470     } |  | 
| 4471 |  | 
| 4472     if (InheritsExtendedAttribute($interface, "ActiveDOMObject")) { |  | 
| 4473         # MessagePort is handled like an active dom object even though it doesn'
      t inherit |  | 
| 4474         # from ActiveDOMObject, so don't try to cast it to ActiveDOMObject. |  | 
| 4475         my $returnValue = $interfaceName eq "MessagePort" ? "0" : "toNative(obje
      ct)"; |  | 
| 4476         $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4477 ActiveDOMObject* ${v8ClassName}::toActiveDOMObject(v8::Handle<v8::Object> object
      ) |  | 
| 4478 { |  | 
| 4479     return $returnValue; |  | 
| 4480 } |  | 
| 4481 |  | 
| 4482 END |  | 
| 4483     } |  | 
| 4484 |  | 
| 4485     if (InheritsInterface($interface, "EventTarget")) { |  | 
| 4486         $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4487 EventTarget* ${v8ClassName}::toEventTarget(v8::Handle<v8::Object> object) |  | 
| 4488 { |  | 
| 4489     return toNative(object); |  | 
| 4490 } |  | 
| 4491 |  | 
| 4492 END |  | 
| 4493     } |  | 
| 4494 |  | 
| 4495     if ($interfaceName eq "Window") { |  | 
| 4496         $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4497 v8::Handle<v8::ObjectTemplate> V8Window::GetShadowObjectTemplate(v8::Isolate* is
      olate, WrapperWorldType currentWorldType) |  | 
| 4498 { |  | 
| 4499     if (currentWorldType == MainWorld) { |  | 
| 4500         DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, V8WindowShadowOb
      jectCacheForMainWorld, ()); |  | 
| 4501         if (V8WindowShadowObjectCacheForMainWorld.IsEmpty()) { |  | 
| 4502             TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate"); |  | 
| 4503             v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); |  | 
| 4504             ConfigureShadowObjectTemplate(templ, isolate, currentWorldType); |  | 
| 4505             V8WindowShadowObjectCacheForMainWorld.Reset(isolate, templ); |  | 
| 4506             return templ; |  | 
| 4507         } |  | 
| 4508         return v8::Local<v8::ObjectTemplate>::New(isolate, V8WindowShadowObjectC
      acheForMainWorld); |  | 
| 4509     } else { |  | 
| 4510         DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, V8WindowShadowOb
      jectCacheForNonMainWorld, ()); |  | 
| 4511         if (V8WindowShadowObjectCacheForNonMainWorld.IsEmpty()) { |  | 
| 4512             TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate"); |  | 
| 4513             v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); |  | 
| 4514             ConfigureShadowObjectTemplate(templ, isolate, currentWorldType); |  | 
| 4515             V8WindowShadowObjectCacheForNonMainWorld.Reset(isolate, templ); |  | 
| 4516             return templ; |  | 
| 4517         } |  | 
| 4518         return v8::Local<v8::ObjectTemplate>::New(isolate, V8WindowShadowObjectC
      acheForNonMainWorld); |  | 
| 4519     } |  | 
| 4520 } |  | 
| 4521 |  | 
| 4522 END |  | 
| 4523     } |  | 
| 4524 |  | 
| 4525     GenerateToV8Converters($interface, $v8ClassName, $nativeType); |  | 
| 4526 |  | 
| 4527     $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4528 void ${v8ClassName}::derefObject(void* object) |  | 
| 4529 { |  | 
| 4530     fromInternalPointer(object)->deref(); |  | 
| 4531 } |  | 
| 4532 |  | 
| 4533 END |  | 
| 4534 } |  | 
| 4535 |  | 
| 4536 sub GenerateHeaderContentHeader |  | 
| 4537 { |  | 
| 4538     my $interface = shift; |  | 
| 4539     my $v8ClassName = GetV8ClassName($interface); |  | 
| 4540     my $conditionalString = GenerateConditionalString($interface); |  | 
| 4541 |  | 
| 4542     my @headerContentHeader = split("\r", $headerTemplate); |  | 
| 4543 |  | 
| 4544     push(@headerContentHeader, "\n#ifndef ${v8ClassName}" . "_h\n"); |  | 
| 4545     push(@headerContentHeader, "#define ${v8ClassName}" . "_h\n\n"); |  | 
| 4546     push(@headerContentHeader, "#if ${conditionalString}\n") if $conditionalStri
      ng; |  | 
| 4547     return join "", @headerContentHeader; |  | 
| 4548 } |  | 
| 4549 |  | 
| 4550 sub GenerateCallbackHeader |  | 
| 4551 { |  | 
| 4552     my $object = shift; |  | 
| 4553     my $interface = shift; |  | 
| 4554 |  | 
| 4555     my $interfaceName = $interface->name; |  | 
| 4556     my $implClassName = GetImplName($interface); |  | 
| 4557     my $v8ClassName = GetV8ClassName($interface); |  | 
| 4558 |  | 
| 4559     $header{root}->addFooter("\n"); |  | 
| 4560 |  | 
| 4561     my @includes = (); |  | 
| 4562     push(@includes, "bindings/v8/ActiveDOMCallback.h"); |  | 
| 4563     push(@includes, "bindings/v8/DOMWrapperWorld.h"); |  | 
| 4564     push(@includes, "bindings/v8/ScopedPersistent.h"); |  | 
| 4565     push(@includes, HeaderFilesForInterface($interfaceName, $implClassName)); |  | 
| 4566     for my $include (sort @includes) { |  | 
| 4567         $header{includes}->add("#include \"$include\"\n"); |  | 
| 4568     } |  | 
| 4569     $header{nameSpaceWebCore}->addHeader("\nclass ScriptExecutionContext;\n\n"); |  | 
| 4570     $header{class}->addHeader("class $v8ClassName : public $implClassName, publi
      c ActiveDOMCallback {"); |  | 
| 4571     $header{class}->addFooter("};\n"); |  | 
| 4572 |  | 
| 4573     $header{classPublic}->add(<<END); |  | 
| 4574     static PassRefPtr<${v8ClassName}> create(v8::Handle<v8::Value> value, Script
      ExecutionContext* context) |  | 
| 4575     { |  | 
| 4576         ASSERT(value->IsObject()); |  | 
| 4577         ASSERT(context); |  | 
| 4578         return adoptRef(new ${v8ClassName}(v8::Handle<v8::Object>::Cast(value), 
      context)); |  | 
| 4579     } |  | 
| 4580 |  | 
| 4581     virtual ~${v8ClassName}(); |  | 
| 4582 |  | 
| 4583 END |  | 
| 4584 |  | 
| 4585     # Functions |  | 
| 4586     my $numFunctions = @{$interface->functions}; |  | 
| 4587     if ($numFunctions > 0) { |  | 
| 4588         $header{classPublic}->add("    // Functions\n"); |  | 
| 4589         foreach my $function (@{$interface->functions}) { |  | 
| 4590             my $code = "    virtual " . GetNativeTypeForCallbacks($function->typ
      e) . " " . $function->name . "("; |  | 
| 4591 |  | 
| 4592             my @args = (); |  | 
| 4593             if (ExtendedAttributeContains($function->extendedAttributes->{"CallW
      ith"}, "ThisValue")) { |  | 
| 4594                 push(@args, GetNativeType("any") . " thisValue"); |  | 
| 4595             } |  | 
| 4596             my @params = @{$function->parameters}; |  | 
| 4597             foreach my $param (@params) { |  | 
| 4598                 push(@args, GetNativeTypeForCallbacks($param->type) . " " . $par
      am->name); |  | 
| 4599             } |  | 
| 4600             $code .= join(", ", @args); |  | 
| 4601             $code .= ");\n"; |  | 
| 4602             $header{classPublic}->add($code); |  | 
| 4603         } |  | 
| 4604     } |  | 
| 4605 |  | 
| 4606     $header{classPublic}->add(<<END); |  | 
| 4607 |  | 
| 4608     virtual ScriptExecutionContext* scriptExecutionContext() const { return Cont
      extLifecycleObserver::scriptExecutionContext(); } |  | 
| 4609 |  | 
| 4610 END |  | 
| 4611     $header{classPrivate}->add(<<END); |  | 
| 4612     ${v8ClassName}(v8::Handle<v8::Object>, ScriptExecutionContext*); |  | 
| 4613 |  | 
| 4614     ScopedPersistent<v8::Object> m_callback; |  | 
| 4615     RefPtr<DOMWrapperWorld> m_world; |  | 
| 4616 END |  | 
| 4617 } |  | 
| 4618 |  | 
| 4619 sub GenerateCallbackImplementation |  | 
| 4620 { |  | 
| 4621     my $object = shift; |  | 
| 4622     my $interface = shift; |  | 
| 4623     my $v8ClassName = GetV8ClassName($interface); |  | 
| 4624 |  | 
| 4625     AddToImplIncludes("core/dom/ScriptExecutionContext.h"); |  | 
| 4626     AddToImplIncludes("bindings/v8/V8Binding.h"); |  | 
| 4627     AddToImplIncludes("bindings/v8/V8Callback.h"); |  | 
| 4628     AddToImplIncludes("wtf/Assertions.h"); |  | 
| 4629 |  | 
| 4630     $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4631 ${v8ClassName}::${v8ClassName}(v8::Handle<v8::Object> callback, ScriptExecutionC
      ontext* context) |  | 
| 4632     : ActiveDOMCallback(context) |  | 
| 4633     , m_callback(toIsolate(context), callback) |  | 
| 4634     , m_world(DOMWrapperWorld::current()) |  | 
| 4635 { |  | 
| 4636 } |  | 
| 4637 |  | 
| 4638 END |  | 
| 4639 |  | 
| 4640     $implementation{nameSpaceWebCore}->add(<<END); |  | 
| 4641 ${v8ClassName}::~${v8ClassName}() |  | 
| 4642 { |  | 
| 4643 } |  | 
| 4644 |  | 
| 4645 END |  | 
| 4646 |  | 
| 4647     # Functions |  | 
| 4648     my $numFunctions = @{$interface->functions}; |  | 
| 4649     if ($numFunctions > 0) { |  | 
| 4650         $implementation{nameSpaceWebCore}->add("// Functions\n"); |  | 
| 4651         foreach my $function (@{$interface->functions}) { |  | 
| 4652             my $code = ""; |  | 
| 4653             my @params = @{$function->parameters}; |  | 
| 4654             next if $function->extendedAttributes->{"Custom"}; |  | 
| 4655 |  | 
| 4656             AddIncludesForType($function->type); |  | 
| 4657             die "We don't yet support callbacks that return non-boolean values.\
      n" if $function->type ne "boolean"; |  | 
| 4658             $code .= "\n" . GetNativeTypeForCallbacks($function->type) . " ${v8C
      lassName}::" . $function->name . "("; |  | 
| 4659             my $callWithThisValue = ExtendedAttributeContains($function->extende
      dAttributes->{"CallWith"}, "ThisValue"); |  | 
| 4660 |  | 
| 4661             my @args = (); |  | 
| 4662             if ($callWithThisValue) { |  | 
| 4663                 push(@args, GetNativeTypeForCallbacks("any") . " thisValue"); |  | 
| 4664             } |  | 
| 4665             foreach my $param (@params) { |  | 
| 4666                 my $paramName = $param->name; |  | 
| 4667                 my $type = $param->type; |  | 
| 4668                 my $arrayOrSequenceType = GetArrayOrSequenceType($type); |  | 
| 4669 |  | 
| 4670                 if ($arrayOrSequenceType) { |  | 
| 4671                     if (IsRefPtrType($arrayOrSequenceType)) { |  | 
| 4672                         AddIncludesForType($arrayOrSequenceType); |  | 
| 4673                      } |  | 
| 4674                 } else { |  | 
| 4675                     AddIncludesForType($type); |  | 
| 4676                 } |  | 
| 4677 |  | 
| 4678                 push(@args, GetNativeTypeForCallbacks($type) . " " . $paramName)
      ; |  | 
| 4679             } |  | 
| 4680             $code .= join(", ", @args); |  | 
| 4681 |  | 
| 4682             $code .= ")\n"; |  | 
| 4683             $code .= "{\n"; |  | 
| 4684             $code .= "    if (!canInvokeCallback())\n"; |  | 
| 4685             $code .= "        return true;\n\n"; |  | 
| 4686             $code .= "    v8::Isolate* isolate = v8::Isolate::GetCurrent();\n"; |  | 
| 4687             $code .= "    v8::HandleScope handleScope(isolate);\n\n"; |  | 
| 4688             $code .= "    v8::Handle<v8::Context> v8Context = toV8Context(script
      ExecutionContext(), m_world.get());\n"; |  | 
| 4689             $code .= "    if (v8Context.IsEmpty())\n"; |  | 
| 4690             $code .= "        return true;\n\n"; |  | 
| 4691             $code .= "    v8::Context::Scope scope(v8Context);\n\n"; |  | 
| 4692 |  | 
| 4693             my $thisObjectHandle = ""; |  | 
| 4694             if ($callWithThisValue) { |  | 
| 4695                 $code .= "    v8::Handle<v8::Value> thisHandle = thisValue.v8Val
      ue();\n"; |  | 
| 4696                 $code .= "    if (thisHandle.IsEmpty()) {\n"; |  | 
| 4697                 $code .= "        if (!isScriptControllerTerminating())\n"; |  | 
| 4698                 $code .= "            CRASH();\n"; |  | 
| 4699                 $code .= "        return true;\n"; |  | 
| 4700                 $code .= "    }\n"; |  | 
| 4701                 $code .= "    ASSERT(thisHandle->isObject());\n"; |  | 
| 4702                 $thisObjectHandle = "v8::Handle<v8::Object>::Cast(thisHandle), "
      ; |  | 
| 4703             } |  | 
| 4704             @args = (); |  | 
| 4705             foreach my $param (@params) { |  | 
| 4706                 my $paramName = $param->name; |  | 
| 4707                 $code .= NativeToJSValue($param->type, $param->extendedAttribute
      s, $paramName, "    ", "v8::Handle<v8::Value> ${paramName}Handle =", "v8::Handle
      <v8::Object>()", "isolate", "") . "\n"; |  | 
| 4708                 $code .= "    if (${paramName}Handle.IsEmpty()) {\n"; |  | 
| 4709                 $code .= "        if (!isScriptControllerTerminating())\n"; |  | 
| 4710                 $code .= "            CRASH();\n"; |  | 
| 4711                 $code .= "        return true;\n"; |  | 
| 4712                 $code .= "    }\n"; |  | 
| 4713                 push(@args, "        ${paramName}Handle"); |  | 
| 4714             } |  | 
| 4715 |  | 
| 4716             if (scalar(@args) > 0) { |  | 
| 4717                 $code .= "\n    v8::Handle<v8::Value> argv[] = {\n"; |  | 
| 4718                 $code .= join(",\n", @args); |  | 
| 4719                 $code .= "\n    };\n\n"; |  | 
| 4720             } else { |  | 
| 4721                 $code .= "\n    v8::Handle<v8::Value> *argv = 0;\n\n"; |  | 
| 4722             } |  | 
| 4723             $code .= "    bool callbackReturnValue = false;\n"; |  | 
| 4724             $code .= "    return !invokeCallback(m_callback.newLocal(isolate), $
      {thisObjectHandle}" . scalar(@args) . ", argv, callbackReturnValue, scriptExecut
      ionContext(), isolate);\n"; |  | 
| 4725             $code .= "}\n"; |  | 
| 4726             $implementation{nameSpaceWebCore}->add($code); |  | 
| 4727         } |  | 
| 4728     } |  | 
| 4729 } |  | 
| 4730 |  | 
| 4731 sub BaseInterfaceName |  | 
| 4732 { |  | 
| 4733     my $interface = shift; |  | 
| 4734 |  | 
| 4735     while ($interface->parent) { |  | 
| 4736         $interface = ParseInterface($interface->parent); |  | 
| 4737     } |  | 
| 4738 |  | 
| 4739     return $interface->name; |  | 
| 4740 } |  | 
| 4741 |  | 
| 4742 sub GenerateToV8Converters |  | 
| 4743 { |  | 
| 4744     my $interface = shift; |  | 
| 4745     my $v8ClassName = shift; |  | 
| 4746     my $nativeType = shift; |  | 
| 4747     my $interfaceName = $interface->name; |  | 
| 4748 |  | 
| 4749     if ($interface->extendedAttributes->{"DoNotGenerateWrap"} || $interface->ext
      endedAttributes->{"DoNotGenerateToV8"}) { |  | 
| 4750         return; |  | 
| 4751     } |  | 
| 4752 |  | 
| 4753     AddToImplIncludes("bindings/v8/ScriptController.h"); |  | 
| 4754 |  | 
| 4755     my $createWrapperArgumentType = GetPassRefPtrType($nativeType); |  | 
| 4756     my $baseType = BaseInterfaceName($interface); |  | 
| 4757 |  | 
| 4758     # FIXME: Do we really need to treat "GenerateIsReachable", "CustomIsReachabl
      e" and /SVG/ |  | 
| 4759     # as dependent DOM objects? |  | 
| 4760     my $wrapperConfiguration = "WrapperConfiguration::Independent"; |  | 
| 4761     if (InheritsExtendedAttribute($interface, "ActiveDOMObject") |  | 
| 4762         || InheritsExtendedAttribute($interface, "DependentLifetime") |  | 
| 4763         || InheritsExtendedAttribute($interface, "GenerateIsReachable") |  | 
| 4764         || InheritsExtendedAttribute($interface, "CustomIsReachable") |  | 
| 4765         || $v8ClassName =~ /SVG/) { |  | 
| 4766         $wrapperConfiguration = "WrapperConfiguration::Dependent"; |  | 
| 4767     } |  | 
| 4768 |  | 
| 4769     my $code = ""; |  | 
| 4770     $code .= <<END; |  | 
| 4771 v8::Handle<v8::Object> ${v8ClassName}::createWrapper(${createWrapperArgumentType
      } impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) |  | 
| 4772 { |  | 
| 4773     ASSERT(impl.get()); |  | 
| 4774     ASSERT(!DOMDataStore::containsWrapper<${v8ClassName}>(impl.get(), isolate)); |  | 
| 4775     if (ScriptWrappable::wrapperCanBeStoredInObject(impl.get())) { |  | 
| 4776         const WrapperTypeInfo* actualInfo = ScriptWrappable::getTypeInfoFromObje
      ct(impl.get()); |  | 
| 4777         // Might be a XXXConstructor::info instead of an XXX::info. These will b
      oth have |  | 
| 4778         // the same object de-ref functions, though, so use that as the basis of
       the check. |  | 
| 4779         RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(actualInfo->derefObjectFunction
       == info.derefObjectFunction); |  | 
| 4780     } |  | 
| 4781 |  | 
| 4782 END |  | 
| 4783 |  | 
| 4784     $code .= <<END if ($baseType ne $interfaceName); |  | 
| 4785 END |  | 
| 4786 |  | 
| 4787     if (InheritsInterface($interface, "Document")) { |  | 
| 4788         AddToImplIncludes("core/page/Frame.h"); |  | 
| 4789         $code .= <<END; |  | 
| 4790     if (Frame* frame = impl->frame()) { |  | 
| 4791         if (frame->script()->initializeMainWorld()) { |  | 
| 4792             // initializeMainWorld may have created a wrapper for the object, re
      try from the start. |  | 
| 4793             v8::Handle<v8::Object> wrapper = DOMDataStore::getWrapper<${v8ClassN
      ame}>(impl.get(), isolate); |  | 
| 4794             if (!wrapper.IsEmpty()) |  | 
| 4795                 return wrapper; |  | 
| 4796         } |  | 
| 4797     } |  | 
| 4798 END |  | 
| 4799     } |  | 
| 4800 |  | 
| 4801     $code .= <<END; |  | 
| 4802     v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext
      , &info, toInternalPointer(impl.get()), isolate); |  | 
| 4803     if (UNLIKELY(wrapper.IsEmpty())) |  | 
| 4804         return wrapper; |  | 
| 4805 |  | 
| 4806 END |  | 
| 4807     if (IsTypedArrayType($interface->name)) { |  | 
| 4808       AddToImplIncludes("bindings/v8/custom/V8ArrayBufferCustom.h"); |  | 
| 4809       $code .= <<END; |  | 
| 4810     if (!impl->buffer()->hasDeallocationObserver()) { |  | 
| 4811         v8::V8::AdjustAmountOfExternalAllocatedMemory(impl->buffer()->byteLength
      ()); |  | 
| 4812         impl->buffer()->setDeallocationObserver(V8ArrayBufferDeallocationObserve
      r::instance()); |  | 
| 4813     } |  | 
| 4814 END |  | 
| 4815     } |  | 
| 4816 |  | 
| 4817     if (InheritsInterface($interface, "AudioBuffer")) { |  | 
| 4818       AddToImplIncludes("modules/webaudio/AudioBuffer.h"); |  | 
| 4819       $code .= <<END; |  | 
| 4820     for (unsigned i = 0, n = impl->numberOfChannels(); i < n; i++) { |  | 
| 4821         Float32Array* channelData = impl->getChannelData(i); |  | 
| 4822         if (!channelData->buffer()->hasDeallocationObserver()) { |  | 
| 4823             v8::V8::AdjustAmountOfExternalAllocatedMemory(channelData->buffer()-
      >byteLength()); |  | 
| 4824             channelData->buffer()->setDeallocationObserver(V8ArrayBufferDealloca
      tionObserver::instance()); |  | 
| 4825         } |  | 
| 4826     } |  | 
| 4827 END |  | 
| 4828     } |  | 
| 4829 |  | 
| 4830 |  | 
| 4831     $code .= <<END; |  | 
| 4832     installPerContextProperties(wrapper, impl.get(), isolate); |  | 
| 4833     V8DOMWrapper::associateObjectWithWrapper<$v8ClassName>(impl, &info, wrapper,
       isolate, $wrapperConfiguration); |  | 
| 4834     return wrapper; |  | 
| 4835 } |  | 
| 4836 |  | 
| 4837 END |  | 
| 4838     $implementation{nameSpaceWebCore}->add($code); |  | 
| 4839 } |  | 
| 4840 |  | 
| 4841 sub GenerateSecurityCheckFunctions |  | 
| 4842 { |  | 
| 4843     my $interface = shift; |  | 
| 4844     my $implClassName = GetImplName($interface); |  | 
| 4845     my $v8ClassName = GetV8ClassName($interface); |  | 
| 4846 |  | 
| 4847     AddToImplIncludes("bindings/v8/BindingSecurity.h"); |  | 
| 4848     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 4849 bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::Access
      Type type, v8::Local<v8::Value>) |  | 
| 4850 { |  | 
| 4851     $implClassName* imp =  ${v8ClassName}::toNative(host); |  | 
| 4852     return BindingSecurity::shouldAllowAccessToFrame(imp->frame(), DoNotReportSe
      curityError); |  | 
| 4853 } |  | 
| 4854 |  | 
| 4855 END |  | 
| 4856     $implementation{nameSpaceInternal}->add(<<END); |  | 
| 4857 bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8
      ::AccessType type, v8::Local<v8::Value>) |  | 
| 4858 { |  | 
| 4859     $implClassName* imp =  ${v8ClassName}::toNative(host); |  | 
| 4860     return BindingSecurity::shouldAllowAccessToFrame(imp->frame(), DoNotReportSe
      curityError); |  | 
| 4861 } |  | 
| 4862 |  | 
| 4863 END |  | 
| 4864 } |  | 
| 4865 |  | 
| 4866 sub GetNativeTypeForConversions |  | 
| 4867 { |  | 
| 4868     my $interface = shift; |  | 
| 4869     my $implClassName = GetImplName($interface); |  | 
| 4870     $implClassName = GetSVGTypeNeedingTearOff($interface->name) if IsSVGTypeNeed
      ingTearOff($interface->name); |  | 
| 4871     return $implClassName; |  | 
| 4872 } |  | 
| 4873 |  | 
| 4874 sub GetNamespaceForInterface |  | 
| 4875 { |  | 
| 4876     my $interface = shift; |  | 
| 4877     return "WTF" if IsTypedArrayType($interface->name); |  | 
| 4878     return "WebCore"; |  | 
| 4879 } |  | 
| 4880 |  | 
| 4881 sub GenerateFunctionCallString |  | 
| 4882 { |  | 
| 4883     my $function = shift; |  | 
| 4884     my $numberOfParameters = shift; |  | 
| 4885     my $indent = shift; |  | 
| 4886     my $interface = shift; |  | 
| 4887     my $forMainWorldSuffix = shift; |  | 
| 4888     my %replacements = @_; |  | 
| 4889 |  | 
| 4890     my $interfaceName = $interface->name; |  | 
| 4891     my $implClassName = GetImplName($interface); |  | 
| 4892     my $name = GetImplName($function); |  | 
| 4893     my $returnType = $function->type; |  | 
| 4894     my $nativeReturnType = GetNativeType($returnType, {}, ""); |  | 
| 4895     my $code = ""; |  | 
| 4896 |  | 
| 4897     my $isSVGTearOffType = (IsSVGTypeNeedingTearOff($returnType) and not $interf
      aceName =~ /List$/); |  | 
| 4898     $nativeReturnType = GetSVGWrappedTypeNeedingTearOff($returnType) if $isSVGTe
      arOffType; |  | 
| 4899 |  | 
| 4900     my $index = 0; |  | 
| 4901 |  | 
| 4902     my @arguments; |  | 
| 4903     my $functionName; |  | 
| 4904     my $implementedBy = $function->extendedAttributes->{"ImplementedBy"}; |  | 
| 4905     if ($implementedBy) { |  | 
| 4906         my $implementedByImplName = GetImplNameFromImplementedBy($implementedBy)
      ; |  | 
| 4907         AddToImplIncludes(HeaderFilesForInterface($implementedBy, $implementedBy
      ImplName)); |  | 
| 4908         unshift(@arguments, "imp") if !$function->isStatic; |  | 
| 4909         $functionName = "${implementedByImplName}::${name}"; |  | 
| 4910     } elsif ($function->isStatic) { |  | 
| 4911         $functionName = "${implClassName}::${name}"; |  | 
| 4912     } else { |  | 
| 4913         $functionName = "imp->${name}"; |  | 
| 4914     } |  | 
| 4915 |  | 
| 4916     my $callWith = $function->extendedAttributes->{"CallWith"}; |  | 
| 4917     my ($callWithArgs, $subCode) = GenerateCallWith($callWith, $indent, 1, $func
      tion); |  | 
| 4918     $code .= $subCode; |  | 
| 4919     unshift(@arguments, @$callWithArgs); |  | 
| 4920     $index += @$callWithArgs; |  | 
| 4921     $numberOfParameters += @$callWithArgs; |  | 
| 4922 |  | 
| 4923     foreach my $parameter (@{$function->parameters}) { |  | 
| 4924         if ($index eq $numberOfParameters) { |  | 
| 4925             last; |  | 
| 4926         } |  | 
| 4927         my $paramName = $parameter->name; |  | 
| 4928         my $paramType = $parameter->type; |  | 
| 4929 |  | 
| 4930         if ($replacements{$paramName}) { |  | 
| 4931             push @arguments, $replacements{$paramName}; |  | 
| 4932         } elsif ($parameter->type eq "NodeFilter" || $parameter->type eq "XPathN
      SResolver") { |  | 
| 4933             push @arguments, "$paramName.get()"; |  | 
| 4934         } elsif (IsSVGTypeNeedingTearOff($parameter->type) and not $interfaceNam
      e =~ /List$/) { |  | 
| 4935             AddToImplIncludes("core/dom/ExceptionCode.h"); |  | 
| 4936             push @arguments, "$paramName->propertyReference()"; |  | 
| 4937             $code .= $indent . "if (!$paramName) {\n"; |  | 
| 4938             $code .= $indent . "    setDOMException(WebCore::TypeMismatchError, 
      args.GetIsolate());\n"; |  | 
| 4939             $code .= $indent . "    return;\n"; |  | 
| 4940             $code .= $indent . "}\n"; |  | 
| 4941         } elsif ($parameter->type eq "SVGMatrix" and $interfaceName eq "SVGTrans
      formList") { |  | 
| 4942             push @arguments, "$paramName.get()"; |  | 
| 4943         } else { |  | 
| 4944             push @arguments, $paramName; |  | 
| 4945         } |  | 
| 4946         $index++; |  | 
| 4947     } |  | 
| 4948 |  | 
| 4949     if ($function->extendedAttributes->{"RaisesException"}) { |  | 
| 4950         push @arguments, "es"; |  | 
| 4951     } |  | 
| 4952 |  | 
| 4953     my $functionString = "$functionName(" . join(", ", @arguments) . ")"; |  | 
| 4954 |  | 
| 4955     my $return = "result"; |  | 
| 4956     my $returnIsRef = IsRefPtrType($returnType); |  | 
| 4957 |  | 
| 4958     if ($returnType eq "void") { |  | 
| 4959         $code .= $indent . "$functionString;\n"; |  | 
| 4960     } elsif (ExtendedAttributeContains($callWith, "ScriptState") or $function->e
      xtendedAttributes->{"RaisesException"}) { |  | 
| 4961         $code .= $indent . $nativeReturnType . " result = $functionString;\n"; |  | 
| 4962     } else { |  | 
| 4963         # Can inline the function call into the return statement to avoid overhe
      ad of using a Ref<> temporary |  | 
| 4964         $return = $functionString; |  | 
| 4965         $returnIsRef = 0; |  | 
| 4966 |  | 
| 4967         if ($interfaceName eq "SVGTransformList" and IsRefPtrType($returnType)) 
      { |  | 
| 4968             $return = "WTF::getPtr(" . $return . ")"; |  | 
| 4969         } |  | 
| 4970     } |  | 
| 4971 |  | 
| 4972     if ($function->extendedAttributes->{"RaisesException"}) { |  | 
| 4973         $code .= $indent . "if (es.throwIfNeeded())\n"; |  | 
| 4974         $code .= $indent . "    return;\n"; |  | 
| 4975     } |  | 
| 4976 |  | 
| 4977     if (ExtendedAttributeContains($callWith, "ScriptState")) { |  | 
| 4978         $code .= $indent . "if (state.hadException()) {\n"; |  | 
| 4979         $code .= $indent . "    v8::Local<v8::Value> exception = state.exception
      ();\n"; |  | 
| 4980         $code .= $indent . "    state.clearException();\n"; |  | 
| 4981         $code .= $indent . "    throwError(exception, args.GetIsolate());\n"; |  | 
| 4982         $code .= $indent . "    return;\n"; |  | 
| 4983         $code .= $indent . "}\n"; |  | 
| 4984     } |  | 
| 4985 |  | 
| 4986     if ($isSVGTearOffType) { |  | 
| 4987         AddToImplIncludes("V8$returnType.h"); |  | 
| 4988         AddToImplIncludes("core/svg/properties/SVGPropertyTearOff.h"); |  | 
| 4989         my $svgNativeType = GetSVGTypeNeedingTearOff($returnType); |  | 
| 4990         # FIXME: Update for all ScriptWrappables. |  | 
| 4991         if (IsDOMNodeType($interfaceName)) { |  | 
| 4992             if ($forMainWorldSuffix eq "ForMainWorld") { |  | 
| 4993                 $code .= $indent . "v8SetReturnValueForMainWorld(args, WTF::getP
      tr(${svgNativeType}::create($return), args.Holder()));\n"; |  | 
| 4994             } else { |  | 
| 4995                 $code .= $indent . "v8SetReturnValueFast(args, WTF::getPtr(${svg
      NativeType}::create($return)), imp);\n"; |  | 
| 4996             } |  | 
| 4997         } else { |  | 
| 4998             $code .= $indent . "v8SetReturnValue${forMainWorldSuffix}(args, WTF:
      :getPtr(${svgNativeType}::create($return)), args.Holder());\n"; |  | 
| 4999         } |  | 
| 5000         $code .= $indent . "return;\n"; |  | 
| 5001         return $code; |  | 
| 5002     } |  | 
| 5003 |  | 
| 5004     # If the implementing class is a POD type, commit changes |  | 
| 5005     if (IsSVGTypeNeedingTearOff($interfaceName) and not $interfaceName =~ /List$
      /) { |  | 
| 5006         $code .= $indent . "wrapper->commitChange();\n"; |  | 
| 5007     } |  | 
| 5008 |  | 
| 5009     $return .= ".release()" if ($returnIsRef); |  | 
| 5010 |  | 
| 5011     my $nativeValue; |  | 
| 5012     # FIXME: Update for all ScriptWrappables. |  | 
| 5013     if (IsDOMNodeType($interfaceName)) { |  | 
| 5014         $nativeValue = NativeToJSValue($function->type, $function->extendedAttri
      butes, $return, $indent, "", "args.Holder()", "args.GetIsolate()", "args", "imp"
      , $forMainWorldSuffix, "return"); |  | 
| 5015     } else { |  | 
| 5016         $nativeValue = NativeToJSValue($function->type, $function->extendedAttri
      butes, $return, $indent, "", "args.Holder()", "args.GetIsolate()", "args", 0, $f
      orMainWorldSuffix, "return"); |  | 
| 5017     } |  | 
| 5018 |  | 
| 5019     $code .= $nativeValue . "\n"; |  | 
| 5020     $code .= $indent . "return;\n"; |  | 
| 5021 |  | 
| 5022     return $code; |  | 
| 5023 } |  | 
| 5024 |  | 
| 5025 sub GetNativeType |  | 
| 5026 { |  | 
| 5027     my $type = shift; |  | 
| 5028     my $extendedAttributes = shift; |  | 
| 5029     my $isParameter = shift; |  | 
| 5030 |  | 
| 5031     my $svgNativeType = GetSVGTypeNeedingTearOff($type); |  | 
| 5032     if ($svgNativeType) { |  | 
| 5033         if ($svgNativeType =~ /List$/) { |  | 
| 5034             return "${svgNativeType}*"; |  | 
| 5035         } else { |  | 
| 5036             return "RefPtr<${svgNativeType} >"; |  | 
| 5037         } |  | 
| 5038     } |  | 
| 5039 |  | 
| 5040     return "float" if $type eq "float"; |  | 
| 5041     return "double" if $type eq "double"; |  | 
| 5042     return "int" if $type eq "long" or $type eq "int" or $type eq "short" or $ty
      pe eq "byte"; |  | 
| 5043     if ($type eq "unsigned long" or $type eq "unsigned int" or $type eq "unsigne
      d short" or $type eq "octet") { |  | 
| 5044         return "unsigned"; |  | 
| 5045     } |  | 
| 5046     return "long long" if $type eq "long long"; |  | 
| 5047     return "unsigned long long" if $type eq "unsigned long long"; |  | 
| 5048     return "bool" if $type eq "boolean"; |  | 
| 5049 |  | 
| 5050     if (($type eq "DOMString" || IsEnumType($type)) and $isParameter) { |  | 
| 5051         # FIXME: This implements [TreatNullAs=NullString] and [TreatUndefinedAs=
      NullString], |  | 
| 5052         # but the Web IDL spec requires [TreatNullAs=EmptyString] and [TreatUnde
      finedAs=EmptyString]. |  | 
| 5053         my $mode = ""; |  | 
| 5054         if (($extendedAttributes->{"TreatNullAs"} and $extendedAttributes->{"Tre
      atNullAs"} eq "NullString") and ($extendedAttributes->{"TreatUndefinedAs"} and $
      extendedAttributes->{"TreatUndefinedAs"} eq "NullString")) { |  | 
| 5055             $mode = "WithUndefinedOrNullCheck"; |  | 
| 5056         } elsif (($extendedAttributes->{"TreatNullAs"} and $extendedAttributes->
      {"TreatNullAs"} eq "NullString") or $extendedAttributes->{"Reflect"}) { |  | 
| 5057             $mode = "WithNullCheck"; |  | 
| 5058         } |  | 
| 5059         # FIXME: Add the case for 'elsif ($attributeOrParameter->extendedAttribu
      tes->{"TreatUndefinedAs"} and $attributeOrParameter->extendedAttributes->{"Treat
      UndefinedAs"} eq "NullString"))'. |  | 
| 5060         return "V8StringResource<$mode>"; |  | 
| 5061     } |  | 
| 5062 |  | 
| 5063     return "String" if $type eq "DOMString" or IsEnumType($type); |  | 
| 5064 |  | 
| 5065     return "ScriptPromise" if $type eq "Promise"; |  | 
| 5066 |  | 
| 5067     return "Range::CompareHow" if $type eq "CompareHow"; |  | 
| 5068     return "DOMTimeStamp" if $type eq "DOMTimeStamp"; |  | 
| 5069     return "double" if $type eq "Date"; |  | 
| 5070     return "ScriptValue" if $type eq "any" or IsCallbackFunctionType($type); |  | 
| 5071     return "Dictionary" if $type eq "Dictionary"; |  | 
| 5072 |  | 
| 5073     return "RefPtr<DOMStringList>" if $type eq "DOMStringList"; |  | 
| 5074     return "RefPtr<MediaQueryListListener>" if $type eq "MediaQueryListListener"
      ; |  | 
| 5075     return "RefPtr<NodeFilter>" if $type eq "NodeFilter"; |  | 
| 5076     return "RefPtr<SerializedScriptValue>" if $type eq "SerializedScriptValue"; |  | 
| 5077     return "RefPtr<XPathNSResolver>" if $type eq "XPathNSResolver"; |  | 
| 5078 |  | 
| 5079     die "UnionType is not supported" if IsUnionType($type); |  | 
| 5080 |  | 
| 5081     if (IsTypedArrayType($type)) { |  | 
| 5082         return $isParameter ? "${type}*" : "RefPtr<${type}>"; |  | 
| 5083     } |  | 
| 5084 |  | 
| 5085     # We need to check [ImplementedAs] extended attribute for wrapper types. |  | 
| 5086     if (IsWrapperType($type)) { |  | 
| 5087         my $interface = ParseInterface($type); |  | 
| 5088         my $implClassName = GetImplName($interface); |  | 
| 5089         return $isParameter ? "${implClassName}*" : "RefPtr<${implClassName}>"; |  | 
| 5090     } |  | 
| 5091     return "RefPtr<${type}>" if IsRefPtrType($type) and not $isParameter; |  | 
| 5092 |  | 
| 5093     my $arrayOrSequenceType = GetArrayOrSequenceType($type); |  | 
| 5094 |  | 
| 5095     if ($arrayOrSequenceType) { |  | 
| 5096         my $nativeType = GetNativeType($arrayOrSequenceType); |  | 
| 5097         $nativeType .= " " if ($nativeType =~ />$/); |  | 
| 5098         return "Vector<${nativeType}>"; |  | 
| 5099     } |  | 
| 5100 |  | 
| 5101     # Default, assume native type is a pointer with same type name as idl type |  | 
| 5102     return "${type}*"; |  | 
| 5103 } |  | 
| 5104 |  | 
| 5105 sub GetNativeTypeForCallbacks |  | 
| 5106 { |  | 
| 5107     my $type = shift; |  | 
| 5108     return "const String&" if $type eq "DOMString"; |  | 
| 5109     return "PassRefPtr<SerializedScriptValue>" if $type eq "SerializedScriptValu
      e"; |  | 
| 5110 |  | 
| 5111     # Callbacks use raw pointers, so pass isParameter = 1 |  | 
| 5112     my $nativeType = GetNativeType($type, {}, "parameter"); |  | 
| 5113     return "const $nativeType&" if $nativeType =~ /^Vector/; |  | 
| 5114     return $nativeType; |  | 
| 5115 } |  | 
| 5116 |  | 
| 5117 sub JSValueToNativeStatement |  | 
| 5118 { |  | 
| 5119     my $type = shift; |  | 
| 5120     my $extendedAttributes = shift; |  | 
| 5121     my $jsValue = shift; |  | 
| 5122     my $variableName = shift; |  | 
| 5123     my $indent = shift; |  | 
| 5124     my $getIsolate = shift; |  | 
| 5125 |  | 
| 5126     my $nativeType = GetNativeType($type, $extendedAttributes, "parameter"); |  | 
| 5127     my $native_value = JSValueToNative($type, $extendedAttributes, $jsValue, $ge
      tIsolate); |  | 
| 5128     my $code = ""; |  | 
| 5129     if ($type eq "DOMString" || IsEnumType($type)) { |  | 
| 5130         die "Wrong native type passed: $nativeType" unless $nativeType =~ /^V8St
      ringResource/; |  | 
| 5131         if ($type eq "DOMString" or IsEnumType($type)) { |  | 
| 5132             $code .= $indent . "V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID($nativeType
      , $variableName, $native_value);\n" |  | 
| 5133         } else { |  | 
| 5134             $code .= $indent . "$nativeType $variableName($native_value, true);\
      n"; |  | 
| 5135         } |  | 
| 5136     } elsif ($extendedAttributes->{"EnforceRange"}) { |  | 
| 5137         $code .= $indent . "V8TRYCATCH_WITH_TYPECHECK_VOID($nativeType, $variabl
      eName, $native_value, $getIsolate);\n"; |  | 
| 5138     } else { |  | 
| 5139         $code .= $indent . "V8TRYCATCH_VOID($nativeType, $variableName, $native_
      value);\n"; |  | 
| 5140     } |  | 
| 5141     return $code; |  | 
| 5142 } |  | 
| 5143 |  | 
| 5144 |  | 
| 5145 sub JSValueToNative |  | 
| 5146 { |  | 
| 5147     my $type = shift; |  | 
| 5148     my $extendedAttributes = shift; |  | 
| 5149     my $value = shift; |  | 
| 5150     my $getIsolate = shift; |  | 
| 5151 |  | 
| 5152     my $intConversion = $extendedAttributes->{"EnforceRange"} ? "EnforceRange" :
       "NormalConversion"; |  | 
| 5153 |  | 
| 5154     return "$value->BooleanValue()" if $type eq "boolean"; |  | 
| 5155     return "static_cast<$type>($value->NumberValue())" if $type eq "float" or $t
      ype eq "double"; |  | 
| 5156 |  | 
| 5157     if ($intConversion ne "NormalConversion") { |  | 
| 5158         return "toInt8($value, $intConversion, ok)" if $type eq "byte"; |  | 
| 5159         return "toUInt8($value, $intConversion, ok)" if $type eq "octet"; |  | 
| 5160         return "toInt32($value, $intConversion, ok)" if $type eq "long" or $type
       eq "short"; |  | 
| 5161         return "toUInt32($value, $intConversion, ok)" if $type eq "unsigned long
      " or $type eq "unsigned short"; |  | 
| 5162         return "toInt64($value, $intConversion, ok)" if $type eq "long long"; |  | 
| 5163         return "toUInt64($value, $intConversion, ok)" if $type eq "unsigned long
       long"; |  | 
| 5164     } else { |  | 
| 5165         return "toInt8($value)" if $type eq "byte"; |  | 
| 5166         return "toUInt8($value)" if $type eq "octet"; |  | 
| 5167         return "toInt32($value)" if $type eq "long" or $type eq "short"; |  | 
| 5168         return "toUInt32($value)" if $type eq "unsigned long" or $type eq "unsig
      ned short"; |  | 
| 5169         return "toInt64($value)" if $type eq "long long"; |  | 
| 5170         return "toUInt64($value)" if $type eq "unsigned long long"; |  | 
| 5171     } |  | 
| 5172     return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "C
      ompareHow"; |  | 
| 5173     return "toWebCoreDate($value)" if $type eq "Date"; |  | 
| 5174     return "toDOMStringList($value, $getIsolate)" if $type eq "DOMStringList"; |  | 
| 5175 |  | 
| 5176     if ($type eq "DOMString" or IsEnumType($type)) { |  | 
| 5177         return $value; |  | 
| 5178     } |  | 
| 5179 |  | 
| 5180     if ($type eq "SerializedScriptValue") { |  | 
| 5181         AddToImplIncludes("bindings/v8/SerializedScriptValue.h"); |  | 
| 5182         return "SerializedScriptValue::create($value, $getIsolate)"; |  | 
| 5183     } |  | 
| 5184 |  | 
| 5185     if ($type eq "Dictionary") { |  | 
| 5186         AddToImplIncludes("bindings/v8/Dictionary.h"); |  | 
| 5187         return "Dictionary($value, $getIsolate)"; |  | 
| 5188     } |  | 
| 5189 |  | 
| 5190     if ($type eq "any" || IsCallbackFunctionType($type)) { |  | 
| 5191         AddToImplIncludes("bindings/v8/ScriptValue.h"); |  | 
| 5192         return "ScriptValue($value, $getIsolate)"; |  | 
| 5193     } |  | 
| 5194 |  | 
| 5195     if ($type eq "Promise") { |  | 
| 5196         AddToImplIncludes("bindings/v8/ScriptPromise.h"); |  | 
| 5197         return "ScriptPromise($value)"; |  | 
| 5198     } |  | 
| 5199 |  | 
| 5200     if ($type eq "NodeFilter") { |  | 
| 5201         return "toNodeFilter($value, $getIsolate)"; |  | 
| 5202     } |  | 
| 5203 |  | 
| 5204     if ($type eq "MediaQueryListListener") { |  | 
| 5205         AddToImplIncludes("core/css/MediaQueryListListener.h"); |  | 
| 5206         return "MediaQueryListListener::create(ScriptValue(" . $value . ", $getI
      solate))"; |  | 
| 5207     } |  | 
| 5208 |  | 
| 5209     if ($type eq "EventTarget") { |  | 
| 5210         return "V8DOMWrapper::isDOMWrapper($value) ? toWrapperTypeInfo(v8::Handl
      e<v8::Object>::Cast($value))->toEventTarget(v8::Handle<v8::Object>::Cast($value)
      ) : 0"; |  | 
| 5211     } |  | 
| 5212 |  | 
| 5213     if (IsTypedArrayType($type)) { |  | 
| 5214         AddIncludesForType($type); |  | 
| 5215         return "$value->Is${type}() ? V8${type}::toNative(v8::Handle<v8::${type}
      >::Cast($value)) : 0" |  | 
| 5216     } |  | 
| 5217 |  | 
| 5218     if ($type eq "XPathNSResolver") { |  | 
| 5219         return "toXPathNSResolver($value, $getIsolate)"; |  | 
| 5220     } |  | 
| 5221 |  | 
| 5222     my $arrayOrSequenceType = GetArrayOrSequenceType($type); |  | 
| 5223 |  | 
| 5224     if ($arrayOrSequenceType) { |  | 
| 5225         if (IsRefPtrType($arrayOrSequenceType)) { |  | 
| 5226             AddToImplIncludes("V8${arrayOrSequenceType}.h"); |  | 
| 5227             return "(toRefPtrNativeArray<${arrayOrSequenceType}, V8${arrayOrSequ
      enceType}>($value, $getIsolate))"; |  | 
| 5228         } |  | 
| 5229         return "toNativeArray<" . GetNativeType($arrayOrSequenceType) . ">($valu
      e, $getIsolate)"; |  | 
| 5230     } |  | 
| 5231 |  | 
| 5232     AddIncludesForType($type); |  | 
| 5233 |  | 
| 5234     AddToImplIncludes("V8${type}.h"); |  | 
| 5235     return "V8${type}::HasInstance($value, $getIsolate, worldType($getIsolate)) 
      ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0"; |  | 
| 5236 } |  | 
| 5237 |  | 
| 5238 sub CreateCustomSignature |  | 
| 5239 { |  | 
| 5240     my $function = shift; |  | 
| 5241     my $count = @{$function->parameters}; |  | 
| 5242     my $name = $function->name; |  | 
| 5243     my $code = "    const int ${name}Argc = ${count};\n" . |  | 
| 5244       "    v8::Handle<v8::FunctionTemplate> ${name}Argv[${name}Argc] = { "; |  | 
| 5245     my $first = 1; |  | 
| 5246     foreach my $parameter (@{$function->parameters}) { |  | 
| 5247         if ($first) { $first = 0; } |  | 
| 5248         else { $code .= ", "; } |  | 
| 5249         if (IsWrapperType($parameter->type) && not IsTypedArrayType($parameter->
      type)) { |  | 
| 5250             if ($parameter->type eq "XPathNSResolver") { |  | 
| 5251                 # Special case for XPathNSResolver.  All other browsers accepts 
      a callable, |  | 
| 5252                 # so, even though it's against IDL, accept objects here. |  | 
| 5253                 $code .= "v8::Handle<v8::FunctionTemplate>()"; |  | 
| 5254             } else { |  | 
| 5255                 my $type = $parameter->type; |  | 
| 5256                 my $arrayOrSequenceType = GetArrayOrSequenceType($type); |  | 
| 5257 |  | 
| 5258                 if ($arrayOrSequenceType) { |  | 
| 5259                     if (IsRefPtrType($arrayOrSequenceType)) { |  | 
| 5260                         AddIncludesForType($arrayOrSequenceType); |  | 
| 5261                     } else { |  | 
| 5262                         $code .= "v8::Handle<v8::FunctionTemplate>()"; |  | 
| 5263                         next; |  | 
| 5264                     } |  | 
| 5265                 } else { |  | 
| 5266                     AddIncludesForType($type); |  | 
| 5267                 } |  | 
| 5268                 $code .= "V8PerIsolateData::from(isolate)->rawTemplate(&V8${type
      }::info, currentWorldType)"; |  | 
| 5269             } |  | 
| 5270         } else { |  | 
| 5271             $code .= "v8::Handle<v8::FunctionTemplate>()"; |  | 
| 5272         } |  | 
| 5273     } |  | 
| 5274     $code .= " };\n"; |  | 
| 5275     $code .= "    v8::Handle<v8::Signature> ${name}Signature = v8::Signature::Ne
      w(desc, ${name}Argc, ${name}Argv);\n"; |  | 
| 5276     return $code; |  | 
| 5277 } |  | 
| 5278 |  | 
| 5279 |  | 
| 5280 sub RequiresCustomSignature |  | 
| 5281 { |  | 
| 5282     my $function = shift; |  | 
| 5283     # No signature needed for Custom function |  | 
| 5284     if (HasCustomMethod($function->extendedAttributes)) { |  | 
| 5285         return 0; |  | 
| 5286     } |  | 
| 5287     # No signature needed for overloaded function |  | 
| 5288     if (@{$function->{overloads}} > 1) { |  | 
| 5289         return 0; |  | 
| 5290     } |  | 
| 5291     if ($function->isStatic) { |  | 
| 5292         return 0; |  | 
| 5293     } |  | 
| 5294     # Type checking is performed in the generated code |  | 
| 5295     if ($function->extendedAttributes->{"StrictTypeChecking"}) { |  | 
| 5296       return 0; |  | 
| 5297     } |  | 
| 5298     foreach my $parameter (@{$function->parameters}) { |  | 
| 5299         if (($parameter->isOptional && !$parameter->extendedAttributes->{"Defaul
      t"}) || IsCallbackInterface($parameter->type)) { |  | 
| 5300             return 0; |  | 
| 5301         } |  | 
| 5302     } |  | 
| 5303 |  | 
| 5304     foreach my $parameter (@{$function->parameters}) { |  | 
| 5305         if (IsWrapperType($parameter->type)) { |  | 
| 5306             return 1; |  | 
| 5307         } |  | 
| 5308     } |  | 
| 5309     return 0; |  | 
| 5310 } |  | 
| 5311 |  | 
| 5312 sub IsUnionType |  | 
| 5313 { |  | 
| 5314     my $type = shift; # string or UnionType |  | 
| 5315     if(ref($type) eq "UnionType") { |  | 
| 5316         die "Currently only 2 values of non-union type is supported as union typ
      e.\n" unless @{$type->unionMemberTypes} == 2; |  | 
| 5317         return 1; |  | 
| 5318     } |  | 
| 5319     return 0; |  | 
| 5320 } |  | 
| 5321 |  | 
| 5322 sub IsWrapperType |  | 
| 5323 { |  | 
| 5324     my $type = shift; |  | 
| 5325     return 0 if GetArrayType($type); |  | 
| 5326     return 0 if GetSequenceType($type); |  | 
| 5327     return 0 if IsCallbackFunctionType($type); |  | 
| 5328     return 0 if IsEnumType($type); |  | 
| 5329     return 0 if IsPrimitiveType($type); |  | 
| 5330     return 0 if $type eq "DOMString"; |  | 
| 5331     return 0 if $type eq "Promise"; |  | 
| 5332     return !$nonWrapperTypes{$type}; |  | 
| 5333 } |  | 
| 5334 |  | 
| 5335 sub IsCallbackInterface |  | 
| 5336 { |  | 
| 5337     my $type = shift; |  | 
| 5338     return 0 unless IsWrapperType($type); |  | 
| 5339     return 0 if IsTypedArrayType($type); |  | 
| 5340 |  | 
| 5341     my $idlFile = IDLFileForInterface($type) |  | 
| 5342         or die("Could NOT find IDL file for interface \"$type\"!\n"); |  | 
| 5343 |  | 
| 5344     open FILE, "<", $idlFile; |  | 
| 5345     my @lines = <FILE>; |  | 
| 5346     close FILE; |  | 
| 5347 |  | 
| 5348     my $fileContents = join('', @lines); |  | 
| 5349     return ($fileContents =~ /callback\s+interface\s+(\w+)/gs); |  | 
| 5350 } |  | 
| 5351 |  | 
| 5352 sub GetNativeTypeOfTypedArray |  | 
| 5353 { |  | 
| 5354     my $interface = shift; |  | 
| 5355     my $interfaceName = $interface->name; |  | 
| 5356     die "TypedArray of unknown type is found" unless $typedArrayHash{$interface-
      >name}; |  | 
| 5357     return @{$typedArrayHash{$interface->name}}; |  | 
| 5358 } |  | 
| 5359 |  | 
| 5360 sub IsDOMNodeType |  | 
| 5361 { |  | 
| 5362     my $type = shift; |  | 
| 5363 |  | 
| 5364     return 1 if $type eq 'Attr'; |  | 
| 5365     return 1 if $type eq 'CDATASection'; |  | 
| 5366     return 1 if $type eq 'CharacterData'; |  | 
| 5367     return 1 if $type eq 'Comment'; |  | 
| 5368     return 1 if $type eq 'Document'; |  | 
| 5369     return 1 if $type eq 'DocumentFragment'; |  | 
| 5370     return 1 if $type eq 'DocumentType'; |  | 
| 5371     return 1 if $type eq 'Element'; |  | 
| 5372     return 1 if $type eq 'Entity'; |  | 
| 5373     return 1 if $type eq 'HTMLDocument'; |  | 
| 5374     return 1 if $type eq 'Node'; |  | 
| 5375     return 1 if $type eq 'Notation'; |  | 
| 5376     return 1 if $type eq 'ProcessingInstruction'; |  | 
| 5377     return 1 if $type eq 'ShadowRoot'; |  | 
| 5378     return 1 if $type eq 'SVGDocument'; |  | 
| 5379     return 1 if $type eq 'Text'; |  | 
| 5380 |  | 
| 5381     return 1 if $type =~ /^HTML.*Element$/; |  | 
| 5382     return 1 if $type =~ /^SVG.*Element$/; |  | 
| 5383 |  | 
| 5384     return 1 if $type eq 'TestNode'; |  | 
| 5385 |  | 
| 5386     return 0; |  | 
| 5387 } |  | 
| 5388 |  | 
| 5389 |  | 
| 5390 sub NativeToJSValue |  | 
| 5391 { |  | 
| 5392     my $type = shift; |  | 
| 5393     my $extendedAttributes = shift; |  | 
| 5394     my $nativeValue = shift; |  | 
| 5395     my $indent = shift;  # added before every line |  | 
| 5396     my $receiver = shift;  # "return" or "<variableName> =" |  | 
| 5397     my $getCreationContext = shift; |  | 
| 5398     my $getIsolate = shift; |  | 
| 5399     die "An Isolate is mandatory for native value => JS value conversion." unles
      s $getIsolate; |  | 
| 5400     my $getCallbackInfo = shift || ""; |  | 
| 5401     my $getCallbackInfoArg = $getCallbackInfo ? ", $getCallbackInfo" : ""; |  | 
| 5402     my $getScriptWrappable = shift || ""; |  | 
| 5403     my $getScriptWrappableArg = $getScriptWrappable ? ", $getScriptWrappable" : 
      ""; |  | 
| 5404     my $forMainWorldSuffix = shift || ""; |  | 
| 5405     my $returnValueArg = shift || 0; |  | 
| 5406     my $isReturnValue = $returnValueArg eq "return"; |  | 
| 5407 |  | 
| 5408     if (IsUnionType($type)) { |  | 
| 5409         my $types = $type->unionMemberTypes; |  | 
| 5410         my @codes = (); |  | 
| 5411         for my $i (0 .. scalar(@$types)-1) { |  | 
| 5412             my $unionMemberType = $types->[$i]; |  | 
| 5413             my $unionMemberNumber = $i + 1; |  | 
| 5414             my $unionMemberVariable = $nativeValue . $i; |  | 
| 5415             my $unionMemberEnabledVariable = $nativeValue . $i . "Enabled"; |  | 
| 5416             my $unionMemberNativeValue = $unionMemberVariable; |  | 
| 5417             $unionMemberNativeValue .= ".release()" if (IsRefPtrType($unionMembe
      rType)); |  | 
| 5418             my $returnJSValueCode = NativeToJSValue($unionMemberType, $extendedA
      ttributes, $unionMemberNativeValue, $indent . "    ", $receiver, $getCreationCon
      text, $getIsolate, $getCallbackInfo, $getScriptWrappable, $forMainWorldSuffix, $
      returnValueArg); |  | 
| 5419             my $code = ""; |  | 
| 5420             if ($isReturnValue) { |  | 
| 5421               $code .= "${indent}if (${unionMemberEnabledVariable}) {\n"; |  | 
| 5422               $code .= "${returnJSValueCode}\n"; |  | 
| 5423               $code .= "${indent}    return;\n"; |  | 
| 5424               $code .= "${indent}}\n"; |  | 
| 5425             } else { |  | 
| 5426               $code .= "${indent}if (${unionMemberEnabledVariable})\n"; |  | 
| 5427               $code .= "${returnJSValueCode}"; |  | 
| 5428             } |  | 
| 5429             push @codes, $code; |  | 
| 5430         } |  | 
| 5431         return join "\n", @codes; |  | 
| 5432     } |  | 
| 5433 |  | 
| 5434     if ($type eq "boolean") { |  | 
| 5435         return "${indent}v8SetReturnValueBool(${getCallbackInfo}, ${nativeValue}
      );" if $isReturnValue; |  | 
| 5436         return "$indent$receiver v8Boolean($nativeValue, $getIsolate);"; |  | 
| 5437     } |  | 
| 5438 |  | 
| 5439     if ($type eq "void") { # equivalent to v8Undefined() |  | 
| 5440         return "" if $isReturnValue; |  | 
| 5441         return "$indent$receiver v8Undefined();" |  | 
| 5442     } |  | 
| 5443 |  | 
| 5444     # HTML5 says that unsigned reflected attributes should be in the range |  | 
| 5445     # [0, 2^31). When a value isn't in this range, a default value (or 0) |  | 
| 5446     # should be returned instead. |  | 
| 5447     if ($extendedAttributes->{"Reflect"} and ($type eq "unsigned long" or $type 
      eq "unsigned short")) { |  | 
| 5448         $nativeValue =~ s/getUnsignedIntegralAttribute/getIntegralAttribute/g; |  | 
| 5449         return "${indent}v8SetReturnValueUnsigned(${getCallbackInfo}, std::max(0
      , ${nativeValue}));" if $isReturnValue; |  | 
| 5450         return "$indent$receiver v8::Integer::NewFromUnsigned(std::max(0, " . $n
      ativeValue . "), $getIsolate);"; |  | 
| 5451     } |  | 
| 5452 |  | 
| 5453     my $nativeType = GetNativeType($type); |  | 
| 5454     if ($nativeType eq "int") { |  | 
| 5455         return "${indent}v8SetReturnValueInt(${getCallbackInfo}, ${nativeValue})
      ;" if $isReturnValue; |  | 
| 5456         return "$indent$receiver v8::Integer::New($nativeValue, $getIsolate);"; |  | 
| 5457     } |  | 
| 5458 |  | 
| 5459     if ($nativeType eq "unsigned") { |  | 
| 5460         return "${indent}v8SetReturnValueUnsigned(${getCallbackInfo}, ${nativeVa
      lue});" if $isReturnValue; |  | 
| 5461         return "$indent$receiver v8::Integer::NewFromUnsigned($nativeValue, $get
      Isolate);"; |  | 
| 5462     } |  | 
| 5463 |  | 
| 5464     if ($type eq "Date") { |  | 
| 5465         return "${indent}v8SetReturnValue(${getCallbackInfo}, v8DateOrNull($nati
      veValue, $getIsolate));" if $isReturnValue; |  | 
| 5466         return "$indent$receiver v8DateOrNull($nativeValue, $getIsolate);" |  | 
| 5467     } |  | 
| 5468 |  | 
| 5469     # long long and unsigned long long are not representable in ECMAScript. |  | 
| 5470     if ($type eq "long long" or $type eq "unsigned long long" or $type eq "DOMTi
      meStamp") { |  | 
| 5471         return "${indent}v8SetReturnValue(${getCallbackInfo}, static_cast<double
      >($nativeValue));" if $isReturnValue; |  | 
| 5472         return "$indent$receiver v8::Number::New($getIsolate, static_cast<double
      >($nativeValue));"; |  | 
| 5473     } |  | 
| 5474 |  | 
| 5475     if (IsPrimitiveType($type)) { |  | 
| 5476         die "unexpected type $type" if not ($type eq "float" or $type eq "double
      "); |  | 
| 5477         return "${indent}v8SetReturnValue(${getCallbackInfo}, ${nativeValue});" 
      if $isReturnValue; |  | 
| 5478         return "$indent$receiver v8::Number::New($getIsolate, $nativeValue);"; |  | 
| 5479     } |  | 
| 5480 |  | 
| 5481     if ($nativeType eq "ScriptValue" or $nativeType eq "ScriptPromise") { |  | 
| 5482         return "${indent}v8SetReturnValue(${getCallbackInfo}, ${nativeValue}.v8V
      alue());" if $isReturnValue; |  | 
| 5483         return "$indent$receiver $nativeValue.v8Value();"; |  | 
| 5484     } |  | 
| 5485 |  | 
| 5486     my $conv = $extendedAttributes->{"TreatReturnedNullStringAs"}; |  | 
| 5487     if (($type eq "DOMString" || IsEnumType($type)) && $isReturnValue) { |  | 
| 5488         my $functionSuffix = ""; |  | 
| 5489         if (defined $conv) { |  | 
| 5490             if ($conv eq "Null") { |  | 
| 5491                 $functionSuffix = "OrNull"; |  | 
| 5492             } elsif ($conv eq "Undefined") { |  | 
| 5493                 $functionSuffix = "OrUndefined"; |  | 
| 5494             } else { |  | 
| 5495                 die "Unknown value for TreatReturnedNullStringAs extended attrib
      ute"; |  | 
| 5496             } |  | 
| 5497         } |  | 
| 5498         return "${indent}v8SetReturnValueString${functionSuffix}(${getCallbackIn
      fo}, $nativeValue, $getIsolate);"; |  | 
| 5499     } |  | 
| 5500 |  | 
| 5501     if ($type eq "DOMString" or IsEnumType($type)) { |  | 
| 5502         my $returnValue = ""; |  | 
| 5503         if (defined $conv) { |  | 
| 5504             if ($conv eq "Null") { |  | 
| 5505                 $returnValue = "v8StringOrNull($nativeValue, $getIsolate)"; |  | 
| 5506             } elsif ($conv eq "Undefined") { |  | 
| 5507                 $returnValue = "v8StringOrUndefined($nativeValue, $getIsolate)"; |  | 
| 5508             } else { |  | 
| 5509                 die "Unknown value for TreatReturnedNullStringAs extended attrib
      ute"; |  | 
| 5510             } |  | 
| 5511         } else { |  | 
| 5512             $returnValue = "v8String($nativeValue, $getIsolate)"; |  | 
| 5513         } |  | 
| 5514         return "$indent$receiver $returnValue;"; |  | 
| 5515     } |  | 
| 5516 |  | 
| 5517     my $arrayOrSequenceType = GetArrayOrSequenceType($type); |  | 
| 5518 |  | 
| 5519     if ($arrayOrSequenceType) { |  | 
| 5520         if (IsRefPtrType($arrayOrSequenceType)) { |  | 
| 5521             AddIncludesForType($arrayOrSequenceType); |  | 
| 5522         } |  | 
| 5523         return "${indent}v8SetReturnValue(${getCallbackInfo}, v8Array($nativeVal
      ue, $getIsolate));" if $isReturnValue; |  | 
| 5524         return "$indent$receiver v8Array($nativeValue, $getIsolate);"; |  | 
| 5525     } |  | 
| 5526 |  | 
| 5527     AddIncludesForType($type); |  | 
| 5528 |  | 
| 5529     if ($type eq "SerializedScriptValue") { |  | 
| 5530         my $returnValue = "$nativeValue ? $nativeValue->deserialize() : v8::Hand
      le<v8::Value>(v8::Null($getIsolate))"; |  | 
| 5531         return "${indent}v8SetReturnValue(${getCallbackInfo}, $returnValue);" if
       $isReturnValue; |  | 
| 5532         return "$indent$receiver $returnValue;"; |  | 
| 5533     } |  | 
| 5534 |  | 
| 5535     AddToImplIncludes("wtf/RefPtr.h"); |  | 
| 5536     AddToImplIncludes("wtf/GetPtr.h"); |  | 
| 5537 |  | 
| 5538     if ($getScriptWrappable) { |  | 
| 5539         # FIXME: Use safe handles |  | 
| 5540         if ($isReturnValue) { |  | 
| 5541             if ($forMainWorldSuffix eq "ForMainWorld") { |  | 
| 5542                 return "${indent}v8SetReturnValueForMainWorld(${getCallbackInfo}
      , $nativeValue, $getCallbackInfo.Holder());"; |  | 
| 5543             } |  | 
| 5544             return "${indent}v8SetReturnValueFast(${getCallbackInfo}, $nativeVal
      ue$getScriptWrappableArg);"; |  | 
| 5545         } |  | 
| 5546     } |  | 
| 5547     # FIXME: Use safe handles |  | 
| 5548     return "${indent}v8SetReturnValue(${getCallbackInfo}, $nativeValue, $getCrea
      tionContext);" if $isReturnValue; |  | 
| 5549     return "$indent$receiver toV8($nativeValue, $getCreationContext, $getIsolate
      );"; |  | 
| 5550 } |  | 
| 5551 |  | 
| 5552 sub WriteData |  | 
| 5553 { |  | 
| 5554     my $object = shift; |  | 
| 5555     my $interface = shift; |  | 
| 5556     my $outputDirectory = shift; |  | 
| 5557 |  | 
| 5558     my $name = $interface->name; |  | 
| 5559     my $headerFileName = "$outputDirectory/V8$name.h"; |  | 
| 5560     my $implFileName = "$outputDirectory/V8$name.cpp"; |  | 
| 5561 |  | 
| 5562     my @includes = (); |  | 
| 5563     foreach my $include (keys %implIncludes) { |  | 
| 5564         push @includes, "\"$include\""; |  | 
| 5565     } |  | 
| 5566 |  | 
| 5567     #FIXME: do not treat main header special |  | 
| 5568     my $mainInclude = "\"V8$name.h\""; |  | 
| 5569     foreach my $include (sort @includes) { |  | 
| 5570         $implementation{includes}->add("#include $include\n") unless $include eq
       $mainInclude; |  | 
| 5571     } |  | 
| 5572     $implementation{includes}->add("\n") unless $interface->isCallback; |  | 
| 5573     WriteFileIfChanged($implFileName, $implementation{root}->toString()); |  | 
| 5574 |  | 
| 5575     %implIncludes = (); |  | 
| 5576 |  | 
| 5577     WriteFileIfChanged($headerFileName, $header{root}->toString()); |  | 
| 5578 } |  | 
| 5579 |  | 
| 5580 sub ConvertToV8StringResource |  | 
| 5581 { |  | 
| 5582     my $attributeOrParameter = shift; |  | 
| 5583     my $nativeType = shift; |  | 
| 5584     my $variableName = shift; |  | 
| 5585     my $value = shift; |  | 
| 5586 |  | 
| 5587     die "Wrong native type passed: $nativeType" unless $nativeType =~ /^V8String
      Resource/; |  | 
| 5588     if ($attributeOrParameter->type eq "DOMString" or IsEnumType($attributeOrPar
      ameter->type)) { |  | 
| 5589         return "V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID($nativeType, $variableName,
       $value);" |  | 
| 5590     } else { |  | 
| 5591         return "$nativeType $variableName($value, true);"; |  | 
| 5592     } |  | 
| 5593 } |  | 
| 5594 |  | 
| 5595 # Returns the RuntimeEnabledFeatures function name that is hooked up to check if
       a method/attribute is enabled. |  | 
| 5596 sub GetRuntimeEnableFunctionName |  | 
| 5597 { |  | 
| 5598     my $signature = shift; |  | 
| 5599 |  | 
| 5600     # Given [EnabledAtRuntime=FeatureName], |  | 
| 5601     # return RuntimeEnabledFeatures::{featureName}Enabled; |  | 
| 5602     my $featureName = ToMethodName($signature->extendedAttributes->{"EnabledAtRu
      ntime"}); |  | 
| 5603     return "RuntimeEnabledFeatures::${featureName}Enabled"; |  | 
| 5604 } |  | 
| 5605 |  | 
| 5606 sub GetContextEnableFunction |  | 
| 5607 { |  | 
| 5608     my $signature = shift; |  | 
| 5609 |  | 
| 5610     # Given [EnabledPerContext=FeatureName], |  | 
| 5611     # return ContextFeatures::{featureName}Enabled |  | 
| 5612     my $featureName = ToMethodName($signature->extendedAttributes->{"EnabledPerC
      ontext"}); |  | 
| 5613     return "ContextFeatures::${featureName}Enabled"; |  | 
| 5614 } |  | 
| 5615 |  | 
| 5616 sub GetPassRefPtrType |  | 
| 5617 { |  | 
| 5618     my $v8ClassName = shift; |  | 
| 5619 |  | 
| 5620     my $angleBracketSpace = $v8ClassName =~ />$/ ? " " : ""; |  | 
| 5621     return "PassRefPtr<${v8ClassName}${angleBracketSpace}>"; |  | 
| 5622 } |  | 
| 5623 |  | 
| 5624 sub WriteFileIfChanged |  | 
| 5625 { |  | 
| 5626     my $fileName = shift; |  | 
| 5627     my $contents = shift; |  | 
| 5628 |  | 
| 5629     if (-f $fileName && $writeFileOnlyIfChanged) { |  | 
| 5630         open FH, "<", $fileName or die "Couldn't open $fileName: $!\n"; |  | 
| 5631         my @lines = <FH>; |  | 
| 5632         my $oldContents = join "", @lines; |  | 
| 5633         close FH; |  | 
| 5634         return if $contents eq $oldContents; |  | 
| 5635     } |  | 
| 5636     open FH, ">", $fileName or die "Couldn't open $fileName: $!\n"; |  | 
| 5637     print FH $contents; |  | 
| 5638     close FH; |  | 
| 5639 } |  | 
| 5640 |  | 
| 5641 sub ForAllParents |  | 
| 5642 { |  | 
| 5643     my $interface = shift; |  | 
| 5644     my $beforeRecursion = shift; |  | 
| 5645     my $afterRecursion = shift; |  | 
| 5646 |  | 
| 5647     my $recurse; |  | 
| 5648     $recurse = sub { |  | 
| 5649         my $currentInterface = shift; |  | 
| 5650 |  | 
| 5651         if ($currentInterface->parent) { |  | 
| 5652             my $parentInterface = ParseInterface($currentInterface->parent); |  | 
| 5653             if ($beforeRecursion) { |  | 
| 5654                 &$beforeRecursion($parentInterface) eq 'prune' and return; |  | 
| 5655             } |  | 
| 5656             &$recurse($parentInterface); |  | 
| 5657             &$afterRecursion($parentInterface) if $afterRecursion; |  | 
| 5658         } |  | 
| 5659     }; |  | 
| 5660 |  | 
| 5661     &$recurse($interface); |  | 
| 5662 } |  | 
| 5663 |  | 
| 5664 sub FindSuperMethod |  | 
| 5665 { |  | 
| 5666     my ($interface, $functionName) = @_; |  | 
| 5667     my $indexer; |  | 
| 5668     ForAllParents($interface, undef, sub { |  | 
| 5669         my $currentInterface = shift; |  | 
| 5670         foreach my $function (@{$currentInterface->functions}) { |  | 
| 5671             if ($function->name eq $functionName) { |  | 
| 5672                 $indexer = $function; |  | 
| 5673                 return 'prune'; |  | 
| 5674             } |  | 
| 5675         } |  | 
| 5676     }); |  | 
| 5677     return $indexer; |  | 
| 5678 } |  | 
| 5679 |  | 
| 5680 sub IsConstructorTemplate |  | 
| 5681 { |  | 
| 5682     my $interface = shift; |  | 
| 5683     my $template = shift; |  | 
| 5684 |  | 
| 5685     return $interface->extendedAttributes->{"ConstructorTemplate"} && $interface
      ->extendedAttributes->{"ConstructorTemplate"} eq $template; |  | 
| 5686 } |  | 
| 5687 |  | 
| 5688 sub IsPrimitiveType |  | 
| 5689 { |  | 
| 5690     my $type = shift; |  | 
| 5691 |  | 
| 5692     return 1 if $primitiveTypeHash{$type}; |  | 
| 5693     return 0; |  | 
| 5694 } |  | 
| 5695 |  | 
| 5696 sub IsCallbackFunctionType |  | 
| 5697 { |  | 
| 5698     my $type = shift; |  | 
| 5699 |  | 
| 5700     return 1 if $callbackFunctionTypeHash{$type}; |  | 
| 5701     return 0; |  | 
| 5702 } |  | 
| 5703 |  | 
| 5704 sub IsEnumType |  | 
| 5705 { |  | 
| 5706     my $type = shift; |  | 
| 5707 |  | 
| 5708     return 1 if $enumTypeHash{$type}; |  | 
| 5709     return 0; |  | 
| 5710 } |  | 
| 5711 |  | 
| 5712 sub ValidEnumValues |  | 
| 5713 { |  | 
| 5714     my $type = shift; |  | 
| 5715 |  | 
| 5716     return @{$enumTypeHash{$type}}; |  | 
| 5717 } |  | 
| 5718 |  | 
| 5719 sub IsSVGTypeNeedingTearOff |  | 
| 5720 { |  | 
| 5721     my $type = shift; |  | 
| 5722 |  | 
| 5723     return 1 if $svgTypeNeedingTearOff{$type}; |  | 
| 5724     return 0; |  | 
| 5725 } |  | 
| 5726 |  | 
| 5727 sub IsSVGTypeWithWritablePropertiesNeedingTearOff |  | 
| 5728 { |  | 
| 5729     my $type = shift; |  | 
| 5730 |  | 
| 5731     return 1 if $svgTypeWithWritablePropertiesNeedingTearOff{$type}; |  | 
| 5732     return 0; |  | 
| 5733 } |  | 
| 5734 |  | 
| 5735 sub IsTypedArrayType |  | 
| 5736 { |  | 
| 5737     my $type = shift; |  | 
| 5738     return 1 if $typedArrayHash{$type}; |  | 
| 5739     return 0; |  | 
| 5740 } |  | 
| 5741 |  | 
| 5742 sub IsRefPtrType |  | 
| 5743 { |  | 
| 5744     my $type = shift; |  | 
| 5745 |  | 
| 5746     return 0 if $type eq "any"; |  | 
| 5747     return 0 if IsPrimitiveType($type); |  | 
| 5748     return 0 if GetArrayType($type); |  | 
| 5749     return 0 if GetSequenceType($type); |  | 
| 5750     return 0 if $type eq "DOMString"; |  | 
| 5751     return 0 if $type eq "Promise"; |  | 
| 5752     return 0 if IsCallbackFunctionType($type); |  | 
| 5753     return 0 if IsEnumType($type); |  | 
| 5754     return 0 if IsUnionType($type); |  | 
| 5755 |  | 
| 5756     return 1; |  | 
| 5757 } |  | 
| 5758 |  | 
| 5759 sub GetSVGTypeNeedingTearOff |  | 
| 5760 { |  | 
| 5761     my $type = shift; |  | 
| 5762 |  | 
| 5763     return $svgTypeNeedingTearOff{$type} if exists $svgTypeNeedingTearOff{$type}
      ; |  | 
| 5764     return undef; |  | 
| 5765 } |  | 
| 5766 |  | 
| 5767 sub GetSVGWrappedTypeNeedingTearOff |  | 
| 5768 { |  | 
| 5769     my $type = shift; |  | 
| 5770 |  | 
| 5771     my $svgTypeNeedingTearOff = GetSVGTypeNeedingTearOff($type); |  | 
| 5772     return $svgTypeNeedingTearOff if not $svgTypeNeedingTearOff; |  | 
| 5773 |  | 
| 5774     if ($svgTypeNeedingTearOff =~ /SVGPropertyTearOff/) { |  | 
| 5775         $svgTypeNeedingTearOff =~ s/SVGPropertyTearOff<//; |  | 
| 5776     } elsif ($svgTypeNeedingTearOff =~ /SVGListPropertyTearOff/) { |  | 
| 5777         $svgTypeNeedingTearOff =~ s/SVGListPropertyTearOff<//; |  | 
| 5778     } elsif ($svgTypeNeedingTearOff =~ /SVGStaticListPropertyTearOff/) { |  | 
| 5779         $svgTypeNeedingTearOff =~ s/SVGStaticListPropertyTearOff<//; |  | 
| 5780     }  elsif ($svgTypeNeedingTearOff =~ /SVGTransformListPropertyTearOff/) { |  | 
| 5781         $svgTypeNeedingTearOff =~ s/SVGTransformListPropertyTearOff<//; |  | 
| 5782     } |  | 
| 5783 |  | 
| 5784     $svgTypeNeedingTearOff =~ s/>//; |  | 
| 5785     return $svgTypeNeedingTearOff; |  | 
| 5786 } |  | 
| 5787 |  | 
| 5788 sub IsSVGAnimatedType |  | 
| 5789 { |  | 
| 5790     my $type = shift; |  | 
| 5791 |  | 
| 5792     return $type =~ /^SVGAnimated/; |  | 
| 5793 } |  | 
| 5794 |  | 
| 5795 sub GetSequenceType |  | 
| 5796 { |  | 
| 5797     my $type = shift; |  | 
| 5798 |  | 
| 5799     return $1 if $type =~ /^sequence<([\w\d_\s]+)>.*/; |  | 
| 5800     return ""; |  | 
| 5801 } |  | 
| 5802 |  | 
| 5803 sub GetArrayType |  | 
| 5804 { |  | 
| 5805     my $type = shift; |  | 
| 5806 |  | 
| 5807     return $1 if $type =~ /^([\w\d_\s]+)\[\]/; |  | 
| 5808     return ""; |  | 
| 5809 } |  | 
| 5810 |  | 
| 5811 sub GetArrayOrSequenceType |  | 
| 5812 { |  | 
| 5813     my $type = shift; |  | 
| 5814 |  | 
| 5815     return GetArrayType($type) || GetSequenceType($type); |  | 
| 5816 } |  | 
| 5817 |  | 
| 5818 sub AssertNotSequenceType |  | 
| 5819 { |  | 
| 5820     my $type = shift; |  | 
| 5821     die "Sequences must not be used as the type of an attribute, constant or exc
      eption field." if GetSequenceType($type); |  | 
| 5822 } |  | 
| 5823 |  | 
| 5824 sub FirstLetterToUpperCase |  | 
| 5825 { |  | 
| 5826     my $param = shift; |  | 
| 5827     my $ret = ucfirst($param); |  | 
| 5828     # xmlEncoding becomes XMLEncoding, but xmlllang becomes Xmllang. |  | 
| 5829     $ret =~ s/Xml/XML/ if $ret =~ /^Xml[^a-z]/; |  | 
| 5830     $ret =~ s/Css/CSS/ if $ret =~ /^Css[^T]/;  # css -> setCSS, except setCssTex
      t. |  | 
| 5831     $ret =~ s/Ime/IME/ if $ret =~ /^Ime/;  # ime -> setIME |  | 
| 5832     $ret =~ s/Svg/SVG/ if $ret =~ /^Svg/;  # svg -> setSVG |  | 
| 5833     return $ret; |  | 
| 5834 } |  | 
| 5835 |  | 
| 5836 # URL becomes url, but SetURL becomes setURL. |  | 
| 5837 sub ToMethodName |  | 
| 5838 { |  | 
| 5839     my $param = shift; |  | 
| 5840     my $ret = lcfirst($param); |  | 
| 5841     $ret =~ s/hTML/html/ if $ret =~ /^hTML/; |  | 
| 5842     $ret =~ s/iME/ime/ if $ret =~ /^iME/; |  | 
| 5843     $ret =~ s/uRL/url/ if $ret =~ /^uRL/; |  | 
| 5844     $ret =~ s/jS/js/ if $ret =~ /^jS/; |  | 
| 5845     $ret =~ s/xML/xml/ if $ret =~ /^xML/; |  | 
| 5846     $ret =~ s/xSLT/xslt/ if $ret =~ /^xSLT/; |  | 
| 5847     $ret =~ s/cSS/css/ if $ret =~ /^cSS/; |  | 
| 5848 |  | 
| 5849     # For HTML5 FileSystem API Flags attributes. |  | 
| 5850     # (create is widely used to instantiate an object and must be avoided.) |  | 
| 5851     $ret =~ s/^create/isCreate/ if $ret =~ /^create$/; |  | 
| 5852     $ret =~ s/^exclusive/isExclusive/ if $ret =~ /^exclusive$/; |  | 
| 5853 |  | 
| 5854     return $ret; |  | 
| 5855 } |  | 
| 5856 |  | 
| 5857 sub NamespaceForAttributeName |  | 
| 5858 { |  | 
| 5859     my ($interfaceName, $attributeName) = @_; |  | 
| 5860     return "SVGNames" if $interfaceName =~ /^SVG/ && !$svgAttributesInHTMLHash{$
      attributeName}; |  | 
| 5861     return "HTMLNames"; |  | 
| 5862 } |  | 
| 5863 |  | 
| 5864 # Identifies overloaded functions and for each function adds an array with |  | 
| 5865 # links to its respective overloads (including itself). |  | 
| 5866 sub LinkOverloadedFunctions |  | 
| 5867 { |  | 
| 5868     my $interface = shift; |  | 
| 5869 |  | 
| 5870     my %nameToFunctionsMap = (); |  | 
| 5871     foreach my $function (@{$interface->functions}) { |  | 
| 5872         my $name = $function->name; |  | 
| 5873         $nameToFunctionsMap{$name} = [] if !exists $nameToFunctionsMap{$name} or
       !$name;  # Nameless functions cannot be overloaded |  | 
| 5874         push(@{$nameToFunctionsMap{$name}}, $function); |  | 
| 5875         $function->{overloads} = $nameToFunctionsMap{$name}; |  | 
| 5876         $function->{overloadIndex} = @{$nameToFunctionsMap{$name}}; |  | 
| 5877     } |  | 
| 5878 } |  | 
| 5879 |  | 
| 5880 sub AttributeNameForGetterAndSetter |  | 
| 5881 { |  | 
| 5882     my $attribute = shift; |  | 
| 5883 |  | 
| 5884     my $attributeName = GetImplName($attribute); |  | 
| 5885     if ($attribute->extendedAttributes->{"ImplementedAs"}) { |  | 
| 5886         $attributeName = $attribute->extendedAttributes->{"ImplementedAs"}; |  | 
| 5887     } |  | 
| 5888     my $attributeType = $attribute->type; |  | 
| 5889 |  | 
| 5890     return $attributeName; |  | 
| 5891 } |  | 
| 5892 |  | 
| 5893 sub ContentAttributeName |  | 
| 5894 { |  | 
| 5895     my ($interfaceName, $attribute) = @_; |  | 
| 5896 |  | 
| 5897     my $contentAttributeName = $attribute->extendedAttributes->{"Reflect"}; |  | 
| 5898     return undef if !$contentAttributeName; |  | 
| 5899 |  | 
| 5900     $contentAttributeName = lc AttributeNameForGetterAndSetter($attribute) if $c
      ontentAttributeName eq "VALUE_IS_MISSING"; |  | 
| 5901 |  | 
| 5902     my $namespace = NamespaceForAttributeName($interfaceName, $contentAttributeN
      ame); |  | 
| 5903 |  | 
| 5904     AddToImplIncludes("${namespace}.h"); |  | 
| 5905     # Attr (not Attribute) used in core content attributes |  | 
| 5906     return "WebCore::${namespace}::${contentAttributeName}Attr"; |  | 
| 5907 } |  | 
| 5908 |  | 
| 5909 sub GetterExpression |  | 
| 5910 { |  | 
| 5911     my ($interfaceName, $attribute) = @_; |  | 
| 5912 |  | 
| 5913     my $contentAttributeName = ContentAttributeName($interfaceName, $attribute); |  | 
| 5914 |  | 
| 5915     if (!$contentAttributeName) { |  | 
| 5916         return (ToMethodName(AttributeNameForGetterAndSetter($attribute))); |  | 
| 5917     } |  | 
| 5918 |  | 
| 5919     my $functionName; |  | 
| 5920     if ($attribute->extendedAttributes->{"URL"}) { |  | 
| 5921         $functionName = "getURLAttribute"; |  | 
| 5922     } elsif ($attribute->type eq "boolean") { |  | 
| 5923         $functionName = "fastHasAttribute"; |  | 
| 5924     } elsif ($attribute->type eq "long") { |  | 
| 5925         $functionName = "getIntegralAttribute"; |  | 
| 5926     } elsif ($attribute->type eq "unsigned long") { |  | 
| 5927         $functionName = "getUnsignedIntegralAttribute"; |  | 
| 5928     } else { |  | 
| 5929         if ($contentAttributeName eq "WebCore::HTMLNames::idAttr") { |  | 
| 5930             $functionName = "getIdAttribute"; |  | 
| 5931             $contentAttributeName = ""; |  | 
| 5932         } elsif ($contentAttributeName eq "WebCore::HTMLNames::nameAttr") { |  | 
| 5933             $functionName = "getNameAttribute"; |  | 
| 5934             $contentAttributeName = ""; |  | 
| 5935         } elsif ($contentAttributeName eq "WebCore::HTMLNames::classAttr") { |  | 
| 5936             $functionName = "getClassAttribute"; |  | 
| 5937             $contentAttributeName = ""; |  | 
| 5938         } else { |  | 
| 5939             # We cannot use fast attributes for animated SVG types. |  | 
| 5940             $functionName = IsSVGAnimatedType($attribute->type) ? "getAttribute"
       : "fastGetAttribute"; |  | 
| 5941         } |  | 
| 5942     } |  | 
| 5943 |  | 
| 5944     return ($functionName, $contentAttributeName); |  | 
| 5945 } |  | 
| 5946 |  | 
| 5947 sub SetterExpression |  | 
| 5948 { |  | 
| 5949     my ($interfaceName, $attribute) = @_; |  | 
| 5950 |  | 
| 5951     my $contentAttributeName = ContentAttributeName($interfaceName, $attribute); |  | 
| 5952 |  | 
| 5953     if (!$contentAttributeName) { |  | 
| 5954         return ("set" . FirstLetterToUpperCase(AttributeNameForGetterAndSetter($
      attribute))); |  | 
| 5955     } |  | 
| 5956 |  | 
| 5957     my $functionName; |  | 
| 5958     if ($attribute->type eq "boolean") { |  | 
| 5959         $functionName = "setBooleanAttribute"; |  | 
| 5960     } elsif ($attribute->type eq "long") { |  | 
| 5961         $functionName = "setIntegralAttribute"; |  | 
| 5962     } elsif ($attribute->type eq "unsigned long") { |  | 
| 5963         $functionName = "setUnsignedIntegralAttribute"; |  | 
| 5964     } else { |  | 
| 5965         $functionName = "setAttribute"; |  | 
| 5966     } |  | 
| 5967 |  | 
| 5968     return ($functionName, $contentAttributeName); |  | 
| 5969 } |  | 
| 5970 |  | 
| 5971 sub GenerateConditionalString |  | 
| 5972 { |  | 
| 5973     my $node = shift; |  | 
| 5974 |  | 
| 5975     my $conditional = $node->extendedAttributes->{"Conditional"}; |  | 
| 5976     if ($conditional) { |  | 
| 5977         return GenerateConditionalStringFromAttributeValue($conditional); |  | 
| 5978     } else { |  | 
| 5979         return ""; |  | 
| 5980     } |  | 
| 5981 } |  | 
| 5982 |  | 
| 5983 sub GenerateConditionalStringFromAttributeValue |  | 
| 5984 { |  | 
| 5985     my $conditional = shift; |  | 
| 5986 |  | 
| 5987     my $operator = ($conditional =~ /&/ ? '&' : ($conditional =~ /\|/ ? '|' : ''
      )); |  | 
| 5988     if ($operator) { |  | 
| 5989         # Avoid duplicated conditions. |  | 
| 5990         my %conditions; |  | 
| 5991         map { $conditions{$_} = 1 } split('\\' . $operator, $conditional); |  | 
| 5992         return "ENABLE(" . join(") $operator$operator ENABLE(", sort keys %condi
      tions) . ")"; |  | 
| 5993     } else { |  | 
| 5994         return "ENABLE(" . $conditional . ")"; |  | 
| 5995     } |  | 
| 5996 } |  | 
| 5997 |  | 
| 5998 sub GenerateCompileTimeCheckForEnumsIfNeeded |  | 
| 5999 { |  | 
| 6000     my $interface = shift; |  | 
| 6001     my $implClassName = GetImplName($interface); |  | 
| 6002     my @checks = (); |  | 
| 6003     # If necessary, check that all constants are available as enums with the sam
      e value. |  | 
| 6004     if (!$interface->extendedAttributes->{"DoNotCheckConstants"} && @{$interface
      ->constants}) { |  | 
| 6005         foreach my $constant (@{$interface->constants}) { |  | 
| 6006             my $reflect = $constant->extendedAttributes->{"Reflect"}; |  | 
| 6007             my $name = $reflect ? $reflect : $constant->name; |  | 
| 6008             my $value = $constant->value; |  | 
| 6009 |  | 
| 6010             if ($constant->extendedAttributes->{"ImplementedBy"}) { |  | 
| 6011                 my $implementedByImplName = GetImplNameFromImplementedBy($consta
      nt->extendedAttributes->{"ImplementedBy"}); |  | 
| 6012                 push(@checks, "    COMPILE_ASSERT($value == " . $implementedByIm
      plName . "::$name, TheValueOf${implClassName}_${name}DoesntMatchWithImplementati
      on);\n"); |  | 
| 6013             } else { |  | 
| 6014                 push(@checks, "    COMPILE_ASSERT($value == ${implClassName}::$n
      ame, TheValueOf${implClassName}_${name}DoesntMatchWithImplementation);\n"); |  | 
| 6015             } |  | 
| 6016         } |  | 
| 6017     } |  | 
| 6018     return @checks; |  | 
| 6019 } |  | 
| 6020 |  | 
| 6021 sub ExtendedAttributeContains |  | 
| 6022 { |  | 
| 6023     my $callWith = shift; |  | 
| 6024     return 0 unless $callWith; |  | 
| 6025     my $keyword = shift; |  | 
| 6026 |  | 
| 6027     my @callWithKeywords = split /\s*\&\s*/, $callWith; |  | 
| 6028     return grep { $_ eq $keyword } @callWithKeywords; |  | 
| 6029 } |  | 
| 6030 |  | 
| 6031 sub InheritsInterface |  | 
| 6032 { |  | 
| 6033     my $interface = shift; |  | 
| 6034     my $interfaceName = shift; |  | 
| 6035     my $found = 0; |  | 
| 6036 |  | 
| 6037     return 1 if $interfaceName eq $interface->name; |  | 
| 6038     ForAllParents($interface, sub { |  | 
| 6039         my $currentInterface = shift; |  | 
| 6040         if ($currentInterface->name eq $interfaceName) { |  | 
| 6041             $found = 1; |  | 
| 6042         } |  | 
| 6043         return 1 if $found; |  | 
| 6044     }, 0); |  | 
| 6045 |  | 
| 6046     return $found; |  | 
| 6047 } |  | 
| 6048 |  | 
| 6049 sub InheritsExtendedAttribute |  | 
| 6050 { |  | 
| 6051     my $interface = shift; |  | 
| 6052     my $extendedAttribute = shift; |  | 
| 6053     my $found = 0; |  | 
| 6054 |  | 
| 6055     return 1 if $interface->extendedAttributes->{$extendedAttribute}; |  | 
| 6056     ForAllParents($interface, sub { |  | 
| 6057         my $currentInterface = shift; |  | 
| 6058         if ($currentInterface->extendedAttributes->{$extendedAttribute}) { |  | 
| 6059             $found = 1; |  | 
| 6060         } |  | 
| 6061         return 1 if $found; |  | 
| 6062     }, 0); |  | 
| 6063 |  | 
| 6064     return $found; |  | 
| 6065 } |  | 
| 6066 |  | 
| 6067 1; |  | 
| OLD | NEW | 
|---|