зеркало из https://github.com/mozilla/gecko-dev.git
Bug 942631 part 5. Add C++ API for clearing the cached value of a [Cached] property or regetting a [StoreInSlot] property. r=peterv
This commit is contained in:
Родитель
be8f33b2af
Коммит
7cea1234f6
|
@ -2430,12 +2430,12 @@ class CGWrapGlobalMethod(CGAbstractMethod):
|
|||
self.descriptor.nativeType,
|
||||
InitUnforgeableProperties(self.descriptor, self.properties))
|
||||
|
||||
class CGUpdateMemberSlotsMethod(CGAbstractMethod):
|
||||
class CGUpdateMemberSlotsMethod(CGAbstractStaticMethod):
|
||||
def __init__(self, descriptor):
|
||||
args = [Argument('JSContext*', 'aCx'),
|
||||
Argument('JS::Handle<JSObject*>', 'aWrapper'),
|
||||
Argument(descriptor.nativeType + '*' , 'aObject')]
|
||||
CGAbstractMethod.__init__(self, descriptor, 'UpdateMemberSlots', 'bool', args)
|
||||
CGAbstractStaticMethod.__init__(self, descriptor, 'UpdateMemberSlots', 'bool', args)
|
||||
|
||||
def definition_body(self):
|
||||
slotMembers = (m for m in self.descriptor.interface.members if
|
||||
|
@ -2459,6 +2459,57 @@ class CGUpdateMemberSlotsMethod(CGAbstractMethod):
|
|||
|
||||
return CGIndenter(body).define()
|
||||
|
||||
class CGClearCachedValueMethod(CGAbstractMethod):
|
||||
def __init__(self, descriptor, member):
|
||||
self.member = member
|
||||
# If we're StoreInSlot, we'll need to call the getter
|
||||
if member.getExtendedAttribute("StoreInSlot"):
|
||||
args = [Argument('JSContext*', 'aCx')]
|
||||
returnType = 'bool'
|
||||
else:
|
||||
args = []
|
||||
returnType = 'void'
|
||||
args.append(Argument(descriptor.nativeType + '*', 'aObject'))
|
||||
name = ("ClearCached%sValue" % MakeNativeName(member.identifier.name))
|
||||
CGAbstractMethod.__init__(self, descriptor, name, returnType, args)
|
||||
|
||||
def definition_body(self):
|
||||
slotIndex = memberReservedSlot(self.member)
|
||||
if self.member.getExtendedAttribute("StoreInSlot"):
|
||||
# We have to root things and save the old value in case
|
||||
# regetting fails, so we can restore it.
|
||||
declObj = "JS::Rooted<JSObject*> obj(aCx);"
|
||||
noopRetval = " true"
|
||||
saveMember = (
|
||||
"JS::Rooted<JS::Value> oldValue(aCx, js::GetReservedSlot(obj, %d));\n" %
|
||||
slotIndex)
|
||||
regetMember = ("\n"
|
||||
"JS::Rooted<JS::Value> temp(aCx);\n"
|
||||
"JSJitGetterCallArgs args(&temp);\n"
|
||||
"if (!get_%s(aCx, obj, aObject, args)) {\n"
|
||||
" js::SetReservedSlot(obj, %d, oldValue);\n"
|
||||
" nsJSUtils::ReportPendingException(aCx);\n"
|
||||
" return false;\n"
|
||||
"}\n"
|
||||
"return true;" % (self.member.identifier.name, slotIndex))
|
||||
else:
|
||||
declObj = "JSObject* obj;"
|
||||
noopRetval = ""
|
||||
saveMember = ""
|
||||
regetMember = ""
|
||||
|
||||
return CGIndenter(CGGeneric(
|
||||
"%s\n"
|
||||
"obj = aObject->GetWrapper();\n"
|
||||
"if (!obj) {\n"
|
||||
" return%s;\n"
|
||||
"}\n"
|
||||
"%s"
|
||||
"js::SetReservedSlot(obj, %d, JS::UndefinedValue());"
|
||||
"%s"
|
||||
% (declObj, noopRetval, saveMember, slotIndex, regetMember)
|
||||
)).define()
|
||||
|
||||
builtinNames = {
|
||||
IDLType.Tags.bool: 'bool',
|
||||
IDLType.Tags.int8: 'int8_t',
|
||||
|
@ -8542,6 +8593,13 @@ class CGDescriptor(CGThing):
|
|||
cgThings.append(CGWrapNonWrapperCacheMethod(descriptor,
|
||||
properties))
|
||||
|
||||
# If we're not wrappercached, we don't know how to clear our
|
||||
# cached values, since we can't get at the JSObject.
|
||||
if descriptor.wrapperCache:
|
||||
cgThings.extend(CGClearCachedValueMethod(descriptor, m) for
|
||||
m in descriptor.interface.members if
|
||||
m.isAttr() and m.slotIndex is not None)
|
||||
|
||||
# CGCreateInterfaceObjectsMethod needs to come after our
|
||||
# CGDOMJSClass, if any.
|
||||
cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
|
||||
|
@ -9394,6 +9452,13 @@ class CGBindingRoot(CGThing):
|
|||
return typeDesc.hasXPConnectImpls
|
||||
addHeaderBasedOnTypes("nsDOMQS.h", checkForXPConnectImpls)
|
||||
|
||||
def descriptorClearsPropsInSlots(descriptor):
|
||||
if not descriptor.wrapperCache:
|
||||
return False
|
||||
return any(m.isAttr() and m.getExtendedAttribute("StoreInSlot")
|
||||
for m in descriptor.interface.members)
|
||||
bindingHeaders["nsJSUtils.h"] = any(descriptorClearsPropsInSlots(d) for d in descriptors)
|
||||
|
||||
# Do codegen for all the enums
|
||||
enums = config.getEnums(webIDLFile)
|
||||
cgthings = [ CGEnum(e) for e in enums ]
|
||||
|
|
|
@ -124,7 +124,7 @@ interface TestInterface {
|
|||
void passNullableByte(byte? arg);
|
||||
void passOptionalNullableByte(optional byte? arg);
|
||||
void passVariadicByte(byte... arg);
|
||||
[Cached, Pure]
|
||||
[StoreInSlot, Pure]
|
||||
readonly attribute byte cachedByte;
|
||||
|
||||
readonly attribute short readonlyShort;
|
||||
|
|
Загрузка…
Ссылка в новой задаче