mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Bug 771636 part 1. Rearrange default-value handling so we actually set C++ values directly instead of round-tripping through jsval. r=peterv
This commit is contained in:
parent
ed5dda2b46
commit
d988f0953a
@ -1355,6 +1355,14 @@ builtinNames = {
|
||||
IDLType.Tags.double: 'double'
|
||||
}
|
||||
|
||||
numericTags = [
|
||||
IDLType.Tags.int8, IDLType.Tags.uint8,
|
||||
IDLType.Tags.int16, IDLType.Tags.uint16,
|
||||
IDLType.Tags.int32, IDLType.Tags.uint32,
|
||||
IDLType.Tags.int64, IDLType.Tags.uint64,
|
||||
IDLType.Tags.float, IDLType.Tags.double
|
||||
]
|
||||
|
||||
class CastableObjectUnwrapper():
|
||||
"""
|
||||
A class for unwrapping an object named by the "source" argument
|
||||
@ -1440,7 +1448,8 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
||||
isDefinitelyObject=False,
|
||||
isMember=False,
|
||||
isOptional=False,
|
||||
invalidEnumValueFatal=True):
|
||||
invalidEnumValueFatal=True,
|
||||
defaultValue=None):
|
||||
"""
|
||||
Get a template for converting a JS value to a native object based on the
|
||||
given type and descriptor. If failureCode is given, then we're actually
|
||||
@ -1461,6 +1470,12 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
||||
If isOptional is true, then we are doing conversion of an optional
|
||||
argument with no default value.
|
||||
|
||||
invalidEnumValueFatal controls whether an invalid enum value conversion
|
||||
attempt will throw (if true) or simply return without doing anything (if
|
||||
false).
|
||||
|
||||
If defaultValue is not None, it's the IDL default value for this conversion
|
||||
|
||||
The return value from this function is a tuple consisting of four things:
|
||||
|
||||
1) A string representing the conversion code. This will have template
|
||||
@ -1470,6 +1485,9 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
||||
${valPtr} is a pointer to the JS::Value in question
|
||||
${holderName} replaced by the holder's name, if any
|
||||
${declName} replaced by the declaration's name
|
||||
${haveValue} replaced by an expression that evaluates to a boolean
|
||||
for whether we have a JS::Value. Only used when
|
||||
defaultValue is not None.
|
||||
|
||||
2) A CGThing representing the native C++ type we're converting to
|
||||
(declType). This is allowed to be None if the conversion code is
|
||||
@ -1488,6 +1506,12 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
||||
If holderType is not None then ${holderName} must be in scope
|
||||
before the generated code is entered.
|
||||
"""
|
||||
# If we have a defaultValue then we're not actually optional for
|
||||
# purposes of what we need to be declared as.
|
||||
assert(defaultValue is None or not isOptional)
|
||||
|
||||
# Also, we should not have a defaultValue if we know we're an object
|
||||
assert(not isDefinitelyObject or defaultValue is None)
|
||||
|
||||
# A helper function for dealing with failures due to the JS value being the
|
||||
# wrong type of value
|
||||
@ -1497,6 +1521,29 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
||||
"return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);"
|
||||
% toStringBool(isWorker)), post="\n")
|
||||
|
||||
# A helper function for handling default values. Takes a template
|
||||
# body and the C++ code to set the default value and wraps the
|
||||
# given template body in handling for the default value.
|
||||
def handleDefault(template, setDefault):
|
||||
if defaultValue is None:
|
||||
return template
|
||||
return CGWrapper(
|
||||
CGIndenter(CGGeneric(template)),
|
||||
pre="if (${haveValue}) {\n",
|
||||
post=("\n"
|
||||
"} else {\n"
|
||||
"%s;\n"
|
||||
"}" %
|
||||
CGIndenter(CGGeneric(setDefault)).define())).define()
|
||||
|
||||
# A helper function for handling null default values. Much like
|
||||
# handleDefault, but checks that the default value, if it exists, is null.
|
||||
def handleDefaultNull(template, codeToSetNull):
|
||||
if (defaultValue is not None and
|
||||
not isinstance(defaultValue, IDLNullValue)):
|
||||
raise TypeError("Can't handle non-null default value here")
|
||||
return handleDefault(template, codeToSetNull)
|
||||
|
||||
# A helper function for wrapping up the template body for
|
||||
# possibly-nullable objecty stuff
|
||||
def wrapObjectTemplate(templateBody, isDefinitelyObject, type,
|
||||
@ -1515,6 +1562,11 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
||||
"} else {\n" +
|
||||
CGIndenter(onFailure(failureCode, isWorker)).define() +
|
||||
"}")
|
||||
if type.nullable():
|
||||
templateBody = handleDefaultNull(templateBody, codeToSetNull)
|
||||
else:
|
||||
assert(defaultValue is None)
|
||||
|
||||
return templateBody
|
||||
|
||||
if type.isArray():
|
||||
@ -1602,11 +1654,13 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
if isMember:
|
||||
raise TypeError("Can't handle unions as members, we have a "
|
||||
"holderType")
|
||||
|
||||
nullable = type.nullable();
|
||||
if nullable:
|
||||
type = type.inner
|
||||
|
||||
assert(defaultValue is None or
|
||||
(isinstance(defaultValue, IDLNullValue) and nullable))
|
||||
|
||||
unionArgumentObj = "${holderName}"
|
||||
if isOptional or nullable:
|
||||
unionArgumentObj += ".ref()"
|
||||
@ -1759,10 +1813,10 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
nonConstDecl = "const_cast<" + typeName + "& >(${declName})"
|
||||
typeName = "const " + typeName
|
||||
|
||||
def handleNull(templateBody, setToNullVar):
|
||||
null = CGGeneric("if (${val}.isNullOrUndefined()) {\n"
|
||||
def handleNull(templateBody, setToNullVar, extraConditionForNull=""):
|
||||
null = CGGeneric("if (%s${val}.isNullOrUndefined()) {\n"
|
||||
" %s.SetNull();\n"
|
||||
"}" % setToNullVar)
|
||||
"}" % (extraConditionForNull, setToNullVar))
|
||||
templateBody = CGWrapper(CGIndenter(templateBody), pre="{\n", post="\n}")
|
||||
return CGList([null, templateBody], " else ")
|
||||
|
||||
@ -1792,7 +1846,13 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
|
||||
templateBody = CGList([constructHolder, templateBody], "\n")
|
||||
if nullable:
|
||||
templateBody = handleNull(templateBody, mutableDecl)
|
||||
if defaultValue:
|
||||
assert(isinstance(defaultValue, IDLNullValue))
|
||||
valueMissing = "!(${haveValue}) || "
|
||||
else:
|
||||
valueMissing = ""
|
||||
templateBody = handleNull(templateBody, mutableDecl,
|
||||
extraConditionForNull=valueMissing)
|
||||
templateBody = CGList([constructDecl, templateBody], "\n")
|
||||
|
||||
return templateBody.define(), declType, holderType, False
|
||||
@ -1980,6 +2040,18 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
nullBehavior = "eStringify"
|
||||
undefinedBehavior = "eStringify"
|
||||
|
||||
if defaultValue is not None:
|
||||
if not isinstance(defaultValue, IDLNullValue):
|
||||
raise TypeError("Can't handle non-null default values for "
|
||||
"strings yet")
|
||||
if not type.nullable():
|
||||
raise TypeError("Null default value for non-nullable string")
|
||||
val = "(${haveValue}) ? ${val} : JSVAL_NULL"
|
||||
valPtr = "(${haveValue}) ? ${valPtr} : NULL"
|
||||
else:
|
||||
val = "${val}"
|
||||
valPtr = "${valPtr}"
|
||||
|
||||
if isMember:
|
||||
# We have to make a copy, because our jsval may well not
|
||||
# live as long as our string needs to.
|
||||
@ -1987,12 +2059,12 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
return (
|
||||
"{\n"
|
||||
" FakeDependentString str;\n"
|
||||
" if (!ConvertJSValueToString(cx, ${val}, ${valPtr}, %s, %s, str)) {\n"
|
||||
" if (!ConvertJSValueToString(cx, %s, %s, %s, %s, str)) {\n"
|
||||
" return false;\n"
|
||||
" }\n"
|
||||
" ${declName} = str;\n"
|
||||
"}\n" %
|
||||
(nullBehavior, undefinedBehavior),
|
||||
(val, valPtr, nullBehavior, undefinedBehavior),
|
||||
declType, None,
|
||||
isOptional)
|
||||
|
||||
@ -2001,16 +2073,19 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
else:
|
||||
declType = "NonNull<nsAString>"
|
||||
return (
|
||||
"if (!ConvertJSValueToString(cx, ${val}, ${valPtr}, %s, %s, ${holderName})) {\n"
|
||||
"if (!ConvertJSValueToString(cx, %s, %s, %s, %s, ${holderName})) {\n"
|
||||
" return false;\n"
|
||||
"}\n"
|
||||
"const_cast<%s&>(${declName}) = &${holderName};" %
|
||||
(nullBehavior, undefinedBehavior, declType),
|
||||
(val, valPtr, nullBehavior, undefinedBehavior, declType),
|
||||
CGGeneric("const " + declType), CGGeneric("FakeDependentString"),
|
||||
# No need to deal with Optional here; we have handled it already
|
||||
False)
|
||||
|
||||
if type.isEnum():
|
||||
if defaultValue is not None:
|
||||
raise TypeError("Can't handle default values for enums")
|
||||
|
||||
if type.nullable():
|
||||
raise TypeError("We don't support nullable enumerated arguments "
|
||||
"yet")
|
||||
@ -2044,18 +2119,26 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
"rooting issues")
|
||||
# XXXbz we're going to assume that callback types are always
|
||||
# nullable and always have [TreatNonCallableAsNull] for now.
|
||||
haveCallable = "${val}.isObject() && JS_ObjectIsCallable(cx, &${val}.toObject())"
|
||||
if defaultValue is not None:
|
||||
assert(isinstance(defaultValue, IDLNullValue))
|
||||
haveCallable = "${haveValue} && " + haveCallable
|
||||
return (
|
||||
"if (${val}.isObject() && JS_ObjectIsCallable(cx, &${val}.toObject())) {\n"
|
||||
"if (%s) {\n"
|
||||
" ${declName} = &${val}.toObject();\n"
|
||||
"} else {\n"
|
||||
" ${declName} = NULL;\n"
|
||||
"}", CGGeneric("JSObject*"), None, isOptional)
|
||||
"}" % haveCallable,
|
||||
CGGeneric("JSObject*"), None, isOptional)
|
||||
|
||||
if type.isAny():
|
||||
if isMember:
|
||||
raise TypeError("Can't handle member 'any'; need to sort out "
|
||||
"rooting issues")
|
||||
return ("${declName} = ${val};", CGGeneric("JS::Value"), None, isOptional)
|
||||
templateBody = "${declName} = ${val};"
|
||||
templateBody = handleDefaultNull(templateBody,
|
||||
"${declName} = JS::NullValue()")
|
||||
return (templateBody, CGGeneric("JS::Value"), None, isOptional)
|
||||
|
||||
if type.isObject():
|
||||
if isMember:
|
||||
@ -2093,9 +2176,17 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
declType = CGWrapper(declType, pre="const ")
|
||||
selfRef = "const_cast<%s&>(%s)" % (typeName, selfRef)
|
||||
|
||||
template = ("if (!%s.Init(cx, ${val})) {\n"
|
||||
# We do manual default value handling here, because we
|
||||
# actually do want a jsval, and we only handle null anyway
|
||||
if defaultValue is not None:
|
||||
assert(isinstance(defaultValue, IDLNullValue))
|
||||
val = "(${haveValue}) ? ${val} : JSVAL_NULL"
|
||||
else:
|
||||
val = "${val}"
|
||||
|
||||
template = ("if (!%s.Init(cx, %s)) {\n"
|
||||
" return false;\n"
|
||||
"}" % selfRef)
|
||||
"}" % (selfRef, val))
|
||||
|
||||
return (template, declType, None, False)
|
||||
|
||||
@ -2105,15 +2196,43 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
# XXXbz need to add support for [EnforceRange] and [Clamp]
|
||||
typeName = builtinNames[type.tag()]
|
||||
if type.nullable():
|
||||
return ("if (${val}.isNullOrUndefined()) {\n"
|
||||
" ${declName}.SetNull();\n"
|
||||
"} else if (!ValueToPrimitive<" + typeName + ">(cx, ${val}, &${declName}.SetValue())) {\n"
|
||||
" return false;\n"
|
||||
"}", CGGeneric("Nullable<" + typeName + ">"), None, isOptional)
|
||||
dataLoc = "${declName}.SetValue()"
|
||||
nullCondition = "${val}.isNullOrUndefined()"
|
||||
if defaultValue is not None and isinstance(defaultValue, IDLNullValue):
|
||||
nullCondition = "!(${haveValue}) || " + nullCondition
|
||||
template = (
|
||||
"if (%s) {\n"
|
||||
" ${declName}.SetNull();\n"
|
||||
"} else if (!ValueToPrimitive<%s>(cx, ${val}, &%s)) {\n"
|
||||
" return false;\n"
|
||||
"}" % (nullCondition, typeName, dataLoc))
|
||||
declType = CGGeneric("Nullable<" + typeName + ">")
|
||||
else:
|
||||
return ("if (!ValueToPrimitive<" + typeName + ">(cx, ${val}, &${declName})) {\n"
|
||||
" return false;\n"
|
||||
"}", CGGeneric(typeName), None, isOptional)
|
||||
assert(defaultValue is None or
|
||||
not isinstance(defaultValue, IDLNullValue))
|
||||
dataLoc = "${declName}"
|
||||
template = (
|
||||
"if (!ValueToPrimitive<%s>(cx, ${val}, &%s)) {\n"
|
||||
" return false;\n"
|
||||
"}" % (typeName, dataLoc))
|
||||
declType = CGGeneric(typeName)
|
||||
if (defaultValue is not None and
|
||||
# We already handled IDLNullValue, so just deal with the other ones
|
||||
not isinstance(defaultValue, IDLNullValue)):
|
||||
tag = defaultValue.type.tag()
|
||||
if tag in numericTags:
|
||||
defaultStr = defaultValue.value
|
||||
else:
|
||||
assert(tag == IDLType.Tags.bool)
|
||||
defaultStr = toStringBool(defaultValue.value)
|
||||
template = CGWrapper(CGIndenter(CGGeneric(template)),
|
||||
pre="if (${haveValue}) {\n",
|
||||
post=("\n"
|
||||
"} else {\n"
|
||||
" %s = %s;\n"
|
||||
"}" % (dataLoc, defaultStr))).define()
|
||||
|
||||
return (template, declType, None, isOptional)
|
||||
|
||||
def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
|
||||
argcAndIndex=None):
|
||||
@ -2216,14 +2335,6 @@ def convertConstIDLValueToJSVal(value):
|
||||
return "DOUBLE_TO_JSVAL(%s)" % (value.value)
|
||||
raise TypeError("Const value of unhandled type: " + value.type)
|
||||
|
||||
def convertIDLDefaultValueToJSVal(value):
|
||||
if value.type:
|
||||
tag = value.type.tag()
|
||||
if (tag == IDLType.Tags.domstring and
|
||||
(not value.type.nullable() or not isinstance(value, IDLNullValue))):
|
||||
assert False # Not implemented!
|
||||
return convertConstIDLValueToJSVal(value)
|
||||
|
||||
class CGArgumentConverter(CGThing):
|
||||
"""
|
||||
A class that takes an IDL argument object, its index in the
|
||||
@ -2237,8 +2348,8 @@ class CGArgumentConverter(CGThing):
|
||||
if argument.variadic:
|
||||
raise TypeError("We don't support variadic arguments yet " +
|
||||
str(argument.location))
|
||||
# XXXbz should optional jsval args get JSVAL_VOID? What about
|
||||
# others?
|
||||
assert(not argument.defaultValue or argument.optional)
|
||||
|
||||
replacer = {
|
||||
"index" : index,
|
||||
"argc" : argc,
|
||||
@ -2248,20 +2359,14 @@ class CGArgumentConverter(CGThing):
|
||||
"declName" : "arg%d" % index,
|
||||
"holderName" : ("arg%d" % index) + "_holder"
|
||||
}
|
||||
if argument.optional and argument.defaultValue:
|
||||
replacer["defaultValue"] = convertIDLDefaultValueToJSVal(argument.defaultValue)
|
||||
self.replacementVariables["val"] = string.Template(
|
||||
"(${index} < ${argc} ? ${argv}[${index}] : ${defaultValue})"
|
||||
).substitute(replacer)
|
||||
self.replacementVariables["valPtr"] = string.Template(
|
||||
"(${index} < ${argc} ? &${argv}[${index}] : NULL)"
|
||||
).substitute(replacer)
|
||||
else:
|
||||
self.replacementVariables["val"] = string.Template(
|
||||
"${argv}[${index}]"
|
||||
).substitute(replacer)
|
||||
self.replacementVariables["valPtr"] = (
|
||||
"&" + self.replacementVariables["val"])
|
||||
self.replacementVariables["val"] = string.Template(
|
||||
"${argv}[${index}]"
|
||||
).substitute(replacer)
|
||||
self.replacementVariables["valPtr"] = (
|
||||
"&" + self.replacementVariables["val"])
|
||||
if argument.defaultValue:
|
||||
self.replacementVariables["haveValue"] = string.Template(
|
||||
"${index} < ${argc}").substitute(replacer)
|
||||
self.descriptorProvider = descriptorProvider
|
||||
if self.argument.optional and not self.argument.defaultValue:
|
||||
self.argcAndIndex = replacer
|
||||
@ -2274,7 +2379,8 @@ class CGArgumentConverter(CGThing):
|
||||
getJSToNativeConversionTemplate(self.argument.type,
|
||||
self.descriptorProvider,
|
||||
isOptional=(self.argcAndIndex is not None),
|
||||
invalidEnumValueFatal=self.invalidEnumValueFatal),
|
||||
invalidEnumValueFatal=self.invalidEnumValueFatal,
|
||||
defaultValue=self.argument.defaultValue),
|
||||
self.replacementVariables,
|
||||
self.argcAndIndex).define()
|
||||
|
||||
@ -3051,6 +3157,7 @@ class FakeArgument():
|
||||
self.type = type
|
||||
self.optional = False
|
||||
self.variadic = False
|
||||
self.defaultValue = None
|
||||
|
||||
class CGSetterCall(CGGetterSetterCall):
|
||||
"""
|
||||
@ -4067,7 +4174,8 @@ class CGDictionary(CGThing):
|
||||
getJSToNativeConversionTemplate(member.type,
|
||||
descriptorProvider,
|
||||
isMember=True,
|
||||
isOptional=(not member.defaultValue)))
|
||||
isOptional=(not member.defaultValue),
|
||||
defaultValue=member.defaultValue))
|
||||
for member in dictionary.members ]
|
||||
except NoSuchDescriptorError, err:
|
||||
if not self.workers:
|
||||
@ -4204,6 +4312,8 @@ class CGDictionary(CGThing):
|
||||
assert holderType is None
|
||||
if dealWithOptional:
|
||||
replacements["declName"] = "(" + replacements["declName"] + ".Value())"
|
||||
if member.defaultValue:
|
||||
replacements["haveValue"] = "found"
|
||||
|
||||
conversionReplacements = {
|
||||
"propId" : self.makeIdName(member.identifier.name),
|
||||
@ -4221,12 +4331,8 @@ class CGDictionary(CGThing):
|
||||
" if (!JS_GetPropertyById(cx, &val.toObject(), ${propId}, &temp)) {\n"
|
||||
" return false;\n"
|
||||
" }\n"
|
||||
"} else {\n"
|
||||
" temp = ${defaultVal};\n"
|
||||
"}\n"
|
||||
"${convert}")
|
||||
conversionReplacements["defaultVal"] = (
|
||||
convertIDLDefaultValueToJSVal(member.defaultValue))
|
||||
else:
|
||||
conversion += (
|
||||
"if (found) {\n"
|
||||
|
@ -1753,7 +1753,8 @@ class IDLNullValue(IDLObject):
|
||||
def coerceToType(self, type, location):
|
||||
if (not isinstance(type, IDLNullableType) and
|
||||
not (type.isUnion() and type.hasNullableType) and
|
||||
not type.isDictionary()):
|
||||
not type.isDictionary() and
|
||||
not type.isAny()):
|
||||
raise WebIDLError("Cannot coerce null value to type %s." % type,
|
||||
[location])
|
||||
|
||||
|
@ -361,6 +361,7 @@ public:
|
||||
// Any types
|
||||
void PassAny(JSContext*, JS::Value, ErrorResult&);
|
||||
void PassOptionalAny(JSContext*, const Optional<JS::Value>&, ErrorResult&);
|
||||
void PassAnyDefaultNull(JSContext*, JS::Value, ErrorResult&);
|
||||
JS::Value ReceiveAny(JSContext*, ErrorResult&);
|
||||
|
||||
// object types
|
||||
|
@ -51,49 +51,49 @@ interface TestInterface {
|
||||
void passShort(short arg);
|
||||
short receiveShort();
|
||||
void passOptionalShort(optional short arg);
|
||||
void passOptionalShortWithDefault(optional short arg = 0);
|
||||
void passOptionalShortWithDefault(optional short arg = 5);
|
||||
|
||||
readonly attribute long readonlyLong;
|
||||
attribute long writableLong;
|
||||
void passLong(long arg);
|
||||
long receiveLong();
|
||||
void passOptionalLong(optional long arg);
|
||||
void passOptionalLongWithDefault(optional long arg = 0);
|
||||
void passOptionalLongWithDefault(optional long arg = 7);
|
||||
|
||||
readonly attribute long long readonlyLongLong;
|
||||
attribute long long writableLongLong;
|
||||
void passLongLong(long long arg);
|
||||
long long receiveLongLong();
|
||||
void passOptionalLongLong(optional long long arg);
|
||||
void passOptionalLongLongWithDefault(optional long long arg = 0);
|
||||
void passOptionalLongLongWithDefault(optional long long arg = -12);
|
||||
|
||||
readonly attribute octet readonlyOctet;
|
||||
attribute octet writableOctet;
|
||||
void passOctet(octet arg);
|
||||
octet receiveOctet();
|
||||
void passOptionalOctet(optional octet arg);
|
||||
void passOptionalOctetWithDefault(optional octet arg = 0);
|
||||
void passOptionalOctetWithDefault(optional octet arg = 19);
|
||||
|
||||
readonly attribute unsigned short readonlyUnsignedShort;
|
||||
attribute unsigned short writableUnsignedShort;
|
||||
void passUnsignedShort(unsigned short arg);
|
||||
unsigned short receiveUnsignedShort();
|
||||
void passOptionalUnsignedShort(optional unsigned short arg);
|
||||
void passOptionalUnsignedShortWithDefault(optional unsigned short arg = 0);
|
||||
void passOptionalUnsignedShortWithDefault(optional unsigned short arg = 2);
|
||||
|
||||
readonly attribute unsigned long readonlyUnsignedLong;
|
||||
attribute unsigned long writableUnsignedLong;
|
||||
void passUnsignedLong(unsigned long arg);
|
||||
unsigned long receiveUnsignedLong();
|
||||
void passOptionalUnsignedLong(optional unsigned long arg);
|
||||
void passOptionalUnsignedLongWithDefault(optional unsigned long arg = 0);
|
||||
void passOptionalUnsignedLongWithDefault(optional unsigned long arg = 6);
|
||||
|
||||
readonly attribute unsigned long long readonlyUnsignedLongLong;
|
||||
attribute unsigned long long writableUnsignedLongLong;
|
||||
void passUnsignedLongLong(unsigned long long arg);
|
||||
unsigned long long receiveUnsignedLongLong();
|
||||
void passOptionalUnsignedLongLong(optional unsigned long long arg);
|
||||
void passOptionalUnsignedLongLongWithDefault(optional unsigned long long arg = 0);
|
||||
void passOptionalUnsignedLongLongWithDefault(optional unsigned long long arg = 17);
|
||||
|
||||
// Castable interface types
|
||||
// XXXbz add tests for infallible versions of all the castable interface stuff
|
||||
@ -259,6 +259,7 @@ interface TestInterface {
|
||||
// Any types
|
||||
void passAny(any arg);
|
||||
void passOptionalAny(optional any arg);
|
||||
void passAnyDefaultNull(optional any arg = null);
|
||||
any receiveAny();
|
||||
|
||||
// object types
|
||||
|
Loading…
Reference in New Issue
Block a user