summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-09-01 19:18:36 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-09-01 19:18:36 (GMT)
commitfd0778237785840ec754f98e847a524590cbf61c (patch)
treeebf4609be11843f9657810515d47faa3873c2db8 /contrib
parent99d2c52f1068b2dd4bd16b8c1c8231beeb94a649 (diff)
downloaduscxml-fd0778237785840ec754f98e847a524590cbf61c.zip
uscxml-fd0778237785840ec754f98e847a524590cbf61c.tar.gz
uscxml-fd0778237785840ec754f98e847a524590cbf61c.tar.bz2
More work on TypedArrays
Diffstat (limited to 'contrib')
-rw-r--r--contrib/dom/idl/TypedArray.idl43
-rw-r--r--contrib/dom/scripts/CodeGenerator.pm4
-rw-r--r--contrib/dom/scripts/CodeGeneratorArabicaJSC.pm302
-rw-r--r--contrib/dom/scripts/CodeGeneratorArabicaV8.pm394
-rw-r--r--contrib/dom/scripts/IDLParser.pm8
5 files changed, 570 insertions, 181 deletions
diff --git a/contrib/dom/idl/TypedArray.idl b/contrib/dom/idl/TypedArray.idl
index 17df5c3..5774a73 100644
--- a/contrib/dom/idl/TypedArray.idl
+++ b/contrib/dom/idl/TypedArray.idl
@@ -8,7 +8,10 @@
* https://www.khronos.org/registry/typedarray/specs/latest/
*/
-[ Constructor(unsigned long length) ]
+[ CustomIndexedGetter,
+ CustomIndexedSetter,
+ Constructor(unsigned long length)
+]
interface ArrayBuffer {
readonly attribute unsigned long byteLength;
ArrayBuffer slice(long begin, optional long end);
@@ -26,13 +29,15 @@ interface ArrayBufferView {
// The 'byte' type does not currently exist in Web IDL.
// In this IDL, it should be a signed 8 bit type.
[
+ CustomIndexedGetter,
+ CustomIndexedSetter,
Constructor(unsigned long length),
Constructor(Int8Array array),
Constructor(byte[] array),
Constructor(ArrayBuffer buffer,
optional unsigned long byteOffset, optional unsigned long length)
]
-interface Int8Array {
+interface Int8Array : ArrayBufferView {
const long BYTES_PER_ELEMENT = 1;
readonly attribute unsigned long length;
@@ -49,13 +54,15 @@ Int8Array implements ArrayBufferView;
// The 'unsigned byte' type does not currently exist in Web IDL, though
// 'octet' is equivalent.
[
+ CustomIndexedGetter,
+ CustomIndexedSetter,
Constructor(unsigned long length),
Constructor(Uint8Array array),
Constructor(octet[] array),
Constructor(ArrayBuffer buffer,
optional unsigned long byteOffset, optional unsigned long length)
]
-interface Uint8Array {
+interface Uint8Array : ArrayBufferView{
const long BYTES_PER_ELEMENT = 1;
readonly attribute unsigned long length;
@@ -70,13 +77,15 @@ Uint8Array implements ArrayBufferView;
[
+ CustomIndexedGetter,
+ CustomIndexedSetter,
Constructor(unsigned long length),
Constructor(Uint8ClampedArray array),
Constructor(octet[] array),
Constructor(ArrayBuffer buffer,
optional unsigned long byteOffset, optional unsigned long length)
]
-interface Uint8ClampedArray {
+interface Uint8ClampedArray : ArrayBufferView {
const long BYTES_PER_ELEMENT = 1;
readonly attribute unsigned long length;
@@ -91,13 +100,15 @@ Uint8ClampedArray implements ArrayBufferView;
[
+ CustomIndexedGetter,
+ CustomIndexedSetter,
Constructor(unsigned long length),
Constructor(Int16Array array),
Constructor(short[] array),
Constructor(ArrayBuffer buffer,
optional unsigned long byteOffset, optional unsigned long length)
]
-interface Int16Array {
+interface Int16Array : ArrayBufferView {
const long BYTES_PER_ELEMENT = 2;
readonly attribute unsigned long length;
@@ -112,13 +123,15 @@ Int16Array implements ArrayBufferView;
[
+ CustomIndexedGetter,
+ CustomIndexedSetter,
Constructor(unsigned long length),
Constructor(Uint16Array array),
Constructor(unsigned short[] array),
Constructor(ArrayBuffer buffer,
optional unsigned long byteOffset, optional unsigned long length)
]
-interface Uint16Array {
+interface Uint16Array : ArrayBufferView {
const long BYTES_PER_ELEMENT = 2;
readonly attribute unsigned long length;
@@ -133,13 +146,15 @@ Uint16Array implements ArrayBufferView;
[
+ CustomIndexedGetter,
+ CustomIndexedSetter,
Constructor(unsigned long length),
Constructor(Int32Array array),
Constructor(long[] array),
Constructor(ArrayBuffer buffer,
optional unsigned long byteOffset, optional unsigned long length)
]
-interface Int32Array {
+interface Int32Array : ArrayBufferView {
const long BYTES_PER_ELEMENT = 4;
readonly attribute unsigned long length;
@@ -154,13 +169,15 @@ Int32Array implements ArrayBufferView;
[
+ CustomIndexedGetter,
+ CustomIndexedSetter,
Constructor(unsigned long length),
Constructor(Uint32Array array),
Constructor(unsigned long[] array),
Constructor(ArrayBuffer buffer,
optional unsigned long byteOffset, optional unsigned long length)
]
-interface Uint32Array {
+interface Uint32Array : ArrayBufferView {
const long BYTES_PER_ELEMENT = 4;
readonly attribute unsigned long length;
@@ -175,13 +192,15 @@ Uint32Array implements ArrayBufferView;
[
+ CustomIndexedGetter,
+ CustomIndexedSetter,
Constructor(unsigned long length),
Constructor(Float32Array array),
Constructor(float[] array),
Constructor(ArrayBuffer buffer,
optional unsigned long byteOffset, optional unsigned long length)
]
-interface Float32Array {
+interface Float32Array : ArrayBufferView {
const long BYTES_PER_ELEMENT = 4;
readonly attribute unsigned long length;
@@ -196,13 +215,15 @@ Float32Array implements ArrayBufferView;
[
+ CustomIndexedGetter,
+ CustomIndexedSetter,
Constructor(unsigned long length),
Constructor(Float64Array array),
Constructor(double[] array),
Constructor(ArrayBuffer buffer,
optional unsigned long byteOffset, optional unsigned long length)
]
-interface Float64Array {
+interface Float64Array : ArrayBufferView {
const long BYTES_PER_ELEMENT = 8;
readonly attribute unsigned long length;
@@ -221,7 +242,7 @@ Float64Array implements ArrayBufferView;
optional unsigned long byteOffset,
optional unsigned long byteLength)
]
-interface DataView {
+interface DataView : ArrayBufferView{
// Gets the value of the given type at the specified byte offset
// from the start of the view. There is no alignment constraint;
// multi-byte values may be fetched from any offset.
diff --git a/contrib/dom/scripts/CodeGenerator.pm b/contrib/dom/scripts/CodeGenerator.pm
index 232cfda..fba0093 100644
--- a/contrib/dom/scripts/CodeGenerator.pm
+++ b/contrib/dom/scripts/CodeGenerator.pm
@@ -277,8 +277,12 @@ sub IDLFileForInterface
$File::Find::prune = 1 if /^\../;
};
find($wanted, @directories);
+ $idlFiles->{"ArrayBufferView"} = "../idl/TypedArray.idl"
}
+ # print Dumper($object);
+ # print Dumper($interfaceName);
+
return $idlFiles->{$interfaceName};
}
diff --git a/contrib/dom/scripts/CodeGeneratorArabicaJSC.pm b/contrib/dom/scripts/CodeGeneratorArabicaJSC.pm
index 8fc67ce..f9a2d25 100644
--- a/contrib/dom/scripts/CodeGeneratorArabicaJSC.pm
+++ b/contrib/dom/scripts/CodeGeneratorArabicaJSC.pm
@@ -127,7 +127,7 @@ sub GenerateHeader
my $interface = shift;
my $interfaceName = $interface->name;
my $extensions = $interface->extendedAttributes;
- #print Dumper($interface);
+# print Dumper($interface);
# Copy contents of parent interfaces except the first parent.
my @parents;
@@ -196,6 +196,10 @@ END
}
push(@headerContent, "\n");
+ if ($extensions->{'Constructors'}) {
+ push(@headerContent, "\n static JSObjectRef jsConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);");
+ }
+
# attribute getter and setters
foreach my $attribute (@{$interface->attributes}) {
my $name = $attribute->signature->name;
@@ -221,7 +225,7 @@ END
push(@headerContent, "\n static JSValueRef getPropertyCustomCallback(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);");
}
if ($extensions->{'CustomIndexedSetter'}) {
- push(@headerContent, "\n static JSValueRef setPropertyCustomCallback(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception);");
+ push(@headerContent, "\n static bool setPropertyCustomCallback(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception);");
}
push(@headerContent, "\n");
@@ -246,6 +250,9 @@ END
if ($extensions->{'CustomIndexedSetter'}) {
push(@headerContent, " classDef.setProperty = setPropertyCustomCallback;\n");
}
+ if ($extensions->{'Constructors'}) {
+ push(@headerContent, " classDef.callAsConstructor = jsConstructor;\n");
+ }
if (@{$interface->parents}) {
my $parent = @{$interface->parents}[0];
push(@headerContent, " classDef.parentClass = JSC${parent}::getTmpl();\n");
@@ -302,12 +309,15 @@ sub GenerateClassDefStatics
push(@implContent, "\n};\n");
push(@implContent, "\nJSStaticFunction JSC${interfaceName}::staticFunctions[] = {");
+ my %generated;
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";
+ next if (exists $generated{"${name}"});
+ $generated{"${name}"} = 1;
push(@implContent, "\n { \"${name}\", ${callback}, ${flags} },");
}
@@ -361,7 +371,7 @@ END
retPrivData->dom = privData->dom;
retPrivData->nativeObj = arabicaRet;
- JSObjectRef arbaicaRetObj = JSObjectMake(ctx, arbaicaRetClass, arabicaRet);
+ JSObjectRef arbaicaRetObj = JSObjectMake(ctx, arbaicaRetClass, retPrivData);
return arbaicaRetObj;
END
} else {
@@ -441,6 +451,130 @@ sub GenerateConditionalUndefReturn
return "if (!$getterExpression) return JSValueMakeUndefined(ctx);";
}
+sub GenerateConstructor
+{
+ my $interface = shift;
+ my $interfaceName = $interface->name;
+ my $extensions = $interface->extendedAttributes;
+ my $wrapperType = IdlToWrapperType($interfaceName);
+
+ if ($extensions->{'Constructors'}) {
+ push(@implContent, <<END);
+
+JSObjectRef JSC${interfaceName}::jsConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) {
+ ${wrapperType}* localInstance = NULL;
+END
+
+
+ # dispatch the actual constructor
+ push(@implContent, "\n if (false) {\n}");
+ my @variants;
+ foreach my $fullCons (@{$extensions->{'Constructors'}}) {
+ push (@variants, $fullCons);
+
+ for (my $i = @{$fullCons}; $i > 0; $i--) {
+ my $variant = @{$fullCons}[$i];
+ if ($variant->{'domSignature::isOptional'}) {
+ my $slice;
+ for (my $j = 0; $j < $i; $j++) {
+ push(@{$slice}, @{$fullCons}[$j]);
+ }
+ push (@variants, $slice);
+ }
+ }
+
+ # sort to put most determinate signatures first
+ @variants = sort {
+ if (@{$b} != @{$a}) {
+ # more arguments are more determinant
+ @{$b} <=> @{$a};
+ } else {
+ my @aWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$a});
+ my @bWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$b});
+ @bWrap <=> @aWrap;
+ }
+ } @variants;
+ }
+ foreach my $constructor (@variants) {
+ push(@implContent, " else if (argumentCount == " . @{$constructor});
+ for (my $i = 0; $i < @{$constructor}; $i++) {
+ my $type = $constructor->[$i]->{'domSignature::type'};
+ AddToImplIncludes("JSC".$type.".h") if (IsWrapperType($type));
+ push(@implContent, " &&\n " . IdlToTypeChecker($type, "arguments[$i]"));
+
+ }
+
+ push(@implContent, ") {\n");
+ my $constructorArgs;
+ my $constructorSep = "";
+ for (my $i = 0; $i < @{$constructor}; $i++) {
+ my $type = $constructor->[$i]->{'domSignature::type'};
+ my $name = $constructor->[$i]->{'domSignature::name'};
+ my ($handle, $deref) = IdlToArgHandle($type, "local".ucfirst($name), "arguments[$i]", $interfaceName);
+ $constructorArgs .= ${constructorSep}.${deref};
+ $constructorSep = ", ";
+ push(@implContent, "\n $handle");
+
+ }
+ push(@implContent, "\n localInstance = new ".IdlToWrapperType($interfaceName)."(${constructorArgs});");
+ push(@implContent, "\n\n }");
+
+ }
+ push(@implContent, "\n");
+
+ push(@implContent, <<END);
+ if (!localInstance) {
+ JSStringRef exceptionString = JSStringCreateWithUTF8CString("Parameter mismatch while calling constructor for ${interfaceName}");
+ *exception = JSValueMakeString(ctx, exceptionString);
+ JSStringRelease(exceptionString);
+ return (JSObjectRef)JSValueMakeNull(ctx);
+ }
+
+ JSClassRef retClass = JSC${interfaceName}::getTmpl();
+
+ struct JSC${interfaceName}::JSC${interfaceName}Private* retPrivData = new JSC${interfaceName}::JSC${interfaceName}Private();
+ retPrivData->nativeObj = localInstance;
+
+ JSObjectRef retObj = JSObjectMake(ctx, retClass, retPrivData);
+ return retObj;
+ }
+END
+ }
+}
+
+sub IdlToTypeChecker
+{
+ my $idlType = shift;
+ my $attr = shift;
+
+ return "JSValueIsString(ctx, ${attr})" if ($idlType eq "DOMString");
+ return "JSValueIsBoolean(ctx, ${attr})" if ($idlType eq "boolean");
+ return "JSValueIsNumber(ctx, ${attr})" if ($idlType eq "short");
+ return "JSValueIsNumber(ctx, ${attr})" if ($idlType eq "long");
+ return "JSValueIsObject(ctx, ${attr})" if ($idlType eq "long[]");
+ return "JSValueIsNumber(ctx, ${attr})" if ($idlType eq "unsigned short");
+ return "JSValueIsNumber(ctx, ${attr})" if ($idlType eq "unsigned long");
+ return "JSValueIsNumber(ctx, ${attr})" if ($idlType eq "byte");
+ return "JSValueIsNumber(ctx, ${attr})" if ($idlType eq "octet");
+ return "JSValueIsNumber(ctx, ${attr})" if ($idlType eq "double");
+ return "JSValueIsObject(ctx, ${attr})" if ($idlType eq "double[]");
+ return "JSValueIsNumber(ctx, ${attr})" if ($idlType eq "float");
+ return "JSValueIsObject(ctx, ${attr})" if ($idlType eq "float[]");
+ return "JSValueIsObject(ctx, ${attr})" if ($idlType eq "short[]");
+ return "JSValueIsObject(ctx, ${attr})" if ($idlType eq "unsigned short[]");
+ return "JSValueIsObject(ctx, ${attr})" if ($idlType eq "unsigned long[]");
+ return "JSValueIsObject(ctx, ${attr})" if ($idlType eq "byte[]");
+ return "JSValueIsObject(ctx, ${attr})" if ($idlType eq "octet[]");
+ return "true" if ($idlType eq "any");
+
+ return "JSValueIsObject(ctx, ${attr}) && JSValueIsObjectOfClass(ctx, ${attr}, JSC${idlType}::getTmpl())" if (IsWrapperType($idlType));
+
+ print $idlType."\n";
+ die();
+
+}
+
+
sub GenerateImplementationFunctionCallbacks
{
my $interface = shift;
@@ -459,22 +593,65 @@ sub GenerateImplementationFunctionCallbacks
next if (exists $generated{"${name}Callback"});
$generated{"${name}Callback"} = 1;
+ # get all functions with this name
+ my @sameFunctions = grep($_->signature->name eq $name, @{$interface->functions});
+
# signature
push(@implContent, <<END);
+
JSValueRef JSC${interfaceName}::${name}Callback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception) {
END
# arguments count and type checking
- push(@implContent, GenerateArgumentsCountCheck($function, $interface));
- my $argCheckExpr = GenerateArgumentsTypeCheck($function, $interface);
+ # push(@implContent, GenerateArgumentsCountCheck($function, $interface));
+ # my $argCheckExpr = GenerateArgumentsTypeCheck($function, $interface);
# get this
push(@implContent, "\n struct JSC${interfaceName}Private* privData = (struct JSC${interfaceName}Private*)JSObjectGetPrivate(thisObj);\n");
+
+ # establish all variants
+ my @variants;
+ foreach my $functionVar (@sameFunctions) {
+ push (@variants, $functionVar->parameters);
+
+ for (my $i = @{$functionVar->parameters}; $i > 0; $i--) {
+ my $variant = @{$functionVar->parameters}[$i];
+ if ($variant->{'domSignature::isOptional'}) {
+ my $slice;
+ for (my $j = 0; $j < $i; $j++) {
+ push(@{$slice}, @{$functionVar->parameters}[$j]);
+ }
+ push (@variants, $slice);
+ }
+ }
+ }
# arguments to local handles
- my $parameterIndex = 0;
- my @argList;
- foreach my $parameter (@{$function->parameters}) {
+ push(@implContent, "\n if (false) {");
+
+ # sort to put most determinate signatures first
+ @variants = sort {
+ if (@{$b} != @{$a}) {
+ # more arguments are more determinant
+ @{$b} <=> @{$a};
+ } else {
+ my @aWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$a});
+ my @bWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$b});
+ @bWrap <=> @aWrap;
+ }
+ } @variants;
+
+ foreach my $variant (@variants) {
+ my $parameterIndex = 0;
+ my @argList;
+
+ push(@implContent, "\n } else if (argumentCount == " . @{$variant});
+ for (my $i = 0; $i < @{$variant}; $i++) {
+ my $type = $variant->[$i]->{'domSignature::type'};
+ push(@implContent, " &&\n " . IdlToTypeChecker($type, "arguments[$i]"));
+ }
+ push(@implContent, ")\n {");
+ foreach my $parameter (@{$variant}) {
my $type = $parameter->type;
AddToImplIncludes("JSC".$type.".h") if (IsWrapperType($type));
@@ -484,40 +661,49 @@ END
push(@argList, $deref);
$parameterIndex++;
- }
+ }
- # invoke native function with argument handles
- my $retNativeType = IdlToNativeType($retType);
- my $wrapperFunctionName = IdlToWrapperFunction($interface, $function);
- if (IsWrapperType($retType)) {
- push(@implContent, "\n\n ${retNativeType}* retVal = new $wrapperRetType(privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . "));\n");
- } elsif ($retNativeType eq "void") {
- push(@implContent, "\n\n privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n");
- } else {
- push(@implContent, "\n\n ${retNativeType} retVal = privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n");
- }
+ # invoke native function with argument handles
+ my $retNativeType = IdlToNativeType($retType);
+ my $wrapperFunctionName = IdlToWrapperFunction($interface, $function);
+ if (IsWrapperType($retType)) {
+ push(@implContent, "\n\n ${retNativeType}* retVal = new $wrapperRetType(privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . "));\n");
+ } elsif ($retNativeType eq "void") {
+ push(@implContent, "\n\n privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n");
+ } else {
+ push(@implContent, "\n\n ${retNativeType} retVal = privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n");
+ }
- # wrap return type if needed
- if (IsWrapperType($retType)) {
- AddToImplIncludes("JSC".$retType.".h");
+ # wrap return type if needed
+ if (IsWrapperType($retType)) {
+ AddToImplIncludes("JSC".$retType.".h");
- push(@implContent, <<END);
- JSClassRef retClass = JSC${retType}::getTmpl();
+ push(@implContent, <<END);
+ JSClassRef retClass = JSC${retType}::getTmpl();
- struct JSC${retType}::JSC${retType}Private* retPrivData = new JSC${retType}::JSC${retType}Private();
- retPrivData->dom = privData->dom;
- retPrivData->nativeObj = retVal;
+ struct JSC${retType}::JSC${retType}Private* retPrivData = new JSC${retType}::JSC${retType}Private();
+ retPrivData->dom = privData->dom;
+ retPrivData->nativeObj = retVal;
- JSObjectRef retObj = JSObjectMake(ctx, retClass, retPrivData);
+ JSObjectRef retObj = JSObjectMake(ctx, retClass, retPrivData);
- return retObj;
+ return retObj;
END
- } else {
- my $toHandleString = NativeToHandle($retNativeType, "retVal", "jscRetVal");
- push(@implContent, "${toHandleString}\n return jscRetVal;");
+ } else {
+ my $toHandleString = NativeToHandle($retNativeType, "retVal", "jscRetVal");
+ push(@implContent, "${toHandleString}\n return jscRetVal;");
+ }
}
+ push(@implContent, <<END);
- push(@implContent, "\n }\n\n");
+ }
+
+ JSStringRef exceptionString = JSStringCreateWithUTF8CString("Parameter mismatch while calling ${name}");
+ *exception = JSValueMakeString(ctx, exceptionString);
+ JSStringRelease(exceptionString);
+ return JSValueMakeUndefined(ctx);
+ }
+END
}
}
@@ -547,6 +733,9 @@ sub GenerateImplementation
push(@implContent, "JSClassRef JSC${interfaceName}::Tmpl;\n");
GenerateClassDefStatics($interface);
+ if ($interface->extendedAttributes->{'Constructors'}) {
+ GenerateConstructor($interface);
+ }
GenerateImplementationAttributes($interface);
GenerateImplementationFunctionCallbacks($interface);
@@ -654,7 +843,7 @@ sub IdlToNativeType
return "unsigned long" if ($idlType eq "unsigned long");
return "void" if ($idlType eq "void");
return "char" if ($idlType eq "byte");
- return "char" if ($idlType eq "octet");
+ return "unsigned char" if ($idlType eq "octet");
return "double" if ($idlType eq "double");
return "float" if ($idlType eq "float");
die(${idlType});
@@ -671,6 +860,7 @@ sub NativeToHandle
return ("\n JSValueRef ${paramName} = JSValueMakeNumber(ctx, ${nativeName});") if ($nativeType eq "float");
return ("\n JSValueRef ${paramName} = JSValueMakeNumber(ctx, ${nativeName});") if ($nativeType eq "short");
return ("\n JSValueRef ${paramName} = JSValueMakeNumber(ctx, ${nativeName});") if ($nativeType eq "char");
+ return ("\n JSValueRef ${paramName} = JSValueMakeNumber(ctx, ${nativeName});") if ($nativeType eq "unsigned char");
return ("\n JSValueRef ${paramName} = JSValueMakeNumber(ctx, ${nativeName});") if ($nativeType eq "unsigned short");
return ("\n JSValueRef ${paramName} = JSValueMakeNumber(ctx, ${nativeName});") if ($nativeType eq "unsigned long");
return ("\n JSValueRef ${paramName} = JSValueMakeNumber(ctx, ${nativeName});") if ($nativeType eq "long");
@@ -731,16 +921,41 @@ sub IdlToArgHandle
return ("double ${localName} = (double)JSValueToNumber(ctx, ${paramName}, exception);", ${localName}) if ($type eq "double");
return ("short ${localName} = (short)JSValueToNumber(ctx, ${paramName}, exception);", ${localName}) if ($type eq "short");
return ("char ${localName} = (char)JSValueToNumber(ctx, ${paramName}, exception);", ${localName}) if ($type eq "byte");
- return ("unsigned char ${localName} = (char)JSValueToNumber(ctx, ${paramName}, exception);", ${localName}) if ($type eq "octet");
+ return ("unsigned char ${localName} = (unsigned char)JSValueToNumber(ctx, ${paramName}, exception);", ${localName}) if ($type eq "octet");
return ("bool ${localName} = JSValueToBoolean(ctx, ${paramName});", ${localName}) if ($type eq "boolean");
- return ("float[] ${localName} = JSObjectGetPrivate(JSValueToObject(ctx, ${paramName}, exception))->getFloatArray();", ${localName}) if ($type eq "float[]");
- return ("double[] ${localName} = JSObjectGetPrivate(JSValueToObject(ctx, ${paramName}, exception))->getDoubleArray();", ${localName}) if ($type eq "double[]");
- return ("long[] ${localName} = JSObjectGetPrivate(JSValueToObject(ctx, ${paramName}, exception))->getLongArray();", ${localName}) if ($type eq "long[]");
return ("void* ${localName} = JSObjectGetPrivate(JSValueToObject(ctx, ${paramName}, exception));", ${localName}) if ($type eq "any");
+
+ if ($type =~ /(.*)\[\]$/) {
+ my $nativeType = $1;
+ $nativeType = "char" if ($nativeType =~ /^byte$/);
+ $nativeType = "unsigned char" if ($nativeType =~ /^octet$/);
+ return ("\
+ std::vector<${nativeType}> ${localName};\n\
+ JSValueRef ${localName}Item;
+ unsigned int ${localName}Index = 0;
+ while((${localName}Item = JSObjectGetPropertyAtIndex(ctx, JSValueToObject(ctx, ${paramName}, exception), ${localName}Index, exception))) {\
+ if (JSValueIsUndefined(ctx, ${localName}Item))\
+ break;\
+ if (JSValueIsNumber(ctx,${localName}Item))\
+ ${localName}.push_back(JSValueToNumber(ctx, ${localName}Item, exception));\
+ ${localName}Index++;\
+ }", "${localName}");
+ }
+ # return ("std::vector<float> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToNumber()->Value());\n}", "${localName}") if ($type eq "float[]");
+ # return ("std::vector<double> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToNumber()->Value());\n}", "${localName}") if ($type eq "double[]");
+ # return ("std::vector<char> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInt32()->Value());\n}", "${localName}") if ($type eq "byte[]");
+ # return ("std::vector<short> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInt32()->Value());\n}", "${localName}") if ($type eq "short[]");
+ # return ("std::vector<unsigned short> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "unsigned short[]");
+ # return ("std::vector<unsigned long> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "unsigned long[]");
+ # return ("std::vector<unsigned char> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "octet[]");
if (IsWrapperType($type)) {
my $wrapperType = IdlToWrapperType($type);
- return ("${wrapperType}* ${localName} = ((struct JSC${type}::JSC${type}Private*)JSObjectGetPrivate(JSValueToObject(ctx, ${paramName}, exception)))->nativeObj;", "*${localName}");
+ if ($wrapperType =~ /^Arabica.*/) {
+ return ("${wrapperType}* ${localName} = ((struct JSC${type}::JSC${type}Private*)JSObjectGetPrivate(JSValueToObject(ctx, ${paramName}, exception)))->nativeObj;", "*${localName}");
+ } else {
+ return ("${wrapperType}* ${localName} = ((struct JSC${type}::JSC${type}Private*)JSObjectGetPrivate(JSValueToObject(ctx, ${paramName}, exception)))->nativeObj;", "${localName}");
+ }
}
print $type."\n";
@@ -832,7 +1047,7 @@ sub GenerateArgumentsTypeCheck
my $parameterIndex = 0;
foreach my $parameter (@{$function->parameters}) {
- my $value = "args[$parameterIndex]";
+ my $value = "arguments[$parameterIndex]";
my $type = $parameter->type;
# Only DOMString or wrapper types are checked.
@@ -895,18 +1110,23 @@ my %non_wrapper_types = (
'long' => 1,
'long[]' => 1,
'short' => 1,
+ 'short[]' => 1,
'void' => 1,
'byte' => 1,
'octet' => 1,
'char' => 1,
'float[]' => 1,
+ 'byte[]' => 1,
'float' => 1,
'double[]' => 1,
'double' => 1,
'unsigned int' => 1,
'unsigned long long' => 1,
'unsigned long' => 1,
- 'unsigned short' => 1
+ 'unsigned long[]' => 1,
+ 'unsigned short' => 1,
+ 'unsigned short[]' => 1,
+ 'octet[]' => 1
);
sub IsWrapperType
diff --git a/contrib/dom/scripts/CodeGeneratorArabicaV8.pm b/contrib/dom/scripts/CodeGeneratorArabicaV8.pm
index 8623694..08a5805 100644
--- a/contrib/dom/scripts/CodeGeneratorArabicaV8.pm
+++ b/contrib/dom/scripts/CodeGeneratorArabicaV8.pm
@@ -84,6 +84,8 @@ sub GenerateInterface
my $object = shift;
my $interface = shift;
+# print Dumper($interface);
+
# Start actual generation
if ($interface->extendedAttributes->{"Callback"}) {
die();
@@ -184,7 +186,6 @@ END
push(@headerContent, "\n static bool hasInstance(v8::Handle<v8::Value>);");
push(@headerContent, "\n");
-
# callbacks for actual functions
my %generated;
foreach my $function (@{$interface->functions}) {
@@ -233,6 +234,22 @@ sub GenerateClassPrototypeHeader
my $interfaceName = $interface->name;
my $extensions = $interface->extendedAttributes;
+ if ($extensions->{'Constructors'}) {
+
+ push(@headerContent, "\n");
+ push(@headerContent, " static v8::Handle<v8::Value> constructor(const v8::Arguments&);\n");
+ push(@headerContent, " static v8::Persistent<v8::FunctionTemplate> Constr;\n");
+ push(@headerContent, <<END);
+ static v8::Handle<v8::FunctionTemplate> getConstructor() {
+ if (Constr.IsEmpty()) {
+ v8::Handle<v8::FunctionTemplate> constr = v8::FunctionTemplate::New(constructor);
+ Constr = v8::Persistent<v8::FunctionTemplate>::New(constr);
+ }
+ return Constr;
+ }
+END
+ }
+
push(@headerContent, "\n static v8::Persistent<v8::FunctionTemplate> Tmpl;\n");
push(@headerContent, <<END);
static v8::Handle<v8::FunctionTemplate> getTmpl() {
@@ -269,10 +286,13 @@ END
}
push(@headerContent, "\n");
+ my %generated;
foreach my $function (@{$interface->functions}) {
my $name = $function->signature->name;
my $attrExt = $function->signature->extendedAttributes;
my $custom = ($attrExt->{'Custom'} ? "Custom" : "");
+ next if (exists $generated{"${name}"});
+ $generated{"${name}"} = 1;
push(@headerContent, <<END);
prototype->Set(v8::String::NewSymbol("${name}"),
v8::FunctionTemplate::New(V8${interfaceName}::${name}${custom}Callback, v8::Undefined()), static_cast<v8::PropertyAttribute>(v8::DontDelete));
@@ -379,7 +399,7 @@ END
push(@implContent, "\n v8::Local<v8::Object> self = info.Holder();");
push(@implContent, "\n struct V8${interfaceName}Private* privData = V8DOM::toClassPtr<V8${interfaceName}Private >(self->GetInternalField(0));");
- my ($handle, $deref) = IdlToArgHandle($attribute->signature->type, "local".ucfirst($attribute->signature->name), "value");
+ my ($handle, $deref) = IdlToArgHandle($attribute->signature->type, "local".ucfirst($attribute->signature->name), "value", $interfaceName);
push(@implContent, "\n $handle");
push(@implContent, "\n privData->nativeObj->${wrapperSetter}(${deref});");
@@ -401,12 +421,108 @@ sub GenerateConditionalUndefReturn
return "if (!$getterExpression) return v8::Undefined();";
}
+sub GenerateConstructor
+{
+ my $interface = shift;
+ my $interfaceName = $interface->name;
+ my $wrapperType = IdlToWrapperType($interfaceName);
+ my $extensions = $interface->extendedAttributes;
+
+ if ($extensions->{'Constructors'}) {
+
+ push(@implContent, "\n v8::Handle<v8::Value> V8${interfaceName}::constructor(const v8::Arguments& args) {");
+ push(@implContent, <<END);
+
+ if (!args.IsConstructCall())
+ return v8::ThrowException(v8::String::New("Cannot call constructor as function"));
+END
+
+ push(@implContent, "\n ".IdlToWrapperType($interfaceName)."* localInstance = NULL;");
+ # dispatch the actual constructor
+ push(@implContent, "\n if (false) {\n}");
+ my @variants;
+ foreach my $fullCons (@{$extensions->{'Constructors'}}) {
+ push (@variants, $fullCons);
+
+ for (my $i = @{$fullCons}; $i > 0; $i--) {
+ my $variant = @{$fullCons}[$i];
+ if ($variant->{'domSignature::isOptional'}) {
+ my $slice;
+ for (my $j = 0; $j < $i; $j++) {
+ push(@{$slice}, @{$fullCons}[$j]);
+ }
+ push (@variants, $slice);
+ }
+ }
+
+ # sort to put most determinate signatures first
+ @variants = sort {
+ if (@{$b} != @{$a}) {
+ # more arguments are more determinant
+ @{$b} <=> @{$a};
+ } else {
+ my @aWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$a});
+ my @bWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$b});
+ @bWrap <=> @aWrap;
+ }
+ } @variants;
+ }
+ foreach my $constructor (@variants) {
+ push(@implContent, " else if (args.Length() == " . @{$constructor});
+
+ for (my $i = 0; $i < @{$constructor}; $i++) {
+ my $type = $constructor->[$i]->{'domSignature::type'};
+ AddToImplIncludes("V8".$type.".h") if (IsWrapperType($type));
+ push(@implContent, " &&\n " . IdlToTypeChecker($type, "args[$i]"));
+
+ }
+ push(@implContent, ") {\n");
+ my $constructorArgs;
+ my $constructorSep = "";
+ for (my $i = 0; $i < @{$constructor}; $i++) {
+ my $type = $constructor->[$i]->{'domSignature::type'};
+ my $name = $constructor->[$i]->{'domSignature::name'};
+ my ($handle, $deref) = IdlToArgHandle($type, "local".ucfirst($name), "args[$i]", $interfaceName);
+ $constructorArgs .= ${constructorSep}.${deref};
+ $constructorSep = ", ";
+ push(@implContent, "\n $handle");
+
+ }
+ push(@implContent, "\n localInstance = new ".IdlToWrapperType($interfaceName)."(${constructorArgs});");
+ push(@implContent, "\n\n }");
+ }
+ push(@implContent, "\n");
+
+ push(@implContent, <<END);
+ if (!localInstance) {
+ throw V8Exception("Parameter mismatch while calling constructor for ${interfaceName}");
+ return v8::Undefined();
+ }
+
+ v8::Handle<v8::Function> retCtor = V8${interfaceName}::getTmpl()->GetFunction();
+ v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance());
+
+ struct V8${interfaceName}::V8${interfaceName}Private* retPrivData = new V8${interfaceName}::V8${interfaceName}Private();
+ retPrivData->nativeObj = localInstance;
+
+ retObj->SetInternalField(0, V8DOM::toExternal(retPrivData));
+
+ retObj.MakeWeak(0, V8${interfaceName}::jsDestructor);
+ return retObj;
+ }
+END
+ }
+
+}
+
sub GenerateImplementationFunctionCallbacks
{
my $interface = shift;
my $interfaceName = $interface->name;
my $wrapperType = IdlToWrapperType($interfaceName);
+ my $extensions = $interface->extendedAttributes;
+
# Generate methods for functions.
my %generated;
foreach my $function (@{$interface->functions}) {
@@ -419,73 +535,112 @@ sub GenerateImplementationFunctionCallbacks
next if (exists $generated{"${name}Callback"});
$generated{"${name}Callback"} = 1;
+ # get all functions with this name
+ my @sameFunctions = grep($_->signature->name eq $name, @{$interface->functions});
+
# signature
push(@implContent, <<END);
- v8::Handle<v8::Value> V8${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 V8Exception(\"Parameter mismatch while calling ${name}\");
+ v8::Handle<v8::Value> V8${interfaceName}::${name}Callback(const v8::Arguments& args) {
END
# get this
push(@implContent, "\n v8::Local<v8::Object> self = args.Holder();");
push(@implContent, "\n struct V8${interfaceName}Private* privData = V8DOM::toClassPtr<V8${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("V8".$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++;
+ # establish all variants
+ my @variants;
+ foreach my $functionVar (@sameFunctions) {
+ push (@variants, $functionVar->parameters);
+
+ for (my $i = @{$functionVar->parameters}; $i > 0; $i--) {
+ my $variant = @{$functionVar->parameters}[$i];
+ if ($variant->{'domSignature::isOptional'}) {
+ my $slice;
+ for (my $j = 0; $j < $i; $j++) {
+ push(@{$slice}, @{$functionVar->parameters}[$j]);
+ }
+ push (@variants, $slice);
+ }
+ }
}
- # invoke native function with argument handles
- my $retNativeType = IdlToNativeType($retType);
- my $wrapperFunctionName = IdlToWrapperFunction($interface, $function);
- if (IsWrapperType($retType)) {
- push(@implContent, "\n\n ${retNativeType}* retVal = new $wrapperRetType(privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . "));\n");
- } elsif ($retNativeType eq "void") {
- push(@implContent, "\n\n privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n");
- } else {
- push(@implContent, "\n\n ${retNativeType} retVal = privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n");
- }
+ # arguments to local handles
+ push(@implContent, "\n if (false) {");
+
+ # sort to put most determinate signatures first
+ @variants = sort {
+ if (@{$b} != @{$a}) {
+ # more arguments are more determinant
+ @{$b} <=> @{$a};
+ } else {
+ my @aWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$a});
+ my @bWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$b});
+ @bWrap <=> @aWrap;
+ }
+ } @variants;
+
+ foreach my $variant (@variants) {
+ my $parameterIndex = 0;
+ my @argList;
+
+ push(@implContent, "\n } else if (args.Length() == " . @{$variant});
+ for (my $i = 0; $i < @{$variant}; $i++) {
+ my $type = $variant->[$i]->{'domSignature::type'};
+ push(@implContent, " &&\n " . IdlToTypeChecker($type, "args[$i]"));
+ }
+ push(@implContent, ")\n {");
+ foreach my $parameter (@{$variant}) {
+ my $value = "args[$parameterIndex]";
+ my $type = $parameter->type;
+ AddToImplIncludes("V8".$type.".h") if (IsWrapperType($type));
+
+ my ($handle, $deref) = IdlToArgHandle($parameter->type, "local".ucfirst($parameter->name), "args[${parameterIndex}]", $interfaceName);
+ push(@implContent, "\n ${handle}");
+ push(@argList, $deref);
+ $parameterIndex++;
+ }
- # wrap return type if needed
- if (IsWrapperType($retType)) {
- AddToImplIncludes("V8".$retType.".h");
+ # invoke native function with argument handles
+ my $retNativeType = IdlToNativeType($retType);
+ my $wrapperFunctionName = IdlToWrapperFunction($interface, $function);
+ if (IsWrapperType($retType)) {
+ push(@implContent, "\n\n ${retNativeType}* retVal = new $wrapperRetType(privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . "));\n");
+ } elsif ($retNativeType eq "void") {
+ push(@implContent, "\n\n privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n");
+ } else {
+ push(@implContent, "\n\n ${retNativeType} retVal = privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n");
+ }
- push(@implContent, <<END);
- v8::Handle<v8::Function> retCtor = V8${retType}::getTmpl()->GetFunction();
- v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance());
+ # wrap return type if needed
+ if (IsWrapperType($retType)) {
+ AddToImplIncludes("V8".$retType.".h");
- struct V8${retType}::V8${retType}Private* retPrivData = new V8${retType}::V8${retType}Private();
- retPrivData->dom = privData->dom;
- retPrivData->nativeObj = retVal;
+ push(@implContent, <<END);
+ v8::Handle<v8::Function> retCtor = V8${retType}::getTmpl()->GetFunction();
+ v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance());
- retObj->SetInternalField(0, V8DOM::toExternal(retPrivData));
+ struct V8${retType}::V8${retType}Private* retPrivData = new V8${retType}::V8${retType}Private();
+ retPrivData->dom = privData->dom;
+ retPrivData->nativeObj = retVal;
- retObj.MakeWeak(0, V8${retType}::jsDestructor);
- return retObj;
+ retObj->SetInternalField(0, V8DOM::toExternal(retPrivData));
+
+ retObj.MakeWeak(0, V8${retType}::jsDestructor);
+ return retObj;
END
- } else {
- my $toHandleString = NativeToHandle($retNativeType, "retVal");
- push(@implContent, "\n return ${toHandleString};");
+ } else {
+ my $toHandleString = NativeToHandle($retNativeType, "retVal");
+ push(@implContent, "\n return ${toHandleString};");
+ }
}
-
- push(@implContent, "\n }\n\n");
+ push(@implContent, <<END);
+
+ }
+ throw V8Exception("Parameter mismatch while calling ${name}");
+ return v8::Undefined();
+ }
+END
}
}
@@ -498,6 +653,7 @@ sub GenerateImplementation
my $visibleInterfaceName = $codeGenerator->GetVisibleInterfaceName($interface);
my $v8InterfaceName = "V8$interfaceName";
my $wrapperType = IdlToWrapperType($interfaceName);
+ my $extensions = $interface->extendedAttributes;
AddToImplIncludes("V8${interfaceName}.h");
@@ -512,11 +668,17 @@ sub GenerateImplementation
}
push(@implContent, "namespace Arabica {\n");
push(@implContent, "namespace DOM {\n\n");
- push(@implContent, " v8::Persistent<v8::FunctionTemplate> V8${interfaceName}::Tmpl;\n\n");
+ push(@implContent, " v8::Persistent<v8::FunctionTemplate> V8${interfaceName}::Tmpl;\n");
+ if ($extensions->{'Constructors'}) {
+ push(@implContent, " v8::Persistent<v8::FunctionTemplate> V8${interfaceName}::Constr;\n");
+ GenerateConstructor($interface);
+ }
+
GenerateImplementationAttributes($interface);
GenerateImplementationFunctionCallbacks($interface);
+
push(@implContent, <<END);
bool V8${interfaceName}::hasInstance(v8::Handle<v8::Value> value) {
return getTmpl()->HasInstance(value);
@@ -624,7 +786,7 @@ sub IdlToNativeType
return "unsigned long" if ($idlType eq "unsigned long");
return "void" if ($idlType eq "void");
return "char" if ($idlType eq "byte");
- return "char" if ($idlType eq "octet");
+ return "unsigned char" if ($idlType eq "octet");
return "double" if ($idlType eq "double");
return "float" if ($idlType eq "float");
die(${idlType});
@@ -643,6 +805,7 @@ sub NativeToHandle
return ("v8::Number::New(${nativeName})") if ($nativeType eq "char");
return ("v8::Number::New(${nativeName})") if ($nativeType eq "unsigned short");
return ("v8::Number::New(${nativeName})") if ($nativeType eq "unsigned long");
+ return ("v8::Number::New(${nativeName})") if ($nativeType eq "unsigned char");
return ("v8::Number::New(${nativeName})") if ($nativeType eq "long");
return ("v8::String::New(${nativeName}.c_str())") if ($nativeType eq "std::string");
return ("v8::Undefined()") if ($nativeType eq "void");
@@ -679,6 +842,7 @@ sub IdlToArgHandle
my $type = shift;
my $localName = shift;
my $paramName = shift;
+ my $thisType = 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");
@@ -691,12 +855,21 @@ sub IdlToArgHandle
return ("short ${localName} = ${paramName}->ToNumber()->Int32Value();", ${localName}) if ($type eq "short");
return ("unsigned char ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "octet");
return ("void* ${localName} = v8::External::Unwrap(${paramName}->ToObject()->GetInternalField(0));", ${localName}) if ($type eq "any");
- return ("long[] ${localName} = V8DOM::toClassPtr<V8${type}::V8${type}Private >(${paramName}->ToObject()->GetInternalField(0))->nativeObj->getLongArray();", "${localName}") if ($type eq "long[]");
- return ("float[] ${localName} = V8DOM::toClassPtr<V8${type}::V8${type}Private >(${paramName}->ToObject()->GetInternalField(0))->nativeObj->getFloatArray();", "${localName}") if ($type eq "float[]");
- return ("double[] ${localName} = V8DOM::toClassPtr<V8${type}::V8${type}Private >(${paramName}->ToObject()->GetInternalField(0))->nativeObj->getDoubleArray();", "${localName}") if ($type eq "double[]");
+ return ("std::vector<long> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInteger()->Value());\n}", "${localName}") if ($type eq "long[]");
+ return ("std::vector<float> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToNumber()->Value());\n}", "${localName}") if ($type eq "float[]");
+ return ("std::vector<double> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToNumber()->Value());\n}", "${localName}") if ($type eq "double[]");
+ return ("std::vector<char> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInt32()->Value());\n}", "${localName}") if ($type eq "byte[]");
+ return ("std::vector<short> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInt32()->Value());\n}", "${localName}") if ($type eq "short[]");
+ return ("std::vector<unsigned short> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "unsigned short[]");
+ return ("std::vector<unsigned long> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "unsigned long[]");
+ return ("std::vector<unsigned char> ${localName};\nv8::Handle<v8::Array> ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "octet[]");
if (IsWrapperType($type)) {
my $wrapperType = IdlToWrapperType($type);
+ if ($type =~ /.*Array$/ or $type =~ /^ArrayBuffer.*/) {
+ return ("${wrapperType}* ${localName} = V8DOM::toClassPtr<V8${type}::V8${type}Private >(${paramName}->ToObject()->GetInternalField(0))->nativeObj;", "${localName}");
+ }
+
return ("${wrapperType}* ${localName} = V8DOM::toClassPtr<V8${type}::V8${type}Private >(${paramName}->ToObject()->GetInternalField(0))->nativeObj;", "*${localName}");
}
@@ -704,6 +877,38 @@ sub IdlToArgHandle
die();
}
+sub IdlToTypeChecker
+{
+ my $idlType = shift;
+ my $attr = shift;
+
+ return $attr."->IsString()" if ($idlType eq "DOMString");
+ return $attr."->IsBoolean()" if ($idlType eq "boolean");
+ return $attr."->IsInt32()" if ($idlType eq "short");
+ return $attr."->IsInt32()" if ($idlType eq "long");
+ return $attr."->IsArray()" if ($idlType eq "long[]");
+ return $attr."->IsUint32()" if ($idlType eq "unsigned short");
+ return $attr."->IsUint32()" if ($idlType eq "unsigned long");
+ return $attr."->IsInt32()" if ($idlType eq "byte");
+ return $attr."->IsUint32()" if ($idlType eq "octet");
+ return $attr."->IsNumber()" if ($idlType eq "double");
+ return $attr."->IsArray()" if ($idlType eq "double[]");
+ return $attr."->IsNumber()" if ($idlType eq "float");
+ return $attr."->IsArray()" if ($idlType eq "float[]");
+ return $attr."->IsArray()" if ($idlType eq "short[]");
+ return $attr."->IsArray()" if ($idlType eq "unsigned short[]");
+ return $attr."->IsArray()" if ($idlType eq "unsigned long[]");
+ return $attr."->IsArray()" if ($idlType eq "byte[]");
+ return $attr."->IsArray()" if ($idlType eq "octet[]");
+ return "true" if ($idlType eq "any");
+
+ return $attr."->IsObject() && V8".$idlType."::hasInstance(".$attr.")" if (IsWrapperType($idlType));
+
+ print $idlType."\n";
+ die();
+
+}
+
sub IdlToWrapperAttrGetter
{
my $interface = shift;
@@ -749,76 +954,6 @@ sub IsReadonly
}
-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 V8Exception(\"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() || V8${type}::hasInstance($value))");
- } else {
- push(@andExpression, "(V8${type}::hasInstance($value))");
- }
- }
-
- $parameterIndex++;
- }
- my $res = join(" && ", @andExpression);
- $res = "($res)" if @andExpression > 1;
- return $res;
-}
-
-
my %non_wrapper_types = (
'CompareHow' => 1,
'DOMObject' => 1,
@@ -844,18 +979,23 @@ my %non_wrapper_types = (
'long' => 1,
'long[]' => 1,
'short' => 1,
+ 'short[]' => 1,
'void' => 1,
'byte' => 1,
+ 'byte[]' => 1,
'octet' => 1,
'char' => 1,
'float[]' => 1,
'float' => 1,
'double[]' => 1,
+ 'octet[]' => 1,
'double' => 1,
'unsigned int' => 1,
'unsigned long long' => 1,
'unsigned long' => 1,
- 'unsigned short' => 1
+ 'unsigned long[]' => 1,
+ 'unsigned short' => 1,
+ 'unsigned short[]' => 1
);
sub IsWrapperType
diff --git a/contrib/dom/scripts/IDLParser.pm b/contrib/dom/scripts/IDLParser.pm
index 654c920..61fab7b 100644
--- a/contrib/dom/scripts/IDLParser.pm
+++ b/contrib/dom/scripts/IDLParser.pm
@@ -25,6 +25,7 @@ use strict;
use preprocessor;
use Class::Struct;
+use Data::Dumper;
use constant StringToken => 0;
use constant IntegerToken => 1;
@@ -75,6 +76,7 @@ struct( domSignature => {
type => '$', # Variable type
extendedAttributes => '$', # Extended attributes
isNullable => '$', # Is variable type Nullable (T?)
+ isOptional => '$', # Is variable optional (T?)
isVariadic => '$' # Is variable variadic (long... numbers)
});
@@ -1282,6 +1284,8 @@ sub parseOptionalOrRequiredArgument
$paramDataNode->type($type);
$paramDataNode->name($self->parseArgumentName());
$self->parseDefault();
+ $paramDataNode->isOptional(1);
+# print Dumper($paramDataNode);
return $paramDataNode;
}
if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
@@ -2431,8 +2435,8 @@ sub applyExtendedAttributeList
$constructor->{overloadedIndex} = $index++;
push(@{$interface->constructors}, $constructor);
}
- delete $extendedAttributeList->{"Constructors"};
- $extendedAttributeList->{"Constructor"} = "VALUE_IS_MISSING";
+ # delete $extendedAttributeList->{"Constructors"};
+ # $extendedAttributeList->{"Constructor"} = "VALUE_IS_MISSING";
} elsif (defined $extendedAttributeList->{"NamedConstructor"}) {
my $newDataNode = domFunction->new();
$newDataNode->signature(domSignature->new());