Bug 1034204 - Implement unforgeable methods; r=bz

This commit is contained in:
Ms2ger 2014-07-04 15:02:10 +02:00
parent 033d32594d
commit 5e7f19500d
9 changed files with 76 additions and 18 deletions

View File

@ -319,6 +319,13 @@ DefinePrefable(JSContext* cx, JS::Handle<JSObject*> obj,
return true;
}
bool
DefineUnforgeableMethods(JSContext* cx, JS::Handle<JSObject*> obj,
const Prefable<const JSFunctionSpec>* props)
{
return DefinePrefable(cx, obj, props);
}
bool
DefineUnforgeableAttributes(JSContext* cx, JS::Handle<JSObject*> obj,
const Prefable<const JSPropertySpec>* props)

View File

@ -624,6 +624,13 @@ DefineProperties(JSContext* cx, JS::Handle<JSObject*> obj,
const NativeProperties* properties,
const NativeProperties* chromeOnlyProperties);
/*
* Define the unforgeable methods on an object.
*/
bool
DefineUnforgeableMethods(JSContext* cx, JS::Handle<JSObject*> obj,
const Prefable<const JSFunctionSpec>* props);
/*
* Define the unforgeable attributes on an object.
*/

View File

@ -492,7 +492,7 @@ def PrototypeIDAndDepth(descriptor):
def UseHolderForUnforgeable(descriptor):
return (descriptor.concrete and
descriptor.proxy and
any(m for m in descriptor.interface.members if m.isAttr() and m.isUnforgeable()))
any(m for m in descriptor.interface.members if (m.isAttr() or m.isMethod()) and m.isUnforgeable()))
def CallOnUnforgeableHolder(descriptor, code, isXrayCheck=None,
@ -1987,7 +1987,8 @@ class MethodDefiner(PropertyDefiner):
"""
A class for defining methods on a prototype object.
"""
def __init__(self, descriptor, name, static):
def __init__(self, descriptor, name, static, unforgeable=False):
assert not (static and unforgeable)
PropertyDefiner.__init__(self, descriptor, name)
# FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=772822
@ -1998,6 +1999,7 @@ class MethodDefiner(PropertyDefiner):
if descriptor.interface.hasInterfacePrototypeObject() or static:
methods = [m for m in descriptor.interface.members if
m.isMethod() and m.isStatic() == static and
m.isUnforgeable() == unforgeable and
not m.isIdentifierLess()]
else:
methods = []
@ -2106,6 +2108,8 @@ class MethodDefiner(PropertyDefiner):
"condition": MemberCondition(None, None)
})
self.unforgeable = unforgeable
if static:
if not descriptor.interface.hasInterfaceObject():
# static methods go on the interface object
@ -2122,6 +2126,10 @@ class MethodDefiner(PropertyDefiner):
def condition(m, d):
return m["condition"]
def flags(m):
unforgeable = " | JSPROP_PERMANENT" if self.unforgeable else ""
return m["flags"] + unforgeable
def specData(m):
if "selfHostedName" in m:
selfHostedName = '"%s"' % m["selfHostedName"]
@ -2157,7 +2165,7 @@ class MethodDefiner(PropertyDefiner):
else:
jitinfo = "nullptr"
return (m["name"], accessor, jitinfo, m["length"], m["flags"], selfHostedName)
return (m["name"], accessor, jitinfo, m["length"], flags(m), selfHostedName)
return self.generatePrefableArray(
array, name,
@ -2287,6 +2295,8 @@ class PropertyArrays():
static=True)
self.methods = MethodDefiner(descriptor, "Methods", static=False)
self.attrs = AttrDefiner(descriptor, "Attributes", static=False)
self.unforgeableMethods = MethodDefiner(descriptor, "UnforgeableMethods",
static=False, unforgeable=True)
self.unforgeableAttrs = AttrDefiner(descriptor, "UnforgeableAttributes",
static=False, unforgeable=True)
self.consts = ConstDefiner(descriptor, "Constants")
@ -2294,7 +2304,7 @@ class PropertyArrays():
@staticmethod
def arrayNames():
return ["staticMethods", "staticAttrs", "methods", "attrs",
"unforgeableAttrs", "consts"]
"unforgeableMethods", "unforgeableAttrs", "consts"]
def hasChromeOnly(self):
return any(getattr(self, a).hasChromeOnly() for a in self.arrayNames())
@ -2774,7 +2784,9 @@ def InitUnforgeablePropertiesOnObject(descriptor, obj, properties, failureReturn
"""
properties is a PropertyArrays instance
"""
defineUnforgeables = fill(
unforgeables = []
defineUnforgeableAttrs = fill(
"""
if (!DefineUnforgeableAttributes(aCx, ${obj}, %s)) {
return${rv};
@ -2782,17 +2794,27 @@ def InitUnforgeablePropertiesOnObject(descriptor, obj, properties, failureReturn
""",
obj=obj,
rv=" " + failureReturnValue if failureReturnValue else "")
defineUnforgeableMethods = fill(
"""
if (!DefineUnforgeableMethods(aCx, ${obj}, %s)) {
return${rv};
}
""",
obj=obj,
rv=" " + failureReturnValue if failureReturnValue else "")
unforgeableMembers = [
(defineUnforgeableAttrs, properties.unforgeableAttrs),
(defineUnforgeableMethods, properties.unforgeableMethods)
]
for (template, array) in unforgeableMembers:
if array.hasNonChromeOnly():
unforgeables.append(CGGeneric(template % array.variableName(False)))
if array.hasChromeOnly():
unforgeables.append(
CGIfWrapper(CGGeneric(template % array.variableName(True)),
"nsContentUtils::ThreadsafeIsCallerChrome()"))
unforgeableAttrs = properties.unforgeableAttrs
unforgeables = []
if unforgeableAttrs.hasNonChromeOnly():
unforgeables.append(CGGeneric(defineUnforgeables %
unforgeableAttrs.variableName(False)))
if unforgeableAttrs.hasChromeOnly():
unforgeables.append(
CGIfWrapper(CGGeneric(defineUnforgeables %
unforgeableAttrs.variableName(True)),
"nsContentUtils::ThreadsafeIsCallerChrome()"))
return CGList(unforgeables)

View File

@ -99,18 +99,27 @@ struct NativeProperties
const Prefable<const JSFunctionSpec>* staticMethods;
jsid* staticMethodIds;
const JSFunctionSpec* staticMethodsSpecs;
const Prefable<const JSPropertySpec>* staticAttributes;
jsid* staticAttributeIds;
const JSPropertySpec* staticAttributeSpecs;
const Prefable<const JSFunctionSpec>* methods;
jsid* methodIds;
const JSFunctionSpec* methodsSpecs;
const Prefable<const JSPropertySpec>* attributes;
jsid* attributeIds;
const JSPropertySpec* attributeSpecs;
const Prefable<const JSFunctionSpec>* unforgeableMethods;
jsid* unforgeableMethodIds;
const JSFunctionSpec* unforgeableMethodSpecs;
const Prefable<const JSPropertySpec>* unforgeableAttributes;
jsid* unforgeableAttributeIds;
const JSPropertySpec* unforgeableAttributeSpecs;
const Prefable<const ConstantSpec>* constants;
jsid* constantIds;
const ConstantSpec* constantSpecs;

View File

@ -3245,6 +3245,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
assert isinstance(jsonifier, bool)
self._jsonifier = jsonifier
self._specialType = specialType
self._unforgeable = False
if static and identifier.name == "prototype":
raise WebIDLError("The identifier of a static operation must not be 'prototype'",
@ -3520,9 +3521,10 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
"[SetterThrows]",
[attr.location, self.location])
elif identifier == "Unforgeable":
raise WebIDLError("Methods must not be flagged as "
"[Unforgeable]",
[attr.location, self.location])
if self.isStatic():
raise WebIDLError("[Unforgeable] is only allowed on non-static "
"methods", [attr.location, self.location])
self._unforgeable = True
elif identifier == "SameObject":
raise WebIDLError("Methods must not be flagged as [SameObject]",
[attr.location, self.location]);
@ -3563,6 +3565,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
def returnsPromise(self):
return self._overloads[0].returnType.isPromise()
def isUnforgeable(self):
return self._unforgeable
def _getDependentObjects(self):
deps = set()
for overload in self._overloads:

View File

@ -783,6 +783,8 @@ public:
void SetAttrWithLenientThis(int32_t);
uint32_t UnforgeableAttr();
uint32_t UnforgeableAttr2();
uint32_t UnforgeableMethod();
uint32_t UnforgeableMethod2();
void Stringify(nsString&);
void PassRenamedInterface(nsRenamedInterface&);
TestInterface* PutForwardsAttr();

View File

@ -763,6 +763,8 @@ interface TestInterface {
[LenientThis] attribute long attrWithLenientThis;
[Unforgeable] readonly attribute long unforgeableAttr;
[Unforgeable, ChromeOnly] readonly attribute long unforgeableAttr2;
[Unforgeable] long unforgeableMethod();
[Unforgeable, ChromeOnly] long unforgeableMethod2();
stringifier;
void passRenamedInterface(TestRenamedInterface arg);
[PutForwards=writableByte] readonly attribute TestInterface putForwardsAttr;

View File

@ -640,6 +640,8 @@ interface TestExampleInterface {
[LenientThis] attribute long attrWithLenientThis;
[Unforgeable] readonly attribute long unforgeableAttr;
[Unforgeable, ChromeOnly] readonly attribute long unforgeableAttr2;
[Unforgeable] long unforgeableMethod();
[Unforgeable, ChromeOnly] long unforgeableMethod2();
stringifier;
void passRenamedInterface(TestRenamedInterface arg);
[PutForwards=writableByte] readonly attribute TestExampleInterface putForwardsAttr;

View File

@ -680,6 +680,8 @@ interface TestJSImplInterface {
// versa.
// [Unforgeable] readonly attribute long unforgeableAttr;
// [Unforgeable, ChromeOnly] readonly attribute long unforgeableAttr2;
// [Unforgeable] long unforgeableMethod();
// [Unforgeable, ChromeOnly] long unforgeableMethod2();
// FIXME: Bug 863955 No stringifiers yet
// stringifier;
void passRenamedInterface(TestRenamedInterface arg);