mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 942631 part 2. Make getters for cached properties check and set the reserved slot as needed. r=peterv
This commit is contained in:
parent
f916e39018
commit
daded4df04
@ -26,6 +26,9 @@ ENUMERATE_HOOK_NAME= '_enumerate'
|
|||||||
ENUM_ENTRY_VARIABLE_NAME = 'strings'
|
ENUM_ENTRY_VARIABLE_NAME = 'strings'
|
||||||
INSTANCE_RESERVED_SLOTS = 3
|
INSTANCE_RESERVED_SLOTS = 3
|
||||||
|
|
||||||
|
def memberReservedSlot(member):
|
||||||
|
return INSTANCE_RESERVED_SLOTS + member.slotIndex
|
||||||
|
|
||||||
def replaceFileIfChanged(filename, newContents):
|
def replaceFileIfChanged(filename, newContents):
|
||||||
"""
|
"""
|
||||||
Read a copy of the old file, so that we don't touch it if it hasn't changed.
|
Read a copy of the old file, so that we don't touch it if it hasn't changed.
|
||||||
@ -2437,8 +2440,6 @@ class CGUpdateMemberSlotsMethod(CGAbstractMethod):
|
|||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
slotMembers = (m for m in self.descriptor.interface.members if
|
slotMembers = (m for m in self.descriptor.interface.members if
|
||||||
m.isAttr() and m.getExtendedAttribute("StoreInSlot"))
|
m.isAttr() and m.getExtendedAttribute("StoreInSlot"))
|
||||||
def slotIndex(member):
|
|
||||||
return member.slotIndex + INSTANCE_RESERVED_SLOTS
|
|
||||||
storeSlots = (
|
storeSlots = (
|
||||||
CGGeneric(
|
CGGeneric(
|
||||||
'static_assert(%d < js::shadow::Object::MAX_FIXED_SLOTS,\n'
|
'static_assert(%d < js::shadow::Object::MAX_FIXED_SLOTS,\n'
|
||||||
@ -2446,9 +2447,10 @@ class CGUpdateMemberSlotsMethod(CGAbstractMethod):
|
|||||||
"if (!get_%s(aCx, aWrapper, aObject, args)) {\n"
|
"if (!get_%s(aCx, aWrapper, aObject, args)) {\n"
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"js::SetReservedSlot(aWrapper, %d, args.rval());" %
|
"// Getter handled setting our reserved slots" %
|
||||||
(slotIndex(m), self.descriptor.interface.identifier.name,
|
(memberReservedSlot(m),
|
||||||
m.identifier.name, m.identifier.name, slotIndex(m)))
|
self.descriptor.interface.identifier.name,
|
||||||
|
m.identifier.name, m.identifier.name))
|
||||||
for m in slotMembers)
|
for m in slotMembers)
|
||||||
body = CGList(storeSlots, "\n\n")
|
body = CGList(storeSlots, "\n\n")
|
||||||
body.prepend(CGGeneric("JS::Rooted<JS::Value> temp(aCx);\n"
|
body.prepend(CGGeneric("JS::Rooted<JS::Value> temp(aCx);\n"
|
||||||
@ -5022,9 +5024,30 @@ if (!${obj}) {
|
|||||||
(self.returnType.isGeckoInterface() and
|
(self.returnType.isGeckoInterface() and
|
||||||
self.descriptor.getDescriptor(self.returnType.unroll().inner.identifier.name).nativeOwnership == 'owned'))
|
self.descriptor.getDescriptor(self.returnType.unroll().inner.identifier.name).nativeOwnership == 'owned'))
|
||||||
|
|
||||||
|
if self.idlNode.isAttr() and self.idlNode.slotIndex is not None:
|
||||||
|
successCode = (
|
||||||
|
"// Be careful here: Have to wrap the value into the\n"
|
||||||
|
"// compartment of reflector before storing, since we might\n"
|
||||||
|
"// be coming in via Xrays and the value is already in the\n"
|
||||||
|
"// caller compartment.\n"
|
||||||
|
"{ // Scope for tempVal\n"
|
||||||
|
" JS::Rooted<JS::Value> tempVal(cx, args.rval());\n"
|
||||||
|
" JSAutoCompartment ac(cx, reflector);\n"
|
||||||
|
" if (!MaybeWrapValue(cx, &tempVal)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
" }\n"
|
||||||
|
" js::SetReservedSlot(reflector, %d, tempVal);\n"
|
||||||
|
"}\n"
|
||||||
|
"return true;" %
|
||||||
|
memberReservedSlot(self.idlNode))
|
||||||
|
else:
|
||||||
|
successCode = None
|
||||||
|
|
||||||
resultTemplateValues = { 'jsvalRef': 'args.rval()',
|
resultTemplateValues = { 'jsvalRef': 'args.rval()',
|
||||||
'jsvalHandle': 'args.rval()',
|
'jsvalHandle': 'args.rval()',
|
||||||
'returnsNewObject': returnsNewObject}
|
'returnsNewObject': returnsNewObject,
|
||||||
|
'successCode': successCode,
|
||||||
|
}
|
||||||
try:
|
try:
|
||||||
return wrapForType(self.returnType, self.descriptor,
|
return wrapForType(self.returnType, self.descriptor,
|
||||||
resultTemplateValues)
|
resultTemplateValues)
|
||||||
@ -5860,8 +5883,35 @@ class CGSpecializedGetter(CGAbstractStaticMethod):
|
|||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
|
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
|
||||||
self.attr)
|
self.attr)
|
||||||
return CGIndenter(CGGetterCall(self.attr.type, nativeName,
|
if self.attr.slotIndex is not None:
|
||||||
self.descriptor, self.attr)).define()
|
if self.descriptor.hasXPConnectImpls:
|
||||||
|
raise TypeError("Interface '%s' has XPConnect impls, so we "
|
||||||
|
"can't use our slot for property '%s'!" %
|
||||||
|
(self.descriptor.interface.identifier.name,
|
||||||
|
self.attr.identifier.name))
|
||||||
|
prefix = (
|
||||||
|
" // Have to either root across the getter call or reget after.\n"
|
||||||
|
" JS::Rooted<JSObject*> reflector(cx);\n"
|
||||||
|
" // Safe to do an unchecked unwrap, since we've gotten this far.\n"
|
||||||
|
" // Also make sure to unwrap outer windows, since we want the\n"
|
||||||
|
" // real DOM object.\n"
|
||||||
|
" reflector = IsDOMObject(obj) ? obj : js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);\n"
|
||||||
|
" {\n"
|
||||||
|
" // Scope for cachedVal\n"
|
||||||
|
" JS::Value cachedVal = js::GetReservedSlot(reflector, %d);\n"
|
||||||
|
" if (!cachedVal.isUndefined()) {\n"
|
||||||
|
" args.rval().set(cachedVal);\n"
|
||||||
|
" // The cached value is in the compartment of reflector,\n"
|
||||||
|
" // so wrap into the caller compartment as needed.\n"
|
||||||
|
" return MaybeWrapValue(cx, args.rval());\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n\n" % memberReservedSlot(self.attr))
|
||||||
|
else:
|
||||||
|
prefix = ""
|
||||||
|
|
||||||
|
return (prefix +
|
||||||
|
CGIndenter(CGGetterCall(self.attr.type, nativeName,
|
||||||
|
self.descriptor, self.attr)).define())
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def makeNativeName(descriptor, attr):
|
def makeNativeName(descriptor, attr):
|
||||||
@ -6097,7 +6147,7 @@ class CGMemberJITInfo(CGThing):
|
|||||||
getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
|
getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
|
||||||
isInSlot = self.member.getExtendedAttribute("StoreInSlot")
|
isInSlot = self.member.getExtendedAttribute("StoreInSlot")
|
||||||
if isInSlot:
|
if isInSlot:
|
||||||
slotIndex = INSTANCE_RESERVED_SLOTS + self.member.slotIndex;
|
slotIndex = memberReservedSlot(self.member);
|
||||||
if slotIndex >= 16 : # JS engine currently allows 16 fixed slots
|
if slotIndex >= 16 : # JS engine currently allows 16 fixed slots
|
||||||
raise TypeError("Make sure we can actually have this many "
|
raise TypeError("Make sure we can actually have this many "
|
||||||
"fixed slots, please!")
|
"fixed slots, please!")
|
||||||
|
Loading…
Reference in New Issue
Block a user