Bug 863094 - Infinity/-Infinity/NaN defaults for unrestricted types, r=bz

--HG--
extra : rebase_source : c2495008be9b084656222e6a0773c72d5224e9cc
This commit is contained in:
Olli Pettay 2013-04-18 19:58:01 +03:00
parent 580391a42b
commit 90a4da3e6f
5 changed files with 174 additions and 9 deletions

View File

@ -8,6 +8,7 @@ import operator
import os
import re
import string
import math
from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType
from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, Descriptor
@ -2045,10 +2046,23 @@ numericSuffixes = {
IDLType.Tags.uint32: 'U',
IDLType.Tags.int64: 'LL',
IDLType.Tags.uint64: 'ULL',
IDLType.Tags.unrestricted_float: 'F',
IDLType.Tags.float: 'F',
IDLType.Tags.unrestricted_double: 'D',
IDLType.Tags.double: 'D'
}
def numericValue(t, v):
if (t == IDLType.Tags.unrestricted_double or
t == IDLType.Tags.unrestricted_float):
if v == float("inf"):
return "MOZ_DOUBLE_POSITIVE_INFINITY()"
if v == float("-inf"):
return "MOZ_DOUBLE_NEGATIVE_INFINITY()"
if math.isnan(v):
return "MOZ_DOUBLE_NaN()"
return "%s%s" % (v, numericSuffixes[t])
class CastableObjectUnwrapper():
"""
A class for unwrapping an object named by the "source" argument
@ -3179,7 +3193,7 @@ for (uint32_t i = 0; i < length; ++i) {
tag = defaultValue.type.tag()
if tag in numericSuffixes:
# Some numeric literals require a suffix to compile without warnings
defaultStr = "%s%s" % (defaultValue.value, numericSuffixes[tag])
defaultStr = numericValue(tag, defaultValue.value)
else:
assert(tag == IDLType.Tags.bool)
defaultStr = toStringBool(defaultValue.value)
@ -3286,7 +3300,7 @@ def convertConstIDLValueToJSVal(value):
if tag == IDLType.Tags.uint32:
return "UINT_TO_JSVAL(%sU)" % (value.value)
if tag in [IDLType.Tags.int64, IDLType.Tags.uint64]:
return "DOUBLE_TO_JSVAL(%s%s)" % (value.value, numericSuffixes[tag])
return "DOUBLE_TO_JSVAL(%s)" % numericValue(tag, value.value)
if tag == IDLType.Tags.bool:
return "JSVAL_TRUE" if value.value else "JSVAL_FALSE"
if tag in [IDLType.Tags.float, IDLType.Tags.double]:

View File

@ -8,6 +8,7 @@ from ply import lex, yacc
import re
import os
import traceback
import math
# Machinery
@ -2257,6 +2258,13 @@ class IDLValue(IDLObject):
% (self.value, type.inner.identifier.name),
[location, type.inner.location])
return self
elif self.type.isFloat() and type.isFloat():
if (not type.isUnrestricted() and
(self.value == float("inf") or self.value == float("-inf") or
math.isnan(self.value))):
raise WebIDLError("Trying to convert unrestricted value %s to non-unrestricted"
% self.value, [location]);
return self
else:
raise WebIDLError("Cannot coerce type %s to type %s." %
(self.type, type), [location])
@ -3148,6 +3156,11 @@ class Tokenizer(object):
"OTHER"
]
def t_FLOATLITERAL(self, t):
r'(-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+|Infinity))|NaN'
t.value = float(t.value)
return t
def t_INTEGER(self, t):
r'-?(0([0-7]+|[Xx][0-9A-Fa-f]+)?|[1-9][0-9]*)'
try:
@ -3161,11 +3174,6 @@ class Tokenizer(object):
filename=self._filename)])
return t
def t_FLOATLITERAL(self, t):
r'-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)'
assert False
return t
def t_IDENTIFIER(self, t):
r'[A-Z_a-z][0-9A-Z_a-z]*'
t.type = self.keywords.get(t.value, 'IDENTIFIER')
@ -3594,8 +3602,8 @@ class Parser(Tokenizer):
"""
ConstValue : FLOATLITERAL
"""
assert False
pass
location = self.getLocation(p, 1)
p[0] = IDLValue(location, BuiltinTypes[IDLBuiltinType.Types.unrestricted_float], p[1])
def p_ConstValueString(self, p):
"""

View File

@ -442,3 +442,111 @@ def WebIDLTest(parser, harness):
threw = True
harness.ok(threw, "Member type must not be a nullable dictionary")
parser = parser.reset();
parser.parse("""
dictionary Foo {
unrestricted float urFloat = 0;
unrestricted float urFloat2 = 1.1;
unrestricted float urFloat3 = -1.1;
unrestricted float? urFloat4 = null;
unrestricted float infUrFloat = Infinity;
unrestricted float negativeInfUrFloat = -Infinity;
unrestricted float nanUrFloat = NaN;
unrestricted double urDouble = 0;
unrestricted double urDouble2 = 1.1;
unrestricted double urDouble3 = -1.1;
unrestricted double? urDouble4 = null;
unrestricted double infUrDouble = Infinity;
unrestricted double negativeInfUrDouble = -Infinity;
unrestricted double nanUrDouble = NaN;
};
""")
results = parser.finish()
harness.ok(True, "Parsing default values for unrestricted types succeeded.")
parser = parser.reset();
threw = False
try:
parser.parse("""
dictionary Foo {
double f = Infinity;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Only unrestricted values can be initialized to Infinity")
parser = parser.reset();
threw = False
try:
parser.parse("""
dictionary Foo {
double f = -Infinity;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Only unrestricted values can be initialized to -Infinity")
parser = parser.reset();
threw = False
try:
parser.parse("""
dictionary Foo {
double f = NaN;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Only unrestricted values can be initialized to NaN")
parser = parser.reset();
threw = False
try:
parser.parse("""
dictionary Foo {
float f = Infinity;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Only unrestricted values can be initialized to Infinity")
parser = parser.reset();
threw = False
try:
parser.parse("""
dictionary Foo {
float f = -Infinity;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Only unrestricted values can be initialized to -Infinity")
parser = parser.reset();
threw = False
try:
parser.parse("""
dictionary Foo {
float f = NaN;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Only unrestricted values can be initialized to NaN")

View File

@ -229,6 +229,15 @@ public:
double LenientDoubleAttr() const;
void SetLenientDoubleAttr(double);
void PassUnrestricted(float arg1,
float arg2,
float arg3,
float arg4,
double arg5,
double arg6,
double arg7,
double arg8);
// Interface types
already_AddRefed<TestInterface> ReceiveSelf();
already_AddRefed<TestInterface> ReceiveNullableSelf();

View File

@ -192,6 +192,15 @@ interface TestInterface {
[LenientFloat]
attribute double lenientDoubleAttr;
void passUnrestricted(optional unrestricted float arg1 = 0,
optional unrestricted float arg2 = Infinity,
optional unrestricted float arg3 = -Infinity,
optional unrestricted float arg4 = NaN,
optional unrestricted double arg5 = 0,
optional unrestricted double arg6 = Infinity,
optional unrestricted double arg7 = -Infinity,
optional unrestricted double arg8 = NaN);
// Castable interface types
// XXXbz add tests for throwing versions of all the castable interface stuff
TestInterface receiveSelf();
@ -589,6 +598,23 @@ dictionary Dict : ParentDict {
object? anotherObj = null;
TestCallback? someCallback = null;
any someAny;
unrestricted float urFloat = 0;
unrestricted float urFloat2 = 1.1;
unrestricted float urFloat3 = -1.1;
unrestricted float? urFloat4 = null;
unrestricted float infUrFloat = Infinity;
unrestricted float negativeInfUrFloat = -Infinity;
unrestricted float nanUrFloat = NaN;
unrestricted double urDouble = 0;
unrestricted double urDouble2 = 1.1;
unrestricted double urDouble3 = -1.1;
unrestricted double? urDouble4 = null;
unrestricted double infUrDouble = Infinity;
unrestricted double negativeInfUrDouble = -Infinity;
unrestricted double nanUrDouble = NaN;
};
dictionary ParentDict : GrandparentDict {