Back out 2ccb9ec11a9f:d27ecea31590 (bug 856410) for b2g mochitest-3 failures

CLOSED TREE
This commit is contained in:
Phil Ringnalda 2013-06-11 21:24:56 -07:00
parent 311073b449
commit f6f5e5401f
23 changed files with 4 additions and 1605 deletions

View File

@ -309,12 +309,6 @@ public:
Optional_base<JS::Handle<T>, JS::Rooted<T> >() Optional_base<JS::Handle<T>, JS::Rooted<T> >()
{} {}
Optional(JSContext* cx) :
Optional_base<JS::Handle<T>, JS::Rooted<T> >()
{
this->Construct(cx);
}
Optional(JSContext* cx, const T& aValue) : Optional(JSContext* cx, const T& aValue) :
Optional_base<JS::Handle<T>, JS::Rooted<T> >(cx, aValue) Optional_base<JS::Handle<T>, JS::Rooted<T> >(cx, aValue)
{} {}

View File

@ -160,19 +160,6 @@ ErrorResult::ReportJSException(JSContext* cx)
JS_RemoveValueRoot(cx, &mJSException); JS_RemoveValueRoot(cx, &mJSException);
} }
void
ErrorResult::StealJSException(JSContext* cx,
JS::MutableHandle<JS::Value> value)
{
MOZ_ASSERT(!mMightHaveUnreportedJSException,
"Must call WouldReportJSException unconditionally in all codepaths that might call StealJSException");
MOZ_ASSERT(IsJSException(), "No exception to steal");
value.set(mJSException);
JS_RemoveValueRoot(cx, &mJSException);
mResult = NS_OK;
}
namespace dom { namespace dom {
bool bool

View File

@ -404,10 +404,6 @@ DOMInterfaces = {
'nativeType': 'nsDOMFocusEvent', 'nativeType': 'nsDOMFocusEvent',
}, },
'Future': {
'implicitJSContext': [ 'constructor' ]
},
'GainNode': { 'GainNode': {
'resultNotAddRefed': [ 'gain' ], 'resultNotAddRefed': [ 'gain' ],
}, },

View File

@ -64,18 +64,11 @@ public:
// Facilities for throwing a preexisting JS exception value via this // Facilities for throwing a preexisting JS exception value via this
// ErrorResult. The contract is that any code which might end up calling // ErrorResult. The contract is that any code which might end up calling
// ThrowJSException() must call MightThrowJSException() even if no exception // ThrowJSException() must call MightThrowJSException() even if no exception
// is being thrown. Code that would call ReportJSException or // is being thrown. Code that would call ReportJSException as needed must
// StealJSException as needed must first call WouldReportJSException even if // first call WouldReportJSException even if this ErrorResult has not failed.
// this ErrorResult has not failed.
void ThrowJSException(JSContext* cx, JS::Handle<JS::Value> exn); void ThrowJSException(JSContext* cx, JS::Handle<JS::Value> exn);
void ReportJSException(JSContext* cx); void ReportJSException(JSContext* cx);
bool IsJSException() const { return ErrorCode() == NS_ERROR_DOM_JS_EXCEPTION; } bool IsJSException() const { return ErrorCode() == NS_ERROR_DOM_JS_EXCEPTION; }
// StealJSException steals the JS Exception from the object. This method must
// be called only if IsJSException() returns true. This method also resets the
// ErrorCode() to NS_OK.
void StealJSException(JSContext* cx, JS::MutableHandle<JS::Value> value);
void MOZ_ALWAYS_INLINE MightThrowJSException() void MOZ_ALWAYS_INLINE MightThrowJSException()
{ {
#ifdef DEBUG #ifdef DEBUG

View File

@ -1,264 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/Future.h"
#include "mozilla/dom/FutureBinding.h"
#include "mozilla/dom/FutureResolver.h"
#include "mozilla/Preferences.h"
#include "FutureCallback.h"
#include "nsContentUtils.h"
#include "nsPIDOMWindow.h"
namespace mozilla {
namespace dom {
// FutureTask
// This class processes the future's callbacks with future's result.
class FutureTask MOZ_FINAL : public nsRunnable
{
public:
FutureTask(Future* aFuture)
: mFuture(aFuture)
{
MOZ_ASSERT(aFuture);
MOZ_COUNT_CTOR(FutureTask);
}
~FutureTask()
{
MOZ_COUNT_DTOR(FutureTask);
}
NS_IMETHOD Run()
{
mFuture->mTaskPending = false;
mFuture->RunTask();
return NS_OK;
}
private:
nsRefPtr<Future> mFuture;
};
// Future
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Future)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mResolver)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mResolveCallbacks);
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRejectCallbacks);
tmp->mResult = JSVAL_VOID;
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Future)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResolver)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResolveCallbacks);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRejectCallbacks);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Future)
NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mResult)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(Future)
NS_IMPL_CYCLE_COLLECTING_RELEASE(Future)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Future)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
Future::Future(nsPIDOMWindow* aWindow)
: mWindow(aWindow)
, mResult(JS::UndefinedValue())
, mState(Pending)
, mTaskPending(false)
{
MOZ_COUNT_CTOR(Future);
NS_HOLD_JS_OBJECTS(this, Future);
SetIsDOMBinding();
mResolver = new FutureResolver(this);
}
Future::~Future()
{
mResult = JSVAL_VOID;
NS_DROP_JS_OBJECTS(this, Future);
MOZ_COUNT_DTOR(Future);
}
JSObject*
Future::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return FutureBinding::Wrap(aCx, aScope, this);
}
/* static */ bool
Future::PrefEnabled()
{
return Preferences::GetBool("dom.future.enabled", false);
}
/* static */ already_AddRefed<Future>
Future::Constructor(const GlobalObject& aGlobal, JSContext* aCx,
FutureInit& aInit, ErrorResult& aRv)
{
MOZ_ASSERT(PrefEnabled());
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.Get());
if (!window) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<Future> future = new Future(window);
aInit.Call(future, *future->mResolver, aRv,
CallbackObject::eRethrowExceptions);
aRv.WouldReportJSException();
if (aRv.IsJSException()) {
Optional<JS::Handle<JS::Value> > value(aCx);
aRv.StealJSException(aCx, &value.Value());
future->mResolver->Reject(aCx, value);
}
return future.forget();
}
/* static */ already_AddRefed<Future>
Future::Resolve(const GlobalObject& aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv)
{
MOZ_ASSERT(PrefEnabled());
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.Get());
if (!window) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<Future> future = new Future(window);
Optional<JS::Handle<JS::Value> > value(aCx, aValue);
future->mResolver->Resolve(aCx, value);
return future.forget();
}
/* static */ already_AddRefed<Future>
Future::Reject(const GlobalObject& aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv)
{
MOZ_ASSERT(PrefEnabled());
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.Get());
if (!window) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<Future> future = new Future(window);
Optional<JS::Handle<JS::Value> > value(aCx, aValue);
future->mResolver->Reject(aCx, value);
return future.forget();
}
already_AddRefed<Future>
Future::Then(AnyCallback* aResolveCallback, AnyCallback* aRejectCallback)
{
nsRefPtr<Future> future = new Future(GetParentObject());
nsRefPtr<FutureCallback> resolveCb =
FutureCallback::Factory(future->mResolver,
aResolveCallback,
FutureCallback::Resolve);
nsRefPtr<FutureCallback> rejectCb =
FutureCallback::Factory(future->mResolver,
aRejectCallback,
FutureCallback::Reject);
AppendCallbacks(resolveCb, rejectCb);
return future.forget();
}
already_AddRefed<Future>
Future::Catch(AnyCallback* aRejectCallback)
{
return Then(nullptr, aRejectCallback);
}
void
Future::Done(AnyCallback* aResolveCallback, AnyCallback* aRejectCallback)
{
if (!aResolveCallback && !aRejectCallback) {
return;
}
nsRefPtr<FutureCallback> resolveCb;
if (aResolveCallback) {
resolveCb = new SimpleWrapperFutureCallback(this, aResolveCallback);
}
nsRefPtr<FutureCallback> rejectCb;
if (aRejectCallback) {
rejectCb = new SimpleWrapperFutureCallback(this, aRejectCallback);
}
AppendCallbacks(resolveCb, rejectCb);
}
void
Future::AppendCallbacks(FutureCallback* aResolveCallback,
FutureCallback* aRejectCallback)
{
if (aResolveCallback) {
mResolveCallbacks.AppendElement(aResolveCallback);
}
if (aRejectCallback) {
mRejectCallbacks.AppendElement(aRejectCallback);
}
// If future's state is resolved, queue a task to process future's resolve
// callbacks with future's result. If future's state is rejected, queue a task
// to process future's reject callbacks with future's result.
if (mState != Pending && !mTaskPending) {
nsRefPtr<FutureTask> task = new FutureTask(this);
NS_DispatchToCurrentThread(task);
mTaskPending = true;
}
}
void
Future::RunTask()
{
MOZ_ASSERT(mState != Pending);
nsTArray<nsRefPtr<FutureCallback> > callbacks;
callbacks.SwapElements(mState == Resolved ? mResolveCallbacks
: mRejectCallbacks);
mResolveCallbacks.Clear();
mRejectCallbacks.Clear();
Optional<JS::Handle<JS::Value> > value(nsContentUtils::GetSafeJSContext(),
mResult);
for (uint32_t i = 0; i < callbacks.Length(); ++i) {
callbacks[i]->Call(value);
}
}
} // namespace dom
} // namespace mozilla

View File

@ -1,118 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_Future_h
#define mozilla_dom_Future_h
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/dom/FutureBinding.h"
#include "nsWrapperCache.h"
#include "nsAutoPtr.h"
struct JSContext;
class nsPIDOMWindow;
namespace mozilla {
namespace dom {
class FutureInit;
class FutureCallback;
class AnyCallback;
class FutureResolver;
class Future MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
friend class FutureTask;
friend class FutureResolver;
friend class FutureResolverTask;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Future)
Future(nsPIDOMWindow* aWindow);
~Future();
static bool PrefEnabled();
// WebIDL
nsPIDOMWindow* GetParentObject() const
{
return mWindow;
}
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
static already_AddRefed<Future>
Constructor(const GlobalObject& aGlobal, JSContext* aCx, FutureInit& aInit,
ErrorResult& aRv);
static already_AddRefed<Future>
Resolve(const GlobalObject& aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
static already_AddRefed<Future>
Reject(const GlobalObject& aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
already_AddRefed<Future>
Then(AnyCallback* aResolveCallback, AnyCallback* aRejectCallback);
already_AddRefed<Future>
Catch(AnyCallback* aRejectCallback);
void Done(AnyCallback* aResolveCallback, AnyCallback* aRejectCallback);
private:
enum FutureState {
Pending,
Resolved,
Rejected
};
void SetState(FutureState aState)
{
MOZ_ASSERT(mState == Pending);
MOZ_ASSERT(aState != Pending);
mState = aState;
}
void SetResult(JS::Handle<JS::Value> aValue)
{
mResult = aValue;
}
// This method processes future's resolve/reject callbacks with future's
// result. It's executed when the resolver.resolve() or resolver.reject() is
// called or when the future already has a result and new callbacks are
// appended by then(), catch() or done().
void RunTask();
void AppendCallbacks(FutureCallback* aResolveCallback,
FutureCallback* aRejectCallback);
nsRefPtr<nsPIDOMWindow> mWindow;
nsRefPtr<FutureResolver> mResolver;
nsTArray<nsRefPtr<FutureCallback> > mResolveCallbacks;
nsTArray<nsRefPtr<FutureCallback> > mRejectCallbacks;
JS::Value mResult;
FutureState mState;
bool mTaskPending;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_Future_h

View File

@ -1,232 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FutureCallback.h"
#include "mozilla/dom/Future.h"
#include "mozilla/dom/FutureResolver.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTING_ADDREF(FutureCallback)
NS_IMPL_CYCLE_COLLECTING_RELEASE(FutureCallback)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FutureCallback)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FutureCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(FutureCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
FutureCallback::FutureCallback()
{
MOZ_COUNT_CTOR(FutureCallback);
}
FutureCallback::~FutureCallback()
{
MOZ_COUNT_DTOR(FutureCallback);
}
// ResolveFutureCallback
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(ResolveFutureCallback,
FutureCallback,
mResolver)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ResolveFutureCallback)
NS_INTERFACE_MAP_END_INHERITING(FutureCallback)
NS_IMPL_ADDREF_INHERITED(ResolveFutureCallback, FutureCallback)
NS_IMPL_RELEASE_INHERITED(ResolveFutureCallback, FutureCallback)
ResolveFutureCallback::ResolveFutureCallback(FutureResolver* aResolver)
: mResolver(aResolver)
{
MOZ_ASSERT(aResolver);
MOZ_COUNT_CTOR(ResolveFutureCallback);
}
ResolveFutureCallback::~ResolveFutureCallback()
{
MOZ_COUNT_DTOR(ResolveFutureCallback);
}
void
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);
}
mResolver->ResolveInternal(cx, aValue, FutureResolver::SyncTask);
}
// RejectFutureCallback
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(RejectFutureCallback,
FutureCallback,
mResolver)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(RejectFutureCallback)
NS_INTERFACE_MAP_END_INHERITING(FutureCallback)
NS_IMPL_ADDREF_INHERITED(RejectFutureCallback, FutureCallback)
NS_IMPL_RELEASE_INHERITED(RejectFutureCallback, FutureCallback)
RejectFutureCallback::RejectFutureCallback(FutureResolver* aResolver)
: mResolver(aResolver)
{
MOZ_ASSERT(aResolver);
MOZ_COUNT_CTOR(RejectFutureCallback);
}
RejectFutureCallback::~RejectFutureCallback()
{
MOZ_COUNT_DTOR(RejectFutureCallback);
}
void
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);
}
mResolver->RejectInternal(cx, aValue, FutureResolver::SyncTask);
}
// WrapperFutureCallback
NS_IMPL_CYCLE_COLLECTION_INHERITED_2(WrapperFutureCallback,
FutureCallback,
mNextResolver, mCallback)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(WrapperFutureCallback)
NS_INTERFACE_MAP_END_INHERITING(FutureCallback)
NS_IMPL_ADDREF_INHERITED(WrapperFutureCallback, FutureCallback)
NS_IMPL_RELEASE_INHERITED(WrapperFutureCallback, FutureCallback)
WrapperFutureCallback::WrapperFutureCallback(FutureResolver* aNextResolver,
AnyCallback* aCallback)
: mNextResolver(aNextResolver)
, mCallback(aCallback)
{
MOZ_ASSERT(aNextResolver);
MOZ_COUNT_CTOR(WrapperFutureCallback);
}
WrapperFutureCallback::~WrapperFutureCallback()
{
MOZ_COUNT_DTOR(WrapperFutureCallback);
}
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);
}
ErrorResult rv;
// If invoking callback threw an exception, run resolver's reject with the
// thrown exception as argument and the synchronous flag set.
Optional<JS::Handle<JS::Value> > value(cx,
mCallback->Call(mNextResolver->GetParentObject(), aValue, rv,
CallbackObject::eRethrowExceptions));
rv.WouldReportJSException();
if (rv.Failed() && rv.IsJSException()) {
Optional<JS::Handle<JS::Value> > value(cx);
rv.StealJSException(cx, &value.Value());
mNextResolver->RejectInternal(cx, value, FutureResolver::SyncTask);
return;
}
// Otherwise, run resolver's resolve with value and the synchronous flag
// set.
mNextResolver->ResolveInternal(cx, value, FutureResolver::SyncTask);
}
// SimpleWrapperFutureCallback
NS_IMPL_CYCLE_COLLECTION_INHERITED_2(SimpleWrapperFutureCallback,
FutureCallback,
mFuture, mCallback)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(SimpleWrapperFutureCallback)
NS_INTERFACE_MAP_END_INHERITING(FutureCallback)
NS_IMPL_ADDREF_INHERITED(SimpleWrapperFutureCallback, FutureCallback)
NS_IMPL_RELEASE_INHERITED(SimpleWrapperFutureCallback, FutureCallback)
SimpleWrapperFutureCallback::SimpleWrapperFutureCallback(Future* aFuture,
AnyCallback* aCallback)
: mFuture(aFuture)
, mCallback(aCallback)
{
MOZ_ASSERT(aFuture);
MOZ_COUNT_CTOR(SimpleWrapperFutureCallback);
}
SimpleWrapperFutureCallback::~SimpleWrapperFutureCallback()
{
MOZ_COUNT_DTOR(SimpleWrapperFutureCallback);
}
void
SimpleWrapperFutureCallback::Call(const Optional<JS::Handle<JS::Value> >& aValue)
{
ErrorResult rv;
mCallback->Call(mFuture, aValue, rv);
}
/* static */ FutureCallback*
FutureCallback::Factory(FutureResolver* aNextResolver,
AnyCallback* aCallback, Task aTask)
{
MOZ_ASSERT(aNextResolver);
// If we have a callback and a next resolver, we have to exec the callback and
// then propagate the return value to the next resolver->resolve().
if (aCallback) {
return new WrapperFutureCallback(aNextResolver, aCallback);
}
if (aTask == Resolve) {
return new ResolveFutureCallback(aNextResolver);
}
if (aTask == Reject) {
return new RejectFutureCallback(aNextResolver);
}
MOZ_ASSERT(false, "This should not happen");
return nullptr;
}
} // namespace dom
} // namespace mozilla

View File

@ -1,121 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_FutureCallback_h
#define mozilla_dom_FutureCallback_h
#include "mozilla/dom/Future.h"
#include "nsCycleCollectionParticipant.h"
namespace mozilla {
namespace dom {
class FutureResolver;
// This is the base class for any FutureCallback.
// It's a logical step in the future chain of callbacks.
class FutureCallback : public nsISupports
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(FutureCallback)
FutureCallback();
virtual ~FutureCallback();
virtual void Call(const Optional<JS::Handle<JS::Value> >& aValue) = 0;
enum Task {
Resolve,
Reject
};
// This factory returns a FutureCallback object with refcount of 0.
static FutureCallback*
Factory(FutureResolver* aNextResolver, AnyCallback* aCallback,
Task aTask);
};
// WrapperFutureCallback execs a JS Callback with a value, and then the return
// value is sent to the aNextResolver->resolve() or to aNextResolver->Reject()
// if the JS Callback throws.
class WrapperFutureCallback MOZ_FINAL : public FutureCallback
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WrapperFutureCallback,
FutureCallback)
void Call(const Optional<JS::Handle<JS::Value> >& aValue) MOZ_OVERRIDE;
WrapperFutureCallback(FutureResolver* aNextResolver,
AnyCallback* aCallback);
~WrapperFutureCallback();
private:
nsRefPtr<FutureResolver> mNextResolver;
nsRefPtr<AnyCallback> mCallback;
};
// SimpleWrapperFutureCallback execs a JS Callback with a value.
class SimpleWrapperFutureCallback MOZ_FINAL : public FutureCallback
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SimpleWrapperFutureCallback,
FutureCallback)
void Call(const Optional<JS::Handle<JS::Value> >& aValue) MOZ_OVERRIDE;
SimpleWrapperFutureCallback(Future* aFuture,
AnyCallback* aCallback);
~SimpleWrapperFutureCallback();
private:
nsRefPtr<Future> mFuture;
nsRefPtr<AnyCallback> mCallback;
};
// ResolveFutureCallback calls aResolver->Resolve() with the value received by
// Call().
class ResolveFutureCallback MOZ_FINAL : public FutureCallback
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ResolveFutureCallback,
FutureCallback)
void Call(const Optional<JS::Handle<JS::Value> >& aValue) MOZ_OVERRIDE;
ResolveFutureCallback(FutureResolver* aResolver);
~ResolveFutureCallback();
private:
nsRefPtr<FutureResolver> mResolver;
};
// RejectFutureCallback calls aResolver->Reject() with the value received by
// Call().
class RejectFutureCallback MOZ_FINAL : public FutureCallback
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(RejectFutureCallback,
FutureCallback)
void Call(const Optional<JS::Handle<JS::Value> >& aValue) MOZ_OVERRIDE;
RejectFutureCallback(FutureResolver* aResolver);
~RejectFutureCallback();
private:
nsRefPtr<FutureResolver> mResolver;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_FutureCallback_h

View File

@ -1,171 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/FutureResolver.h"
#include "mozilla/dom/FutureBinding.h"
#include "mozilla/dom/Future.h"
#include "FutureCallback.h"
namespace mozilla {
namespace dom {
// FutureResolverTask
// This class processes the future's callbacks with future's result.
class FutureResolverTask MOZ_FINAL : public nsRunnable
{
public:
FutureResolverTask(FutureResolver* aResolver,
const JS::Handle<JS::Value> aValue,
Future::FutureState aState)
: mResolver(aResolver)
, mValue(aValue)
, mState(aState)
{
MOZ_ASSERT(aResolver);
MOZ_ASSERT(mState != Future::Pending);
MOZ_COUNT_CTOR(FutureResolverTask);
JSContext* cx = nsContentUtils::GetSafeJSContext();
JS_AddNamedValueRootRT(JS_GetRuntime(cx), &mValue,
"FutureResolverTask.mValue");
}
~FutureResolverTask()
{
MOZ_COUNT_DTOR(FutureResolverTask);
JSContext* cx = nsContentUtils::GetSafeJSContext();
JS_RemoveValueRootRT(JS_GetRuntime(cx), &mValue);
}
NS_IMETHOD Run()
{
mResolver->RunTask(JS::Handle<JS::Value>::fromMarkedLocation(&mValue),
mState, FutureResolver::SyncTask);
return NS_OK;
}
private:
nsRefPtr<FutureResolver> mResolver;
JS::Value mValue;
Future::FutureState mState;
};
// FutureResolver
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(FutureResolver, mFuture)
NS_IMPL_CYCLE_COLLECTING_ADDREF(FutureResolver)
NS_IMPL_CYCLE_COLLECTING_RELEASE(FutureResolver)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FutureResolver)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
FutureResolver::FutureResolver(Future* aFuture)
: mFuture(aFuture)
, mResolvePending(false)
{
SetIsDOMBinding();
}
JSObject*
FutureResolver::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return FutureResolverBinding::Wrap(aCx, aScope, this);
}
void
FutureResolver::Resolve(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aValue,
FutureTaskSync aAsynchronous)
{
if (mResolvePending) {
return;
}
ResolveInternal(aCx, aValue, aAsynchronous);
}
void
FutureResolver::ResolveInternal(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aValue,
FutureTaskSync aAsynchronous)
{
mResolvePending = true;
// TODO: Bug 879245 - Then-able objects
if (aValue.WasPassed() && aValue.Value().isObject()) {
JS::Rooted<JSObject*> valueObj(aCx, &aValue.Value().toObject());
Future* nextFuture;
nsresult rv = UnwrapObject<Future>(aCx, valueObj, nextFuture);
if (NS_SUCCEEDED(rv)) {
nsRefPtr<FutureCallback> resolveCb = new ResolveFutureCallback(this);
nsRefPtr<FutureCallback> rejectCb = new RejectFutureCallback(this);
nextFuture->AppendCallbacks(resolveCb, rejectCb);
return;
}
}
// If the synchronous flag is set, process future's resolve callbacks with
// value. Otherwise, the synchronous flag is unset, queue a task to process
// future's resolve callbacks with value. Otherwise, the synchronous flag is
// unset, queue a task to process future's resolve callbacks with value.
RunTask(aValue.WasPassed() ? aValue.Value() : JS::UndefinedHandleValue,
Future::Resolved, aAsynchronous);
}
void
FutureResolver::Reject(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aValue,
FutureTaskSync aAsynchronous)
{
if (mResolvePending) {
return;
}
RejectInternal(aCx, aValue, aAsynchronous);
}
void
FutureResolver::RejectInternal(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aValue,
FutureTaskSync aAsynchronous)
{
mResolvePending = true;
// If the synchronous flag is set, process future's reject callbacks with
// value. Otherwise, the synchronous flag is unset, queue a task to process
// future's reject callbacks with value.
RunTask(aValue.WasPassed() ? aValue.Value() : JS::UndefinedHandleValue,
Future::Rejected, aAsynchronous);
}
void
FutureResolver::RunTask(JS::Handle<JS::Value> aValue,
Future::FutureState aState,
FutureTaskSync aAsynchronous)
{
// If the synchronous flag is unset, queue a task to process future's
// accept callbacks with value.
if (aAsynchronous == AsyncTask) {
nsRefPtr<FutureResolverTask> task =
new FutureResolverTask(this, aValue, aState);
NS_DispatchToCurrentThread(task);
return;
}
mFuture->SetResult(aValue);
mFuture->SetState(aState);
mFuture->RunTask();
mFuture = nullptr;
}
} // namespace dom
} // namespace mozilla

View File

@ -1,75 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_FutureResolver_h
#define mozilla_dom_FutureResolver_h
#include "mozilla/dom/Future.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
struct JSContext;
namespace mozilla {
namespace dom {
class FutureResolver MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
friend class FutureResolverTask;
friend class WrapperFutureCallback;
friend class ResolveFutureCallback;
friend class RejectFutureCallback;
private:
enum FutureTaskSync {
SyncTask,
AsyncTask
};
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FutureResolver)
FutureResolver(Future* aFuture);
Future* GetParentObject() const
{
return mFuture;
}
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
void Resolve(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aValue,
FutureTaskSync aSync = AsyncTask);
void Reject(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aValue,
FutureTaskSync aSync = AsyncTask);
private:
void ResolveInternal(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aValue,
FutureTaskSync aSync = AsyncTask);
void RejectInternal(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aValue,
FutureTaskSync aSync = AsyncTask);
void RunTask(JS::Handle<JS::Value> aValue,
Future::FutureState aState, FutureTaskSync aSync);
nsRefPtr<Future> mFuture;
bool mResolvePending;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_FutureResolver_h

View File

@ -1,18 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = domfuture_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
FAIL_ON_WARNINGS := 1
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk

View File

@ -1,22 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
TEST_DIRS += ['tests']
XPIDL_MODULE = 'dom_future'
MODULE = 'dom'
EXPORTS.mozilla.dom += [
'Future.h',
'FutureResolver.h',
]
CPP_SOURCES += [
'Future.cpp',
'FutureResolver.cpp',
'FutureCallback.cpp',
]

View File

@ -1,19 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
MOCHITEST_FILES = \
test_future.html \
test_resolve.html \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -1,6 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

View File

@ -1,412 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Basic Future Test</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 futureResolve() {
ok(Future, "Future object should exist");
var future = new Future(function(resolver) {
ok(resolver, "FutureResolver exists");
ok("reject" in resolver, "FutureResolver.reject exists");
ok("resolve" in resolver, "FutureResolver.resolve exists");
resolver.resolve(42);
}).done(function(what) {
ok(true, "Done - resolveCb has been called");
is(what, 42, "ResolveCb received 42");
runTest();
}, function() {
ok(false, "Done - rejectCb has been called");
runTest();
});
}
function futureReject() {
var future = new Future(function(resolver) {
resolver.reject(42);
}).done(function(what) {
ok(false, "Done - resolveCb has been called");
runTest();
}, function(what) {
ok(true, "Done - rejectCb has been called");
is(what, 42, "RejectCb received 42");
runTest();
});
}
function futureException() {
var future = new Future(function(resolver) {
throw 42;
}).done(function(what) {
ok(false, "Done - resolveCb has been called");
runTest();
}, function(what) {
ok(true, "Done - rejectCb has been called");
is(what, 42, "RejectCb received 42");
runTest();
});
}
function futureGC() {
var resolver;
var future = new Future(function(r) {
resolver = r;
}).done(function(what) {
ok(true, "Done - future is still alive");
runTest();
});
future = null;
SpecialPowers.gc();
SpecialPowers.forceGC();
SpecialPowers.forceCC();
resolver.resolve(42);
}
function futureAsync() {
var global = "foo";
var f = new Future(function(r) {
is(global, "foo", "Global should be foo");
r.resolve(42);
is(global, "foo", "Global should still be foo");
setTimeout(function() {
is(global, "bar", "Global should still be bar!");
runTest();
}, 0);
}).done(function() {
global = "bar";
});
is(global, "foo", "Global should still be foo (2)");
}
function futureDoubleDone() {
var steps = 0;
var future = new Future(function(resolver) {
resolver.resolve(42);
});
future.done(function(what) {
ok(true, "Done.resolve has been called");
is(what, 42, "Value == 42");
steps++;
}, function(what) {
ok(false, "Done.reject has been called");
});
future.done(function(what) {
ok(true, "Done.resolve has been called");
is(steps, 1, "Done.resolve - step == 1");
is(what, 42, "Value == 42");
runTest();
}, function(what) {
ok(false, "Done.reject has been called");
});
}
function futureDoneException() {
var future = new Future(function(resolver) {
resolver.resolve(42);
});
onErrorCb = window.onerror;
window.onerror = function(e) {
ok(true, "window.onerror has been called!");
window.onerror = onErrorCb;
runTest();
};
future.done(function(what) {
ok(true, "Done.resolve has been called");
throw "booh";
});
}
function futureThenCatchDone() {
var future = new Future(function(resolver) {
resolver.resolve(42);
});
var future2 = future.then(function(what) {
ok(true, "Then.resolve has been called");
is(what, 42, "Value == 42");
return what + 1;
}, function(what) {
ok(false, "Then.reject has been called");
});
isnot(future, future2, "These 2 future objs are different");
future2.then(function(what) {
ok(true, "Then.resolve has been called");
is(what, 43, "Value == 43");
return what + 1;
}, function(what) {
ok(false, "Then.reject has been called");
}).catch(function() {
ok(false, "Catch has been called");
}).done(function(what) {
ok(true, "Done.resolve has been called");
is(what, 44, "Value == 44");
runTest();
}, function(what) {
ok(false, "Done.reject has been called");
});
}
function futureRejectThenCatchDone() {
var future = new Future(function(resolver) {
resolver.reject(42);
});
var future2 = future.then(function(what) {
ok(false, "Then.resolve has been called");
}, function(what) {
ok(true, "Then.reject has been called");
is(what, 42, "Value == 42");
return what + 1;
});
isnot(future, future2, "These 2 future objs are different");
future2.then(function(what) {
ok(true, "Then.resolve has been called");
is(what, 43, "Value == 43");
return what+1;
}).catch(function(what) {
ok(false, "Catch has been called");
}).done(function(what) {
ok(true, "Then.resolve has been called");
is(what, 44, "Value == 44");
runTest();
});
}
function futureRejectThenCatchDone2() {
var future = new Future(function(resolver) {
resolver.reject(42);
});
future.then(function(what) {
ok(true, "Then.resolve has been called");
is(what, 42, "Value == 42");
return what+1;
}).catch(function(what) {
is(what, 42, "Value == 42");
ok(true, "Catch has been called");
return what+1;
}).done(function(what) {
ok(true, "Then.resolve has been called");
is(what, 43, "Value == 43");
runTest();
});
}
function futureRejectThenCatchExceptionDone() {
var future = new Future(function(resolver) {
resolver.reject(42);
});
future.then(function(what) {
ok(false, "Then.resolve has been called");
}, function(what) {
ok(true, "Then.reject has been called");
is(what, 42, "Value == 42");
throw(what + 1);
}).catch(function(what) {
ok(true, "Catch has been called");
is(what, 43, "Value == 43");
return what + 1;
}).done(function(what) {
ok(true, "Then.resolve has been called");
is(what, 44, "Value == 44");
runTest();
});
}
function futureThenCatchOrderingResolve() {
var global = 0;
var f = new Future(function(r) {
r.resolve(42);
});
f.done(function() {
f.then(function() {
global++;
});
f.catch(function() {
global++;
});
f.done(function() {
global++;
});
setTimeout(function() {
is(global, 2, "Many steps... should return 2");
runTest();
}, 0);
});
}
function futureThenCatchOrderingReject() {
var global = 0;
var f = new Future(function(r) {
r.reject(42);
})
f.done(function() {}, function() {
f.then(function() {
global++;
});
f.catch(function() {
global++;
});
f.done(function() {}, function() {
global++;
});
setTimeout(function() {
is(global, 2, "Many steps... should return 2");
runTest();
}, 0);
});
}
function futureNestedFuture() {
new Future(function(resolver) {
resolver.resolve(new Future(function(r) {
ok(true, "Nested future is executed");
r.resolve(42);
}));
}).then(function(value) {
is(value, 42, "Nested future is executed and then == 42");
runTest();
});
}
function futureNestedNestedFuture() {
new Future(function(resolver) {
resolver.resolve(new Future(function(r) {
ok(true, "Nested future is executed");
r.resolve(42);
}).then(function(what) { return what+1; }));
}).then(function(value) {
is(value, 43, "Nested future is executed and then == 43");
runTest();
});
}
function futureWrongNestedFuture() {
new Future(function(resolver) {
resolver.resolve(new Future(function(r) {
ok(true, "Nested future is executed");
r.resolve(42);
}));
resolver.reject(42);
}).then(function(value) {
is(value, 42, "Nested future is executed and then == 42");
runTest();
}, function(value) {
ok(false, "This is wrong");
});
}
function futureLoop() {
new Future(function(resolver) {
resolver.resolve(new Future(function(r) {
ok(true, "Nested future is executed");
r.resolve(new Future(function(r) {
ok(true, "Nested nested future is executed");
r.resolve(42);
}));
}));
}).then(function(value) {
is(value, 42, "Nested nested future is executed and then == 42");
runTest();
}, function(value) {
ok(false, "This is wrong");
});
}
function futureReject() {
var future = Future.reject(42).done(function(what) {
ok(false, "This should not be called");
}, function(what) {
is(what, 42, "Value == 42");
runTest();
});
}
function futureResolve() {
var future = Future.resolve(42).done(function(what) {
is(what, 42, "Value == 42");
runTest();
}, function() {
ok(false, "This should not be called");
});
}
function futureResolveNestedFuture() {
var future = Future.resolve(new Future(function(r) {
ok(true, "Nested future is executed");
r.resolve(42);
}, function() {
ok(false, "This should not be called");
})).done(function(what) {
is(what, 42, "Value == 42");
runTest();
}, function() {
ok(false, "This should not be called");
});
}
var tests = [ futureResolve, futureReject,
futureException, futureGC, futureAsync,
futureDoubleDone, futureDoneException,
futureThenCatchDone, futureRejectThenCatchDone,
futureRejectThenCatchDone2,
futureRejectThenCatchExceptionDone,
futureThenCatchOrderingResolve,
futureThenCatchOrderingReject,
futureNestedFuture, futureNestedNestedFuture,
futureWrongNestedFuture, futureLoop,
futureReject, futureResolve,
futureResolveNestedFuture,
];
function runTest() {
if (!tests.length) {
SimpleTest.finish();
return;
}
var test = tests.shift();
test();
}
var p = SpecialPowers.getBoolPref("dom.future.enabled");
SpecialPowers.setBoolPref("dom.future.enabled", false);
ok(!("Future" in window), "Future object should not exist if disabled by pref");
SpecialPowers.setBoolPref("dom.future.enabled", p);
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["dom.future.enabled", true]]}, runTest);
// -->
</script>
</pre>
</body>
</html>

View File

@ -1,67 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Future.resolve(anything) Test</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"><!--
var tests = [
null,
42,
"hello world",
true,
false,
{},
{ a: 42 },
[ 1, 2, 3, 4, null, true, "hello world" ],
function() {},
window,
undefined,
document.createElement('input'),
new Date(),
];
function cbError() {
ok(false, "Nothing should arrive here!");
}
function runTest() {
if (!tests.length) {
SimpleTest.finish();
return;
}
var test = tests.pop();
new Future(function(resolver) {
resolver.resolve(test);
}).then(function(what) {
ok(test === what, "What is: " + what);
}, cbError).done(function() {
new Future(function(resolver) {
resolver.reject(test)
}).then(cbError, function(what) {
ok(test === what, "What is: " + what);
}).done(runTest, cbError);
});
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["dom.future.enabled", true]]}, runTest);
// -->
</script>
</pre>
</body>
</html>

View File

@ -71,7 +71,6 @@ PARALLEL_DIRS += [
'workers', 'workers',
'camera', 'camera',
'audiochannel', 'audiochannel',
'future',
'wappush' 'wappush'
] ]

View File

@ -1,36 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://dom.spec.whatwg.org/#futures
*/
interface FutureResolver {
void resolve(optional any value);
void reject(optional any value);
};
callback FutureInit = void (FutureResolver resolver);
callback AnyCallback = any (optional any value);
[PrefControlled, Constructor(FutureInit init)]
interface Future {
// TODO: update this interface - bug 875289
[Creator, Throws]
static Future resolve(any value); // same as any(value)
[Creator, Throws]
static Future reject(any value);
[Creator]
Future then(optional AnyCallback? resolveCallback = null,
optional AnyCallback? rejectCallback = null);
[Creator]
Future catch(optional AnyCallback? rejectCallback = null);
void done(optional AnyCallback? resolveCallback = null,
optional AnyCallback? rejectCallback = null);
};

View File

@ -86,7 +86,6 @@ webidl_files = \
FocusEvent.webidl \ FocusEvent.webidl \
FormData.webidl \ FormData.webidl \
Function.webidl \ Function.webidl \
Future.webidl \
GainNode.webidl \ GainNode.webidl \
Geolocation.webidl \ Geolocation.webidl \
HTMLAnchorElement.webidl \ HTMLAnchorElement.webidl \

View File

@ -223,7 +223,7 @@ AutoJSContext::Init(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
} }
} }
AutoJSContext::operator JSContext*() const AutoJSContext::operator JSContext*()
{ {
return mCx; return mCx;
} }

View File

@ -61,7 +61,7 @@ namespace mozilla {
class MOZ_STACK_CLASS AutoJSContext { class MOZ_STACK_CLASS AutoJSContext {
public: public:
AutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM); AutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
operator JSContext*() const; operator JSContext*();
protected: protected:
AutoJSContext(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM); AutoJSContext(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM);

View File

@ -71,7 +71,6 @@ SHARED_LIBRARY_LIBS = \
$(DEPTH)/dom/src/offline/$(LIB_PREFIX)jsdomoffline_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/src/offline/$(LIB_PREFIX)jsdomoffline_s.$(LIB_SUFFIX) \
$(DEPTH)/dom/src/geolocation/$(LIB_PREFIX)jsdomgeolocation_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/src/geolocation/$(LIB_PREFIX)jsdomgeolocation_s.$(LIB_SUFFIX) \
$(DEPTH)/dom/audiochannel/$(LIB_PREFIX)domaudiochannel_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/audiochannel/$(LIB_PREFIX)domaudiochannel_s.$(LIB_SUFFIX) \
$(DEPTH)/dom/future/$(LIB_PREFIX)domfuture_s.$(LIB_SUFFIX) \
$(DEPTH)/dom/src/notification/$(LIB_PREFIX)jsdomnotification_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/src/notification/$(LIB_PREFIX)jsdomnotification_s.$(LIB_SUFFIX) \
$(DEPTH)/dom/system/$(LIB_PREFIX)domsystem_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/system/$(LIB_PREFIX)domsystem_s.$(LIB_SUFFIX) \
$(DEPTH)/dom/workers/$(LIB_PREFIX)domworkers_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/workers/$(LIB_PREFIX)domworkers_s.$(LIB_SUFFIX) \

View File

@ -1822,13 +1822,6 @@ pref("dom.max_script_run_time", 10);
// If true, ArchiveReader will be enabled // If true, ArchiveReader will be enabled
pref("dom.archivereader.enabled", false); pref("dom.archivereader.enabled", false);
// If true, Future will be enabled
#ifdef RELEASE_BUILD
pref("dom.future.enabled", false);
#else
pref("dom.future.enabled", true);
#endif
// Hang monitor timeout after which we kill the browser, in seconds // Hang monitor timeout after which we kill the browser, in seconds
// (0 is disabled) // (0 is disabled)
// Disabled on all platforms per bug 705748 until the found issues are // Disabled on all platforms per bug 705748 until the found issues are