Bug 835417 part 2. Implement WebIDL parser and codegen support for marking things pure. r=peterv

This commit is contained in:
Boris Zbarsky 2013-01-29 17:53:53 -05:00
parent 8b394535e8
commit ae32f60c9d
4 changed files with 39 additions and 15 deletions

View File

@ -4547,11 +4547,13 @@ class CGMemberJITInfo(CGThing):
return ""
def defineJitInfo(self, infoName, opName, opType, infallible, constant,
returnTypes):
pure, returnTypes):
assert(not constant or pure) # constants are always pure
protoID = "prototypes::id::%s" % self.descriptor.name
depth = "PrototypeTraits<%s>::Depth" % protoID
failstr = toStringBool(infallible)
conststr = toStringBool(constant)
purestr = toStringBool(pure)
returnType = reduce(CGMemberJITInfo.getSingleReturnType, returnTypes,
"")
return ("\n"
@ -4562,26 +4564,30 @@ class CGMemberJITInfo(CGThing):
" JSJitInfo::%s,\n"
" %s, /* isInfallible. False in setters. */\n"
" %s, /* isConstant. Only relevant for getters. */\n"
" %s, /* isPure. Only relevant for getters. */\n"
" %s /* returnType. Only relevant for getters/methods. */\n"
"};\n" % (infoName, opName, protoID, depth, opType, failstr,
conststr, returnType))
conststr, purestr, returnType))
def define(self):
if self.member.isAttr():
getterinfo = ("%s_getterinfo" % self.member.identifier.name)
getter = ("(JSJitPropertyOp)get_%s" % self.member.identifier.name)
getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
getterconst = self.member.getExtendedAttribute("Constant")
getterpure = getterconst or self.member.getExtendedAttribute("Pure")
assert (getterinfal or (not getterconst and not getterpure))
getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
result = self.defineJitInfo(getterinfo, getter, "Getter",
getterinfal, getterconst,
getterinfal, getterconst, getterpure,
[self.member.type])
if not self.member.readonly or self.member.getExtendedAttribute("PutForwards") is not None:
setterinfo = ("%s_setterinfo" % self.member.identifier.name)
setter = ("(JSJitPropertyOp)set_%s" % self.member.identifier.name)
# Setters are always fallible, since they have to do a typed unwrap.
result += self.defineJitInfo(setterinfo, setter, "Setter",
False, False,
False, False, False,
[BuiltinTypes[IDLBuiltinType.Types.void]])
return result
if self.member.isMethod():
@ -4593,18 +4599,22 @@ class CGMemberJITInfo(CGThing):
# Methods are infallible if they are infallible, have no arguments
# to unwrap, and have a return type that's infallible to wrap up for
# return.
methodInfal = False
sigs = self.member.signatures()
if len(sigs) == 1:
# Don't handle overloading. If there's more than one signature,
if len(sigs) != 1:
# Don't handle overloading. If there's more than one signature,
# one of them must take arguments.
methodInfal = False
else:
sig = sigs[0]
if len(sig[1]) == 0 and infallibleForMember(self.member, sig[0], self.descriptor):
# No arguments and infallible return boxing
methodInfal = True
if (len(sig[1]) != 0 or
not infallibleForMember(self.member, sig[0], self.descriptor)):
# We have arguments or our return-value boxing can fail
methodInfal = False
else:
methodInfal = "infallible" in self.descriptor.getExtendedAttributes(self.member)
result = self.defineJitInfo(methodinfo, method, "Method",
methodInfal, False,
methodInfal, False, False,
[s[0] for s in sigs])
return result
raise TypeError("Illegal member type to CGPropertyJITInfo")

View File

@ -2194,6 +2194,14 @@ class IDLAttribute(IDLInterfaceMember):
raise WebIDLError("Readonly attributes must not be flagged as "
"[SetterThrows]",
[self.location])
elif (((identifier == "Throws" or identifier == "GetterThrows") and
(self.getExtendedAttribute("Pure") or
self.getExtendedAttribute("Constant"))) or
((identifier == "Pure" or identifier == "Constant") and
(self.getExtendedAttribute("Throws") or
self.getExtendedAttribute("GetterThrows")))):
raise WebIDLError("Throwing things can't be [Pure] or [Constant]",
[attr.location])
elif identifier == "LenientThis":
if not attr.noArguments():
raise WebIDLError("[LenientThis] must take no arguments",
@ -2736,8 +2744,11 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
"[Unforgeable]",
[attr.location, self.location])
elif identifier == "Constant":
raise WebIDLError("Methods must not be flagged as "
"[Constant]",
raise WebIDLError("Methods must not be flagged as [Constant]",
[attr.location, self.location]);
elif identifier == "Pure":
raise WebIDLError("Methods must not be flagged as [Pure] and if "
"that changes, don't forget to check for [Throws]",
[attr.location, self.location]);
elif identifier == "PutForwards":
raise WebIDLError("Only attributes support [PutForwards]",

View File

@ -31,7 +31,7 @@ enum VisibilityState { "hidden", "visible" };
/* http://dom.spec.whatwg.org/#interface-document */
[Constructor]
interface Document : Node {
[Throws, Constant]
[Throws]
readonly attribute DOMImplementation implementation;
readonly attribute DOMString URL;
readonly attribute DOMString documentURI;

View File

@ -1263,6 +1263,9 @@ struct JSJitInfo {
OpType type;
bool isInfallible; /* Is op fallible? False in setters. */
bool isConstant; /* Getting a construction-time constant? */
bool isPure; /* As long as no non-pure DOM things happen, will
keep returning the same value for the given
"this" object" */
JSValueType returnType; /* The return type tag. Might be JSVAL_TYPE_UNKNOWN */
};