Bug 929609 part 2. Fix passing of typed arrays to JS-implemented WebIDL to actually work. r=peterv

This commit is contained in:
Boris Zbarsky 2014-08-25 15:07:45 -04:00
Родитель 30b87a2b87
Коммит be14202b3d
5 изменённых файлов: 94 добавлений и 52 удалений

Просмотреть файл

@ -1035,6 +1035,12 @@ class CGHeaders(CGWrapper):
elif unrolled.isInterface():
if unrolled.isSpiderMonkeyInterface():
bindingHeaders.add("jsfriendapi.h")
if jsImplementedDescriptors:
# Since we can't forward-declare typed array types
# (because they're typedefs), we have to go ahead and
# just include their header if we need to have functions
# taking references to them declared in that header.
headerSet = declareIncludes
headerSet.add("mozilla/dom/TypedArray.h")
else:
providers = getRelevantProviders(descriptor, config)
@ -5485,7 +5491,8 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
'jsvalHandle': "&tmp",
'returnsNewObject': returnsNewObject,
'exceptionCode': exceptionCode,
'obj': "returnArray"
'obj': "returnArray",
'typedArraysAreStructs': typedArraysAreStructs
})
sequenceWrapLevel -= 1
code = fill(
@ -5538,7 +5545,8 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
'jsvalHandle': "&tmp",
'returnsNewObject': returnsNewObject,
'exceptionCode': exceptionCode,
'obj': "returnObj"
'obj': "returnObj",
'typedArraysAreStructs': typedArraysAreStructs
})
mozMapWrapLevel -= 1
code = fill(
@ -11809,6 +11817,8 @@ class CGForwardDeclarations(CGWrapper):
builder.add(desc.nativeType)
except NoSuchDescriptorError:
pass
# Note: Spidermonkey interfaces are typedefs, so can't be
# forward-declared
elif t.isCallback():
builder.addInMozillaDom(str(t))
elif t.isDictionary():
@ -12015,7 +12025,7 @@ class CGBindingRoot(CGThing):
return {desc.getDescriptor(desc.interface.parent.identifier.name)}
for x in dependencySortObjects(jsImplemented, getParentDescriptor,
lambda d: d.interface.identifier.name):
cgthings.append(CGCallbackInterface(x))
cgthings.append(CGCallbackInterface(x, typedArraysAreStructs=True))
cgthings.append(CGJSImplClass(x))
# And make sure we have the right number of newlines at the end
@ -12196,9 +12206,9 @@ class CGNativeMember(ClassMethod):
# No need for a third element in the isMember case
return "JSObject*", None, None
if type.nullable():
returnCode = "${declName}.IsNull() ? nullptr : ${declName}.Value().Obj();\n"
returnCode = "${declName}.IsNull() ? nullptr : ${declName}.Value().Obj()"
else:
returnCode = "${declName}.Obj();\n"
returnCode = "${declName}.Obj()"
return "void", "", "aRetVal.set(%s);\n" % returnCode
if type.isSequence():
# If we want to handle sequence-of-sequences return values, we're
@ -13369,16 +13379,17 @@ class CGCallbackFunction(CGCallback):
class CGCallbackInterface(CGCallback):
def __init__(self, descriptor):
def __init__(self, descriptor, typedArraysAreStructs=False):
iface = descriptor.interface
attrs = [m for m in iface.members if m.isAttr() and not m.isStatic()]
getters = [CallbackGetter(a, descriptor) for a in attrs]
setters = [CallbackSetter(a, descriptor) for a in attrs
if not a.readonly]
getters = [CallbackGetter(a, descriptor, typedArraysAreStructs)
for a in attrs]
setters = [CallbackSetter(a, descriptor, typedArraysAreStructs)
for a in attrs if not a.readonly]
methods = [m for m in iface.members
if m.isMethod() and not m.isStatic() and not m.isIdentifierLess()]
methods = [CallbackOperation(m, sig, descriptor) for m in methods
for sig in m.signatures()]
methods = [CallbackOperation(m, sig, descriptor, typedArraysAreStructs)
for m in methods for sig in m.signatures()]
if iface.isJSImplemented() and iface.ctor():
sigs = descriptor.interface.ctor().signatures()
if len(sigs) != 1:
@ -13419,7 +13430,8 @@ class FakeMember():
class CallbackMember(CGNativeMember):
def __init__(self, sig, name, descriptorProvider, needThisHandling, rethrowContentException=False):
def __init__(self, sig, name, descriptorProvider, needThisHandling,
rethrowContentException=False, typedArraysAreStructs=False):
"""
needThisHandling is True if we need to be able to accept a specified
thisObj, False otherwise.
@ -13451,7 +13463,7 @@ class CallbackMember(CGNativeMember):
extendedAttrs={},
passJSBitsAsNeeded=False,
visibility=visibility,
typedArraysAreStructs=False)
typedArraysAreStructs=typedArraysAreStructs)
# We have to do all the generation of our body now, because
# the caller relies on us throwing if we can't manage it.
self.exceptionCode = ("aRv.Throw(NS_ERROR_UNEXPECTED);\n"
@ -13567,7 +13579,8 @@ class CallbackMember(CGNativeMember):
# CallSetup already handled the unmark-gray bits for us.
'obj': 'CallbackPreserveColor()',
'returnsNewObject': False,
'exceptionCode': self.exceptionCode
'exceptionCode': self.exceptionCode,
'typedArraysAreStructs': self.typedArraysAreStructs
})
except MethodNotNewObjectError as err:
raise TypeError("%s being passed as an argument to %s but is not "
@ -13670,9 +13683,10 @@ class CallbackMember(CGNativeMember):
class CallbackMethod(CallbackMember):
def __init__(self, sig, name, descriptorProvider, needThisHandling,
rethrowContentException=False):
rethrowContentException=False, typedArraysAreStructs=False):
CallbackMember.__init__(self, sig, name, descriptorProvider,
needThisHandling, rethrowContentException)
needThisHandling, rethrowContentException,
typedArraysAreStructs=typedArraysAreStructs)
def getRvalDecl(self):
return "JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());\n"
@ -13729,10 +13743,14 @@ class CallbackOperationBase(CallbackMethod):
"""
Common class for implementing various callback operations.
"""
def __init__(self, signature, jsName, nativeName, descriptor, singleOperation, rethrowContentException=False):
def __init__(self, signature, jsName, nativeName, descriptor,
singleOperation, rethrowContentException=False,
typedArraysAreStructs=False):
self.singleOperation = singleOperation
self.methodName = descriptor.binaryNameFor(jsName)
CallbackMethod.__init__(self, signature, nativeName, descriptor, singleOperation, rethrowContentException)
CallbackMethod.__init__(self, signature, nativeName, descriptor,
singleOperation, rethrowContentException,
typedArraysAreStructs=typedArraysAreStructs)
def getThisDecl(self):
if not self.singleOperation:
@ -13783,7 +13801,7 @@ class CallbackOperation(CallbackOperationBase):
"""
Codegen actual WebIDL operations on callback interfaces.
"""
def __init__(self, method, signature, descriptor):
def __init__(self, method, signature, descriptor, typedArraysAreStructs):
self.ensureASCIIName(method)
self.method = method
jsName = method.identifier.name
@ -13791,7 +13809,8 @@ class CallbackOperation(CallbackOperationBase):
jsName,
MakeNativeName(descriptor.binaryNameFor(jsName)),
descriptor, descriptor.interface.isSingleOperationInterface(),
rethrowContentException=descriptor.interface.isJSImplemented())
rethrowContentException=descriptor.interface.isJSImplemented(),
typedArraysAreStructs=typedArraysAreStructs)
def getPrettyName(self):
return "%s.%s" % (self.descriptorProvider.interface.identifier.name,
@ -13802,12 +13821,13 @@ class CallbackAccessor(CallbackMember):
"""
Shared superclass for CallbackGetter and CallbackSetter.
"""
def __init__(self, attr, sig, name, descriptor):
def __init__(self, attr, sig, name, descriptor, typedArraysAreStructs):
self.ensureASCIIName(attr)
self.attrName = attr.identifier.name
CallbackMember.__init__(self, sig, name, descriptor,
needThisHandling=False,
rethrowContentException=descriptor.interface.isJSImplemented())
rethrowContentException=descriptor.interface.isJSImplemented(),
typedArraysAreStructs=typedArraysAreStructs)
def getPrettyName(self):
return "%s.%s" % (self.descriptorProvider.interface.identifier.name,
@ -13815,11 +13835,12 @@ class CallbackAccessor(CallbackMember):
class CallbackGetter(CallbackAccessor):
def __init__(self, attr, descriptor):
def __init__(self, attr, descriptor, typedArraysAreStructs):
CallbackAccessor.__init__(self, attr,
(attr.type, []),
callbackGetterName(attr, descriptor),
descriptor)
descriptor,
typedArraysAreStructs)
def getRvalDecl(self):
return "JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());\n"
@ -13841,12 +13862,12 @@ class CallbackGetter(CallbackAccessor):
class CallbackSetter(CallbackAccessor):
def __init__(self, attr, descriptor):
def __init__(self, attr, descriptor, typedArraysAreStructs):
CallbackAccessor.__init__(self, attr,
(BuiltinTypes[IDLBuiltinType.Types.void],
[FakeArgument(attr.type, attr)]),
callbackSetterName(attr, descriptor),
descriptor)
descriptor, typedArraysAreStructs)
def getRvalDecl(self):
# We don't need an rval

Просмотреть файл

@ -461,6 +461,8 @@ public:
void PassVariadicTypedArray(const Sequence<Float32Array>&);
void PassVariadicNullableTypedArray(const Sequence<Nullable<Float32Array> >&);
void ReceiveUint8Array(JSContext*, JS::MutableHandle<JSObject*>);
void SetUint8ArrayAttr(const Uint8Array&);
void GetUint8ArrayAttr(JSContext*, JS::MutableHandle<JSObject*>);
// DOMString types
void PassString(const nsAString&);

Просмотреть файл

@ -34,6 +34,26 @@ callback interface TestCallbackInterface {
MozMap<long> getMozMapOfLong();
Dict? getDictionary();
void passArrayBuffer(ArrayBuffer arg);
void passNullableArrayBuffer(ArrayBuffer? arg);
void passOptionalArrayBuffer(optional ArrayBuffer arg);
void passOptionalNullableArrayBuffer(optional ArrayBuffer? arg);
void passOptionalNullableArrayBufferWithDefaultValue(optional ArrayBuffer? arg= null);
void passArrayBufferView(ArrayBufferView arg);
void passInt8Array(Int8Array arg);
void passInt16Array(Int16Array arg);
void passInt32Array(Int32Array arg);
void passUint8Array(Uint8Array arg);
void passUint16Array(Uint16Array arg);
void passUint32Array(Uint32Array arg);
void passUint8ClampedArray(Uint8ClampedArray arg);
void passFloat32Array(Float32Array arg);
void passFloat64Array(Float64Array arg);
void passSequenceOfArrayBuffers(sequence<ArrayBuffer> arg);
void passSequenceOfNullableArrayBuffers(sequence<ArrayBuffer?> arg);
void passVariadicTypedArray(Float32Array... arg);
void passVariadicNullableTypedArray(Float32Array?... arg);
Uint8Array receiveUint8Array();
attribute Uint8Array uint8ArrayAttr;
};
callback interface TestSingleOperationCallbackInterface {
@ -421,6 +441,7 @@ interface TestInterface {
void passVariadicTypedArray(Float32Array... arg);
void passVariadicNullableTypedArray(Float32Array?... arg);
Uint8Array receiveUint8Array();
attribute Uint8Array uint8ArrayAttr;
// DOMString types
void passString(DOMString arg);

Просмотреть файл

@ -307,6 +307,7 @@ interface TestExampleInterface {
void passVariadicTypedArray(Float32Array... arg);
void passVariadicNullableTypedArray(Float32Array?... arg);
Uint8Array receiveUint8Array();
attribute Uint8Array uint8ArrayAttr;
// DOMString types
void passString(DOMString arg);

Просмотреть файл

@ -303,33 +303,30 @@ interface TestJSImplInterface {
//MozMap<MozMap<long>> receiveMozMapOfMozMaps();
MozMap<any> receiveAnyMozMap();
// ArrayBuffer is handled differently in callback interfaces and the example generator.
// Need to figure out what should be done there. Seems like other typed array stuff is
// similarly not working in the JS implemented generator. Probably some other issues
// here as well.
// Typed array types
//void passArrayBuffer(ArrayBuffer arg);
//void passNullableArrayBuffer(ArrayBuffer? arg);
//void passOptionalArrayBuffer(optional ArrayBuffer arg);
//void passOptionalNullableArrayBuffer(optional ArrayBuffer? arg);
//void passOptionalNullableArrayBufferWithDefaultValue(optional ArrayBuffer? arg= null);
//void passArrayBufferView(ArrayBufferView arg);
//void passInt8Array(Int8Array arg);
//void passInt16Array(Int16Array arg);
//void passInt32Array(Int32Array arg);
//void passUint8Array(Uint8Array arg);
//void passUint16Array(Uint16Array arg);
//void passUint32Array(Uint32Array arg);
//void passUint8ClampedArray(Uint8ClampedArray arg);
//void passFloat32Array(Float32Array arg);
//void passFloat64Array(Float64Array arg);
//void passSequenceOfArrayBuffers(sequence<ArrayBuffer> arg);
//void passSequenceOfNullableArrayBuffers(sequence<ArrayBuffer?> arg);
//void passMozMapOfArrayBuffers(MozMap<ArrayBuffer> arg);
//void passMozMapOfNullableArrayBuffers(MozMap<ArrayBuffer?> arg);
//void passVariadicTypedArray(Float32Array... arg);
//void passVariadicNullableTypedArray(Float32Array?... arg);
//Uint8Array receiveUint8Array();
void passArrayBuffer(ArrayBuffer arg);
void passNullableArrayBuffer(ArrayBuffer? arg);
void passOptionalArrayBuffer(optional ArrayBuffer arg);
void passOptionalNullableArrayBuffer(optional ArrayBuffer? arg);
void passOptionalNullableArrayBufferWithDefaultValue(optional ArrayBuffer? arg= null);
void passArrayBufferView(ArrayBufferView arg);
void passInt8Array(Int8Array arg);
void passInt16Array(Int16Array arg);
void passInt32Array(Int32Array arg);
void passUint8Array(Uint8Array arg);
void passUint16Array(Uint16Array arg);
void passUint32Array(Uint32Array arg);
void passUint8ClampedArray(Uint8ClampedArray arg);
void passFloat32Array(Float32Array arg);
void passFloat64Array(Float64Array arg);
void passSequenceOfArrayBuffers(sequence<ArrayBuffer> arg);
void passSequenceOfNullableArrayBuffers(sequence<ArrayBuffer?> arg);
void passMozMapOfArrayBuffers(MozMap<ArrayBuffer> arg);
void passMozMapOfNullableArrayBuffers(MozMap<ArrayBuffer?> arg);
void passVariadicTypedArray(Float32Array... arg);
void passVariadicNullableTypedArray(Float32Array?... arg);
Uint8Array receiveUint8Array();
attribute Uint8Array uint8ArrayAttr;
// DOMString types
void passString(DOMString arg);