зеркало из https://github.com/mozilla/gecko-dev.git
Bug 938544 - Add support for a Chrome-only constructor in WebIDL. r=bz.
--HG-- extra : rebase_source : e36fef0090d57947ceae6c2fc11bea8b115423e4
This commit is contained in:
Родитель
97c1353a69
Коммит
794b2d6bd9
|
@ -1141,6 +1141,11 @@ class CGClassConstructor(CGAbstractStaticMethod):
|
|||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
JS::Rooted<JSObject*> obj(cx, &args.callee());
|
||||
"""
|
||||
if isChromeOnly(self._ctor):
|
||||
preamble += """ if (!%s) {
|
||||
return ThrowingConstructor(cx, argc, vp);
|
||||
}
|
||||
""" % GetAccessCheck(self.descriptor, "cx", "obj")
|
||||
name = self._ctor.identifier.name
|
||||
nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
|
||||
callGenerator = CGMethodCall(nativeName, True, self.descriptor,
|
||||
|
@ -1957,7 +1962,7 @@ if (!unforgeableHolder) {
|
|||
else:
|
||||
properties = "nullptr"
|
||||
if self.properties.hasChromeOnly():
|
||||
accessCheck = GetAccessCheck(self.descriptor, "aGlobal")
|
||||
accessCheck = GetAccessCheck(self.descriptor, "aCx", "aGlobal")
|
||||
chromeProperties = accessCheck + " ? &sChromeOnlyNativeProperties : nullptr"
|
||||
else:
|
||||
chromeProperties = "nullptr"
|
||||
|
@ -2143,7 +2148,7 @@ class CGConstructorEnabledChromeOnly(CGAbstractMethod):
|
|||
Argument("JS::Handle<JSObject*>", "aObj")])
|
||||
|
||||
def definition_body(self):
|
||||
return " return %s;" % GetAccessCheck(self.descriptor, "aObj")
|
||||
return " return %s;" % GetAccessCheck(self.descriptor, "aCx", "aObj")
|
||||
|
||||
class CGConstructorEnabledViaFunc(CGAbstractMethod):
|
||||
"""
|
||||
|
@ -2211,13 +2216,14 @@ def CreateBindingJSObject(descriptor, properties, parent):
|
|||
"""
|
||||
return create % parent
|
||||
|
||||
def GetAccessCheck(descriptor, object):
|
||||
def GetAccessCheck(descriptor, context, object):
|
||||
"""
|
||||
context is the name of a JSContext*
|
||||
object is the name of a JSObject*
|
||||
|
||||
returns a string
|
||||
"""
|
||||
return "ThreadsafeCheckIsChrome(aCx, %s)" % object
|
||||
return "ThreadsafeCheckIsChrome(%s, %s)" % (context, object)
|
||||
|
||||
def InitUnforgeablePropertiesOnObject(descriptor, obj, properties, failureReturnValue=""):
|
||||
"""
|
||||
|
@ -2241,7 +2247,7 @@ def InitUnforgeablePropertiesOnObject(descriptor, obj, properties, failureReturn
|
|||
unforgeables.append(
|
||||
CGIfWrapper(CGGeneric(defineUnforgeables %
|
||||
unforgeableAttrs.variableName(True)),
|
||||
GetAccessCheck(descriptor, obj)))
|
||||
GetAccessCheck(descriptor, "aCx", obj)))
|
||||
return CGList(unforgeables, "\n")
|
||||
|
||||
def InitUnforgeableProperties(descriptor, properties):
|
||||
|
|
|
@ -868,7 +868,7 @@ class IDLInterface(IDLObjectWithScope):
|
|||
[self.location])
|
||||
|
||||
self._noInterfaceObject = True
|
||||
elif identifier == "Constructor" or identifier == "NamedConstructor":
|
||||
elif identifier == "Constructor" or identifier == "NamedConstructor" or identifier == "ChromeConstructor":
|
||||
if identifier == "Constructor" and not self.hasInterfaceObject():
|
||||
raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible",
|
||||
[self.location])
|
||||
|
@ -877,11 +877,15 @@ class IDLInterface(IDLObjectWithScope):
|
|||
raise WebIDLError("NamedConstructor must either take an identifier or take a named argument list",
|
||||
[attr.location])
|
||||
|
||||
if identifier == "ChromeConstructor" and not self.hasInterfaceObject():
|
||||
raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible",
|
||||
[self.location])
|
||||
|
||||
args = attr.args() if attr.hasArgs() else []
|
||||
|
||||
retType = IDLWrapperType(self.location, self)
|
||||
|
||||
if identifier == "Constructor":
|
||||
if identifier == "Constructor" or identifier == "ChromeConstructor":
|
||||
name = "constructor"
|
||||
allowForbidden = True
|
||||
else:
|
||||
|
@ -900,9 +904,11 @@ class IDLInterface(IDLObjectWithScope):
|
|||
method.addExtendedAttributes(
|
||||
[IDLExtendedAttribute(self.location, ("NewObject",)),
|
||||
IDLExtendedAttribute(self.location, ("Throws",))])
|
||||
if identifier == "ChromeConstructor":
|
||||
method.addExtendedAttributes(
|
||||
[IDLExtendedAttribute(self.location, ("ChromeOnly",))])
|
||||
|
||||
|
||||
if identifier == "Constructor":
|
||||
if identifier == "Constructor" or identifier == "ChromeConstructor":
|
||||
method.resolve(self)
|
||||
else:
|
||||
# We need to detect conflicts for NamedConstructors across
|
||||
|
|
|
@ -12,7 +12,8 @@ def WebIDLTest(parser, harness):
|
|||
|
||||
def checkMethod(method, QName, name, signatures,
|
||||
static=True, getter=False, setter=False, creator=False,
|
||||
deleter=False, legacycaller=False, stringifier=False):
|
||||
deleter=False, legacycaller=False, stringifier=False,
|
||||
chromeOnly=False):
|
||||
harness.ok(isinstance(method, WebIDL.IDLMethod),
|
||||
"Should be an IDLMethod")
|
||||
harness.ok(method.isMethod(), "Method is a method")
|
||||
|
@ -27,6 +28,7 @@ def WebIDLTest(parser, harness):
|
|||
harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
|
||||
harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
|
||||
harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
|
||||
harness.check(method.getExtendedAttribute("ChromeOnly") is not None, chromeOnly, "Method has the correct value for ChromeOnly")
|
||||
harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures")
|
||||
|
||||
sigpairs = zip(method.signatures(), signatures)
|
||||
|
@ -55,11 +57,13 @@ def WebIDLTest(parser, harness):
|
|||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
harness.check(len(results), 3, "Should be two productions")
|
||||
harness.check(len(results), 3, "Should be three productions")
|
||||
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
|
||||
"Should be an IDLInterface")
|
||||
harness.ok(isinstance(results[1], WebIDL.IDLInterface),
|
||||
"Should be an IDLInterface")
|
||||
harness.ok(isinstance(results[2], WebIDL.IDLInterface),
|
||||
"Should be an IDLInterface")
|
||||
|
||||
checkMethod(results[0].ctor(), "::TestConstructorNoArgs::constructor",
|
||||
"constructor", [("TestConstructorNoArgs (Wrapper)", [])])
|
||||
|
@ -73,3 +77,33 @@ def WebIDLTest(parser, harness):
|
|||
[("::TestConstructorOverloads::constructor::foo", "foo", "Object", False, False)]),
|
||||
("TestConstructorOverloads (Wrapper)",
|
||||
[("::TestConstructorOverloads::constructor::bar", "bar", "Boolean", False, False)])])
|
||||
|
||||
parser = parser.reset()
|
||||
parser.parse("""
|
||||
[ChromeConstructor()]
|
||||
interface TestChromeConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
harness.check(len(results), 1, "Should be one production")
|
||||
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
|
||||
"Should be an IDLInterface")
|
||||
|
||||
checkMethod(results[0].ctor(), "::TestChromeConstructor::constructor",
|
||||
"constructor", [("TestChromeConstructor (Wrapper)", [])],
|
||||
chromeOnly=True)
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[Constructor(),
|
||||
ChromeConstructor(DOMString a)]
|
||||
interface TestChromeConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a Constructor and a ChromeConstructor")
|
||||
|
|
Загрузка…
Ссылка в новой задаче