summaryrefslogtreecommitdiffstats
path: root/contrib/dom/scripts/CodeGeneratorArabicaJSC.pm
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-01-21 23:47:54 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-01-21 23:47:54 (GMT)
commit3be96d1aa3024c1acc129e587f5d3165c9434e48 (patch)
treefae65a932b899ed9424a5a76b9b98562d979fe40 /contrib/dom/scripts/CodeGeneratorArabicaJSC.pm
parent3bda299c6d2efce71d76b44dea8e732a073304f3 (diff)
downloaduscxml-3be96d1aa3024c1acc129e587f5d3165c9434e48.zip
uscxml-3be96d1aa3024c1acc129e587f5d3165c9434e48.tar.gz
uscxml-3be96d1aa3024c1acc129e587f5d3165c9434e48.tar.bz2
See detailed commitlog
- Started DirectoryMonitor invoker - Refactored Invoker / IOProcessor interface - Started with JavaScriptCore bindings - Embedding applications can now use setParentQueue to receive events sent to #_parent
Diffstat (limited to 'contrib/dom/scripts/CodeGeneratorArabicaJSC.pm')
-rw-r--r--contrib/dom/scripts/CodeGeneratorArabicaJSC.pm786
1 files changed, 786 insertions, 0 deletions
diff --git a/contrib/dom/scripts/CodeGeneratorArabicaJSC.pm b/contrib/dom/scripts/CodeGeneratorArabicaJSC.pm
new file mode 100644
index 0000000..affa51f
--- /dev/null
+++ b/contrib/dom/scripts/CodeGeneratorArabicaJSC.pm
@@ -0,0 +1,786 @@
+# Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
+# Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
+# Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+# Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
+# Copyright (C) 2006 Apple Computer, Inc.
+# Copyright (C) 2007, 2008, 2009, 2012 Google Inc.
+# Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
+# Copyright (C) Research In Motion Limited 2010. All rights reserved.
+# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+# Copyright (C) 2012 Ericsson AB. All rights reserved.
+# Copyright (C) 2013 Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+package CodeGeneratorArabicaJSC;
+
+use strict;
+use Data::Dumper;
+use Carp qw/longmess cluck confess/;
+
+use constant FileNamePrefix => "JSC";
+
+my $codeGenerator;
+
+
+my @headerContent = ();
+my @implContentHeader = ();
+my @implContent = ();
+my @implContentDecls = ();
+my %implIncludes = ();
+my %headerIncludes = ();
+
+# Default .h template
+my $headerTemplate = << "EOF";
+/*
+ This file is part of the Arabica open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+EOF
+
+# Default constructor
+sub new
+{
+ my $object = shift;
+ my $reference = { };
+
+ $codeGenerator = shift;
+
+ bless($reference, $object);
+ return $reference;
+}
+
+sub GenerateInterface
+{
+ my $object = shift;
+ my $interface = shift;
+
+ # Start actual generation
+ if ($interface->extendedAttributes->{"Callback"}) {
+ die();
+ $object->GenerateCallbackHeader($interface);
+ $object->GenerateCallbackImplementation($interface);
+ } else {
+ $object->GenerateHeader($interface);
+ $object->GenerateImplementation($interface);
+ }
+}
+
+sub AddToImplIncludes
+{
+ my $header = shift;
+ my $conditional = shift;
+
+ if ($header eq "JSCbool.h") {
+ confess();
+ }
+
+ if (not $conditional) {
+ $implIncludes{$header} = 1;
+ } elsif (not exists($implIncludes{$header})) {
+ $implIncludes{$header} = $conditional;
+ } else {
+ my $oldValue = $implIncludes{$header};
+ if ($oldValue ne 1) {
+ my %newValue = ();
+ $newValue{$conditional} = 1;
+ foreach my $condition (split(/\|/, $oldValue)) {
+ $newValue{$condition} = 1;
+ }
+ $implIncludes{$header} = join("|", sort keys %newValue);
+ }
+ }
+}
+
+sub GenerateHeader
+{
+ my $object = shift;
+ my $interface = shift;
+ my $interfaceName = $interface->name;
+ my $extensions = $interface->extendedAttributes;
+# print Dumper($extensions);
+
+ # Copy contents of parent interfaces except the first parent.
+ my @parents;
+ $codeGenerator->AddMethodsConstantsAndAttributesFromParentInterfaces($interface, \@parents, 1);
+ $codeGenerator->LinkOverloadedFunctions($interface);
+
+ # - Add default header template
+ push(@headerContent, GenerateHeaderContentHeader($interface));
+
+ $headerIncludes{"uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDOM.h"} = 1;
+ $headerIncludes{"DOM/Node.hpp"} = 1;
+ $headerIncludes{"JavaScriptCore/JavaScriptCore.h"} = 1;
+
+ foreach (@{$interface->parents}) {
+ my $parent = $_;
+ $headerIncludes{"JSC${parent}.h"} = 1;
+ }
+
+ foreach my $headerInclude (sort keys(%headerIncludes)) {
+ if ($headerInclude =~ /wtf|JavaScriptCore\/JavaScriptCore\.h/) {
+ push(@headerContent, "#include \<${headerInclude}\>\n");
+ } else {
+ push(@headerContent, "#include \"${headerInclude}\"\n");
+ }
+ }
+
+ push(@headerContent, "");
+ push(@headerContent, "\nnamespace Arabica {");
+ push(@headerContent, "\nnamespace DOM {\n");
+
+ push(@headerContent, "\nclass JSC${interfaceName} {");
+ push(@headerContent, "\npublic:");
+
+ my $arabicaType = IdlToArabicaType($interfaceName);
+ push(@headerContent, <<END);
+
+ struct JSC${interfaceName}Private {
+ JSCDOM* dom;
+ ${arabicaType}* arabicaThis;
+ };
+END
+
+ push(@headerContent, "\n JSC_DESTRUCTOR(JSC${interfaceName}Private);");
+ push(@headerContent, "\n");
+
+
+ # callbacks for actual functions
+ foreach my $function (@{$interface->functions}) {
+ my $name = $function->signature->name;
+ my $attrExt = $function->signature->extendedAttributes;
+ my $custom = ($attrExt->{'Custom'} ? "Custom" : "");
+ push(@headerContent, "\n static JSValueRef ${name}${custom}Callback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception);");
+ }
+ push(@headerContent, "\n");
+
+ # attribute getter and setters
+ foreach my $attribute (@{$interface->attributes}) {
+ my $name = $attribute->signature->name;
+ my $attrExt = $attribute->signature->extendedAttributes;
+ my $customGetter = ($attrExt->{'CustomGetter'} ? "Custom" : "");
+ my $customSetter = ($attrExt->{'CustomSetter'} ? "Custom" : "");
+ push(@headerContent, "\n static JSValueRef ${name}${customGetter}AttrGetter(JSContextRef ctx, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception);");
+ if (!IsReadonly($attribute)) {
+ push(@headerContent, "\n static bool ${name}${customSetter}AttrSetter(JSContextRef ctx, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef value, JSValueRef* exception);");
+ }
+ }
+
+ push(@headerContent, "\n");
+ # constant getters
+ foreach my $constant (@{$interface->constants}) {
+ my $name = $constant->name;
+ push(@headerContent, "\n static JSValueRef ${name}ConstGetter(JSContextRef ctx, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception);");
+ }
+
+ # if ($extensions->{'CustomIndexedGetter'}) {
+ # push(@headerContent, "\n static v8::Handle<v8::Value> indexedPropertyCustomGetter(uint32_t, const v8::AccessorInfo&);");
+ # }
+ # if ($extensions->{'CustomIndexedSetter'}) {
+ # push(@headerContent, "\n static v8::Handle<v8::Value> indexedPropertyCustomSetter(uint32_t, v8::Local<v8::Value>, const v8::AccessorInfo&);");
+ # }
+ # push(@headerContent, "\n");
+
+# GenerateClassPrototypeHeader($interface);
+
+ push(@headerContent, <<END);
+
+
+ static JSStaticValue staticValues[];
+ static JSStaticFunction staticFunctions[];
+
+ static JSClassRef Tmpl;
+ static JSClassRef getTmpl() {
+ if (Tmpl == NULL) {
+ JSClassDefinition classDef = kJSClassDefinitionEmpty;
+ classDef.staticValues = staticValues;
+ classDef.staticFunctions = staticFunctions;
+ classDef.finalize = jsDestructor;
+
+ Tmpl = JSClassCreate(&classDef);
+ JSClassRetain(Tmpl);
+ }
+ return Tmpl;
+ }
+
+END
+
+ push(@headerContent, "\n};\n\n}\n}\n\n");
+ push(@headerContent, "#endif // JSC${interfaceName}" . "_h\n");
+
+}
+
+#
+# Write class template prototype constructor
+#
+sub GenerateClassDefStatics
+{
+ my $interface = shift;
+ my $interfaceName = $interface->name;
+ my $extensions = $interface->extendedAttributes;
+
+ push(@implContent, "\nJSStaticValue JSC${interfaceName}::staticValues[] = {");
+ foreach my $attribute (@{$interface->attributes}) {
+ my $name = $attribute->signature->name;
+ my $attrExt = $attribute->signature->extendedAttributes;
+ my $customGetter = ($attrExt->{'CustomGetter'} ? "Custom" : "");
+ my $customSetter = ($attrExt->{'CustomSetter'} ? "Custom" : "");
+ my $getter = "${name}${customGetter}AttrGetter";
+ my $setter = (IsReadonly($attribute) ? "0" : "${name}${customSetter}AttrSetter");
+ my $flags = "kJSPropertyAttributeDontDelete";
+ $flags .= " | kJSPropertyAttributeReadOnly" if (IsReadonly($attribute));
+ push(@implContent, "\n { \"${name}\", ${getter}, ${setter}, ${flags} },");
+
+ }
+
+ push(@implContent, "\n");
+ foreach my $constant (@{$interface->constants}) {
+ my $name = $constant->name;
+ my $value = $constant->value;
+ my $getter = "${name}ConstGetter";
+ my $flags = "kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly";
+ push(@implContent, "\n { \"${name}\", ${getter}, 0, ${flags} },");
+ }
+
+ push(@implContent, "\n { 0, 0, 0, 0 }");
+ push(@implContent, "\n};\n");
+
+ push(@implContent, "\nJSStaticFunction JSC${interfaceName}::staticFunctions[] = {");
+ foreach my $function (@{$interface->functions}) {
+ my $name = $function->signature->name;
+ my $attrExt = $function->signature->extendedAttributes;
+ my $custom = ($attrExt->{'Custom'} ? "Custom" : "");
+ my $callback = ${name}.${custom}."Callback";
+ my $flags = "kJSPropertyAttributeDontDelete";
+ push(@implContent, "\n { \"${name}\", ${callback}, ${flags} },");
+
+ }
+ push(@implContent, "\n { 0, 0, 0 }");
+ push(@implContent, "\n};\n");
+
+}
+
+sub GenerateImplementationAttributes
+{
+ my $interface = shift;
+ my $interfaceName = $interface->name;
+
+ # Generate property accessors for attributes.
+ for (my $index = 0; $index < @{$interface->attributes}; $index++) {
+ my $attribute = @{$interface->attributes}[$index];
+ my $attrType = $attribute->signature->type;
+ my $attrName = $attribute->signature->name;
+ my $attrExt = $attribute->signature->extendedAttributes;
+
+ my $arabicaRetType = IdlToArabicaType($attrType);
+ my $arabicaType = IdlToArabicaType($interfaceName);
+ my $arabicaGetter = IdlToArabicaAttrGetter($interface, $attribute);
+
+ next if ($attrExt->{'Custom'});
+
+ # getter
+ if (!$attrExt->{'CustomGetter'}) {
+ push(@implContent, <<END);
+
+JSValueRef JSC${interfaceName}::${attrName}AttrGetter(JSContextRef ctx, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception) {
+ struct JSC${interfaceName}Private* privData = static_cast<JSC${interfaceName}::JSC${interfaceName}Private* >(JSObjectGetPrivate(thisObj));
+END
+ if (IsWrapperType($attrType)) {
+ AddToImplIncludes("JSC".$attrType.".h");
+ push(@implContent, <<END);
+ ${arabicaRetType}* arbaicaRet = new ${arabicaRetType}(privData->arabicaThis->${arabicaGetter}());
+
+ struct JSC${attrType}::JSC${attrType}Private* retPrivData = new JSC${attrType}::JSC${attrType}Private();
+ retPrivData->dom = privData->dom;
+ retPrivData->arabicaThis = arbaicaRet;
+
+ JSObjectRef arbaicaRetObj = JSObjectMake(ctx, JSC${attrType}::getTmpl(), retPrivData);
+ return arbaicaRetObj;
+END
+ } else {
+ my $jscType = IdlToJSCType($attrType);
+ if ($attrType eq "DOMString") {
+ push(@implContent, <<END);
+ JSStringRef retString = JSStringCreateWithUTF8CString(privData->arabicaThis->${arabicaGetter}().c_str());
+ JSValueRef retObj = JSValueMakeString(ctx, retString);
+ JSStringRelease(retString);
+ return retObj;
+END
+ } else {
+ push(@implContent, "\n return ${jscType}(ctx, privData->arabicaThis->${arabicaGetter}());");
+ }
+ }
+ push(@implContent, "\n}\n");
+ }
+
+ if (!$attrExt->{'CustomSetter'}) {
+ # setter
+ if (!IsReadonly($attribute) && 0) {
+ my $arabicaSetter = IdlToArabicaAttrSetter($attrName);
+ push(@implContent, "\n void JSC${interfaceName}::${attrName}AttrSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {");
+ push(@implContent, "\n v8::Local<v8::Object> self = info.Holder();");
+ push(@implContent, "\n struct JSC${interfaceName}Private* privData = JSCDOM::toClassPtr<JSC${interfaceName}Private >(self->GetInternalField(0));");
+
+ my ($handle, $deref) = IdlToArgHandle($attribute->signature->type, "local".ucfirst($attribute->signature->name), "value");
+
+ push(@implContent, "\n $handle");
+ push(@implContent, "\n privData->arabicaThis->${arabicaSetter}(${deref});");
+ push(@implContent, "\n }\n");
+
+ }
+ }
+ }
+}
+
+sub GenerateImplementationFunctionCallbacks
+{
+ my $interface = shift;
+ my $interfaceName = $interface->name;
+ my $arabicaType = IdlToArabicaType($interfaceName);
+
+ # Generate methods for functions.
+ foreach my $function (@{$interface->functions}) {
+ my $name = $function->signature->name;
+ my $attrExt = $function->signature->extendedAttributes;
+ my $retType = $function->signature->type;
+ my $arabicaRetType = IdlToArabicaType($retType);
+
+ next if ($attrExt->{'Custom'});
+
+ # signature
+ push(@implContent, <<END);
+ v8::Handle<v8::Value> JSC${interfaceName}::${name}Callback(const v8::Arguments& args) {
+END
+
+ # arguments count and type checking
+ push(@implContent, GenerateArgumentsCountCheck($function, $interface));
+ my $argCheckExpr = GenerateArgumentsTypeCheck($function, $interface);
+
+ push(@implContent, <<END) if ($argCheckExpr);
+ if (!${argCheckExpr})
+ throw JSCException(\"Parameter mismatch while calling ${name}\");
+END
+
+ # get this
+ push(@implContent, "\n v8::Local<v8::Object> self = args.Holder();");
+ push(@implContent, "\n struct JSC${interfaceName}Private* privData = JSCDOM::toClassPtr<JSC${interfaceName}Private >(self->GetInternalField(0));");
+
+ # arguments to local handles
+ my $parameterIndex = 0;
+ my @argList;
+ foreach my $parameter (@{$function->parameters}) {
+ my $value = "args[$parameterIndex]";
+ my $type = $parameter->type;
+ AddToImplIncludes("JSC".$type.".h") if (IsWrapperType($type));
+
+ my ($handle, $deref) = IdlToArgHandle($parameter->type, "local".ucfirst($parameter->name), "args[${parameterIndex}]");
+ push(@implContent, "\n ${handle}");
+ push(@argList, $deref);
+
+ $parameterIndex++;
+ }
+
+ # invoke native function with argument handles
+ my $retNativeType = IdlToNativeType($retType);
+ my $arabicaFunctionName = IdlToArabicaFunction($interface, $function);
+ if (IsWrapperType($retType)) {
+ push(@implContent, "\n\n ${retNativeType}* retVal = new $arabicaRetType(privData->arabicaThis->${arabicaFunctionName}(" . join(", ", @argList) . "));\n");
+ } elsif ($retNativeType eq "void") {
+ push(@implContent, "\n\n privData->arabicaThis->${arabicaFunctionName}(" . join(", ", @argList) . ");\n");
+ } else {
+ push(@implContent, "\n\n ${retNativeType} retVal = privData->arabicaThis->${arabicaFunctionName}(" . join(", ", @argList) . ");\n");
+ }
+
+ # wrap return type if needed
+ if (IsWrapperType($retType)) {
+ AddToImplIncludes("JSC".$retType.".h");
+
+ push(@implContent, <<END);
+ v8::Handle<v8::Function> retCtor = JSC${retType}::getTmpl()->GetFunction();
+ v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance());
+
+ struct JSC${retType}::JSC${retType}Private* retPrivData = new JSC${retType}::JSC${retType}Private();
+ retPrivData->dom = privData->dom;
+ retPrivData->arabicaThis = retVal;
+
+ retObj->SetInternalField(0, JSCDOM::toExternal(retPrivData));
+
+ retObj.MakeWeak(0, JSC${retType}::jsDestructor);
+ return retObj;
+END
+ } else {
+ my $toHandleString = NativeToHandle($retNativeType, "retVal");
+ push(@implContent, "\n return ${toHandleString};");
+ }
+
+ push(@implContent, "\n }\n\n");
+ }
+
+}
+
+sub GenerateImplementation
+{
+ my $object = shift;
+ my $interface = shift;
+ my $interfaceName = $interface->name;
+ my $visibleInterfaceName = $codeGenerator->GetVisibleInterfaceName($interface);
+ my $v8InterfaceName = "JSC$interfaceName";
+ my $arabicaType = IdlToArabicaType($interfaceName);
+
+ AddToImplIncludes("JSC${interfaceName}.h");
+
+ # Find the super descriptor.
+ my $parentClass = "";
+ my $parentClassTemplate = "";
+ foreach (@{$interface->parents}) {
+ my $parent = $_;
+ AddToImplIncludes("JSC${parent}.h");
+ $parentClass = "JSC" . $parent;
+ last;
+ }
+ push(@implContent, "namespace Arabica {\n");
+ push(@implContent, "namespace DOM {\n\n");
+
+ GenerateClassDefStatics($interface);
+ GenerateImplementationAttributes($interface);
+# GenerateImplementationFunctionCallbacks($interface);
+
+ push(@implContent, <<END);
+
+}
+}
+END
+}
+
+sub WriteData
+{
+ my $object = shift;
+ my $interface = shift;
+ my $outputDir = shift;
+ my $outputHeadersDir = shift;
+
+ my $name = $interface->name;
+ my $prefix = FileNamePrefix;
+ my $headerFileName = "$outputHeadersDir/$prefix$name.h";
+ my $implFileName = "$outputDir/$prefix$name.cpp";
+
+ # print "WriteData\n";
+ # print Dumper($interface);
+ # exit();
+
+ # Update a .cpp file if the contents are changed.
+ my $contents = join "", @implContentHeader;
+
+ my @includes = ();
+ my %implIncludeConditions = ();
+ foreach my $include (keys %implIncludes) {
+ my $condition = $implIncludes{$include};
+ my $checkType = $include;
+ $checkType =~ s/\.h//;
+ next if $codeGenerator->IsSVGAnimatedType($checkType);
+
+ if ($include =~ /wtf/) {
+ $include = "\<$include\>";
+ } else {
+ $include = "\"$include\"";
+ }
+
+ if ($condition eq 1) {
+ push @includes, $include;
+ } else {
+ push @{$implIncludeConditions{$condition}}, $include;
+ }
+ }
+ foreach my $include (sort @includes) {
+ $contents .= "#include $include\n";
+ }
+ foreach my $condition (sort keys %implIncludeConditions) {
+ $contents .= "\n#if " . $codeGenerator->GenerateConditionalStringFromAttributeValue($condition) . "\n";
+ foreach my $include (sort @{$implIncludeConditions{$condition}}) {
+ $contents .= "#include $include\n";
+ }
+ $contents .= "#endif\n";
+ }
+
+ $contents .= "\n";
+ $contents .= join "", @implContentDecls, @implContent;
+ $codeGenerator->UpdateFile($implFileName, $contents);
+
+ %implIncludes = ();
+ @implContentHeader = ();
+ @implContentDecls = ();
+ @implContent = ();
+
+ # Update a .h file if the contents are changed.
+ $contents = join "", @headerContent;
+ $codeGenerator->UpdateFile($headerFileName, $contents);
+
+ @headerContent = ();
+}
+
+sub IdlToJSCType
+{
+ my $idlType = shift;
+ return "JSValueMakeNumber" if ($idlType eq "unsigned short");
+ return "JSValueMakeNumber" if ($idlType eq "short");
+ return "JSValueMakeNumber" if ($idlType eq "unsigned long");
+ return "JSValueMakeNumber" if ($idlType eq "long");
+ return "JSValueMakeString" if ($idlType eq "DOMString");
+ return "JSValueMakeBoolean" if ($idlType eq "boolean");
+ return "JSValueMakeNumber" if ($idlType eq "double");
+ die($idlType);
+}
+
+sub IdlToNativeType
+{
+ my $idlType = shift;
+
+ return IdlToArabicaType($idlType) if (IsWrapperType($idlType));
+
+ return "std::string" if ($idlType eq "DOMString");
+ return "bool" if ($idlType eq "boolean");
+ return "void" if ($idlType eq "void");
+ return "double" if ($idlType eq "double");
+ die(${idlType});
+}
+
+sub NativeToHandle
+{
+ my $nativeType = shift;
+ my $nativeName = shift;
+
+ return ("v8::Boolean::New(${nativeName})") if ($nativeType eq "bool");
+ return ("v8::Number::New(${nativeName})") if ($nativeType eq "double");
+ return ("v8::String::New(${nativeName}.c_str())") if ($nativeType eq "std::string");
+ return ("v8::Undefined()") if ($nativeType eq "void");
+
+ die($nativeType);
+}
+
+sub IdlToArabicaType
+{
+ my $idlType = shift;
+ return "Arabica::XPath::XPathValue<std::string>" if ($idlType eq "XPathResult");
+ return "Arabica::XPath::NodeSet<std::string>" if ($idlType eq "NodeSet");
+ return "Arabica::DOM::Node<std::string>" if ($idlType eq "Node");
+ return "Arabica::DOM::Element<std::string>" if ($idlType eq "Element");
+ return "Arabica::DOM::${idlType}<std::string>";
+}
+
+sub IdlToArgHandle
+{
+ my $type = shift;
+ my $localName = shift;
+ my $paramName = shift;
+
+ return ("v8::String::AsciiValue ${localName}(${paramName});", "*${localName}") if ($type eq "DOMString");
+ return ("unsigned long ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "unsigned long");
+ return ("unsigned short ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "unsigned short");
+ return ("bool ${localName} = ${paramName}->ToBoolean()->BooleanValue();", ${localName}) if ($type eq "boolean");
+
+ if (IsWrapperType($type)) {
+ my $arabicaType = IdlToArabicaType($type);
+ return ("${arabicaType}* ${localName} = JSCDOM::toClassPtr<JSC${type}::JSC${type}Private >(${paramName}->ToObject()->GetInternalField(0))->arabicaThis;", "*${localName}");
+ }
+
+ print $type."\n";
+ die();
+}
+
+sub IdlToArabicaAttrGetter
+{
+ my $interface = shift;
+ my $attribute = shift;
+
+ return $attribute->signature->name if ($interface->name eq "NodeSet" && $attribute->signature->name eq "size");
+ return $attribute->signature->name if ($interface->name eq "NodeSet" && $attribute->signature->name eq "empty");
+ return "asString" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "stringValue");
+ return "asBool" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "booleanValue");
+ return "asNumber" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "numberValue");
+
+ return "get" . ucfirst($attribute->signature->name);
+}
+
+sub IdlToArabicaFunction
+{
+ my $interface = shift;
+ my $function = shift;
+
+ # if ($interface->name eq "NodeSet" && $function->signature->name eq "toDocumentOrder") {
+ # print Dumper($interface);
+ # print Dumper($function);
+ # }
+
+ return "to_document_order" if ($interface->name eq "NodeSet" && $function->signature->name eq "toDocumentOrder");
+
+ return $function->signature->name;
+
+}
+
+sub IdlToArabicaAttrSetter
+{
+ my $idlAttr = shift;
+ return "set" . ucfirst($idlAttr);
+}
+
+
+sub IsReadonly
+{
+ my $attribute = shift;
+ my $attrExt = $attribute->signature->extendedAttributes;
+ return ($attribute->type =~ /readonly/ || $attrExt->{"JSCReadOnly"}) && !$attrExt->{"Replaceable"};
+}
+
+
+sub GenerateArgumentsCountCheck
+{
+ my $function = shift;
+ my $interface = shift;
+
+ my $numMandatoryParams = 0;
+ my $allowNonOptional = 1;
+ foreach my $param (@{$function->parameters}) {
+ if ($param->extendedAttributes->{"Optional"} or $param->isVariadic) {
+ $allowNonOptional = 0;
+ } else {
+ die "An argument must not be declared to be optional unless all subsequent arguments to the operation are also optional." if !$allowNonOptional;
+ $numMandatoryParams++;
+ }
+ }
+
+ my $argumentsCountCheckString = "";
+ if ($numMandatoryParams >= 1) {
+ $argumentsCountCheckString .= " if (args.Length() < $numMandatoryParams)\n";
+ $argumentsCountCheckString .= " throw JSCException(\"Wrong number of arguments in " . $function->signature->name . "\");\n";
+ }
+ return $argumentsCountCheckString;
+}
+
+sub GenerateArgumentsTypeCheck
+{
+ my $function = shift;
+ my $interface = shift;
+
+ my @andExpression = ();
+
+ my $parameterIndex = 0;
+ foreach my $parameter (@{$function->parameters}) {
+ my $value = "args[$parameterIndex]";
+ my $type = $parameter->type;
+
+ # Only DOMString or wrapper types are checked.
+ # For DOMString with StrictTypeChecking only Null, Undefined and Object
+ # are accepted for compatibility. Otherwise, no restrictions are made to
+ # match the non-overloaded behavior.
+ # FIXME: Implement WebIDL overload resolution algorithm.
+ if ($codeGenerator->IsStringType($type)) {
+ if ($parameter->extendedAttributes->{"StrictTypeChecking"}) {
+ push(@andExpression, "(${value}->IsNull() || ${value}->IsUndefined() || ${value}->IsString() || ${value}->IsObject())");
+ }
+ } elsif ($parameter->extendedAttributes->{"Callback"}) {
+ # For Callbacks only checks if the value is null or object.
+ push(@andExpression, "(${value}->IsNull() || ${value}->IsFunction())");
+ } elsif ($codeGenerator->IsArrayType($type) || $codeGenerator->GetSequenceType($type)) {
+ if ($parameter->isNullable) {
+ push(@andExpression, "(${value}->IsNull() || ${value}->IsArray())");
+ } else {
+ push(@andExpression, "(${value}->IsArray())");
+ }
+ } elsif (IsWrapperType($type)) {
+ if ($parameter->isNullable) {
+ push(@andExpression, "(${value}->IsNull() || JSC${type}::hasInstance($value))");
+ } else {
+ push(@andExpression, "(JSC${type}::hasInstance($value))");
+ }
+ }
+
+ $parameterIndex++;
+ }
+ my $res = join(" && ", @andExpression);
+ $res = "($res)" if @andExpression > 1;
+ return $res;
+}
+
+
+my %non_wrapper_types = (
+ 'CompareHow' => 1,
+ 'DOMObject' => 1,
+ 'DOMString' => 1,
+ 'DOMString[]' => 1,
+ 'DOMTimeStamp' => 1,
+ 'Date' => 1,
+ 'Dictionary' => 1,
+ 'EventListener' => 1,
+ # FIXME: When EventTarget is an interface and not a mixin, fix this so that
+ # EventTarget is treated as a wrapper type.
+ 'EventTarget' => 1,
+ 'IDBKey' => 1,
+ 'JSObject' => 1,
+ 'MediaQueryListListener' => 1,
+ 'NodeFilter' => 1,
+ 'SerializedScriptValue' => 1,
+ 'any' => 1,
+ 'boolean' => 1,
+ 'double' => 1,
+ 'float' => 1,
+ 'int' => 1,
+ 'long long' => 1,
+ 'long' => 1,
+ 'short' => 1,
+ 'void' => 1,
+ 'unsigned int' => 1,
+ 'unsigned long long' => 1,
+ 'unsigned long' => 1,
+ 'unsigned short' => 1
+);
+
+sub IsWrapperType
+{
+ my $type = shift;
+ return !($non_wrapper_types{$type});
+}
+
+sub GenerateHeaderContentHeader
+{
+ my $interface = shift;
+ my $v8InterfaceName = "JSC" . $interface->name;
+ my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
+
+ my @headerContentHeader = split("\r", $headerTemplate);
+
+ push(@headerContentHeader, "\n#if ${conditionalString}\n") if $conditionalString;
+ push(@headerContentHeader, "\n#ifndef ${v8InterfaceName}" . "_h");
+ push(@headerContentHeader, "\n#define ${v8InterfaceName}" . "_h\n\n");
+ return @headerContentHeader;
+}
+
+1;