| OLD | NEW |
| (Empty) |
| 1 | |
| 2 # Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> | |
| 3 # Copyright (C) 2006 Anders Carlsson <andersca@mac.com> | |
| 4 # Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> | |
| 5 # Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org> | |
| 6 # Copyright (C) 2006 Apple Computer, Inc. | |
| 7 # Copyright (C) 2007, 2008, 2009 Google Inc. | |
| 8 # | |
| 9 # This file is part of the KDE project | |
| 10 # | |
| 11 # This library is free software; you can redistribute it and/or | |
| 12 # modify it under the terms of the GNU Library General Public | |
| 13 # License as published by the Free Software Foundation; either | |
| 14 # version 2 of the License, or (at your option) any later version. | |
| 15 # | |
| 16 # This library is distributed in the hope that it will be useful, | |
| 17 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 19 # Library General Public License for more details. | |
| 20 # | |
| 21 # You should have received a copy of the GNU Library General Public License | |
| 22 # aint with this library; see the file COPYING.LIB. If not, write to | |
| 23 # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
| 24 # Boston, MA 02111-1307, USA. | |
| 25 # | |
| 26 | |
| 27 package CodeGeneratorV8; | |
| 28 | |
| 29 use File::stat; | |
| 30 | |
| 31 my $module = ""; | |
| 32 my $outputDir = ""; | |
| 33 | |
| 34 my @headerContent = (); | |
| 35 my @implContentHeader = (); | |
| 36 my @implFixedHeader = (); | |
| 37 my @implContent = (); | |
| 38 my @implContentDecls = (); | |
| 39 my %implIncludes = (); | |
| 40 | |
| 41 my @allParents = (); | |
| 42 | |
| 43 # Default .h template | |
| 44 my $headerTemplate = << "EOF"; | |
| 45 /* | |
| 46 This file is part of the WebKit open source project. | |
| 47 This file has been generated by generate-bindings.pl. DO NOT MODIFY! | |
| 48 | |
| 49 This library is free software; you can redistribute it and/or | |
| 50 modify it under the terms of the GNU Library General Public | |
| 51 License as published by the Free Software Foundation; either | |
| 52 version 2 of the License, or (at your option) any later version. | |
| 53 | |
| 54 This library is distributed in the hope that it will be useful, | |
| 55 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 56 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 57 Library General Public License for more details. | |
| 58 | |
| 59 You should have received a copy of the GNU Library General Public License | |
| 60 along with this library; see the file COPYING.LIB. If not, write to | |
| 61 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
| 62 Boston, MA 02111-1307, USA. | |
| 63 */ | |
| 64 EOF | |
| 65 | |
| 66 # Default constructor | |
| 67 sub new | |
| 68 { | |
| 69 my $object = shift; | |
| 70 my $reference = { }; | |
| 71 | |
| 72 $codeGenerator = shift; | |
| 73 $outputDir = shift; | |
| 74 | |
| 75 bless($reference, $object); | |
| 76 return $reference; | |
| 77 } | |
| 78 | |
| 79 sub finish | |
| 80 { | |
| 81 my $object = shift; | |
| 82 | |
| 83 # Commit changes! | |
| 84 $object->WriteData(); | |
| 85 } | |
| 86 | |
| 87 sub leftShift($$) { | |
| 88 my ($value, $distance) = @_; | |
| 89 return (($value << $distance) & 0xFFFFFFFF); | |
| 90 } | |
| 91 | |
| 92 # Uppercase the first letter, while respecting WebKit style guidelines. | |
| 93 # E.g., xmlEncoding becomes XMLEncoding, but xmlllang becomes Xmllang. | |
| 94 sub WK_ucfirst | |
| 95 { | |
| 96 my $param = shift; | |
| 97 my $ret = ucfirst($param); | |
| 98 $ret =~ s/Xml/XML/ if $ret =~ /^Xml[^a-z]/; | |
| 99 return $ret; | |
| 100 } | |
| 101 | |
| 102 # Lowercase the first letter while respecting WebKit style guidelines. | |
| 103 # URL becomes url, but SetURL becomes setURL. | |
| 104 sub WK_lcfirst | |
| 105 { | |
| 106 my $param = shift; | |
| 107 my $ret = lcfirst($param); | |
| 108 $ret =~ s/uRL/url/; | |
| 109 return $ret; | |
| 110 } | |
| 111 | |
| 112 # Params: 'domClass' struct | |
| 113 sub GenerateInterface | |
| 114 { | |
| 115 my $object = shift; | |
| 116 my $dataNode = shift; | |
| 117 my $defines = shift; | |
| 118 | |
| 119 # Start actual generation | |
| 120 $object->GenerateHeader($dataNode); | |
| 121 $object->GenerateImplementation($dataNode); | |
| 122 | |
| 123 my $name = $dataNode->name; | |
| 124 | |
| 125 # Open files for writing | |
| 126 my $headerFileName = "$outputDir/V8$name.h"; | |
| 127 my $implFileName = "$outputDir/V8$name.cpp"; | |
| 128 | |
| 129 open($IMPL, ">$implFileName") || die "Couldn't open file $implFileName"; | |
| 130 open($HEADER, ">$headerFileName") || die "Couldn't open file $headerFileName
"; | |
| 131 } | |
| 132 | |
| 133 # Params: 'idlDocument' struct | |
| 134 sub GenerateModule | |
| 135 { | |
| 136 my $object = shift; | |
| 137 my $dataNode = shift; | |
| 138 | |
| 139 $module = $dataNode->module; | |
| 140 } | |
| 141 | |
| 142 sub GetLegacyHeaderIncludes | |
| 143 { | |
| 144 my $legacyParent = shift; | |
| 145 | |
| 146 die "Don't know what headers to include for module $module"; | |
| 147 } | |
| 148 | |
| 149 sub AvoidInclusionOfType | |
| 150 { | |
| 151 my $type = shift; | |
| 152 | |
| 153 # Special case: SVGRect.h / SVGPoint.h / SVGNumber.h / SVGMatrix.h do not ex
ist. | |
| 154 return 1 if $type eq "SVGRect" or $type eq "SVGPoint" or $type eq "SVGNumber
" or $type eq "SVGMatrix"; | |
| 155 return 0; | |
| 156 } | |
| 157 | |
| 158 sub UsesManualToJSImplementation | |
| 159 { | |
| 160 my $type = shift; | |
| 161 | |
| 162 return 1 if $type eq "SVGPathSeg"; | |
| 163 return 0; | |
| 164 } | |
| 165 | |
| 166 sub AddIncludesForType | |
| 167 { | |
| 168 my $type = $codeGenerator->StripModule(shift); | |
| 169 | |
| 170 # When we're finished with the one-file-per-class | |
| 171 # reorganization, we won't need these special cases. | |
| 172 if ($codeGenerator->IsPrimitiveType($type) or AvoidInclusionOfType($type) | |
| 173 # jhaas: there doesn't seem to be any harm in leaving these in | |
| 174 # or $type eq "DOMString" or $type eq "DOMObject" or $type eq "RGBColor"
or $type eq "Rect") { | |
| 175 ) { | |
| 176 } elsif ($type =~ /SVGPathSeg/) { | |
| 177 $joinedName = $type; | |
| 178 $joinedName =~ s/Abs|Rel//; | |
| 179 $implIncludes{"${joinedName}.h"} = 1; | |
| 180 } else { | |
| 181 # default, include the same named file | |
| 182 $implIncludes{GetImplementationFileName(${type})} = 1; | |
| 183 } | |
| 184 | |
| 185 # additional includes (things needed to compile the bindings but not the hea
der) | |
| 186 | |
| 187 if ($type eq "CanvasRenderingContext2D") { | |
| 188 $implIncludes{"CanvasGradient.h"} = 1; | |
| 189 $implIncludes{"CanvasPattern.h"} = 1; | |
| 190 $implIncludes{"CanvasStyle.h"} = 1; | |
| 191 } | |
| 192 | |
| 193 if ($type eq "CanvasGradient" or $type eq "XPathNSResolver") { | |
| 194 $implIncludes{"PlatformString.h"} = 1; | |
| 195 } | |
| 196 | |
| 197 if ($type eq "CSSStyleDeclaration") { | |
| 198 $implIncludes{"CSSMutableStyleDeclaration.h"} = 1; | |
| 199 } | |
| 200 | |
| 201 if ($type eq "Plugin" or $type eq "PluginArray" or $type eq "MimeTypeArray")
{ | |
| 202 # So we can get String -> AtomicString conversion for namedItem(). | |
| 203 $implIncludes{"AtomicString.h"} = 1; | |
| 204 } | |
| 205 } | |
| 206 | |
| 207 sub AddIncludesForSVGAnimatedType | |
| 208 { | |
| 209 my $type = shift; | |
| 210 $type =~ s/SVGAnimated//; | |
| 211 | |
| 212 if ($type eq "Point" or $type eq "Rect") { | |
| 213 $implIncludes{"Float$type.h"} = 1; | |
| 214 } elsif ($type eq "String") { | |
| 215 $implIncludes{"PlatformString.h"} = 1; | |
| 216 } | |
| 217 | |
| 218 $implIncludes{"SVGAnimatedTemplate.h"} = 1; | |
| 219 } | |
| 220 | |
| 221 sub AddClassForwardIfNeeded | |
| 222 { | |
| 223 my $implClassName = shift; | |
| 224 | |
| 225 # SVGAnimatedLength/Number/etc.. are typedefs to SVGAnimtatedTemplate, so do
n't use class forwards for them! | |
| 226 push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsS
VGAnimatedType($implClassName); | |
| 227 } | |
| 228 | |
| 229 sub GetImplementationFileName | |
| 230 { | |
| 231 my $iface = shift; | |
| 232 return "HTMLCollection.h" if $iface eq "UndetectableHTMLCollection"; | |
| 233 return "Event.h" if $iface eq "DOMTimeStamp"; | |
| 234 return "NamedAttrMap.h" if $iface eq "NamedNodeMap"; | |
| 235 return "NameNodeList.h" if $iface eq "NodeList"; | |
| 236 return "XMLHttpRequest.h" if $iface eq "XMLHttpRequest"; | |
| 237 | |
| 238 return "${iface}.h"; | |
| 239 } | |
| 240 | |
| 241 sub GenerateHeader | |
| 242 { | |
| 243 my $object = shift; | |
| 244 my $dataNode = shift; | |
| 245 | |
| 246 my $interfaceName = $dataNode->name; | |
| 247 my $className = "V8$interfaceName"; | |
| 248 my $implClassName = $interfaceName; | |
| 249 | |
| 250 # Copy contents of parent classes except the first parent or if it is | |
| 251 # EventTarget. | |
| 252 $codeGenerator->AddMethodsConstantsAndAttributesFromParentClasses($dataNode)
; | |
| 253 | |
| 254 my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"}; | |
| 255 my $conditional = $dataNode->extendedAttributes->{"Conditional"}; | |
| 256 | |
| 257 # - Add default header template | |
| 258 @headerContent = split("\r", $headerTemplate); | |
| 259 | |
| 260 my $conditionalString; | |
| 261 if ($conditional) { | |
| 262 $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $condit
ional)) . ")"; | |
| 263 push(@headerContent, "\n#if ${conditionalString}\n\n"); | |
| 264 } | |
| 265 | |
| 266 push(@headerContent, "\n#ifndef $className" . "_H"); | |
| 267 push(@headerContent, "\n#define $className" . "_H\n\n"); | |
| 268 | |
| 269 # Get correct pass/store types respecting PODType flag | |
| 270 my $podType = $dataNode->extendedAttributes->{"PODType"}; | |
| 271 my $passType = $podType ? "JSSVGPODTypeWrapper<$podType>*" : "$implClassName
*"; | |
| 272 | |
| 273 push(@headerContent, "#include \"$podType.h\"\n") if $podType and ($podType
ne "double" and $podType ne "float" and $podType ne "RGBA32"); | |
| 274 | |
| 275 push(@headerContent, "#include <v8.h>\n"); | |
| 276 push(@headerContent, "#include <wtf/HashMap.h>\n"); | |
| 277 push(@headerContent, "#include \"StringHash.h\"\n"); | |
| 278 | |
| 279 push(@headerContent, "\nnamespace WebCore {\n\n"); | |
| 280 push(@headerContent, "class V8ClassIndex;\n"); | |
| 281 push(@headerContent, "\nclass $className {\n"); | |
| 282 push(@headerContent, <<END); | |
| 283 | |
| 284 public: | |
| 285 static bool HasInstance(v8::Handle<v8::Value> value); | |
| 286 static v8::Persistent<v8::FunctionTemplate> GetRawTemplate(); | |
| 287 END | |
| 288 | |
| 289 if ($implClassName eq "DOMWindow") { | |
| 290 push(@headerContent, <<END); | |
| 291 static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate(); | |
| 292 END | |
| 293 } | |
| 294 | |
| 295 push(@headerContent, <<END); | |
| 296 | |
| 297 private: | |
| 298 static v8::Persistent<v8::FunctionTemplate> GetTemplate(); | |
| 299 | |
| 300 friend class V8ClassIndex; | |
| 301 }; | |
| 302 | |
| 303 END | |
| 304 | |
| 305 push(@headerContent, "}\n\n"); | |
| 306 push(@headerContent, "#endif // $className" . "_H\n"); | |
| 307 | |
| 308 push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditional; | |
| 309 } | |
| 310 | |
| 311 | |
| 312 sub GenerateSetDOMException | |
| 313 { | |
| 314 my $indent = shift; | |
| 315 my $result = ""; | |
| 316 | |
| 317 $result .= $indent . "if (ec) {\n"; | |
| 318 $result .= $indent . " V8Proxy::SetDOMException(ec);\n"; | |
| 319 $result .= $indent . " return v8::Handle<v8::Value>();\n"; | |
| 320 $result .= $indent . "}\n"; | |
| 321 | |
| 322 return $result; | |
| 323 } | |
| 324 | |
| 325 sub IsNodeSubType | |
| 326 { | |
| 327 my $dataNode = shift; | |
| 328 return 1 if ($dataNode->name eq "Node"); | |
| 329 foreach (@allParents) { | |
| 330 my $parent = $codeGenerator->StripModule($_); | |
| 331 return 1 if $parent eq "Node"; | |
| 332 } | |
| 333 return 0; | |
| 334 } | |
| 335 | |
| 336 sub HolderToNative | |
| 337 { | |
| 338 my $dataNode = shift; | |
| 339 my $implClassName = shift; | |
| 340 my $classIndex = shift; | |
| 341 | |
| 342 if (IsNodeSubType($dataNode)) { | |
| 343 push(@implContentDecls, <<END); | |
| 344 $implClassName* imp = V8Proxy::DOMWrapperToNode<$implClassName>(holder); | |
| 345 END | |
| 346 | |
| 347 } else { | |
| 348 push(@implContentDecls, <<END); | |
| 349 $implClassName* imp = V8Proxy::ToNativeObject<$implClassName>(V8ClassIndex::
$classIndex, holder); | |
| 350 END | |
| 351 | |
| 352 } | |
| 353 } | |
| 354 | |
| 355 sub GenerateDomainSafeFunctionGetter | |
| 356 { | |
| 357 my $function = shift; | |
| 358 my $dataNode = shift; | |
| 359 my $classIndex = shift; | |
| 360 my $implClassName = shift; | |
| 361 | |
| 362 my $className = "V8" . $dataNode->name; | |
| 363 my $funcName = $function->signature->name; | |
| 364 | |
| 365 my $signature = "v8::Signature::New(" . $className . "::GetRawTemplate())"; | |
| 366 if ($function->signature->extendedAttributes->{"V8DoNotCheckSignature"}) { | |
| 367 $signature = "v8::Local<v8::Signature>()"; | |
| 368 } | |
| 369 | |
| 370 my $newTemplateString = GenerateNewFunctionTemplate($function, $dataNode, $sig
nature); | |
| 371 | |
| 372 $implIncludes{"v8_proxy.h"} = 1; | |
| 373 | |
| 374 push(@implContentDecls, <<END); | |
| 375 static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name,
const v8::AccessorInfo& info) { | |
| 376 INC_STATS(\"DOM.$implClassName.$funcName._get\"); | |
| 377 static v8::Persistent<v8::FunctionTemplate> private_template = | |
| 378 v8::Persistent<v8::FunctionTemplate>::New($newTemplateString); | |
| 379 v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::$cla
ssIndex, info.This()); | |
| 380 if (holder.IsEmpty()) { | |
| 381 // can only reach here by 'object.__proto__.func', and it should passed | |
| 382 // domain security check already | |
| 383 | |
| 384 return private_template->GetFunction(); | |
| 385 } | |
| 386 END | |
| 387 | |
| 388 HolderToNative($dataNode, $implClassName, $classIndex); | |
| 389 | |
| 390 push(@implContentDecls, <<END); | |
| 391 if (!V8Proxy::CanAccessFrame(imp->frame(), false)) { | |
| 392 static v8::Persistent<v8::FunctionTemplate> shared_template = | |
| 393 v8::Persistent<v8::FunctionTemplate>::New($newTemplateString); | |
| 394 return shared_template->GetFunction(); | |
| 395 | |
| 396 } else { | |
| 397 return private_template->GetFunction(); | |
| 398 } | |
| 399 } | |
| 400 | |
| 401 END | |
| 402 } | |
| 403 | |
| 404 sub GenerateConstructorGetter | |
| 405 { | |
| 406 my $implClassName = shift; | |
| 407 my $classIndex = shift; | |
| 408 | |
| 409 push(@implContentDecls, <<END); | |
| 410 static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::S
tring> name, const v8::AccessorInfo& info) { | |
| 411 INC_STATS(\"DOM.$implClassName.constructors._get\"); | |
| 412 v8::Handle<v8::Value> data = info.Data(); | |
| 413 ASSERT(data->IsNumber()); | |
| 414 V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(data->Int32Value())
; | |
| 415 END | |
| 416 | |
| 417 if ($classIndex eq "DOMWINDOW") { | |
| 418 push(@implContentDecls, <<END); | |
| 419 DOMWindow* window = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWIND
OW, info.Holder()); | |
| 420 Frame* frame = window->frame(); | |
| 421 if (frame) { | |
| 422 // Get the proxy corresponding to the DOMWindow if possible to | |
| 423 // make sure that the constructor function is constructed in the | |
| 424 // context of the DOMWindow and not in the context of the caller. | |
| 425 return V8Proxy::retrieve(frame)->GetConstructor(type); | |
| 426 } | |
| 427 END | |
| 428 } | |
| 429 | |
| 430 if ($classIndex eq "WORKERCONTEXT") { | |
| 431 $implIncludes{"WorkerContextExecutionProxy.h"} = 1; | |
| 432 push(@implContentDecls, <<END); | |
| 433 return WorkerContextExecutionProxy::retrieve()->GetConstructor(type); | |
| 434 END | |
| 435 } else { | |
| 436 push(@implContentDecls, " return v8::Undefined();"); | |
| 437 } | |
| 438 | |
| 439 push(@implContentDecls, <<END); | |
| 440 | |
| 441 } | |
| 442 | |
| 443 END | |
| 444 } | |
| 445 | |
| 446 sub GenerateNormalAttrGetter | |
| 447 { | |
| 448 my $attribute = shift; | |
| 449 my $dataNode = shift; | |
| 450 my $classIndex = shift; | |
| 451 my $implClassName = shift; | |
| 452 | |
| 453 my $attrExt = $attribute->signature->extendedAttributes; | |
| 454 | |
| 455 my $attrName = $attribute->signature->name; | |
| 456 $implIncludes{"v8_proxy.h"} = 1; | |
| 457 | |
| 458 my $attrType = $codeGenerator->StripModule($attribute->signature->type); | |
| 459 my $attrIsPodType = $codeGenerator->IsPodType($attrType); | |
| 460 my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0); | |
| 461 my $isPodType = $codeGenerator->IsPodType($implClassName); | |
| 462 my $skipContext = 0; | |
| 463 | |
| 464 | |
| 465 if ($isPodType) { | |
| 466 $implClassName = GetNativeType($implClassName); | |
| 467 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1; | |
| 468 } | |
| 469 | |
| 470 # Special case: SVGZoomEvent's attributes are all read-only | |
| 471 if ($implClassName eq "SVGZoomEvent") { | |
| 472 $attrIsPodType = 0; | |
| 473 $skipContext = 1; | |
| 474 } | |
| 475 | |
| 476 # Special case: SVGSVGEelement::viewport is read-only | |
| 477 if (($implClassName eq "SVGSVGElement") and ($attrName eq "viewport")) { | |
| 478 $attrIsPodType = 0; | |
| 479 $skipContext = 1; | |
| 480 } | |
| 481 | |
| 482 # Special case for SVGColor | |
| 483 if (($implClassName eq "SVGColor") and ($attrName eq "rgbColor")) { | |
| 484 $attrIsPodType = 0; | |
| 485 } | |
| 486 | |
| 487 my $getterStringUsesImp = $implClassName ne "double"; | |
| 488 | |
| 489 # Getter | |
| 490 push(@implContentDecls, <<END); | |
| 491 static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name,
const v8::AccessorInfo& info) { | |
| 492 INC_STATS(\"DOM.$implClassName.$attrName._get\"); | |
| 493 END | |
| 494 | |
| 495 if ($isPodType) { | |
| 496 push(@implContentDecls, <<END); | |
| 497 V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8Proxy::ToNativeObject<V
8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder()); | |
| 498 $implClassName imp_instance = *imp_wrapper; | |
| 499 END | |
| 500 if ($getterStringUsesImp) { | |
| 501 push(@implContentDecls, <<END); | |
| 502 $implClassName* imp = &imp_instance; | |
| 503 END | |
| 504 } | |
| 505 | |
| 506 } elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) { | |
| 507 # perform lookup first | |
| 508 push(@implContentDecls, <<END); | |
| 509 v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::$cla
ssIndex, info.This()); | |
| 510 if (holder.IsEmpty()) return v8::Undefined(); | |
| 511 END | |
| 512 HolderToNative($dataNode, $implClassName, $classIndex); | |
| 513 } else { | |
| 514 push(@implContentDecls, <<END); | |
| 515 v8::Handle<v8::Object> holder = info.Holder(); | |
| 516 END | |
| 517 HolderToNative($dataNode, $implClassName, $classIndex); | |
| 518 } | |
| 519 | |
| 520 # Generate security checks if necessary | |
| 521 if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) { | |
| 522 push(@implContentDecls, " if (!V8Proxy::CheckNodeSecurity(imp->$attrName(
))) return v8::Undefined();\n\n"); | |
| 523 } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) { | |
| 524 push(@implContentDecls, " if (!V8Proxy::CheckNodeSecurity(imp->contentDoc
ument())) return v8::Undefined();\n\n"); | |
| 525 } | |
| 526 | |
| 527 my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType); | |
| 528 if ($useExceptions) { | |
| 529 $implIncludes{"ExceptionCode.h"} = 1; | |
| 530 push(@implContentDecls, " ExceptionCode ec = 0;\n"); | |
| 531 } | |
| 532 | |
| 533 if ($attribute->signature->extendedAttributes->{"v8referenceattr"}) { | |
| 534 $attrName = $attribute->signature->extendedAttributes->{"v8referenceattr"}; | |
| 535 } | |
| 536 | |
| 537 my $getterFunc = WK_lcfirst($attrName); | |
| 538 $getterFunc .= "Animated" if $codeGenerator->IsSVGAnimatedType($attribute->sig
nature->type); | |
| 539 | |
| 540 my $returnType = $codeGenerator->StripModule($attribute->signature->type); | |
| 541 | |
| 542 my $getterString; | |
| 543 if ($getterStringUsesImp) { | |
| 544 $getterString = "imp->$getterFunc("; | |
| 545 $getterString .= "ec" if $useExceptions; | |
| 546 $getterString .= ")"; | |
| 547 if (IsRefPtrType($returnType)) { | |
| 548 $implIncludes{"wtf/GetPtr.h"} = 1; | |
| 549 $getterString = "WTF::getPtr(" . $getterString . ")"; | |
| 550 } | |
| 551 if ($nativeType eq "int" and | |
| 552 $attribute->signature->extendedAttributes->{"ConvertFromString"}) { | |
| 553 $getterString .= ".toInt()"; | |
| 554 } | |
| 555 } else { | |
| 556 $getterString = "imp_instance"; | |
| 557 } | |
| 558 if ($nativeType eq "String") { | |
| 559 $getterString = "ToString($getterString)"; | |
| 560 } | |
| 561 | |
| 562 my $result; | |
| 563 my $wrapper; | |
| 564 | |
| 565 if ($attrIsPodType) { | |
| 566 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1; | |
| 567 | |
| 568 my $getter = $getterString; | |
| 569 $getter =~ s/imp->//; | |
| 570 $getter =~ s/\(\)//; | |
| 571 my $setter = "set" . WK_ucfirst($getter); | |
| 572 | |
| 573 my $implClassIsAnimatedType = $codeGenerator->IsSVGAnimatedType($implClassNa
me); | |
| 574 if (not $implClassIsAnimatedType | |
| 575 and $codeGenerator->IsPodTypeWithWriteableProperties($attrType) | |
| 576 and not defined $attribute->signature->extendedAttributes->{"Immutable"}
) { | |
| 577 if ($codeGenerator->IsPodType($implClassName)) { | |
| 578 $wrapper = "new V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType,
$implClassName>($getterString, imp_wrapper)"; | |
| 579 } else { | |
| 580 $wrapper = "new V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implCl
assName>(imp, &${implClassName}::$getter, &${implClassName}::$setter)"; | |
| 581 } | |
| 582 } else { | |
| 583 if ($implClassIsAnimatedType) { | |
| 584 $wrapper = "V8SVGDynamicPODTypeWrapperCache<$nativeType, $implClassName>
::lookupOrCreateWrapper(imp, &${implClassName}::$getter, &${implClassName}::$set
ter)"; | |
| 585 } else { | |
| 586 $wrapper = GenerateSVGStaticPodTypeWrapper($returnType, $getterString); | |
| 587 } | |
| 588 } | |
| 589 | |
| 590 push(@implContentDecls, " void* wrapper = $wrapper;\n"); | |
| 591 } elsif ($nativeType ne "RGBColor") { | |
| 592 push(@implContentDecls, " $nativeType v = "); | |
| 593 | |
| 594 push(@implContentDecls, "$getterString;\n"); | |
| 595 | |
| 596 if ($useExceptions) { | |
| 597 push(@implContentDecls, GenerateSetDOMException(" ")); | |
| 598 } | |
| 599 | |
| 600 $result = "v"; | |
| 601 if (IsRefPtrType($returnType)) { | |
| 602 $result = "WTF::getPtr(" . $result . ")"; | |
| 603 } | |
| 604 } else { | |
| 605 # Special case: RGBColor is noncopyable | |
| 606 $result = $getterString; | |
| 607 } | |
| 608 | |
| 609 | |
| 610 if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) { | |
| 611 my $resultObject = $result; | |
| 612 if ($attrIsPodType) { | |
| 613 $resultObject = "wrapper"; | |
| 614 } | |
| 615 | |
| 616 push(@implContentDecls, GenerateSVGContextAssignment($implClassName, $result
Object, " ")); | |
| 617 } | |
| 618 | |
| 619 if ($attrIsPodType) { | |
| 620 my $classIndex = uc($attrType); | |
| 621 push(@implContentDecls, " return V8Proxy::ToV8Object(V8ClassIndex::$class
Index, wrapper);\n"); | |
| 622 } else { | |
| 623 push(@implContentDecls, " return " . NativeToJSValue($attribute->signatur
e, $result). ";\n"); | |
| 624 } | |
| 625 | |
| 626 push(@implContentDecls, " }\n\n"); # end of getter | |
| 627 } | |
| 628 | |
| 629 | |
| 630 sub GenerateReplaceableAttrSetter | |
| 631 { | |
| 632 my $implClassName = shift; | |
| 633 | |
| 634 $implIncludes{"v8_proxy.h"} = 1; | |
| 635 | |
| 636 push(@implContentDecls, | |
| 637 " static void ${attrName}AttrSetter(v8::Local<v8::String> name," . | |
| 638 " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n"); | |
| 639 | |
| 640 push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");
\n"); | |
| 641 | |
| 642 push(@implContentDecls, " v8::Local<v8::String> ${attrName}_string = v8::St
ring::New(\"${attrName}\");\n"); | |
| 643 push(@implContentDecls, " info.Holder()->Delete(${attrName}_string);\n"); | |
| 644 push(@implContentDecls, " info.This()->Set(${attrName}_string, value);\n"); | |
| 645 push(@implContentDecls, " }\n\n"); | |
| 646 } | |
| 647 | |
| 648 | |
| 649 sub GenerateNormalAttrSetter | |
| 650 { | |
| 651 my $attribute = shift; | |
| 652 my $dataNode = shift; | |
| 653 my $classIndex = shift; | |
| 654 my $implClassName = shift; | |
| 655 | |
| 656 my $attrExt = $attribute->signature->extendedAttributes; | |
| 657 | |
| 658 $implIncludes{"v8_proxy.h"} = 1; | |
| 659 | |
| 660 push(@implContentDecls, | |
| 661 " static void ${attrName}AttrSetter(v8::Local<v8::String> name," . | |
| 662 " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n"); | |
| 663 | |
| 664 push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");
\n"); | |
| 665 | |
| 666 my $isPodType = $codeGenerator->IsPodType($implClassName); | |
| 667 | |
| 668 if ($isPodType) { | |
| 669 $implClassName = GetNativeType($implClassName); | |
| 670 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1; | |
| 671 push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper =
V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$cla
ssIndex, info.Holder());\n"); | |
| 672 push(@implContentDecls, " $implClassName imp_instance = *wrapper;\n"); | |
| 673 push(@implContentDecls, " $implClassName* imp = &imp_instance;\n"); | |
| 674 | |
| 675 } elsif ($attrExt->{"v8OnProto"}) { | |
| 676 # perform lookup first | |
| 677 push(@implContentDecls, <<END); | |
| 678 v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::$cla
ssIndex, info.This()); | |
| 679 if (holder.IsEmpty()) return v8::Undefined(); | |
| 680 END | |
| 681 HolderToNative($dataNode, $implClassName, $classIndex); | |
| 682 } else { | |
| 683 push(@implContentDecls, <<END); | |
| 684 v8::Handle<v8::Object> holder = info.Holder(); | |
| 685 END | |
| 686 HolderToNative($dataNode, $implClassName, $classIndex); | |
| 687 } | |
| 688 | |
| 689 my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0); | |
| 690 push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->s
ignature, "value") . ";\n"); | |
| 691 | |
| 692 my $result = ""; | |
| 693 if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"Conv
ertFromString"}) { | |
| 694 $result .= "WebCore::String::number("; | |
| 695 } | |
| 696 $result .= "v"; | |
| 697 if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"Conv
ertFromString"}) { | |
| 698 $result .= ")"; | |
| 699 } | |
| 700 my $returnType = $codeGenerator->StripModule($attribute->signature->type); | |
| 701 if (IsRefPtrType($returnType)) { | |
| 702 $result = "WTF::getPtr(" . $result . ")"; | |
| 703 } | |
| 704 | |
| 705 my $useExceptions = 1 if @{$attribute->setterExceptions} and !($isPodType); | |
| 706 | |
| 707 if ($useExceptions) { | |
| 708 $implIncludes{"ExceptionCode.h"} = 1; | |
| 709 push(@implContentDecls, " ExceptionCode ec = 0;\n"); | |
| 710 } | |
| 711 | |
| 712 if ($implClassName eq "double") { | |
| 713 push(@implContentDecls, " *imp = $result;\n"); | |
| 714 } else { | |
| 715 push(@implContentDecls, " imp->set" . WK_ucfirst($attrName) . "(" . $resu
lt); | |
| 716 push(@implContentDecls, ", ec") if $useExceptions; | |
| 717 push(@implContentDecls, ");\n"); | |
| 718 } | |
| 719 | |
| 720 if ($useExceptions) { | |
| 721 push(@implContentDecls, " V8Proxy::SetDOMException(ec);\n"); | |
| 722 } | |
| 723 | |
| 724 if ($isPodType) { | |
| 725 push(@implContentDecls, " wrapper->commitChange(*imp, V8Proxy::GetSVGCont
ext(wrapper));\n"); | |
| 726 } elsif (IsSVGTypeNeedingContextParameter($implClassName)) { | |
| 727 $implIncludes{"SVGElement.h"} = 1; | |
| 728 | |
| 729 my $currentObject = "imp"; | |
| 730 if ($isPodType) { | |
| 731 $currentObject = "wrapper"; | |
| 732 } | |
| 733 | |
| 734 push(@implContentDecls, " if (SVGElement* context = V8Proxy::GetSVGContex
t($currentObject)) {\n"); | |
| 735 push(@implContentDecls, " context->svgAttributeChanged(imp->associate
dAttributeName());\n"); | |
| 736 push(@implContentDecls, " }\n"); | |
| 737 } | |
| 738 | |
| 739 push(@implContentDecls, " return;\n"); | |
| 740 push(@implContentDecls, " }\n\n"); # end of setter | |
| 741 } | |
| 742 | |
| 743 | |
| 744 sub GenerateNewFunctionTemplate | |
| 745 { | |
| 746 $function = shift; | |
| 747 $dataNode = shift; | |
| 748 $signature = shift; | |
| 749 | |
| 750 my $interfaceName = $dataNode->name; | |
| 751 my $name = $function->signature->name; | |
| 752 | |
| 753 if ($function->signature->extendedAttributes->{"Custom"} || | |
| 754 $function->signature->extendedAttributes->{"V8Custom"}) { | |
| 755 if ($function->signature->extendedAttributes->{"Custom"} && | |
| 756 $function->signature->extendedAttributes->{"V8Custom"}) { | |
| 757 die "Custom and V8Custom should be mutually exclusive!" | |
| 758 } | |
| 759 my $customFunc = $function->signature->extendedAttributes->{"Custom"} || | |
| 760 $function->signature->extendedAttributes->{"V8Custom"}; | |
| 761 if ($customFunc eq 1) { | |
| 762 $customFunc = $interfaceName . WK_ucfirst($name); | |
| 763 } | |
| 764 return "v8::FunctionTemplate::New(V8Custom::v8${customFunc}Callback, v8::Han
dle<v8::Value>(), $signature)"; | |
| 765 } else { | |
| 766 return "v8::FunctionTemplate::New(${interfaceName}Internal::${name}Callback,
v8::Handle<v8::Value>(), $signature)"; | |
| 767 } | |
| 768 } | |
| 769 | |
| 770 | |
| 771 sub GenerateFunctionCallback | |
| 772 { | |
| 773 my $function = shift; | |
| 774 my $dataNode = shift; | |
| 775 my $classIndex = shift; | |
| 776 my $implClassName = shift; | |
| 777 | |
| 778 my $interfaceName = $dataNode->name; | |
| 779 my $name = $function->signature->name; | |
| 780 | |
| 781 push(@implContentDecls, | |
| 782 " static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {\n"
. | |
| 783 " INC_STATS(\"DOM.$implClassName.$name\");\n"); | |
| 784 | |
| 785 my $numParameters = @{$function->parameters}; | |
| 786 | |
| 787 if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) { | |
| 788 push(@implContentDecls, | |
| 789 " if (args.Length() < $numParameters) return v8::Undefined();\n"); | |
| 790 } | |
| 791 | |
| 792 if ($codeGenerator->IsPodType($implClassName)) { | |
| 793 my $nativeClassName = GetNativeType($implClassName); | |
| 794 push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrap
per = V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<$nativeClassName> >(V8ClassInd
ex::$classIndex, args.Holder());\n"); | |
| 795 push(@implContentDecls, " $nativeClassName imp_instance = *imp_wrapper;\n
"); | |
| 796 push(@implContentDecls, " $nativeClassName* imp = &imp_instance;\n"); | |
| 797 } else { | |
| 798 push(@implContentDecls, <<END); | |
| 799 v8::Handle<v8::Value> holder = args.Holder(); | |
| 800 END | |
| 801 HolderToNative($dataNode, $implClassName, $classIndex); | |
| 802 } | |
| 803 | |
| 804 # Check domain security if needed | |
| 805 if (($dataNode->extendedAttributes->{"CheckDomainSecurity"} | |
| 806 || $interfaceName eq "DOMWindow") | |
| 807 && !$function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"})
{ | |
| 808 # We have not find real use cases yet. | |
| 809 push(@implContentDecls, | |
| 810 " if (!V8Proxy::CanAccessFrame(imp->frame(), true)) {\n". | |
| 811 " return v8::Undefined();\n" . | |
| 812 " }\n"); | |
| 813 } | |
| 814 | |
| 815 | |
| 816 if (@{$function->raisesExceptions}) { | |
| 817 $implIncludes{"ExceptionCode.h"} = 1; | |
| 818 push(@implContentDecls, " ExceptionCode ec = 0;\n"); | |
| 819 } | |
| 820 | |
| 821 if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) { | |
| 822 push(@implContentDecls, " ScriptCallStack callStack(args, $numParameters)
;\n"); | |
| 823 $implIncludes{"ScriptCallStack.h"} = 1; | |
| 824 } | |
| 825 | |
| 826 my $paramIndex = 0; | |
| 827 foreach my $parameter (@{$function->parameters}) { | |
| 828 TranslateParameter($parameter); | |
| 829 | |
| 830 my $parameterName = $parameter->name; | |
| 831 | |
| 832 if ($parameter->extendedAttributes->{"Optional"}) { | |
| 833 # Generate early call if there are not enough parameters. | |
| 834 push(@implContentDecls, " if (args.Length() <= $paramIndex) {\n"); | |
| 835 my $functionCall = GenerateFunctionCallString($function, $paramIndex, "
" x 2, $implClassName); | |
| 836 push(@implContentDecls, $functionCall); | |
| 837 push(@implContentDecls, " }\n"); | |
| 838 } | |
| 839 | |
| 840 if (BasicTypeCanFailConversion($parameter)) { | |
| 841 push(@implContentDecls, " bool ${parameterName}Ok;\n"); | |
| 842 } | |
| 843 | |
| 844 push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, 1) .
" $parameterName = "); | |
| 845 push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]", | |
| 846 BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : unde
f) . ";\n"); | |
| 847 | |
| 848 if (TypeCanFailConversion($parameter)) { | |
| 849 $implIncludes{"ExceptionCode.h"} = 1; | |
| 850 push(@implContentDecls, | |
| 851 " if (!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "")
. ") {\n" . | |
| 852 " V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);\n" . | |
| 853 " return v8::Handle<v8::Value>();\n" . | |
| 854 " }\n"); | |
| 855 } | |
| 856 | |
| 857 if ($parameter->extendedAttributes->{"IsIndex"}) { | |
| 858 $implIncludes{"ExceptionCode.h"} = 1; | |
| 859 push(@implContentDecls, | |
| 860 " if ($parameterName < 0) {\n" . | |
| 861 " V8Proxy::SetDOMException(INDEX_SIZE_ERR);\n" . | |
| 862 " return v8::Handle<v8::Value>();\n" . | |
| 863 " }\n"); | |
| 864 } | |
| 865 | |
| 866 $paramIndex++; | |
| 867 } | |
| 868 | |
| 869 # Build the function call string. | |
| 870 my $callString = GenerateFunctionCallString($function, $paramIndex, " ", $i
mplClassName); | |
| 871 push(@implContentDecls, "$callString"); | |
| 872 push(@implContentDecls, " }\n\n"); | |
| 873 } | |
| 874 | |
| 875 | |
| 876 sub GenerateBatchedAttributeData | |
| 877 { | |
| 878 my $interfaceName = shift; | |
| 879 my $attributes = shift; | |
| 880 | |
| 881 foreach my $attribute (@$attributes) { | |
| 882 my $attrName = $attribute->signature->name; | |
| 883 my $attrExt = $attribute->signature->extendedAttributes; | |
| 884 | |
| 885 my $accessControl = "v8::DEFAULT"; | |
| 886 if ($attrExt->{"DoNotCheckDomainSecurityOnGet"}) { | |
| 887 $accessControl = "v8::ALL_CAN_READ"; | |
| 888 } elsif ($attrExt->{"DoNotCheckDomainSecurityOnSet"}) { | |
| 889 $accessControl = "v8::ALL_CAN_WRITE"; | |
| 890 } elsif ($attrExt->{"DoNotCheckDomainSecurity"}) { | |
| 891 $accessControl = "v8::ALL_CAN_READ"; | |
| 892 if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) { | |
| 893 $accessControl .= "|v8::ALL_CAN_WRITE"; | |
| 894 } | |
| 895 } | |
| 896 if ($attrExt->{"V8DisallowShadowing"}) { | |
| 897 $accessControl .= "|v8::PROHIBITS_OVERWRITING"; | |
| 898 } | |
| 899 $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")"; | |
| 900 | |
| 901 | |
| 902 my $customAccessor = | |
| 903 $attrExt->{"Custom"} || | |
| 904 $attrExt->{"CustomSetter"} || | |
| 905 $attrExt->{"CustomGetter"} || | |
| 906 $attrExt->{"V8Custom"} || | |
| 907 $attrExt->{"V8CustomSetter"} || | |
| 908 $attrExt->{"V8CustomGetter"} || | |
| 909 ""; | |
| 910 if ($customAccessor eq 1) { | |
| 911 # use the naming convension, interface + (capitalize) attr name | |
| 912 $customAccessor = $interfaceName . WK_ucfirst($attrName); | |
| 913 } | |
| 914 | |
| 915 my $getter; | |
| 916 my $setter; | |
| 917 my $propAttr = "v8::None"; | |
| 918 my $hasCustomSetter = 0; | |
| 919 | |
| 920 # Check attributes. | |
| 921 if ($attrExt->{"DontEnum"}) { | |
| 922 $propAttr .= "|v8::DontEnum"; | |
| 923 } | |
| 924 if ($attrExt->{"V8DisallowShadowing"}) { | |
| 925 $propAttr .= "|v8::DontDelete"; | |
| 926 } | |
| 927 | |
| 928 my $on_proto = "0 /* on instance */"; | |
| 929 my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */"; | |
| 930 | |
| 931 # Constructor | |
| 932 if ($attribute->signature->type =~ /Constructor$/) { | |
| 933 my $constructorType = $codeGenerator->StripModule($attribute->signature->t
ype); | |
| 934 $constructorType =~ s/Constructor$//; | |
| 935 my $constructorIndex = uc($constructorType); | |
| 936 $data = "V8ClassIndex::${constructorIndex}"; | |
| 937 $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter"; | |
| 938 $setter = "0"; | |
| 939 $propAttr = "v8::ReadOnly"; | |
| 940 | |
| 941 # EventListeners | |
| 942 } elsif ($attribute->signature->type eq "EventListener") { | |
| 943 if ($interfaceName eq "DOMWindow") { | |
| 944 $getter = "V8Custom::v8DOMWindowEventHandlerAccessorGetter"; | |
| 945 $setter = "V8Custom::v8DOMWindowEventHandlerAccessorSetter"; | |
| 946 } elsif ($interfaceName eq "Element" || $interfaceName eq "Document" || $i
nterfaceName eq "HTMLBodyElement" || $interfaceName eq "SVGElementInstance" || $
interfaceName eq "HTMLFrameSetElement") { | |
| 947 $getter = "V8Custom::v8ElementEventHandlerAccessorGetter"; | |
| 948 $setter = "V8Custom::v8ElementEventHandlerAccessorSetter"; | |
| 949 } else { | |
| 950 $getter = "V8Custom::v8${customAccessor}AccessorGetter"; | |
| 951 if ($interfaceName eq "WorkerContext" and $attrName eq "self") { | |
| 952 $setter = "0"; | |
| 953 $propAttr = "v8::ReadOnly"; | |
| 954 } else { | |
| 955 $setter = "V8Custom::v8${customAccessor}AccessorSetter"; | |
| 956 } | |
| 957 } | |
| 958 | |
| 959 # Custom Getter and Setter | |
| 960 } elsif ($attrExt->{"Custom"} || $attrExt->{"V8Custom"}) { | |
| 961 $getter = "V8Custom::v8${customAccessor}AccessorGetter"; | |
| 962 if ($interfaceName eq "WorkerContext" and $attrName eq "self") { | |
| 963 $setter = "0"; | |
| 964 $propAttr = "v8::ReadOnly"; | |
| 965 } else { | |
| 966 $hasCustomSetter = 1; | |
| 967 $setter = "V8Custom::v8${customAccessor}AccessorSetter"; | |
| 968 } | |
| 969 | |
| 970 # Custom Setter | |
| 971 } elsif ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"}) { | |
| 972 $hasCustomSetter = 1; | |
| 973 $getter = "${interfaceName}Internal::${attrName}AttrGetter"; | |
| 974 $setter = "V8Custom::v8${customAccessor}AccessorSetter"; | |
| 975 | |
| 976 # Custom Getter | |
| 977 } elsif ($attrExt->{"CustomGetter"}) { | |
| 978 $getter = "V8Custom::v8${customAccessor}AccessorGetter"; | |
| 979 $setter = "${interfaceName}Internal::${attrName}AttrSetter"; | |
| 980 | |
| 981 # Replaceable | |
| 982 } elsif ($attrExt->{"Replaceable"}) { | |
| 983 # Replaceable accessor is put on instance template with ReadOnly attribute
. | |
| 984 $getter = "${interfaceName}Internal::${attrName}AttrGetter"; | |
| 985 $setter = "0"; | |
| 986 | |
| 987 # Mark to avoid duplicate v8::ReadOnly flags in output. | |
| 988 $hasCustomSetter = 1; | |
| 989 | |
| 990 # Handle the special case of window.top being marked upstream as Replaceab
le. | |
| 991 # TODO(dglazkov): Investigate why [Replaceable] is not marked as ReadOnly | |
| 992 # upstream and reach parity. | |
| 993 if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) { | |
| 994 $propAttr .= "|v8::ReadOnly"; | |
| 995 } | |
| 996 | |
| 997 # Normal | |
| 998 } else { | |
| 999 $getter = "${interfaceName}Internal::${attrName}AttrGetter"; | |
| 1000 $setter = "${interfaceName}Internal::${attrName}AttrSetter"; | |
| 1001 } | |
| 1002 | |
| 1003 if ($attrExt->{"Replaceable"} && !$hasCustomSetter) { | |
| 1004 $setter = "0"; | |
| 1005 $propAttr .= "|v8::ReadOnly"; | |
| 1006 } | |
| 1007 | |
| 1008 # Read only attributes | |
| 1009 if ($attribute->type =~ /^readonly/ || $attrExt->{"V8ReadOnly"}) { | |
| 1010 $setter = "0"; | |
| 1011 } | |
| 1012 | |
| 1013 # An accessor can be installed on the proto | |
| 1014 if ($attrExt->{"v8OnProto"}) { | |
| 1015 $on_proto = "1 /* on proto */"; | |
| 1016 } | |
| 1017 | |
| 1018 my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type . | |
| 1019 "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')"; | |
| 1020 push(@implContent, <<END); | |
| 1021 // $commentInfo | |
| 1022 { "$attrName", | |
| 1023 $getter, | |
| 1024 $setter, | |
| 1025 $data, | |
| 1026 $accessControl, | |
| 1027 static_cast<v8::PropertyAttribute>($propAttr), | |
| 1028 $on_proto }, | |
| 1029 END | |
| 1030 } | |
| 1031 } | |
| 1032 | |
| 1033 | |
| 1034 sub GenerateImplementation | |
| 1035 { | |
| 1036 my $object = shift; | |
| 1037 my $dataNode = shift; | |
| 1038 my $interfaceName = $dataNode->name; | |
| 1039 my $className = "V8$interfaceName"; | |
| 1040 my $implClassName = $interfaceName; | |
| 1041 my $classIndex = uc($codeGenerator->StripModule($interfaceName)); | |
| 1042 | |
| 1043 my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"}; | |
| 1044 my $conditional = $dataNode->extendedAttributes->{"Conditional"}; | |
| 1045 | |
| 1046 @allParents = $codeGenerator->FindParentsRecursively($dataNode); | |
| 1047 | |
| 1048 # - Add default header template | |
| 1049 @implContentHeader = split("\r", $headerTemplate); | |
| 1050 | |
| 1051 push(@implFixedHeader, | |
| 1052 "#include \"config.h\"\n" . | |
| 1053 "#include \"v8_proxy.h\"\n" . | |
| 1054 "#include \"v8_binding.h\"\n\n" . | |
| 1055 "#undef LOG\n\n"); | |
| 1056 | |
| 1057 my $conditionalString; | |
| 1058 if ($conditional) { | |
| 1059 $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $condit
ional)) . ")"; | |
| 1060 push(@implFixedHeader, "\n#if ${conditionalString}\n\n"); | |
| 1061 } | |
| 1062 | |
| 1063 if ($className =~ /^V8SVGAnimated/) { | |
| 1064 AddIncludesForSVGAnimatedType($interfaceName); | |
| 1065 } | |
| 1066 | |
| 1067 $implIncludes{"${className}.h"} = 1; | |
| 1068 | |
| 1069 AddIncludesForType($interfaceName); | |
| 1070 $implIncludes{"v8_proxy.h"} = 1; | |
| 1071 | |
| 1072 push(@implContentDecls, "namespace WebCore {\n"); | |
| 1073 push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n"); | |
| 1074 push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n"); | |
| 1075 | |
| 1076 my $hasConstructors = 0; | |
| 1077 | |
| 1078 # Generate property accessors for attributes. | |
| 1079 for ($index = 0; $index < @{$dataNode->attributes}; $index++) { | |
| 1080 $attribute = @{$dataNode->attributes}[$index]; | |
| 1081 $attrName = $attribute->signature->name; | |
| 1082 $attrType = $attribute->signature->type; | |
| 1083 | |
| 1084 # Generate special code for the constructor attributes. | |
| 1085 if ($attrType =~ /Constructor$/) { | |
| 1086 $hasConstructors = 1; | |
| 1087 next; | |
| 1088 } | |
| 1089 | |
| 1090 # Make EventListeners always custom. | |
| 1091 # TODO(mbelshe): make the perl code capable of generating the | |
| 1092 # event setters/getters. For now, WebKit has started removing the | |
| 1093 # [Custom] attribute, so just automatically insert it to avoid forking | |
| 1094 # other files. This should be okay because we can't generate stubs | |
| 1095 # for any event getter/setters anyway. | |
| 1096 if ($attrType eq "EventListener") { | |
| 1097 $attribute->signature->extendedAttributes->{"Custom"} = 1; | |
| 1098 $implIncludes{"V8CustomBinding.h"} = 1; | |
| 1099 next; | |
| 1100 } | |
| 1101 | |
| 1102 # Do not generate accessor if this is a custom attribute. The | |
| 1103 # call will be forwarded to a hand-written accessor | |
| 1104 # implementation. | |
| 1105 if ($attribute->signature->extendedAttributes->{"Custom"} || | |
| 1106 $attribute->signature->extendedAttributes->{"V8Custom"}) { | |
| 1107 $implIncludes{"V8CustomBinding.h"} = 1; | |
| 1108 next; | |
| 1109 } | |
| 1110 | |
| 1111 # Generate the accessor. | |
| 1112 if ($attribute->signature->extendedAttributes->{"CustomGetter"}) { | |
| 1113 $implIncludes{"V8CustomBinding.h"} = 1; | |
| 1114 } else { | |
| 1115 GenerateNormalAttrGetter($attribute, $dataNode, $classIndex, $implCl
assName); | |
| 1116 } | |
| 1117 if ($attribute->signature->extendedAttributes->{"CustomSetter"} || | |
| 1118 $attribute->signature->extendedAttributes->{"V8CustomSetter"}) { | |
| 1119 $implIncludes{"V8CustomBinding.h"} = 1; | |
| 1120 } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) { | |
| 1121 $dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"} || die "Replac
eable attribute can only be used in interface that defines ExtendsDOMGlobalObjec
t attribute!"; | |
| 1122 # GenerateReplaceableAttrSetter($implClassName); | |
| 1123 } elsif ($attribute->type !~ /^readonly/ && | |
| 1124 !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) { | |
| 1125 GenerateNormalAttrSetter($attribute, $dataNode, $classIndex, $implClassN
ame); | |
| 1126 } | |
| 1127 } | |
| 1128 | |
| 1129 if ($hasConstructors) { | |
| 1130 GenerateConstructorGetter($implClassName, $classIndex); | |
| 1131 } | |
| 1132 | |
| 1133 # Generate methods for functions. | |
| 1134 foreach my $function (@{$dataNode->functions}) { | |
| 1135 # hack for addEventListener/RemoveEventListener | |
| 1136 # TODO(fqian): avoid naming conflict | |
| 1137 if ($function->signature->extendedAttributes->{"Custom"} || | |
| 1138 $function->signature->extendedAttributes->{"V8Custom"}) { | |
| 1139 $implIncludes{"V8CustomBinding.h"} = 1; | |
| 1140 | |
| 1141 } else { | |
| 1142 GenerateFunctionCallback($function, $dataNode, $classIndex, $implClassNa
me); | |
| 1143 } | |
| 1144 | |
| 1145 | |
| 1146 # If the function does not need domain security check, we need to | |
| 1147 # generate an access getter that returns different function objects | |
| 1148 # for different calling context. | |
| 1149 if (($dataNode->extendedAttributes->{"CheckDomainSecurity"} | |
| 1150 || ($interfaceName eq "DOMWindow")) | |
| 1151 && $function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"
}){ | |
| 1152 GenerateDomainSafeFunctionGetter($function, $dataNode, $classIndex, $imp
lClassName); | |
| 1153 } | |
| 1154 } | |
| 1155 | |
| 1156 # Attributes | |
| 1157 my $attributes = $dataNode->attributes; | |
| 1158 | |
| 1159 # For the DOMWindow interface we partition the attributes into the | |
| 1160 # ones that disallows shadowing and the rest. | |
| 1161 my @disallows_shadowing; | |
| 1162 my @normal; | |
| 1163 if ($interfaceName eq "DOMWindow") { | |
| 1164 foreach my $attribute (@$attributes) { | |
| 1165 if ($attribute->signature->extendedAttributes->{"V8DisallowShadowing"})
{ | |
| 1166 push(@disallows_shadowing, $attribute); | |
| 1167 } else { | |
| 1168 push(@normal, $attribute); | |
| 1169 } | |
| 1170 } | |
| 1171 # Put the attributes that disallow shadowing on the shadow object. | |
| 1172 $attributes = \@normal; | |
| 1173 push(@implContent, "static const BatchedAttribute shadow_attrs[] = {\n"); | |
| 1174 GenerateBatchedAttributeData($interfaceName, \@disallows_shadowing); | |
| 1175 push(@implContent, "};\n"); | |
| 1176 | |
| 1177 } | |
| 1178 | |
| 1179 my $has_attributes = 0; | |
| 1180 if (@$attributes) { | |
| 1181 $has_attributes = 1; | |
| 1182 push(@implContent, "static const BatchedAttribute attrs[] = {\n"); | |
| 1183 GenerateBatchedAttributeData($interfaceName, $attributes); | |
| 1184 push(@implContent, "};\n"); | |
| 1185 } | |
| 1186 | |
| 1187 # Setup constants | |
| 1188 my $has_constants = 0; | |
| 1189 if (@{$dataNode->constants}) { | |
| 1190 $has_constants = 1; | |
| 1191 push(@implContent, "static const BatchedConstant consts[] = {\n"); | |
| 1192 } | |
| 1193 foreach my $constant (@{$dataNode->constants}) { | |
| 1194 my $name = $constant->name; | |
| 1195 my $value = $constant->value; | |
| 1196 # TODO we need the static_cast here only because of one constant, NodeFilt
er.idl | |
| 1197 # defines "const unsigned long SHOW_ALL = 0xFFFFFFFF". It would be better
if we | |
| 1198 # handled this here, and converted it to a -1 constant in the c++ output. | |
| 1199 push(@implContent, <<END); | |
| 1200 { "${name}", static_cast<signed int>($value) }, | |
| 1201 END | |
| 1202 } | |
| 1203 if ($has_constants) { | |
| 1204 push(@implContent, "};\n"); | |
| 1205 } | |
| 1206 | |
| 1207 push(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n"); | |
| 1208 | |
| 1209 my $access_check = "/* no access check */"; | |
| 1210 if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && | |
| 1211 !($interfaceName eq "DOMWindow")) { | |
| 1212 $access_check = "instance->SetAccessCheckCallbacks(V8Custom::v8${interface
Name}NamedSecurityCheck, V8Custom::v8${interfaceName}IndexedSecurityCheck, v8::I
nteger::New(V8ClassIndex::ToInt(V8ClassIndex::${classIndex})));"; | |
| 1213 } | |
| 1214 | |
| 1215 # For the DOMWindow interface, generate the shadow object template | |
| 1216 # configuration method. | |
| 1217 if ($implClassName eq "DOMWindow") { | |
| 1218 push(@implContent, <<END); | |
| 1219 static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Pers
istent<v8::ObjectTemplate> templ) { | |
| 1220 BatchConfigureAttributes(templ, | |
| 1221 v8::Handle<v8::ObjectTemplate>(), | |
| 1222 shadow_attrs, | |
| 1223 sizeof(shadow_attrs)/sizeof(*shadow_attrs)); | |
| 1224 return templ; | |
| 1225 } | |
| 1226 END | |
| 1227 } | |
| 1228 | |
| 1229 # Generate the template configuration method | |
| 1230 push(@implContent, <<END); | |
| 1231 static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Pe
rsistent<v8::FunctionTemplate> desc) { | |
| 1232 v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate(); | |
| 1233 instance->SetInternalFieldCount(2); | |
| 1234 v8::Local<v8::Signature> default_signature = v8::Signature::New(desc); | |
| 1235 v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate(); | |
| 1236 $access_check | |
| 1237 END | |
| 1238 | |
| 1239 | |
| 1240 # Set up our attributes if we have them | |
| 1241 if ($has_attributes) { | |
| 1242 push(@implContent, <<END); | |
| 1243 BatchConfigureAttributes(instance, proto, attrs, sizeof(attrs)/sizeof(*attrs))
; | |
| 1244 END | |
| 1245 } | |
| 1246 | |
| 1247 # Define our functions with Set() or SetAccessor() | |
| 1248 foreach my $function (@{$dataNode->functions}) { | |
| 1249 my $attrExt = $function->signature->extendedAttributes; | |
| 1250 my $name = $function->signature->name; | |
| 1251 | |
| 1252 my $property_attributes = "v8::DontDelete"; | |
| 1253 if ($attrExt->{"DontEnum"}) { | |
| 1254 $property_attributes .= "|v8::DontEnum"; | |
| 1255 } | |
| 1256 if ($attrExt->{"V8ReadOnly"}) { | |
| 1257 $property_attributes .= "|v8::ReadOnly"; | |
| 1258 } | |
| 1259 | |
| 1260 my $commentInfo = "Function '$name' (ExtAttr: '" . join(' ', keys(%{$attrE
xt})) . "')"; | |
| 1261 | |
| 1262 my $template = "proto"; | |
| 1263 if ($attrExt->{"V8OnInstance"}) { | |
| 1264 $template = "instance"; | |
| 1265 } | |
| 1266 | |
| 1267 if ($attrExt->{"DoNotCheckDomainSecurity"} && | |
| 1268 ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceN
ame eq "DOMWindow")) { | |
| 1269 # Mark the accessor as ReadOnly and set it on the proto object so | |
| 1270 # it can be shadowed. This is really a hack to make it work. | |
| 1271 # There are several sceneria to call into the accessor: | |
| 1272 # 1) from the same domain: "window.open": | |
| 1273 # the accessor finds the DOM wrapper in the proto chain; | |
| 1274 # 2) from the same domain: "window.__proto__.open": | |
| 1275 # the accessor will NOT find a DOM wrapper in the prototype chain | |
| 1276 # 3) from another domain: "window.open": | |
| 1277 # the access find the DOM wrapper in the prototype chain | |
| 1278 # "window.__proto__.open" from another domain will fail when | |
| 1279 # accessing '__proto__' | |
| 1280 # | |
| 1281 # The solution is very hacky and fragile, it really needs to be replaced | |
| 1282 # by a better solution. | |
| 1283 $property_attributes .= "|v8::ReadOnly"; | |
| 1284 push(@implContent, <<END); | |
| 1285 | |
| 1286 // $commentInfo | |
| 1287 $template->SetAccessor( | |
| 1288 v8::String::New("$name"), | |
| 1289 ${interfaceName}Internal::${name}AttrGetter, | |
| 1290 0, | |
| 1291 v8::Handle<v8::Value>(), | |
| 1292 v8::ALL_CAN_READ, | |
| 1293 static_cast<v8::PropertyAttribute>($property_attributes)); | |
| 1294 END | |
| 1295 next; | |
| 1296 } | |
| 1297 | |
| 1298 my $signature = "default_signature"; | |
| 1299 if ($attrExt->{"V8DoNotCheckSignature"}){ | |
| 1300 $signature = "v8::Local<v8::Signature>()"; | |
| 1301 } | |
| 1302 | |
| 1303 if (RequiresCustomSignature($function)) { | |
| 1304 $signature = "${name}_signature"; | |
| 1305 push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSign
ature($function)); | |
| 1306 } | |
| 1307 | |
| 1308 # Normal function call is a template | |
| 1309 my $templateFunction = GenerateNewFunctionTemplate($function, $dataNode, $
signature); | |
| 1310 | |
| 1311 | |
| 1312 push(@implContent, <<END); | |
| 1313 | |
| 1314 // $commentInfo | |
| 1315 ${template}->Set( | |
| 1316 v8::String::New("$name"), | |
| 1317 $templateFunction, | |
| 1318 static_cast<v8::PropertyAttribute>($property_attributes)); | |
| 1319 END | |
| 1320 } | |
| 1321 | |
| 1322 # set the super descriptor | |
| 1323 foreach (@{$dataNode->parents}) { | |
| 1324 my $parent = $codeGenerator->StripModule($_); | |
| 1325 if ($parent eq "EventTarget") { next; } | |
| 1326 $implIncludes{"V8${parent}.h"} = 1; | |
| 1327 my $parentClassIndex = uc($codeGenerator->StripModule($parent)); | |
| 1328 push(@implContent, " desc->Inherit(V8Proxy::GetTemplate(V8ClassIndex::${p
arentClassIndex}));\n"); | |
| 1329 last; | |
| 1330 } | |
| 1331 | |
| 1332 # Set the class name. This is used when printing objects. | |
| 1333 push(@implContent, " desc->SetClassName(v8::String::New(\"" . GetClassName(
${interfaceName}) . "\"));\n"); | |
| 1334 | |
| 1335 if ($has_constants) { | |
| 1336 push(@implContent, <<END); | |
| 1337 BatchConfigureConstants(desc, proto, consts, sizeof(consts)/sizeof(*consts)); | |
| 1338 END | |
| 1339 } | |
| 1340 | |
| 1341 push(@implContent, <<END); | |
| 1342 return desc; | |
| 1343 } | |
| 1344 | |
| 1345 v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() { | |
| 1346 static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_; | |
| 1347 if (${className}_raw_cache_.IsEmpty()) { | |
| 1348 v8::HandleScope scope; | |
| 1349 v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(V8Proxy::
CheckNewLegal); | |
| 1350 ${className}_raw_cache_ = v8::Persistent<v8::FunctionTemplate>::New(result); | |
| 1351 } | |
| 1352 return ${className}_raw_cache_; | |
| 1353 } | |
| 1354 | |
| 1355 v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() { | |
| 1356 static v8::Persistent<v8::FunctionTemplate> ${className}_cache_; | |
| 1357 if (${className}_cache_.IsEmpty()) | |
| 1358 ${className}_cache_ = Configure${className}Template(GetRawTemplate()); | |
| 1359 return ${className}_cache_; | |
| 1360 } | |
| 1361 | |
| 1362 bool ${className}::HasInstance(v8::Handle<v8::Value> value) { | |
| 1363 return GetRawTemplate()->HasInstance(value); | |
| 1364 } | |
| 1365 | |
| 1366 END | |
| 1367 | |
| 1368 if ($implClassName eq "DOMWindow") { | |
| 1369 push(@implContent, <<END); | |
| 1370 v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate() { | |
| 1371 static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_; | |
| 1372 if (V8DOMWindowShadowObject_cache_.IsEmpty()) { | |
| 1373 V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8:
:ObjectTemplate::New()); | |
| 1374 ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_); | |
| 1375 } | |
| 1376 return V8DOMWindowShadowObject_cache_; | |
| 1377 } | |
| 1378 END | |
| 1379 } | |
| 1380 | |
| 1381 push(@implContent, <<END); | |
| 1382 } // namespace WebCore | |
| 1383 END | |
| 1384 | |
| 1385 push(@implContent, "\n#endif // ${conditionalString}\n") if $conditional; | |
| 1386 } | |
| 1387 | |
| 1388 | |
| 1389 sub GenerateFunctionCallString() | |
| 1390 { | |
| 1391 my $function = shift; | |
| 1392 my $numberOfParameters = shift; | |
| 1393 my $indent = shift; | |
| 1394 my $implClassName = shift; | |
| 1395 | |
| 1396 my $name = $function->signature->name; | |
| 1397 my $isPodType = $codeGenerator->IsPodType($implClassName); | |
| 1398 my $returnType = $codeGenerator->StripModule($function->signature->type); | |
| 1399 my $returnsPodType = $codeGenerator->IsPodType($returnType); | |
| 1400 my $nativeReturnType = GetNativeType($returnType, 0); | |
| 1401 my $result = ""; | |
| 1402 | |
| 1403 # Special case: SVG matrix transform methods should not mutate | |
| 1404 # the matrix but return a copy | |
| 1405 my $copyFirst = 0; | |
| 1406 if ($implClassName eq "SVGMatrix" && $function->signature->type eq "SVGMatrix"
) { | |
| 1407 $copyFirst = 1; | |
| 1408 } | |
| 1409 | |
| 1410 if ($function->signature->extendedAttributes->{"v8implname"}) { | |
| 1411 $name = $function->signature->extendedAttributes->{"v8implname"}; | |
| 1412 } | |
| 1413 | |
| 1414 if ($function->signature->extendedAttributes->{"ImplementationFunction"}) { | |
| 1415 $name = $function->signature->extendedAttributes->{"ImplementationFunction"}
; | |
| 1416 } | |
| 1417 | |
| 1418 my $functionString = "imp->${name}("; | |
| 1419 | |
| 1420 if ($copyFirst) { | |
| 1421 $functionString = "result.${name}("; | |
| 1422 } | |
| 1423 | |
| 1424 my $returnsListItemPodType = 0; | |
| 1425 # SVG lists functions that return POD types require special handling | |
| 1426 if (IsSVGListTypeNeedingSpecialHandling($implClassName) && IsSVGListMethod($na
me) && $returnsPodType) { | |
| 1427 $returnsListItemPodType = 1; | |
| 1428 $result .= $indent . "SVGList<RefPtr<SVGPODListItem<$nativeReturnType> > >*
listImp = imp;\n"; | |
| 1429 $functionString = "listImp->${name}("; | |
| 1430 } | |
| 1431 | |
| 1432 my $first = 1; | |
| 1433 my $index = 0; | |
| 1434 my $nodeToReturn = 0; | |
| 1435 | |
| 1436 foreach my $parameter (@{$function->parameters}) { | |
| 1437 if ($index eq $numberOfParameters) { | |
| 1438 last; | |
| 1439 } | |
| 1440 if ($first) { $first = 0; } | |
| 1441 else { $functionString .= ", "; } | |
| 1442 my $paramName = $parameter->name; | |
| 1443 my $paramType = $parameter->type; | |
| 1444 | |
| 1445 # This is a bit of a hack... we need to convert parameters to methods on SVG
lists | |
| 1446 # of POD types which are items in the list to appropriate SVGList<> instance
s | |
| 1447 if ($returnsListItemPodType && $paramType . "List" eq $implClassName) { | |
| 1448 $paramName = "SVGPODListItem<" . GetNativeType($paramType, 1) . ">::copy($
paramName)"; | |
| 1449 } | |
| 1450 | |
| 1451 if ($parameter->type eq "NodeFilter") { | |
| 1452 $functionString .= "$paramName.get()"; | |
| 1453 } else { | |
| 1454 $functionString .= $paramName; | |
| 1455 } | |
| 1456 | |
| 1457 if ($parameter->extendedAttributes->{"Return"}) { | |
| 1458 $nodeToReturn = $parameter->name; | |
| 1459 } | |
| 1460 $index++; | |
| 1461 } | |
| 1462 | |
| 1463 if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) { | |
| 1464 $functionString .= ", " if not $first; | |
| 1465 $functionString .= "&callStack"; | |
| 1466 if ($first) { $first = 0; } | |
| 1467 } | |
| 1468 | |
| 1469 if (@{$function->raisesExceptions}) { | |
| 1470 $functionString .= ", " if not $first; | |
| 1471 $functionString .= "ec"; | |
| 1472 } | |
| 1473 $functionString .= ")"; | |
| 1474 | |
| 1475 if ((IsRefPtrType($returnType) || $returnsListItemPodType) && | |
| 1476 !$nodeToReturn) { | |
| 1477 # We don't use getPtr when $nodeToReturn because that situation is | |
| 1478 # special-cased below to return a bool. | |
| 1479 $implIncludes{"wtf/GetPtr.h"} = 1; | |
| 1480 $functionString = "WTF::getPtr(" . $functionString . ")"; | |
| 1481 } | |
| 1482 | |
| 1483 if ($nodeToReturn) { | |
| 1484 # Special case for insertBefore, replaceChild, removeChild and | |
| 1485 # appendChild functions from Node. | |
| 1486 $result .= $indent . "bool success = $functionString;\n"; | |
| 1487 if (@{$function->raisesExceptions}) { | |
| 1488 $result .= GenerateSetDOMException($indent); | |
| 1489 } | |
| 1490 $result .= $indent . "if (success)\n"; | |
| 1491 $result .= $indent . " " . | |
| 1492 "return V8Proxy::NodeToV8Object($nodeToReturn);\n"; | |
| 1493 $result .= $indent . "return v8::Null();\n"; | |
| 1494 return $result; | |
| 1495 } elsif ($returnType eq "void") { | |
| 1496 $result .= $indent . "$functionString;\n"; | |
| 1497 } elsif ($copyFirst) { | |
| 1498 $result .= | |
| 1499 $indent . GetNativeType($returnType, 0) . " result = *imp;\n" . | |
| 1500 $indent . "$functionString;\n"; | |
| 1501 } elsif ($returnsListItemPodType) { | |
| 1502 $result .= $indent . "RefPtr<SVGPODListItem<$nativeReturnType> > result = $f
unctionString;\n"; | |
| 1503 } else { | |
| 1504 $result .= $indent . $nativeReturnType . " result = $functionString;\n"; | |
| 1505 } | |
| 1506 | |
| 1507 if (@{$function->raisesExceptions}) { | |
| 1508 $result .= GenerateSetDOMException($indent); | |
| 1509 } | |
| 1510 | |
| 1511 my $return = "result"; | |
| 1512 if (IsRefPtrType($returnType) || $returnsListItemPodType) { | |
| 1513 $implIncludes{"wtf/GetPtr.h"} = 1; | |
| 1514 $return = "WTF::getPtr(" . $return . ")"; | |
| 1515 } | |
| 1516 | |
| 1517 # If the return type is a POD type, separate out the wrapper generation | |
| 1518 if ($returnsListItemPodType) { | |
| 1519 $result .= $indent . "V8SVGPODTypeWrapper<" . $nativeReturnType . ">* wrappe
r = new "; | |
| 1520 $result .= "V8SVGPODTypeWrapperCreatorForList<" . $nativeReturnType . ">($re
turn, imp->associatedAttributeName());\n"; | |
| 1521 $return = "wrapper"; | |
| 1522 } elsif ($returnsPodType) { | |
| 1523 $result .= $indent . "V8SVGPODTypeWrapper<" . $nativeReturnType . ">* wrappe
r = "; | |
| 1524 $result .= GenerateSVGStaticPodTypeWrapper($returnType, $return) . ";\n"; | |
| 1525 $return = "wrapper"; | |
| 1526 } | |
| 1527 | |
| 1528 my $generatedSVGContextRetrieval = 0; | |
| 1529 # If the return type needs an SVG context, output it | |
| 1530 if (IsSVGTypeNeedingContextParameter($returnType)) { | |
| 1531 $result .= GenerateSVGContextAssignment($implClassName, $return, $indent); | |
| 1532 $generatedSVGContextRetrieval = 1; | |
| 1533 } | |
| 1534 | |
| 1535 if (IsSVGTypeNeedingContextParameter($implClassName) && $implClassName =~ /Lis
t$/ && IsSVGListMutator($name)) { | |
| 1536 if (!$generatedSVGContextRetrieval) { | |
| 1537 $result .= GenerateSVGContextRetrieval($implClassName, $indent); | |
| 1538 $generatedSVGContextRetrieval = 1; | |
| 1539 } | |
| 1540 | |
| 1541 $result .= $indent . "context->svgAttributeChanged(imp->associatedAttributeN
ame());\n"; | |
| 1542 $implIncludes{"SVGElement.h"} = 1; | |
| 1543 } | |
| 1544 | |
| 1545 # If the implementing class is a POD type, commit changes | |
| 1546 if ($isPodType) { | |
| 1547 if (!$generatedSVGContextRetrieval) { | |
| 1548 $result .= GenerateSVGContextRetrieval($implClassName, $indent); | |
| 1549 $generatedSVGContextRetrieval = 1; | |
| 1550 } | |
| 1551 | |
| 1552 $result .= $indent . "imp_wrapper->commitChange(imp_instance, context);\n"; | |
| 1553 } | |
| 1554 | |
| 1555 if ($returnsPodType) { | |
| 1556 my $classIndex = uc($returnType); | |
| 1557 $result .= $indent . "return V8Proxy::ToV8Object(V8ClassIndex::$classIndex,
wrapper);\n"; | |
| 1558 } else { | |
| 1559 $result .= $indent . "return " . NativeToJSValue($function->signature, $retu
rn) . ";\n"; | |
| 1560 } | |
| 1561 | |
| 1562 return $result; | |
| 1563 } | |
| 1564 | |
| 1565 | |
| 1566 # Get the class name used for printing javascript DOM-object wrappers. | |
| 1567 sub GetClassName | |
| 1568 { | |
| 1569 my $type = shift; | |
| 1570 return "HTMLCollection" if $type eq "UndetectableHTMLCollection"; | |
| 1571 return $type; | |
| 1572 } | |
| 1573 | |
| 1574 | |
| 1575 sub GetNativeTypeFromSignature | |
| 1576 { | |
| 1577 my $signature = shift; | |
| 1578 my $isParameter = shift; | |
| 1579 | |
| 1580 my $type = $codeGenerator->StripModule($signature->type); | |
| 1581 | |
| 1582 return GetNativeType($type, $isParameter); | |
| 1583 } | |
| 1584 | |
| 1585 sub IsRefPtrType | |
| 1586 { | |
| 1587 my $type = shift; | |
| 1588 return 1 if $type eq "Attr"; | |
| 1589 return 1 if $type eq "CanvasGradient"; | |
| 1590 return 1 if $type eq "ClientRect"; | |
| 1591 return 1 if $type eq "ClientRectList"; | |
| 1592 return 1 if $type eq "CDATASection"; | |
| 1593 return 1 if $type eq "Comment"; | |
| 1594 return 1 if $type eq "CSSRule"; | |
| 1595 return 1 if $type eq "CSSStyleRule"; | |
| 1596 return 1 if $type eq "CSSCharsetRule"; | |
| 1597 return 1 if $type eq "CSSImportRule"; | |
| 1598 return 1 if $type eq "CSSMediaRule"; | |
| 1599 return 1 if $type eq "CSSFontFaceRule"; | |
| 1600 return 1 if $type eq "CSSPageRule"; | |
| 1601 return 1 if $type eq "CSSPrimitiveValue"; | |
| 1602 return 1 if $type eq "CSSStyleSheet"; | |
| 1603 return 1 if $type eq "CSSStyleDeclaration"; | |
| 1604 return 1 if $type eq "CSSValue"; | |
| 1605 return 1 if $type eq "CSSRuleList"; | |
| 1606 return 1 if $type eq "Database"; | |
| 1607 return 1 if $type eq "Document"; | |
| 1608 return 1 if $type eq "DocumentFragment"; | |
| 1609 return 1 if $type eq "DocumentType"; | |
| 1610 return 1 if $type eq "Element"; | |
| 1611 return 1 if $type eq "EntityReference"; | |
| 1612 return 1 if $type eq "Event"; | |
| 1613 return 1 if $type eq "FileList"; | |
| 1614 return 1 if $type eq "HTMLCollection"; | |
| 1615 return 1 if $type eq "HTMLDocument"; | |
| 1616 return 1 if $type eq "HTMLElement"; | |
| 1617 return 1 if $type eq "HTMLOptionsCollection"; | |
| 1618 return 1 if $type eq "ImageData"; | |
| 1619 return 1 if $type eq "MediaError"; | |
| 1620 return 1 if $type eq "MimeType"; | |
| 1621 return 1 if $type eq "Node"; | |
| 1622 return 1 if $type eq "NodeList"; | |
| 1623 return 1 if $type eq "NodeFilter"; | |
| 1624 return 1 if $type eq "NodeIterator"; | |
| 1625 return 1 if $type eq "NSResolver"; | |
| 1626 return 1 if $type eq "Plugin"; | |
| 1627 return 1 if $type eq "ProcessingInstruction"; | |
| 1628 return 1 if $type eq "Range"; | |
| 1629 return 1 if $type eq "Text"; | |
| 1630 return 1 if $type eq "TextMetrics"; | |
| 1631 return 1 if $type eq "TimeRanges"; | |
| 1632 return 1 if $type eq "TreeWalker"; | |
| 1633 return 1 if $type eq "WebKitCSSMatrix"; | |
| 1634 return 1 if $type eq "WebKitPoint"; | |
| 1635 return 1 if $type eq "XPathExpression"; | |
| 1636 return 1 if $type eq "XPathNSResolver"; | |
| 1637 return 1 if $type eq "XPathResult"; | |
| 1638 | |
| 1639 return 1 if $type eq "SVGAngle"; | |
| 1640 return 1 if $type eq "SVGElementInstance"; | |
| 1641 return 1 if $type eq "SVGElementInstanceList"; | |
| 1642 return 1 if $type =~ /^SVGPathSeg/; | |
| 1643 | |
| 1644 return 1 if $type =~ /^SVGAnimated/; | |
| 1645 | |
| 1646 return 0; | |
| 1647 } | |
| 1648 | |
| 1649 sub IsVideoClassName | |
| 1650 { | |
| 1651 my $class = shift; | |
| 1652 return 1 if $class eq "V8HTMLAudioElement"; | |
| 1653 return 1 if $class eq "V8HTMLMediaElement"; | |
| 1654 return 1 if $class eq "V8HTMLSourceElement"; | |
| 1655 return 1 if $class eq "V8HTMLVideoElement"; | |
| 1656 return 1 if $class eq "V8MediaError"; | |
| 1657 return 1 if $class eq "V8TimeRanges"; | |
| 1658 | |
| 1659 return 0; | |
| 1660 } | |
| 1661 | |
| 1662 sub IsWorkerClassName | |
| 1663 { | |
| 1664 my $class = shift; | |
| 1665 return 1 if $class eq "V8Worker"; | |
| 1666 return 1 if $class eq "V8WorkerContext"; | |
| 1667 return 1 if $class eq "V8WorkerLocation"; | |
| 1668 return 1 if $class eq "V8WorkerNavigator"; | |
| 1669 | |
| 1670 return 0; | |
| 1671 } | |
| 1672 | |
| 1673 sub GetNativeType | |
| 1674 { | |
| 1675 my $type = shift; | |
| 1676 my $isParameter = shift; | |
| 1677 | |
| 1678 if ($type eq "float" or $type eq "AtomicString" or $type eq "double") { | |
| 1679 return $type | |
| 1680 } | |
| 1681 | |
| 1682 return "int" if $type eq "int"; | |
| 1683 return "int" if $type eq "short" or $type eq "unsigned short"; | |
| 1684 return "int" if $type eq "long" or $type eq "unsigned long"; | |
| 1685 return "unsigned long long" if $type eq "unsigned long long"; | |
| 1686 return "bool" if $type eq "boolean"; | |
| 1687 return "String" if $type eq "DOMString"; | |
| 1688 return "Range::CompareHow" if $type eq "CompareHow"; | |
| 1689 return "FloatRect" if $type eq "SVGRect"; | |
| 1690 return "FloatPoint" if $type eq "SVGPoint"; | |
| 1691 return "TransformationMatrix" if $type eq "SVGMatrix"; | |
| 1692 return "SVGTransform" if $type eq "SVGTransform"; | |
| 1693 return "SVGLength" if $type eq "SVGLength"; | |
| 1694 return "double" if $type eq "SVGNumber"; | |
| 1695 return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType"; | |
| 1696 return "DOMTimeStamp" if $type eq "DOMTimeStamp"; | |
| 1697 return "unsigned" if $type eq "unsigned int"; | |
| 1698 return "unsigned" if $type eq "RGBColor"; | |
| 1699 return "Node*" if $type eq "EventTarget" and $isParameter; | |
| 1700 | |
| 1701 return "String" if $type eq "DOMUserData"; # temporary hack, TODO | |
| 1702 | |
| 1703 # temporary hack | |
| 1704 return "RefPtr<NodeFilter>" if $type eq "NodeFilter"; | |
| 1705 | |
| 1706 return "RefPtr<${type}>" if IsRefPtrType($type) and not $isParameter; | |
| 1707 | |
| 1708 # Default, assume native type is a pointer with same type name as idl type | |
| 1709 return "${type}*"; | |
| 1710 } | |
| 1711 | |
| 1712 | |
| 1713 my %typeCanFailConversion = ( | |
| 1714 "AtomicString" => 0, | |
| 1715 "Attr" => 1, | |
| 1716 "CompareHow" => 0, | |
| 1717 "DataGridColumn" => 0, | |
| 1718 "DOMString" => 0, | |
| 1719 "DOMWindow" => 0, | |
| 1720 "DocumentType" => 0, | |
| 1721 "Element" => 0, | |
| 1722 "Event" => 0, | |
| 1723 "EventListener" => 0, | |
| 1724 "EventTarget" => 0, | |
| 1725 "HTMLElement" => 0, | |
| 1726 "HTMLOptionElement" => 0, | |
| 1727 "Node" => 0, | |
| 1728 "NodeFilter" => 0, | |
| 1729 "MessagePort" => 0, | |
| 1730 "NSResolver" => 0, | |
| 1731 "Range" => 0, | |
| 1732 "SQLResultSet" => 0, | |
| 1733 "Storage" => 0, | |
| 1734 "SVGAngle" => 0, | |
| 1735 "SVGElement" => 0, | |
| 1736 "SVGLength" => 1, | |
| 1737 "SVGMatrix" => 1, | |
| 1738 "SVGNumber" => 0, | |
| 1739 "SVGPaintType" => 0, | |
| 1740 "SVGPathSeg" => 0, | |
| 1741 "SVGPoint" => 1, | |
| 1742 "SVGRect" => 1, | |
| 1743 "SVGTransform" => 1, | |
| 1744 "VoidCallback" => 1, | |
| 1745 "WebKitCSSMatrix" => 0, | |
| 1746 "WebKitPoint" => 0, | |
| 1747 "XPathEvaluator" => 0, | |
| 1748 "XPathNSResolver" => 0, | |
| 1749 "XPathResult" => 0, | |
| 1750 "boolean" => 0, | |
| 1751 "double" => 0, | |
| 1752 "float" => 0, | |
| 1753 "long" => 0, | |
| 1754 "unsigned long" => 0, | |
| 1755 "unsigned short" => 0, | |
| 1756 ); | |
| 1757 | |
| 1758 | |
| 1759 sub TranslateParameter | |
| 1760 { | |
| 1761 my $signature = shift; | |
| 1762 | |
| 1763 # The IDL uses some pseudo-types which don't really exist. | |
| 1764 if ($signature->type eq "TimeoutHandler") { | |
| 1765 $signature->type("DOMString"); | |
| 1766 } | |
| 1767 } | |
| 1768 | |
| 1769 sub BasicTypeCanFailConversion | |
| 1770 { | |
| 1771 my $signature = shift; | |
| 1772 my $type = $codeGenerator->StripModule($signature->type); | |
| 1773 | |
| 1774 return 1 if $type eq "SVGLength"; | |
| 1775 return 1 if $type eq "SVGMatrix"; | |
| 1776 return 1 if $type eq "SVGPoint"; | |
| 1777 return 1 if $type eq "SVGRect"; | |
| 1778 return 1 if $type eq "SVGTransform"; | |
| 1779 return 0; | |
| 1780 } | |
| 1781 | |
| 1782 sub TypeCanFailConversion | |
| 1783 { | |
| 1784 my $signature = shift; | |
| 1785 | |
| 1786 my $type = $codeGenerator->StripModule($signature->type); | |
| 1787 | |
| 1788 $implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr"; | |
| 1789 | |
| 1790 return $typeCanFailConversion{$type} if exists $typeCanFailConversion{$type}
; | |
| 1791 | |
| 1792 die "Don't know whether a JS value can fail conversion to type $type."; | |
| 1793 } | |
| 1794 | |
| 1795 sub JSValueToNative | |
| 1796 { | |
| 1797 my $signature = shift; | |
| 1798 my $value = shift; | |
| 1799 my $okParam = shift; | |
| 1800 my $maybeOkParam = $okParam ? ", ${okParam}" : ""; | |
| 1801 | |
| 1802 my $type = $codeGenerator->StripModule($signature->type); | |
| 1803 | |
| 1804 return "$value" if $type eq "JSObject"; | |
| 1805 return "$value->BooleanValue()" if $type eq "boolean"; | |
| 1806 return "static_cast<$type>($value->NumberValue())" if $type eq "float" or $t
ype eq "double"; | |
| 1807 return "$value->NumberValue()" if $type eq "SVGNumber"; | |
| 1808 | |
| 1809 return "ToInt32($value${maybeOkParam})" if $type eq "unsigned long" or $type
eq "unsigned short" or $type eq "long"; | |
| 1810 return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "C
ompareHow"; | |
| 1811 return "static_cast<SVGPaint::SVGPaintType>($value->ToInt32()->Int32Value())
" if $type eq "SVGPaintType"; | |
| 1812 | |
| 1813 return "ToWebCoreString($value)" if $type eq "AtomicString" or $type eq "DOM
UserData"; | |
| 1814 if ($type eq "DOMString") { | |
| 1815 return "valueToStringWithNullCheck($value)" if $signature->extendedAttri
butes->{"ConvertNullToNullString"}; | |
| 1816 return "valueToStringWithNullOrUndefinedCheck($value)" if $signature->ex
tendedAttributes->{"ConvertUndefinedOrNullToNullString"}; | |
| 1817 return "ToWebCoreString($value)"; | |
| 1818 } | |
| 1819 | |
| 1820 if ($type eq "NodeFilter") { | |
| 1821 return "V8Proxy::ToNativeNodeFilter($value)"; | |
| 1822 } | |
| 1823 | |
| 1824 if ($type eq "SVGRect") { | |
| 1825 $implIncludes{"FloatRect.h"} = 1; | |
| 1826 } | |
| 1827 | |
| 1828 if ($type eq "SVGPoint") { | |
| 1829 $implIncludes{"FloatPoint.h"} = 1; | |
| 1830 } | |
| 1831 | |
| 1832 # Default, assume autogenerated type conversion routines | |
| 1833 $implIncludes{"v8_proxy.h"} = 1; | |
| 1834 if ($type eq "EventTarget") { | |
| 1835 $implIncludes{"V8Node.h"} = 1; | |
| 1836 | |
| 1837 # EventTarget is not in DOM hierarchy, but all Nodes are EventTarget. | |
| 1838 return "V8Node::HasInstance($value) ? V8Proxy::DOMWrapperToNode<Node>($val
ue) : 0"; | |
| 1839 } | |
| 1840 | |
| 1841 AddIncludesForType($type); | |
| 1842 # $implIncludes{"$type.h"} = 1 unless AvoidInclusionOfType($type); | |
| 1843 | |
| 1844 if (IsDOMNodeType($type)) { | |
| 1845 $implIncludes{"V8${type}.h"} = 1; | |
| 1846 | |
| 1847 # Perform type checks on the parameter, if it is expected Node type, | |
| 1848 # return NULL. | |
| 1849 return "V8${type}::HasInstance($value) ? V8Proxy::DOMWrapperToNode<${type}
>($value) : 0"; | |
| 1850 | |
| 1851 } else { | |
| 1852 # TODO: Temporary to avoid Window name conflict. | |
| 1853 my $classIndex = uc($type); | |
| 1854 my $implClassName = ${type}; | |
| 1855 | |
| 1856 $implIncludes{"V8$type.h"} = 1; | |
| 1857 | |
| 1858 if ($codeGenerator->IsPodType($type)) { | |
| 1859 my $nativeType = GetNativeType($type); | |
| 1860 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1; | |
| 1861 | |
| 1862 return "V8SVGPODTypeUtil::ToSVGPODType<${nativeType}>(V8ClassIndex::${cl
assIndex}, $value${maybeOkParam})" | |
| 1863 } | |
| 1864 | |
| 1865 $implIncludes{"V8${type}.h"} = 1; | |
| 1866 | |
| 1867 # Perform type checks on the parameter, if it is expected Node type, | |
| 1868 # return NULL. | |
| 1869 return "V8${type}::HasInstance($value) ? V8Proxy::ToNativeObject<${implCla
ssName}>(V8ClassIndex::${classIndex}, $value) : 0"; | |
| 1870 } | |
| 1871 } | |
| 1872 | |
| 1873 | |
| 1874 sub GetV8HeaderName | |
| 1875 { | |
| 1876 my $type = shift; | |
| 1877 return "V8" . GetImplementationFileName($type); | |
| 1878 } | |
| 1879 | |
| 1880 | |
| 1881 sub CreateCustomSignature | |
| 1882 { | |
| 1883 my $function = shift; | |
| 1884 my $count = @{$function->parameters}; | |
| 1885 my $name = $function->signature->name; | |
| 1886 my $result = " const int ${name}_argc = ${count};\n" . | |
| 1887 " v8::Handle<v8::FunctionTemplate> ${name}_argv[${name}_argc] = { "; | |
| 1888 my $first = 1; | |
| 1889 foreach my $parameter (@{$function->parameters}) { | |
| 1890 if ($first) { $first = 0; } | |
| 1891 else { $result .= ", "; } | |
| 1892 if (IsWrapperType($parameter->type)) { | |
| 1893 my $type = $parameter->type; | |
| 1894 my $header = GetV8HeaderName($type); | |
| 1895 $implIncludes{$header} = 1; | |
| 1896 $result .= "V8${type}::GetRawTemplate()"; | |
| 1897 } else { | |
| 1898 $result .= "v8::Handle<v8::FunctionTemplate>()"; | |
| 1899 } | |
| 1900 } | |
| 1901 $result .= " };\n"; | |
| 1902 $result .= " v8::Handle<v8::Signature> ${name}_signature = v8::Signature::N
ew(desc, ${name}_argc, ${name}_argv);\n"; | |
| 1903 return $result; | |
| 1904 } | |
| 1905 | |
| 1906 | |
| 1907 sub RequiresCustomSignature | |
| 1908 { | |
| 1909 my $function = shift; | |
| 1910 # No signature needed for Custom function | |
| 1911 if ($function->signature->extendedAttributes->{"Custom"} || | |
| 1912 $function->signature->extendedAttributes->{"V8Custom"}) { | |
| 1913 return 0; | |
| 1914 } | |
| 1915 | |
| 1916 foreach my $parameter (@{$function->parameters}) { | |
| 1917 if (IsWrapperType($parameter->type)) { | |
| 1918 return 1; | |
| 1919 } | |
| 1920 } | |
| 1921 return 0; | |
| 1922 } | |
| 1923 | |
| 1924 | |
| 1925 my %non_wrapper_types = ( | |
| 1926 'float' => 1, | |
| 1927 'AtomicString' => 1, | |
| 1928 'double' => 1, | |
| 1929 'short' => 1, | |
| 1930 'unsigned short' => 1, | |
| 1931 'long' => 1, | |
| 1932 'unsigned long' => 1, | |
| 1933 'boolean' => 1, | |
| 1934 'DOMString' => 1, | |
| 1935 'CompareHow' => 1, | |
| 1936 'SVGRect' => 1, | |
| 1937 'SVGPoint' => 1, | |
| 1938 'SVGMatrix' => 1, | |
| 1939 'SVGTransform' => 1, | |
| 1940 'SVGLength' => 1, | |
| 1941 'SVGNumber' => 1, | |
| 1942 'SVGPaintType' => 1, | |
| 1943 'DOMTimeStamp' => 1, | |
| 1944 'JSObject' => 1, | |
| 1945 'EventTarget' => 1, | |
| 1946 'NodeFilter' => 1, | |
| 1947 'EventListener' => 1 | |
| 1948 ); | |
| 1949 | |
| 1950 | |
| 1951 sub IsWrapperType | |
| 1952 { | |
| 1953 my $type = $codeGenerator->StripModule(shift); | |
| 1954 return !($non_wrapper_types{$type}); | |
| 1955 } | |
| 1956 | |
| 1957 sub IsDOMNodeType | |
| 1958 { | |
| 1959 my $type = shift; | |
| 1960 | |
| 1961 return 1 if $type eq 'Attr'; | |
| 1962 return 1 if $type eq 'CDATASection'; | |
| 1963 return 1 if $type eq 'Comment'; | |
| 1964 return 1 if $type eq 'Document'; | |
| 1965 return 1 if $type eq 'DocumentFragment'; | |
| 1966 return 1 if $type eq 'DocumentType'; | |
| 1967 return 1 if $type eq 'Element'; | |
| 1968 return 1 if $type eq 'EntityReference'; | |
| 1969 return 1 if $type eq 'HTMLCanvasElement'; | |
| 1970 return 1 if $type eq 'HTMLDocument'; | |
| 1971 return 1 if $type eq 'HTMLElement'; | |
| 1972 return 1 if $type eq 'HTMLFormElement'; | |
| 1973 return 1 if $type eq 'HTMLTableCaptionElement'; | |
| 1974 return 1 if $type eq 'HTMLTableSectionElement'; | |
| 1975 return 1 if $type eq 'Node'; | |
| 1976 return 1 if $type eq 'ProcessingInstruction'; | |
| 1977 return 1 if $type eq 'SVGElement'; | |
| 1978 return 1 if $type eq 'SVGDocument'; | |
| 1979 return 1 if $type eq 'SVGSVGElement'; | |
| 1980 return 1 if $type eq 'SVGUseElement'; | |
| 1981 return 1 if $type eq 'Text'; | |
| 1982 | |
| 1983 return 0; | |
| 1984 } | |
| 1985 | |
| 1986 | |
| 1987 sub NativeToJSValue | |
| 1988 { | |
| 1989 my $signature = shift; | |
| 1990 my $value = shift; | |
| 1991 my $type = $codeGenerator->StripModule($signature->type); | |
| 1992 my $className= "V8$type"; | |
| 1993 | |
| 1994 return "v8::Date::New(static_cast<double>($value))" if $type eq "DOMTimeStam
p"; | |
| 1995 return "$value ? v8::True() : v8::False()" if $type eq "boolean"; | |
| 1996 return "v8::Undefined()" if $type eq "void"; | |
| 1997 | |
| 1998 # For all the types where we use 'int' as the representation type, | |
| 1999 # we use Integer::New which has a fast Smi conversion check. | |
| 2000 return "v8::Integer::New($value)" if GetNativeType($type) eq "int"; | |
| 2001 | |
| 2002 return "v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) o
r $type eq "SVGPaintType"; | |
| 2003 | |
| 2004 if ($codeGenerator->IsStringType($type)) { | |
| 2005 my $conv = $signature->extendedAttributes->{"ConvertNullStringTo"}; | |
| 2006 if (defined $conv) { | |
| 2007 return "v8StringOrNull($value)" if $conv eq "Null"; | |
| 2008 return "v8StringOrUndefined($value)" if $conv eq "Undefined"; | |
| 2009 return "v8StringOrFalse($value)" if $conv eq "False"; | |
| 2010 | |
| 2011 die "Unknown value for ConvertNullStringTo extended attribute"; | |
| 2012 } | |
| 2013 return "v8String($value)"; | |
| 2014 } | |
| 2015 | |
| 2016 # V8 specific. | |
| 2017 my $implClassName = $type; | |
| 2018 AddIncludesForType($type); | |
| 2019 # $implIncludes{GetImplementationFileName($type)} = 1 unless AvoidInclusionO
fType($type); | |
| 2020 | |
| 2021 # special case for non-DOM node interfaces | |
| 2022 if (IsDOMNodeType($type)) { | |
| 2023 return "V8Proxy::NodeToV8Object($value)"; | |
| 2024 } | |
| 2025 | |
| 2026 if ($type eq "EventTarget" or $type eq "SVGElementInstance") { | |
| 2027 return "V8Proxy::EventTargetToV8Object($value)"; | |
| 2028 } | |
| 2029 | |
| 2030 if ($type eq "Event") { | |
| 2031 return "V8Proxy::EventToV8Object($value)"; | |
| 2032 } | |
| 2033 | |
| 2034 if ($type eq "EventListener") { | |
| 2035 return "V8Proxy::EventListenerToV8Object($value)"; | |
| 2036 } | |
| 2037 | |
| 2038 if ($type eq "RGBColor") { | |
| 2039 return "V8Proxy::ToV8Object(V8ClassIndex::RGBCOLOR, new RGBColor($value))"
; | |
| 2040 } | |
| 2041 | |
| 2042 if ($type eq "WorkerContext" or $type eq "WorkerLocation" or $type eq "Worke
rNavigator") { | |
| 2043 $implIncludes{"WorkerContextExecutionProxy.h"} = 1; | |
| 2044 my $classIndex = uc($type); | |
| 2045 | |
| 2046 return "WorkerContextExecutionProxy::ToV8Object(V8ClassIndex::$classIndex,
$value)"; | |
| 2047 } | |
| 2048 | |
| 2049 else { | |
| 2050 $implIncludes{"wtf/RefCounted.h"} = 1; | |
| 2051 $implIncludes{"wtf/RefPtr.h"} = 1; | |
| 2052 my $classIndex = uc($type); | |
| 2053 | |
| 2054 if ($codeGenerator->IsPodType($type)) { | |
| 2055 $value = GenerateSVGStaticPodTypeWrapper($type, $value); | |
| 2056 } | |
| 2057 | |
| 2058 return "V8Proxy::ToV8Object(V8ClassIndex::$classIndex, $value)"; | |
| 2059 } | |
| 2060 } | |
| 2061 | |
| 2062 sub GenerateSVGStaticPodTypeWrapper { | |
| 2063 my $type = shift; | |
| 2064 my $value = shift; | |
| 2065 | |
| 2066 $implIncludes{"V8$type.h"}=1; | |
| 2067 $implIncludes{"V8SVGPODTypeWrapper.h"} = 1; | |
| 2068 | |
| 2069 my $nativeType = GetNativeType($type); | |
| 2070 return "new V8SVGStaticPODTypeWrapper<$nativeType>($value)"; | |
| 2071 } | |
| 2072 | |
| 2073 # Internal helper | |
| 2074 sub WriteData | |
| 2075 { | |
| 2076 if (defined($IMPL)) { | |
| 2077 # Write content to file. | |
| 2078 print $IMPL @implContentHeader; | |
| 2079 | |
| 2080 print $IMPL @implFixedHeader; | |
| 2081 | |
| 2082 foreach my $implInclude (sort keys(%implIncludes)) { | |
| 2083 my $checkType = $implInclude; | |
| 2084 $checkType =~ s/\.h//; | |
| 2085 | |
| 2086 print $IMPL "#include \"$implInclude\"\n" unless $codeGenerator->IsS
VGAnimatedType($checkType); | |
| 2087 } | |
| 2088 | |
| 2089 print $IMPL "\n"; | |
| 2090 print $IMPL @implContentDecls; | |
| 2091 print $IMPL @implContent; | |
| 2092 close($IMPL); | |
| 2093 undef($IMPL); | |
| 2094 | |
| 2095 %implIncludes = (); | |
| 2096 @implFixedHeader = (); | |
| 2097 @implHeaderContent = (); | |
| 2098 @implContentDecls = (); | |
| 2099 @implContent = (); | |
| 2100 } | |
| 2101 | |
| 2102 if (defined($HEADER)) { | |
| 2103 # Write content to file. | |
| 2104 print $HEADER @headerContent; | |
| 2105 close($HEADER); | |
| 2106 undef($HEADER); | |
| 2107 | |
| 2108 @headerContent = (); | |
| 2109 } | |
| 2110 } | |
| 2111 | |
| 2112 sub IsSVGTypeNeedingContextParameter | |
| 2113 { | |
| 2114 my $implClassName = shift; | |
| 2115 | |
| 2116 if ($implClassName =~ /SVG/ and not $implClassName =~ /Element/) { | |
| 2117 return 1 unless $implClassName =~ /SVGPaint/ or $implClassName =~ /SVGCo
lor/ or $implClassName =~ /SVGDocument/; | |
| 2118 } | |
| 2119 | |
| 2120 return 0; | |
| 2121 } | |
| 2122 | |
| 2123 sub GenerateSVGContextAssignment | |
| 2124 { | |
| 2125 my $srcType = shift; | |
| 2126 my $value = shift; | |
| 2127 my $indent = shift; | |
| 2128 | |
| 2129 $result = GenerateSVGContextRetrieval($srcType, $indent); | |
| 2130 $result .= $indent . "V8Proxy::SetSVGContext($value, context);\n"; | |
| 2131 | |
| 2132 return $result; | |
| 2133 } | |
| 2134 | |
| 2135 sub GenerateSVGContextRetrieval | |
| 2136 { | |
| 2137 my $srcType = shift; | |
| 2138 my $indent = shift; | |
| 2139 | |
| 2140 my $srcIsPodType = $codeGenerator->IsPodType($srcType); | |
| 2141 | |
| 2142 my $srcObject = "imp"; | |
| 2143 if ($srcIsPodType) { | |
| 2144 $srcObject = "imp_wrapper"; | |
| 2145 } | |
| 2146 | |
| 2147 my $contextDecl; | |
| 2148 | |
| 2149 if (IsSVGTypeNeedingContextParameter($srcType)) { | |
| 2150 $contextDecl = "V8Proxy::GetSVGContext($srcObject)"; | |
| 2151 } else { | |
| 2152 $contextDecl = $srcObject; | |
| 2153 } | |
| 2154 | |
| 2155 return $indent . "SVGElement* context = $contextDecl;\n"; | |
| 2156 } | |
| 2157 | |
| 2158 sub IsSVGListMutator | |
| 2159 { | |
| 2160 my $functionName = shift; | |
| 2161 | |
| 2162 return 1 if $functionName eq "clear"; | |
| 2163 return 1 if $functionName eq "initialize"; | |
| 2164 return 1 if $functionName eq "insertItemBefore"; | |
| 2165 return 1 if $functionName eq "replaceItem"; | |
| 2166 return 1 if $functionName eq "removeItem"; | |
| 2167 return 1 if $functionName eq "appendItem"; | |
| 2168 | |
| 2169 return 0; | |
| 2170 } | |
| 2171 | |
| 2172 sub IsSVGListMethod | |
| 2173 { | |
| 2174 my $functionName = shift; | |
| 2175 | |
| 2176 return 1 if $functionName eq "getFirst"; | |
| 2177 return 1 if $functionName eq "getLast"; | |
| 2178 return 1 if $functionName eq "getItem"; | |
| 2179 | |
| 2180 return IsSVGListMutator($functionName); | |
| 2181 } | |
| 2182 | |
| 2183 sub IsSVGListTypeNeedingSpecialHandling | |
| 2184 { | |
| 2185 my $className = shift; | |
| 2186 | |
| 2187 return 1 if $className eq "SVGPointList"; | |
| 2188 return 1 if $className eq "SVGTransformList"; | |
| 2189 | |
| 2190 return 0; | |
| 2191 } | |
| 2192 | |
| 2193 sub DebugPrint | |
| 2194 { | |
| 2195 my $output = shift; | |
| 2196 | |
| 2197 print $output; | |
| 2198 print "\n"; | |
| 2199 } | |
| OLD | NEW |