mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 09:45:41 +00:00
Bug 946898. Make sure to not accidentally store COWs in the slot for [Cached] properties. r=peterv
This commit is contained in:
parent
0134bf3556
commit
919ba9e509
@ -4174,8 +4174,9 @@ def getMaybeWrapValueFuncForType(type):
|
||||
if type.nullable():
|
||||
return "MaybeWrapObjectOrNullValue"
|
||||
return "MaybeWrapObjectValue"
|
||||
# Spidermonkey interfaces are never DOM objects
|
||||
if type.isSpiderMonkeyInterface():
|
||||
# Spidermonkey interfaces are never DOM objects. Neither are sequences or
|
||||
# dictionaries, since those are always plain JS objects.
|
||||
if type.isSpiderMonkeyInterface() or type.isDictionary() or type.isSequence():
|
||||
if type.nullable():
|
||||
return "MaybeWrapNonDOMObjectOrNullValue"
|
||||
return "MaybeWrapNonDOMObjectValue"
|
||||
@ -5118,7 +5119,8 @@ if (!${obj}) {
|
||||
(self.returnType.isGeckoInterface() and
|
||||
self.descriptor.getDescriptor(self.returnType.unroll().inner.identifier.name).nativeOwnership == 'owned'))
|
||||
|
||||
if self.idlNode.isAttr() and self.idlNode.slotIndex is not None:
|
||||
setSlot = self.idlNode.isAttr() and self.idlNode.slotIndex is not None
|
||||
if setSlot:
|
||||
# For the case of Cached attributes, go ahead and preserve our
|
||||
# wrapper if needed. We need to do this because otherwise the
|
||||
# wrapper could get garbage-collected and the cached value would
|
||||
@ -5129,26 +5131,14 @@ if (!${obj}) {
|
||||
# already-preserved wrapper.
|
||||
if (self.idlNode.getExtendedAttribute("Cached") and
|
||||
self.descriptor.wrapperCache):
|
||||
preserveWrapper = " PreserveWrapper(self);\n"
|
||||
preserveWrapper = "PreserveWrapper(self);\n"
|
||||
else:
|
||||
preserveWrapper = ""
|
||||
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 (!%s(cx, &tempVal)) {\n"
|
||||
" return false;\n"
|
||||
" }\n"
|
||||
" js::SetReservedSlot(reflector, %s, tempVal);\n"
|
||||
"js::SetReservedSlot(reflector, %s, args.rval());\n"
|
||||
"%s"
|
||||
"}\n"
|
||||
"return true;" %
|
||||
(getMaybeWrapValueFuncForType(self.idlNode.type),
|
||||
memberReservedSlot(self.idlNode), preserveWrapper))
|
||||
"break;" %
|
||||
(memberReservedSlot(self.idlNode), preserveWrapper))
|
||||
else:
|
||||
successCode = None
|
||||
|
||||
@ -5158,14 +5148,28 @@ if (!${obj}) {
|
||||
'successCode': successCode,
|
||||
}
|
||||
try:
|
||||
return wrapForType(self.returnType, self.descriptor,
|
||||
resultTemplateValues)
|
||||
wrapCode = CGGeneric(wrapForType(self.returnType, self.descriptor,
|
||||
resultTemplateValues))
|
||||
except MethodNotNewObjectError, err:
|
||||
assert not returnsNewObject
|
||||
raise TypeError("%s being returned from non-NewObject method or property %s.%s" %
|
||||
(err.typename,
|
||||
self.descriptor.interface.identifier.name,
|
||||
self.idlNode.identifier.name))
|
||||
if setSlot:
|
||||
# We need to make sure that our initial wrapping is done
|
||||
# in the reflector compartment, but that we finally set
|
||||
# args.rval() in the caller compartment.
|
||||
wrapCode = CGWrapper(
|
||||
CGIndenter(wrapCode),
|
||||
pre=("do { // block we break out of when done wrapping\n"
|
||||
" // Make sure we wrap and store in the slot in reflector's compartment\n"
|
||||
" JSAutoCompartment ac(cx, reflector);\n"),
|
||||
post=("\n} while (0);\n"
|
||||
"// And now make sure args.rval() is in the caller compartment\n"
|
||||
"return %s(cx, args.rval());" %
|
||||
getMaybeWrapValueFuncForType(self.idlNode.type)))
|
||||
return wrapCode.define()
|
||||
|
||||
def getErrorReport(self):
|
||||
jsImplemented = ""
|
||||
|
@ -342,6 +342,7 @@ public:
|
||||
// Sequence types
|
||||
void GetReadonlySequence(nsTArray<int32_t>&);
|
||||
void GetReadonlySequenceOfDictionaries(JSContext*, nsTArray<Dict>&);
|
||||
void GetReadonlyNullableSequenceOfDictionaries(JSContext*, Nullable<nsTArray<Dict> >&);
|
||||
void ReceiveSequence(nsTArray<int32_t>&);
|
||||
void ReceiveNullableSequence(Nullable< nsTArray<int32_t> >&);
|
||||
void ReceiveSequenceOfNullableInts(nsTArray< Nullable<int32_t> >&);
|
||||
|
@ -299,6 +299,8 @@ interface TestInterface {
|
||||
readonly attribute sequence<long> readonlySequence;
|
||||
[Cached, Pure]
|
||||
readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
|
||||
[Cached, Pure]
|
||||
readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
|
||||
sequence<long> receiveSequence();
|
||||
sequence<long>? receiveNullableSequence();
|
||||
sequence<long?> receiveSequenceOfNullableInts();
|
||||
|
@ -195,6 +195,8 @@ interface TestExampleInterface {
|
||||
readonly attribute sequence<long> readonlySequence;
|
||||
[Cached, Pure]
|
||||
readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
|
||||
[Cached, Pure]
|
||||
readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
|
||||
sequence<long> receiveSequence();
|
||||
sequence<long>? receiveNullableSequence();
|
||||
sequence<long?> receiveSequenceOfNullableInts();
|
||||
|
@ -216,6 +216,8 @@ interface TestJSImplInterface {
|
||||
readonly attribute sequence<long> readonlySequence;
|
||||
[Cached, Pure]
|
||||
readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
|
||||
[Cached, Pure]
|
||||
readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
|
||||
sequence<long> receiveSequence();
|
||||
sequence<long>? receiveNullableSequence();
|
||||
sequence<long?> receiveSequenceOfNullableInts();
|
||||
|
Loading…
Reference in New Issue
Block a user