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 |