mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-27 07:34:20 +00:00
Bug 1395421 part 2. When a get() happens on a JS-implemented maplike, notify the JS implementation so it can take some sort of action (e.g. logging or warning). r=peterv
MozReview-Commit-ID: 9G115wOyzvm
This commit is contained in:
parent
2697cc0235
commit
056d8fe612
@ -15570,6 +15570,17 @@ class CGJSImplClass(CGBindingImplClass):
|
||||
static=True,
|
||||
body=self.getCreateFromExistingBody()))
|
||||
|
||||
if (descriptor.interface.isJSImplemented() and
|
||||
descriptor.interface.maplikeOrSetlikeOrIterable and
|
||||
descriptor.interface.maplikeOrSetlikeOrIterable.isMaplike()):
|
||||
self.methodDecls.append(
|
||||
ClassMethod("__OnGet",
|
||||
"void",
|
||||
[Argument("JS::Handle<JS::Value>", "aKey"),
|
||||
Argument("JS::Handle<JS::Value>", "aValue"),
|
||||
Argument("ErrorResult&", "aRv")],
|
||||
body="mImpl->__OnGet(aKey, aValue, aRv);\n"))
|
||||
|
||||
CGClass.__init__(self, descriptor.name,
|
||||
bases=baseClasses,
|
||||
constructors=[constructor],
|
||||
@ -15931,16 +15942,31 @@ class CGCallbackInterface(CGCallback):
|
||||
not iface.isJSImplemented()))]
|
||||
methods = [CallbackOperation(m, sig, descriptor, spiderMonkeyInterfacesAreStructs)
|
||||
for m in methods for sig in m.signatures()]
|
||||
|
||||
needInitId = False
|
||||
if iface.isJSImplemented() and iface.ctor():
|
||||
sigs = descriptor.interface.ctor().signatures()
|
||||
if len(sigs) != 1:
|
||||
raise TypeError("We only handle one constructor. See bug 869268.")
|
||||
methods.append(CGJSImplInitOperation(sigs[0], descriptor))
|
||||
if any(m.isAttr() or m.isMethod() for m in iface.members) or (iface.isJSImplemented() and iface.ctor()):
|
||||
methods.append(initIdsClassMethod([descriptor.binaryNameFor(m.identifier.name)
|
||||
for m in iface.members
|
||||
if m.isAttr() or m.isMethod()] +
|
||||
(["__init"] if iface.isJSImplemented() and iface.ctor() else []),
|
||||
needInitId = True
|
||||
|
||||
needOnGetId = False
|
||||
if (iface.isJSImplemented() and
|
||||
iface.maplikeOrSetlikeOrIterable and
|
||||
iface.maplikeOrSetlikeOrIterable.isMaplike()):
|
||||
methods.append(CGJSImplOnGetOperation(descriptor))
|
||||
needOnGetId = True
|
||||
|
||||
idlist = [descriptor.binaryNameFor(m.identifier.name)
|
||||
for m in iface.members
|
||||
if m.isAttr() or m.isMethod()]
|
||||
if needInitId:
|
||||
idlist.append("__init")
|
||||
if needOnGetId:
|
||||
idlist.append("__onget")
|
||||
if len(idlist) != 0:
|
||||
methods.append(initIdsClassMethod(idlist,
|
||||
iface.identifier.name + "Atoms"))
|
||||
CGCallback.__init__(self, iface, descriptor, "CallbackInterface",
|
||||
methods, getters=getters, setters=setters)
|
||||
@ -16459,6 +16485,32 @@ class CGJSImplInitOperation(CallbackOperationBase):
|
||||
return "__init"
|
||||
|
||||
|
||||
class CGJSImplOnGetOperation(CallbackOperationBase):
|
||||
"""
|
||||
Codegen the __OnGet() method used to notify the JS impl that a get() is
|
||||
happening on a JS-implemented maplike. This method takes two arguments
|
||||
(key and value) and returns nothing.
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
CallbackOperationBase.__init__(
|
||||
self,
|
||||
(BuiltinTypes[IDLBuiltinType.Types.void],
|
||||
[FakeArgument(BuiltinTypes[IDLBuiltinType.Types.any],
|
||||
None,
|
||||
"key"),
|
||||
FakeArgument(BuiltinTypes[IDLBuiltinType.Types.any],
|
||||
None,
|
||||
"value")]),
|
||||
"__onget", "__OnGet",
|
||||
descriptor,
|
||||
singleOperation=False,
|
||||
rethrowContentException=True,
|
||||
spiderMonkeyInterfacesAreStructs=True)
|
||||
|
||||
def getPrettyName(self):
|
||||
return "__onget"
|
||||
|
||||
|
||||
def getMaplikeOrSetlikeErrorReturn(helperImpl):
|
||||
"""
|
||||
Generate return values based on whether a maplike or setlike generated
|
||||
@ -16741,7 +16793,21 @@ class CGMaplikeOrSetlikeMethodGenerator(CGThing):
|
||||
JS::Rooted<JS::Value> result(cx);
|
||||
"""))]
|
||||
arguments = ["&result"]
|
||||
return self.mergeTuples(r, (code, arguments, []))
|
||||
if self.descriptor.interface.isJSImplemented():
|
||||
callOnGet = [CGGeneric(dedent(
|
||||
"""
|
||||
{
|
||||
JS::ExposeValueToActiveJS(result);
|
||||
ErrorResult onGetResult;
|
||||
self->__OnGet(arg0Val, result, onGetResult);
|
||||
if (onGetResult.MaybeSetPendingException(cx)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
"""))]
|
||||
else:
|
||||
callOnGet = []
|
||||
return self.mergeTuples(r, (code, arguments, callOnGet))
|
||||
|
||||
def has(self):
|
||||
"""
|
||||
@ -17041,6 +17107,11 @@ class GlobalGenRoots():
|
||||
if d.interface.isJSImplemented() and d.interface.ctor():
|
||||
# We'll have an __init() method.
|
||||
members.append(FakeMember('__init'))
|
||||
if (d.interface.isJSImplemented() and
|
||||
d.interface.maplikeOrSetlikeOrIterable and
|
||||
d.interface.maplikeOrSetlikeOrIterable.isMaplike()):
|
||||
# We'll have an __onget() method.
|
||||
members.append(FakeMember('__onget'))
|
||||
if len(members) == 0:
|
||||
continue
|
||||
|
||||
|
@ -32,7 +32,11 @@ TestInterfaceJSMaplike.prototype = {
|
||||
|
||||
clearInternal: function() {
|
||||
return this.__DOM_IMPL__.__clear();
|
||||
}
|
||||
},
|
||||
|
||||
__onget: function(key, value) {
|
||||
/* no-op */
|
||||
},
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TestInterfaceJSMaplike])
|
||||
|
@ -327,6 +327,10 @@ class RTCStatsReport {
|
||||
}
|
||||
|
||||
get mozPcid() { return this._pcid; }
|
||||
|
||||
__onget(key, value) {
|
||||
/* Do whatever here */
|
||||
}
|
||||
}
|
||||
setupPrototype(RTCStatsReport, {
|
||||
classID: PC_STATS_CID,
|
||||
|
Loading…
x
Reference in New Issue
Block a user