mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 883683 - Leak with DOM promises. r=bz
This commit is contained in:
parent
7f4d63c6b8
commit
12938be54b
@ -108,6 +108,17 @@ Future::PrefEnabled()
|
||||
return Preferences::GetBool("dom.future.enabled", false);
|
||||
}
|
||||
|
||||
static void
|
||||
EnterCompartment(Maybe<JSAutoCompartment>& aAc, JSContext* aCx,
|
||||
const Optional<JS::Handle<JS::Value> >& aValue)
|
||||
{
|
||||
// FIXME Bug 878849
|
||||
if (aValue.WasPassed() && aValue.Value().isObject()) {
|
||||
JS::Rooted<JSObject*> rooted(aCx, &aValue.Value().toObject());
|
||||
aAc.construct(aCx, rooted);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<Future>
|
||||
Future::Constructor(const GlobalObject& aGlobal, JSContext* aCx,
|
||||
FutureInit& aInit, ErrorResult& aRv)
|
||||
@ -129,6 +140,9 @@ Future::Constructor(const GlobalObject& aGlobal, JSContext* aCx,
|
||||
if (aRv.IsJSException()) {
|
||||
Optional<JS::Handle<JS::Value> > value(aCx);
|
||||
aRv.StealJSException(aCx, &value.Value());
|
||||
|
||||
Maybe<JSAutoCompartment> ac;
|
||||
EnterCompartment(ac, aCx, value);
|
||||
future->mResolver->Reject(aCx, value);
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,17 @@ FutureCallback::~FutureCallback()
|
||||
MOZ_COUNT_DTOR(FutureCallback);
|
||||
}
|
||||
|
||||
static void
|
||||
EnterCompartment(Maybe<JSAutoCompartment>& aAc, JSContext* aCx,
|
||||
const Optional<JS::Handle<JS::Value> >& aValue)
|
||||
{
|
||||
// FIXME Bug 878849
|
||||
if (aValue.WasPassed() && aValue.Value().isObject()) {
|
||||
JS::Rooted<JSObject*> rooted(aCx, &aValue.Value().toObject());
|
||||
aAc.construct(aCx, rooted);
|
||||
}
|
||||
}
|
||||
|
||||
// ResolveFutureCallback
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(ResolveFutureCallback,
|
||||
@ -63,12 +74,8 @@ ResolveFutureCallback::Call(const Optional<JS::Handle<JS::Value> >& aValue)
|
||||
{
|
||||
// Run resolver's algorithm with value and the synchronous flag set.
|
||||
AutoJSContext cx;
|
||||
// FIXME Bug 878849
|
||||
Maybe<JSAutoCompartment> ac;
|
||||
if (aValue.WasPassed() && aValue.Value().isObject()) {
|
||||
JS::Rooted<JSObject*> rooted(cx, &aValue.Value().toObject());
|
||||
ac.construct(cx, rooted);
|
||||
}
|
||||
EnterCompartment(ac, cx, aValue);
|
||||
|
||||
mResolver->ResolveInternal(cx, aValue, FutureResolver::SyncTask);
|
||||
}
|
||||
@ -102,12 +109,8 @@ RejectFutureCallback::Call(const Optional<JS::Handle<JS::Value> >& aValue)
|
||||
{
|
||||
// Run resolver's algorithm with value and the synchronous flag set.
|
||||
AutoJSContext cx;
|
||||
// FIXME Bug 878849
|
||||
Maybe<JSAutoCompartment> ac;
|
||||
if (aValue.WasPassed() && aValue.Value().isObject()) {
|
||||
JS::Rooted<JSObject*> rooted(cx, &aValue.Value().toObject());
|
||||
ac.construct(cx, rooted);
|
||||
}
|
||||
EnterCompartment(ac, cx, aValue);
|
||||
|
||||
mResolver->RejectInternal(cx, aValue, FutureResolver::SyncTask);
|
||||
}
|
||||
@ -142,12 +145,8 @@ void
|
||||
WrapperFutureCallback::Call(const Optional<JS::Handle<JS::Value> >& aValue)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
// FIXME Bug 878849
|
||||
Maybe<JSAutoCompartment> ac;
|
||||
if (aValue.WasPassed() && aValue.Value().isObject()) {
|
||||
JS::Rooted<JSObject*> rooted(cx, &aValue.Value().toObject());
|
||||
ac.construct(cx, rooted);
|
||||
}
|
||||
EnterCompartment(ac, cx, aValue);
|
||||
|
||||
ErrorResult rv;
|
||||
|
||||
@ -162,12 +161,17 @@ WrapperFutureCallback::Call(const Optional<JS::Handle<JS::Value> >& aValue)
|
||||
if (rv.Failed() && rv.IsJSException()) {
|
||||
Optional<JS::Handle<JS::Value> > value(cx);
|
||||
rv.StealJSException(cx, &value.Value());
|
||||
|
||||
Maybe<JSAutoCompartment> ac2;
|
||||
EnterCompartment(ac2, cx, value);
|
||||
mNextResolver->RejectInternal(cx, value, FutureResolver::SyncTask);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, run resolver's resolve with value and the synchronous flag
|
||||
// set.
|
||||
Maybe<JSAutoCompartment> ac2;
|
||||
EnterCompartment(ac2, cx, value);
|
||||
mNextResolver->ResolveInternal(cx, value, FutureResolver::SyncTask);
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ include $(DEPTH)/config/autoconf.mk
|
||||
MOCHITEST_FILES = \
|
||||
test_future.html \
|
||||
test_resolve.html \
|
||||
test_bug883683.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
41
dom/future/tests/test_bug883683.html
Normal file
41
dom/future/tests/test_bug883683.html
Normal file
@ -0,0 +1,41 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Future - bug 883683</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript"><!--
|
||||
|
||||
function runTest() {
|
||||
[{}, {}, {}, {}, {}].reduce(Future.reject);
|
||||
ok(true, "No leaks with reject?");
|
||||
|
||||
[{}, {}, {}, {}, {}].reduce(Future.resolve);
|
||||
ok(true, "No leaks with resolve?");
|
||||
|
||||
[{}, {}, {}, {}, {}].reduce(function(a, b, c, d) { return new Future(function(r) { throw a; }); });
|
||||
ok(true, "No leaks with exception?");
|
||||
|
||||
[{}, {}, {}, {}, {}].reduce(function(a, b, c, d) { return new Future(function(r) { }); });
|
||||
ok(true, "No leaks with empty future?");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.future.enabled", true]]}, runTest);
|
||||
// -->
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user