Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(656)

Side by Side Diff: webkit/port/bindings/scripts/CodeGeneratorV8.pm

Issue 147210: Switch over to use V8 code generator upstream.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 }
OLDNEW
« no previous file with comments | « webkit/port/bindings/scripts/CodeGenerator.pm ('k') | webkit/port/bindings/scripts/IDLParser.pm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698