Bug 1268798 part 3 - Add LenientSetter extended attribute. r=khuey

MozReview-Commit-ID: 61wybyS36KE

--HG--
extra : source : 98e1ae5fa2ddf5308fba6e09b47cbb831c60ac8a
This commit is contained in:
Xidorn Quan 2016-05-12 10:28:56 +10:00
parent fe0ed0d00a
commit 114633161f
4 changed files with 106 additions and 3 deletions

View File

@ -44,3 +44,4 @@ DEPRECATED_OPERATION(NavigatorGetUserMedia)
DEPRECATED_OPERATION(WebrtcDeprecatedPrefix)
DEPRECATED_OPERATION(AppCache)
DEPRECATED_OPERATION(PrefixedFullscreenAPI)
DEPRECATED_OPERATION(LenientSetter)

View File

@ -2548,7 +2548,8 @@ class AttrDefiner(PropertyDefiner):
def setter(attr):
if (attr.readonly and
attr.getExtendedAttribute("PutForwards") is None and
attr.getExtendedAttribute("Replaceable") is None):
attr.getExtendedAttribute("Replaceable") is None and
attr.getExtendedAttribute("LenientSetter") is None):
return "JSNATIVE_WRAPPER(nullptr)"
if self.static:
accessor = 'set_' + IDLToCIdentifier(attr.identifier.name)
@ -8832,6 +8833,24 @@ class CGSpecializedReplaceableSetter(CGSpecializedSetter):
attrName)
class CGSpecializedLenientSetter(CGSpecializedSetter):
"""
A class for generating the code for a specialized attribute setter with
LenientSetter that the JIT can call with lower overhead.
"""
def __init__(self, descriptor, attr):
CGSpecializedSetter.__init__(self, descriptor, attr)
def definition_body(self):
attrName = self.attr.identifier.name
# JS_DefineProperty can only deal with ASCII
assert all(ord(c) < 128 for c in attrName)
return dedent("""
DeprecationWarning(cx, obj, nsIDocument::eLenientSetter);
return true;
""")
def memberReturnsNewObject(member):
return member.getExtendedAttribute("NewObject") is not None
@ -8969,7 +8988,8 @@ class CGMemberJITInfo(CGThing):
[self.member.type], None)
if (not self.member.readonly or
self.member.getExtendedAttribute("PutForwards") is not None or
self.member.getExtendedAttribute("Replaceable") is not None):
self.member.getExtendedAttribute("Replaceable") is not None or
self.member.getExtendedAttribute("LenientSetter") is not None):
setterinfo = ("%s_setterinfo" %
IDLToCIdentifier(self.member.identifier.name))
# Actually a JSJitSetterOp, but JSJitGetterOp is first in the
@ -11838,7 +11858,8 @@ def memberProperties(m, descriptor):
props.isCrossOriginSetter = True
elif descriptor.needsSpecialGenericOps():
props.isGenericSetter = True
elif m.getExtendedAttribute("Replaceable"):
elif (m.getExtendedAttribute("Replaceable") or
m.getExtendedAttribute("LenientSetter")):
if descriptor.needsSpecialGenericOps():
props.isGenericSetter = True
@ -11950,6 +11971,8 @@ class CGDescriptor(CGThing):
crossOriginSetters.add(m.identifier.name)
elif m.getExtendedAttribute("Replaceable"):
cgThings.append(CGSpecializedReplaceableSetter(descriptor, m))
elif m.getExtendedAttribute("LenientSetter"):
cgThings.append(CGSpecializedLenientSetter(descriptor, m))
if (not m.isStatic() and
descriptor.interface.hasInterfacePrototypeObject()):
cgThings.append(CGMemberJITInfo(descriptor, m))

View File

@ -4080,6 +4080,24 @@ class IDLAttribute(IDLInterfaceMember):
raise WebIDLError("[PutForwards] and [Replaceable] can't both "
"appear on the same attribute",
[attr.location, self.location])
elif identifier == "LenientSetter":
if not attr.noArguments():
raise WebIDLError("[LenientSetter] must take no arguments",
[attr.location])
if not self.readonly:
raise WebIDLError("[LenientSetter] is only allowed on readonly "
"attributes", [attr.location, self.location])
if self.isStatic():
raise WebIDLError("[LenientSetter] is only allowed on non-static "
"attributes", [attr.location, self.location])
if self.getExtendedAttribute("PutForwards") is not None:
raise WebIDLError("[LenientSetter] and [PutForwards] can't both "
"appear on the same attribute",
[attr.location, self.location])
if self.getExtendedAttribute("Replaceable") is not None:
raise WebIDLError("[LenientSetter] and [Replaceable] can't both "
"appear on the same attribute",
[attr.location, self.location])
elif identifier == "LenientFloat":
if self.readonly:
raise WebIDLError("[LenientFloat] used on a readonly attribute",
@ -4818,6 +4836,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
elif identifier == "PutForwards":
raise WebIDLError("Only attributes support [PutForwards]",
[attr.location, self.location])
elif identifier == "LenientSetter":
raise WebIDLError("Only attributes support [LenientSetter]",
[attr.location, self.location])
elif identifier == "LenientFloat":
# This is called before we've done overload resolution
assert len(self.signatures()) == 1

View File

@ -0,0 +1,58 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
def should_throw(parser, harness, message, code):
parser = parser.reset();
threw = False
try:
parser.parse(code)
parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown: %s" % message)
def WebIDLTest(parser, harness):
# The [LenientSetter] extended attribute MUST take no arguments.
should_throw(parser, harness, "no arguments", """
interface I {
[LenientSetter=X] readonly attribute long A;
};
""")
# An attribute with the [LenientSetter] extended attribute MUST NOT
# also be declared with the [PutForwards] extended attribute.
should_throw(parser, harness, "PutForwards", """
interface I {
[PutForwards=B, LenientSetter] readonly attribute J A;
};
interface J {
attribute long B;
};
""")
# An attribute with the [LenientSetter] extended attribute MUST NOT
# also be declared with the [Replaceable] extended attribute.
should_throw(parser, harness, "Replaceable", """
interface I {
[Replaceable, LenientSetter] readonly attribute J A;
};
""")
# The [LenientSetter] extended attribute MUST NOT be used on an
# attribute that is not read only.
should_throw(parser, harness, "writable attribute", """
interface I {
[LenientSetter] attribute long A;
};
""")
# The [LenientSetter] extended attribute MUST NOT be used on a
# static attribute.
should_throw(parser, harness, "static attribute", """
interface I {
[LenientSetter] static readonly attribute long A;
};
""")