Diff
Modified: trunk/Source/WebCore/ChangeLog (205256 => 205257)
--- trunk/Source/WebCore/ChangeLog 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/ChangeLog 2016-08-31 18:36:46 UTC (rev 205257)
@@ -1,3 +1,133 @@
+2016-08-30 Ryosuke Niwa <[email protected]>
+
+ Avoid using strong reference in JSDOMPromise’s DeferredWrapper
+ https://bugs.webkit.org/show_bug.cgi?id=161426
+ <rdar://problem/28091123>
+
+ Reviewed by Geoffrey Garen.
+
+ Replace JSC::Strong in DeferredWrapper by JSC::Weak, and make the global object own JSPromiseDeferred.
+
+ DeferredWrapper adds itself to JSDOMGlobalObject's newly added HashSet when it's created and clears itself
+ from the HashSet inside its destructor as well as when the promise is resolved or rejected.
+ This is so that JSDOMGlobalObject's visitChildren can visit every live DeferredWrapper.
+
+ Because this operation is rather expense, this patch turns DeferredWrapper into a RefCounted object to avoid
+ HashMap churns. Most of code changes in this patch is due to this type change, and the fact lambda cannot
+ capture Ref<DeferredWrapper> since its copy constructor doesn't exist.
+
+ We also create a write barrier from the global object to JSPromiseDeferred so that they won't be collected
+ during an eden collection when it happens before JSDOMGlobalObject's visitChildren is invoked.
+
+ Note that it's possible for the entire DOM wrapper world of the promise to go away before the promise is
+ resolved or rejected by a ref-counted C++ object. In this case, m_deferred and m_globalObject become dead.
+ Various member resolve* and reject functions of DeferredWrapper have been modified to check this condition.
+
+ Because JSDOMGlobalObject can be finalized before DeferredWrapper is finalized. DeferredWrapper's destructor,
+ which calls DeferredWrapper::clear, should only remove itself from m_globalObject when m_globalObject is alive.
+
+ Finally, this patch makes DeferredWrapper inherit from ActiveDOMCallback so that it won't try to execute scripts
+ when the active DOM objects have been suspended; e.g. after a page navigation.
+
+ No new tests since there should be no author/user visible behavioral change.
+
+ * Modules/applepay/ApplePaySession.cpp:
+ (WebCore::ApplePaySession::canMakePaymentsWithActiveCard):
+ * Modules/applepay/ApplePaySession.h:
+ * Modules/fetch/DOMWindowFetch.cpp:
+ (WebCore::DOMWindowFetch::fetch):
+ * Modules/fetch/DOMWindowFetch.h:
+ * Modules/fetch/FetchBody.cpp:
+ (WebCore::FetchBody::arrayBuffer):
+ (WebCore::FetchBody::blob):
+ (WebCore::FetchBody::json):
+ (WebCore::FetchBody::text):
+ (WebCore::FetchBody::consume):
+ (WebCore::FetchBody::consumeArrayBuffer):
+ (WebCore::FetchBody::consumeArrayBufferView):
+ (WebCore::FetchBody::consumeText):
+ (WebCore::FetchBody::consumeBlob):
+ (WebCore::FetchBody::loadingFailed):
+ (WebCore::FetchBody::loadingSucceeded):
+ * Modules/fetch/FetchBody.h:
+ (WebCore::FetchBody::formData):
+ (WebCore::FetchBody::cleanConsumePromise):
+ (WebCore::FetchBody): Use RefPtr<DeferredWrapper> instead of Optional<DeferredWrapper> now that DeferredWrapper
+ is ref counted. Perhaps we could use Optional<Ref<DeferredWrapper>> here but that seemed rather verbose.
+ * Modules/fetch/FetchBodyConsumer.cpp:
+ (WebCore::FetchBodyConsumer::resolveWithData):
+ (WebCore::FetchBodyConsumer::resolve):
+ * Modules/fetch/FetchBodyConsumer.h:
+ * Modules/fetch/FetchBodyOwner.cpp:
+ (WebCore::FetchBodyOwner::arrayBuffer):
+ (WebCore::FetchBodyOwner::blob):
+ (WebCore::FetchBodyOwner::formData):
+ (WebCore::FetchBodyOwner::json):
+ (WebCore::FetchBodyOwner::text):
+ * Modules/fetch/FetchBodyOwner.h:
+ * Modules/fetch/FetchResponse.cpp:
+ (WebCore::FetchResponse::consume):
+ (WebCore::FetchResponse::finishConsumingStream):
+ * Modules/fetch/FetchResponse.h:
+ * Modules/fetch/WorkerGlobalScopeFetch.cpp:
+ (WebCore::WorkerGlobalScopeFetch::fetch):
+ * Modules/fetch/WorkerGlobalScopeFetch.h:
+ * Modules/mediastream/UserMediaPermissionCheck.h:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/JSDOMGlobalObject.cpp:
+ (WebCore::JSDOMGlobalObject::~JSDOMGlobalObject): Added.
+ (WebCore::JSDOMGlobalObject::visitChildren): Added visits to each JSPromiseDeferred owned by this global object.
+ * bindings/js/JSDOMGlobalObject.h:
+ (WebCore::JSDOMGlobalObject::deferredWrappers): Added. This map is only used by JSDOMGlobalObject's visitChildren.
+ * bindings/js/JSDOMPromise.cpp:
+ (WebCore::DeferredWrapper::DeferredWrapper):
+ (WebCore::DeferredWrapper::~DeferredWrapper): Calls clear. When the global object has already been finalized,
+ m_globalObject is dead. In that case, there is no need to remove itself from the global object. When m_deferred
+ has been cleared, either clear() has already been called (1) or the callback is dead (2). Since (2) happens only
+ when the global object itself is dead (as its visitChildren would have visited m_deferred otherwise), again, there
+ is no need to remove itself from global object.
+ (WebCore::DeferredWrapper::clear): Added. Clears m_deferred and removes itself from JSDOMGlobalObject.
+ (WebCore::DeferredWrapper::contextDestroyed): ScriptExecutionContext has been destroyed. We must call clear().
+ (WebCore::DeferredWrapper::callFunction): Check canInvokeCallback in ActiveDOMCallback.
+ (WebCore::DeferredWrapper::reject): Exit early when isSuspended() is true. See below.
+ (WebCore::rejectPromiseWithExceptionIfAny):
+ (WebCore::fulfillPromiseWithJSON):
+ (WebCore::fulfillPromiseWithArrayBuffer):
+ * bindings/js/JSDOMPromise.h:
+ (WebCore::DeferredWrapper::create): Added.
+ (WebCore::DeferredWrapper::isSuspended): Added. Returns true iff the DOM wrapper world has gone away or active DOM
+ objects have been suspended.
+ (WebCore::DeferredWrapper::globalObject): Made this inline.
+ (WebCore::DeferredWrapper::visitAggregate): Added. Called by JSDOMGlobalObject::visitChildren.
+ (WebCore::DOMPromise::resolve):
+ (WebCore::DOMPromise::reject):
+ (WebCore::DeferredWrapper::resolveWithValue): Exit early when isSuspended() is true.
+ (WebCore::DeferredWrapper::resolveWithNewlyCreated): Ditto.
+ (WebCore::DeferredWrapper::rejectWithValue): Ditto.
+ (WebCore::DeferredWrapper::resolve): Ditto.
+ (WebCore::DeferredWrapper::reject): Ditto.
+ * bindings/js/JSFontFaceCustom.cpp:
+ (WebCore::JSFontFace::loaded):
+ * bindings/js/JSFontFaceSetCustom.cpp:
+ (WebCore::JSFontFaceSet::ready):
+ * bindings/js/JSMediaDevicesCustom.cpp:
+ (WebCore::JSMediaDevices::getUserMedia):
+ * bindings/js/JSReadableStreamSourceCustom.cpp:
+ (WebCore::JSReadableStreamSource::start):
+ * bindings/js/JSWebKitSubtleCryptoCustom.cpp:
+ (WebCore::JSWebKitSubtleCrypto::encrypt):
+ (WebCore::JSWebKitSubtleCrypto::decrypt):
+ (WebCore::JSWebKitSubtleCrypto::sign):
+ (WebCore::JSWebKitSubtleCrypto::verify):
+ (WebCore::JSWebKitSubtleCrypto::digest):
+ (WebCore::JSWebKitSubtleCrypto::generateKey):
+ (WebCore::JSWebKitSubtleCrypto::importKey):
+ (WebCore::JSWebKitSubtleCrypto::exportKey):
+ (WebCore::JSWebKitSubtleCrypto::wrapKey):
+ (WebCore::JSWebKitSubtleCrypto::unwrapKey):
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (GenerateReturnParameters):
+
2016-08-31 Youenn Fablet <[email protected]>
[Fetch API] Request construction failure should not set "bodyUsed"
Modified: trunk/Source/WebCore/Modules/applepay/ApplePaySession.cpp (205256 => 205257)
--- trunk/Source/WebCore/Modules/applepay/ApplePaySession.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/applepay/ApplePaySession.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -733,7 +733,7 @@
return paymentCoordinator.canMakePayments();
}
-void ApplePaySession::canMakePaymentsWithActiveCard(ScriptExecutionContext& scriptExecutionContext, const String& merchantIdentifier, DeferredWrapper&& promise, ExceptionCode& ec)
+void ApplePaySession::canMakePaymentsWithActiveCard(ScriptExecutionContext& scriptExecutionContext, const String& merchantIdentifier, Ref<DeferredWrapper>&& passedPromise, ExceptionCode& ec)
{
auto& document = downcast<Document>(scriptExecutionContext);
DOMWindow& window = *document.domWindow();
@@ -745,12 +745,13 @@
return;
}
+ RefPtr<DeferredWrapper> promise(WTFMove(passedPromise));
if (!shouldDiscloseApplePayCapability(document)) {
auto& paymentCoordinator = document.frame()->mainFrame().paymentCoordinator();
bool canMakePayments = paymentCoordinator.canMakePayments();
RunLoop::main().dispatch([promise, canMakePayments]() mutable {
- promise.resolve(canMakePayments);
+ promise->resolve(canMakePayments);
});
return;
}
@@ -758,7 +759,7 @@
auto& paymentCoordinator = document.frame()->mainFrame().paymentCoordinator();
paymentCoordinator.canMakePaymentsWithActiveCard(merchantIdentifier, document.domain(), [promise](bool canMakePayments) mutable {
- promise.resolve(canMakePayments);
+ promise->resolve(canMakePayments);
});
}
Modified: trunk/Source/WebCore/Modules/applepay/ApplePaySession.h (205256 => 205257)
--- trunk/Source/WebCore/Modules/applepay/ApplePaySession.h 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/applepay/ApplePaySession.h 2016-08-31 18:36:46 UTC (rev 205257)
@@ -63,7 +63,7 @@
static bool supportsVersion(ScriptExecutionContext&, unsigned version, ExceptionCode&);
static bool canMakePayments(ScriptExecutionContext&, ExceptionCode&);
- static void canMakePaymentsWithActiveCard(ScriptExecutionContext&, const String& merchantIdentifier, DeferredWrapper&&, ExceptionCode&);
+ static void canMakePaymentsWithActiveCard(ScriptExecutionContext&, const String& merchantIdentifier, Ref<DeferredWrapper>&&, ExceptionCode&);
void begin(ExceptionCode&);
void abort(ExceptionCode&);
Modified: trunk/Source/WebCore/Modules/fetch/DOMWindowFetch.cpp (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/DOMWindowFetch.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/DOMWindowFetch.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -37,7 +37,7 @@
namespace WebCore {
-void DOMWindowFetch::fetch(DOMWindow& window, FetchRequest& request, DeferredWrapper&& promise)
+void DOMWindowFetch::fetch(DOMWindow& window, FetchRequest& request, DOMPromise<FetchResponse>&& promise)
{
if (!window.scriptExecutionContext())
return;
Modified: trunk/Source/WebCore/Modules/fetch/DOMWindowFetch.h (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/DOMWindowFetch.h 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/DOMWindowFetch.h 2016-08-31 18:36:46 UTC (rev 205257)
@@ -30,6 +30,7 @@
#if ENABLE(FETCH_API)
+#include "JSDOMPromise.h"
#include <wtf/Forward.h>
namespace WebCore {
@@ -38,10 +39,11 @@
class DeferredWrapper;
class Dictionary;
class FetchRequest;
+class FetchResponse;
class DOMWindowFetch {
public:
- static void fetch(DOMWindow&, FetchRequest&, DeferredWrapper&&);
+ static void fetch(DOMWindow&, FetchRequest&, DOMPromise<FetchResponse>&&);
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/fetch/FetchBody.cpp (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/FetchBody.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/FetchBody.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -124,7 +124,7 @@
headers.fastSet(HTTPHeaderName::ContentType, m_contentType);
}
-void FetchBody::arrayBuffer(FetchBodyOwner& owner, DeferredWrapper&& promise)
+void FetchBody::arrayBuffer(FetchBodyOwner& owner, Ref<DeferredWrapper>&& promise)
{
ASSERT(m_type != Type::None);
m_consumer.setType(FetchBodyConsumer::Type::ArrayBuffer);
@@ -131,7 +131,7 @@
consume(owner, WTFMove(promise));
}
-void FetchBody::blob(FetchBodyOwner& owner, DeferredWrapper&& promise)
+void FetchBody::blob(FetchBodyOwner& owner, Ref<DeferredWrapper>&& promise)
{
ASSERT(m_type != Type::None);
m_consumer.setType(FetchBodyConsumer::Type::Blob);
@@ -139,12 +139,12 @@
consume(owner, WTFMove(promise));
}
-void FetchBody::json(FetchBodyOwner& owner, DeferredWrapper&& promise)
+void FetchBody::json(FetchBodyOwner& owner, Ref<DeferredWrapper>&& promise)
{
ASSERT(m_type != Type::None);
if (m_type == Type::Text) {
- fulfillPromiseWithJSON(promise, m_text);
+ fulfillPromiseWithJSON(WTFMove(promise), m_text);
return;
}
m_consumer.setType(FetchBodyConsumer::Type::JSON);
@@ -151,12 +151,12 @@
consume(owner, WTFMove(promise));
}
-void FetchBody::text(FetchBodyOwner& owner, DeferredWrapper&& promise)
+void FetchBody::text(FetchBodyOwner& owner, Ref<DeferredWrapper>&& promise)
{
ASSERT(m_type != Type::None);
if (m_type == Type::Text) {
- promise.resolve(m_text);
+ promise->resolve(m_text);
return;
}
m_consumer.setType(FetchBodyConsumer::Type::Text);
@@ -163,7 +163,7 @@
consume(owner, WTFMove(promise));
}
-void FetchBody::consume(FetchBodyOwner& owner, DeferredWrapper&& promise)
+void FetchBody::consume(FetchBodyOwner& owner, Ref<DeferredWrapper>&& promise)
{
// This should be handled by FetchBodyOwner
ASSERT(m_type != Type::None);
@@ -172,13 +172,13 @@
switch (m_type) {
case Type::ArrayBuffer:
- consumeArrayBuffer(promise);
+ consumeArrayBuffer(WTFMove(promise));
return;
case Type::ArrayBufferView:
- consumeArrayBufferView(promise);
+ consumeArrayBufferView(WTFMove(promise));
return;
case Type::Text:
- consumeText(promise);
+ consumeText(WTFMove(promise));
return;
case Type::Blob:
consumeBlob(owner, WTFMove(promise));
@@ -187,11 +187,11 @@
m_consumePromise = WTFMove(promise);
return;
case Type::Loaded:
- m_consumer.resolve(promise);
+ m_consumer.resolve(WTFMove(promise));
return;
case Type::FormData:
// FIXME: Support consuming FormData.
- promise.reject(0);
+ promise->reject(0);
return;
default:
ASSERT_NOT_REACHED();
@@ -246,28 +246,28 @@
}
#endif
-void FetchBody::consumeArrayBuffer(DeferredWrapper& promise)
+void FetchBody::consumeArrayBuffer(Ref<DeferredWrapper>&& promise)
{
ASSERT(m_data);
- m_consumer.resolveWithData(promise, static_cast<const uint8_t*>(m_data->data()), m_data->byteLength());
+ m_consumer.resolveWithData(WTFMove(promise), static_cast<const uint8_t*>(m_data->data()), m_data->byteLength());
m_data = nullptr;
}
-void FetchBody::consumeArrayBufferView(DeferredWrapper& promise)
+void FetchBody::consumeArrayBufferView(Ref<DeferredWrapper>&& promise)
{
ASSERT(m_dataView);
- m_consumer.resolveWithData(promise, static_cast<const uint8_t*>(m_dataView->baseAddress()), m_dataView->byteLength());
+ m_consumer.resolveWithData(WTFMove(promise), static_cast<const uint8_t*>(m_dataView->baseAddress()), m_dataView->byteLength());
m_dataView = nullptr;
}
-void FetchBody::consumeText(DeferredWrapper& promise)
+void FetchBody::consumeText(Ref<DeferredWrapper>&& promise)
{
Vector<uint8_t> data = ""
- m_consumer.resolveWithData(promise, data.data(), data.size());
+ m_consumer.resolveWithData(WTFMove(promise), data.data(), data.size());
m_text = { };
}
-void FetchBody::consumeBlob(FetchBodyOwner& owner, DeferredWrapper&& promise)
+void FetchBody::consumeBlob(FetchBodyOwner& owner, Ref<DeferredWrapper>&& promise)
{
ASSERT(m_blob);
@@ -290,7 +290,7 @@
{
if (m_consumePromise) {
m_consumePromise->reject(0);
- m_consumePromise = Nullopt;
+ m_consumePromise = nullptr;
}
}
@@ -297,10 +297,8 @@
void FetchBody::loadingSucceeded()
{
m_type = m_consumer.hasData() ? Type::Loaded : Type::None;
- if (m_consumePromise) {
- m_consumer.resolve(*m_consumePromise);
- m_consumePromise = Nullopt;
- }
+ if (m_consumePromise)
+ m_consumer.resolve(m_consumePromise.releaseNonNull());
}
RefPtr<FormData> FetchBody::bodyForInternalRequest(ScriptExecutionContext& context) const
Modified: trunk/Source/WebCore/Modules/fetch/FetchBody.h (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/FetchBody.h 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/FetchBody.h 2016-08-31 18:36:46 UTC (rev 205257)
@@ -52,11 +52,11 @@
class FetchBody {
public:
- void arrayBuffer(FetchBodyOwner&, DeferredWrapper&&);
- void blob(FetchBodyOwner&, DeferredWrapper&&);
- void json(FetchBodyOwner&, DeferredWrapper&&);
- void text(FetchBodyOwner&, DeferredWrapper&&);
- void formData(FetchBodyOwner&, DeferredWrapper&& promise) { promise.reject(0); }
+ void arrayBuffer(FetchBodyOwner&, Ref<DeferredWrapper>&&);
+ void blob(FetchBodyOwner&, Ref<DeferredWrapper>&&);
+ void json(FetchBodyOwner&, Ref<DeferredWrapper>&&);
+ void text(FetchBodyOwner&, Ref<DeferredWrapper>&&);
+ void formData(FetchBodyOwner&, Ref<DeferredWrapper>&& promise) { promise.get().reject(0); }
#if ENABLE(STREAMS_API)
void consumeAsStream(FetchBodyOwner&, FetchResponseSource&);
@@ -83,7 +83,7 @@
FetchBodyConsumer& consumer() { return m_consumer; }
- void cleanConsumePromise() { m_consumePromise = Nullopt; }
+ void cleanConsumePromise() { m_consumePromise = nullptr; }
private:
FetchBody(Ref<Blob>&&);
@@ -93,13 +93,13 @@
FetchBody(String&&);
FetchBody(Type type) : m_type(type) { }
- void consume(FetchBodyOwner&, DeferredWrapper&&);
+ void consume(FetchBodyOwner&, Ref<DeferredWrapper>&&);
Vector<uint8_t> extractFromText() const;
- void consumeArrayBuffer(DeferredWrapper&);
- void consumeArrayBufferView(DeferredWrapper&);
- void consumeText(DeferredWrapper&);
- void consumeBlob(FetchBodyOwner&, DeferredWrapper&&);
+ void consumeArrayBuffer(Ref<DeferredWrapper>&&);
+ void consumeArrayBufferView(Ref<DeferredWrapper>&&);
+ void consumeText(Ref<DeferredWrapper>&&);
+ void consumeBlob(FetchBodyOwner&, Ref<DeferredWrapper>&&);
Type m_type { Type::None };
String m_contentType;
@@ -112,7 +112,7 @@
String m_text;
FetchBodyConsumer m_consumer { FetchBodyConsumer::Type::None };
- Optional<DeferredWrapper> m_consumePromise;
+ RefPtr<DeferredWrapper> m_consumePromise;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.cpp (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -59,20 +59,20 @@
return decoder->decodeAndFlush(reinterpret_cast<const char*>(data), length);
}
-void FetchBodyConsumer::resolveWithData(DeferredWrapper& promise, const unsigned char* data, unsigned length)
+void FetchBodyConsumer::resolveWithData(Ref<DeferredWrapper>&& promise, const unsigned char* data, unsigned length)
{
switch (m_type) {
case Type::ArrayBuffer:
- fulfillPromiseWithArrayBuffer(promise, data, length);
+ fulfillPromiseWithArrayBuffer(WTFMove(promise), data, length);
return;
case Type::Blob:
- promise.resolveWithNewlyCreated(blobFromData(data, length, m_contentType));
+ promise->resolveWithNewlyCreated(blobFromData(data, length, m_contentType));
return;
case Type::JSON:
- fulfillPromiseWithJSON(promise, textFromUTF8(data, length));
+ fulfillPromiseWithJSON(WTFMove(promise), textFromUTF8(data, length));
return;
case Type::Text:
- promise.resolve(textFromUTF8(data, length));
+ promise->resolve(textFromUTF8(data, length));
return;
case Type::None:
ASSERT_NOT_REACHED();
@@ -80,21 +80,21 @@
}
}
-void FetchBodyConsumer::resolve(DeferredWrapper& promise)
+void FetchBodyConsumer::resolve(Ref<DeferredWrapper>&& promise)
{
ASSERT(m_type != Type::None);
switch (m_type) {
case Type::ArrayBuffer:
- fulfillPromiseWithArrayBuffer(promise, takeAsArrayBuffer().get());
+ fulfillPromiseWithArrayBuffer(WTFMove(promise), takeAsArrayBuffer().get());
return;
case Type::Blob:
- promise.resolveWithNewlyCreated(takeAsBlob());
+ promise->resolveWithNewlyCreated(takeAsBlob());
return;
case Type::JSON:
- fulfillPromiseWithJSON(promise, takeAsText());
+ fulfillPromiseWithJSON(WTFMove(promise), takeAsText());
return;
case Type::Text:
- promise.resolve(takeAsText());
+ promise->resolve(takeAsText());
return;
case Type::None:
ASSERT_NOT_REACHED();
Modified: trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.h (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.h 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.h 2016-08-31 18:36:46 UTC (rev 205257)
@@ -57,8 +57,8 @@
void clean() { m_buffer = nullptr; }
- void resolve(DeferredWrapper&);
- void resolveWithData(DeferredWrapper&, const unsigned char*, unsigned);
+ void resolve(Ref<DeferredWrapper>&&);
+ void resolveWithData(Ref<DeferredWrapper>&&, const unsigned char*, unsigned);
bool hasData() const { return !!m_buffer; }
Modified: trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -71,14 +71,14 @@
return false;
}
-void FetchBodyOwner::arrayBuffer(DeferredWrapper&& promise)
+void FetchBodyOwner::arrayBuffer(Ref<DeferredWrapper>&& promise)
{
if (m_body.isEmpty()) {
- fulfillPromiseWithArrayBuffer(promise, nullptr, 0);
+ fulfillPromiseWithArrayBuffer(WTFMove(promise), nullptr, 0);
return;
}
if (isDisturbedOrLocked()) {
- promise.reject(TypeError);
+ promise->reject(TypeError);
return;
}
m_isDisturbed = true;
@@ -85,14 +85,14 @@
m_body.arrayBuffer(*this, WTFMove(promise));
}
-void FetchBodyOwner::blob(DeferredWrapper&& promise)
+void FetchBodyOwner::blob(Ref<DeferredWrapper>&& promise)
{
if (m_body.isEmpty()) {
- promise.resolve(Blob::create(Vector<uint8_t>(), Blob::normalizedContentType(extractMIMETypeFromMediaType(m_body.contentType()))));
+ promise->resolve(Blob::create(Vector<uint8_t>(), Blob::normalizedContentType(extractMIMETypeFromMediaType(m_body.contentType()))));
return;
}
if (isDisturbedOrLocked()) {
- promise.reject(TypeError);
+ promise->reject(TypeError);
return;
}
m_isDisturbed = true;
@@ -99,14 +99,14 @@
m_body.blob(*this, WTFMove(promise));
}
-void FetchBodyOwner::formData(DeferredWrapper&& promise)
+void FetchBodyOwner::formData(Ref<DeferredWrapper>&& promise)
{
if (m_body.isEmpty()) {
- promise.reject(0);
+ promise->reject(0);
return;
}
if (isDisturbedOrLocked()) {
- promise.reject(TypeError);
+ promise->reject(TypeError);
return;
}
m_isDisturbed = true;
@@ -113,14 +113,14 @@
m_body.formData(*this, WTFMove(promise));
}
-void FetchBodyOwner::json(DeferredWrapper&& promise)
+void FetchBodyOwner::json(Ref<DeferredWrapper>&& promise)
{
if (m_body.isEmpty()) {
- promise.reject(SYNTAX_ERR);
+ promise->reject(SYNTAX_ERR);
return;
}
if (isDisturbedOrLocked()) {
- promise.reject(TypeError);
+ promise->reject(TypeError);
return;
}
m_isDisturbed = true;
@@ -127,14 +127,14 @@
m_body.json(*this, WTFMove(promise));
}
-void FetchBodyOwner::text(DeferredWrapper&& promise)
+void FetchBodyOwner::text(Ref<DeferredWrapper>&& promise)
{
if (m_body.isEmpty()) {
- promise.resolve(String());
+ promise->resolve(String());
return;
}
if (isDisturbedOrLocked()) {
- promise.reject(TypeError);
+ promise->reject(TypeError);
return;
}
m_isDisturbed = true;
Modified: trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.h (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.h 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.h 2016-08-31 18:36:46 UTC (rev 205257)
@@ -46,11 +46,11 @@
// Exposed Body API
bool isDisturbed() const { return m_isDisturbed; };
- void arrayBuffer(DeferredWrapper&&);
- void blob(DeferredWrapper&&);
- void formData(DeferredWrapper&&);
- void json(DeferredWrapper&&);
- void text(DeferredWrapper&&);
+ void arrayBuffer(Ref<DeferredWrapper>&&);
+ void blob(Ref<DeferredWrapper>&&);
+ void formData(Ref<DeferredWrapper>&&);
+ void json(Ref<DeferredWrapper>&&);
+ void text(Ref<DeferredWrapper>&&);
bool isDisturbedOrLocked() const;
Modified: trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -206,7 +206,7 @@
m_loader->stop();
}
-void FetchResponse::consume(unsigned type, DeferredWrapper&& wrapper)
+void FetchResponse::consume(unsigned type, Ref<DeferredWrapper>&& wrapper)
{
ASSERT(type <= static_cast<unsigned>(FetchBodyConsumer::Type::Text));
@@ -241,9 +241,9 @@
m_consumer.append(chunk->data(), chunk->byteLength());
}
-void FetchResponse::finishConsumingStream(DeferredWrapper&& promise)
+void FetchResponse::finishConsumingStream(Ref<DeferredWrapper>&& promise)
{
- m_consumer.resolve(promise);
+ m_consumer.resolve(WTFMove(promise));
}
void FetchResponse::consumeBodyAsStream()
Modified: trunk/Source/WebCore/Modules/fetch/FetchResponse.h (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/FetchResponse.h 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/FetchResponse.h 2016-08-31 18:36:46 UTC (rev 205257)
@@ -60,11 +60,11 @@
using FetchPromise = DOMPromise<FetchResponse>;
static void fetch(ScriptExecutionContext&, FetchRequest&, FetchPromise&&);
- void consume(unsigned, DeferredWrapper&&);
+ void consume(unsigned, Ref<DeferredWrapper>&&);
#if ENABLE(STREAMS_API)
void startConsumingStream(unsigned);
void consumeChunk(Ref<JSC::Uint8Array>&&);
- void finishConsumingStream(DeferredWrapper&&);
+ void finishConsumingStream(Ref<DeferredWrapper>&&);
#endif
void setStatus(int, const String&, ExceptionCode&);
Modified: trunk/Source/WebCore/Modules/fetch/WorkerGlobalScopeFetch.cpp (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/WorkerGlobalScopeFetch.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/WorkerGlobalScopeFetch.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -36,7 +36,7 @@
namespace WebCore {
-void WorkerGlobalScopeFetch::fetch(WorkerGlobalScope& scope, FetchRequest& request, DeferredWrapper&& promise)
+void WorkerGlobalScopeFetch::fetch(WorkerGlobalScope& scope, FetchRequest& request, Ref<DeferredWrapper>&& promise)
{
if (!scope.scriptExecutionContext())
return;
Modified: trunk/Source/WebCore/Modules/fetch/WorkerGlobalScopeFetch.h (205256 => 205257)
--- trunk/Source/WebCore/Modules/fetch/WorkerGlobalScopeFetch.h 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/fetch/WorkerGlobalScopeFetch.h 2016-08-31 18:36:46 UTC (rev 205257)
@@ -41,7 +41,7 @@
class WorkerGlobalScopeFetch {
public:
- static void fetch(WorkerGlobalScope&, FetchRequest&, DeferredWrapper&&);
+ static void fetch(WorkerGlobalScope&, FetchRequest&, Ref<DeferredWrapper>&&);
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.h (205256 => 205257)
--- trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.h 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.h 2016-08-31 18:36:46 UTC (rev 205257)
@@ -30,7 +30,6 @@
#if ENABLE(MEDIA_STREAM)
#include "ActiveDOMObject.h"
-#include "MediaDevices.h"
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (205256 => 205257)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-08-31 18:36:46 UTC (rev 205257)
@@ -4941,7 +4941,7 @@
B5B7A17017C10AA800E4AA0A /* ElementData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5B7A16F17C1080600E4AA0A /* ElementData.cpp */; };
B5B7A17117C10AC000E4AA0A /* ElementData.h in Headers */ = {isa = PBXBuildFile; fileRef = B5B7A16E17C1048000E4AA0A /* ElementData.h */; settings = {ATTRIBUTES = (Private, ); }; };
B5D31DFA11CF610B009F22B4 /* ActiveDOMCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5D31DF811CF610B009F22B4 /* ActiveDOMCallback.cpp */; };
- B5D31DFB11CF610B009F22B4 /* ActiveDOMCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B5D31DF911CF610B009F22B4 /* ActiveDOMCallback.h */; };
+ B5D31DFB11CF610B009F22B4 /* ActiveDOMCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B5D31DF911CF610B009F22B4 /* ActiveDOMCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
B6566270120B1227006EA85C /* JSIDBTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = B656626E120B1227006EA85C /* JSIDBTransaction.h */; };
B658FFA11522EF3A00DD5595 /* JSRadioNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B658FF9F1522EF3A00DD5595 /* JSRadioNodeList.cpp */; };
B658FFA21522EF3A00DD5595 /* JSRadioNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = B658FFA01522EF3A00DD5595 /* JSRadioNodeList.h */; };
Modified: trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp (205256 => 205257)
--- trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -28,6 +28,7 @@
#include "JSDOMGlobalObject.h"
#include "Document.h"
+#include "JSDOMPromise.h"
#include "JSDOMWindow.h"
#include "JSEventListener.h"
#include "JSMediaStream.h"
@@ -61,6 +62,10 @@
{
}
+JSDOMGlobalObject::~JSDOMGlobalObject()
+{
+}
+
void JSDOMGlobalObject::destroy(JSCell* cell)
{
static_cast<JSDOMGlobalObject*>(cell)->JSDOMGlobalObject::~JSDOMGlobalObject();
@@ -167,6 +172,9 @@
for (auto& constructor : thisObject->constructors().values())
visitor.append(&constructor);
+ for (auto& deferredWrapper : thisObject->deferredWrappers())
+ deferredWrapper->visitAggregate(visitor);
+
thisObject->m_builtinInternalFunctions.visit(visitor);
}
Modified: trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.h (205256 => 205257)
--- trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.h 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.h 2016-08-31 18:36:46 UTC (rev 205257)
@@ -34,6 +34,7 @@
namespace WebCore {
+ class DeferredWrapper;
class Document;
class Event;
class DOMWrapperWorld;
@@ -41,6 +42,7 @@
typedef HashMap<const JSC::ClassInfo*, JSC::WriteBarrier<JSC::Structure>> JSDOMStructureMap;
typedef HashMap<const JSC::ClassInfo*, JSC::WriteBarrier<JSC::JSObject>> JSDOMConstructorMap;
+ typedef HashSet<DeferredWrapper*> DeferredWrapperSet;
class WEBCORE_EXPORT JSDOMGlobalObject : public JSC::JSGlobalObject {
typedef JSC::JSGlobalObject Base;
@@ -56,6 +58,8 @@
JSDOMStructureMap& structures() { return m_structures; }
JSDOMConstructorMap& constructors() { return m_constructors; }
+ DeferredWrapperSet& deferredWrappers() { return m_deferredWrappers; }
+
ScriptExecutionContext* scriptExecutionContext() const;
// Make binding code generation easier.
@@ -75,6 +79,8 @@
static const JSC::ClassInfo s_info;
public:
+ ~JSDOMGlobalObject();
+
static const JSC::ClassInfo* info() { return &s_info; }
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSValue prototype)
@@ -85,6 +91,7 @@
protected:
JSDOMStructureMap m_structures;
JSDOMConstructorMap m_constructors;
+ DeferredWrapperSet m_deferredWrappers;
Event* m_currentEvent;
Ref<DOMWrapperWorld> m_world;
Modified: trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp (205256 => 205257)
--- trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -35,18 +35,33 @@
namespace WebCore {
-DeferredWrapper::DeferredWrapper(ExecState* exec, JSDOMGlobalObject* globalObject, JSPromiseDeferred* promiseDeferred)
- : m_globalObject(exec->vm(), globalObject)
- , m_deferred(exec->vm(), promiseDeferred)
+DeferredWrapper::DeferredWrapper(ExecState*, JSDOMGlobalObject* globalObject, JSPromiseDeferred* promiseDeferred)
+ : ActiveDOMCallback(globalObject->scriptExecutionContext())
+ , m_deferred(promiseDeferred)
+ , m_globalObject(globalObject)
{
+ globalObject->vm().heap.writeBarrier(globalObject, promiseDeferred);
+ m_globalObject->deferredWrappers().add(this);
}
-JSDOMGlobalObject& DeferredWrapper::globalObject() const
+DeferredWrapper::~DeferredWrapper()
{
- ASSERT(m_globalObject);
- return *m_globalObject.get();
+ clear();
}
+void DeferredWrapper::clear()
+{
+ ASSERT(!m_deferred || m_globalObject);
+ if (m_deferred && m_globalObject)
+ m_globalObject->deferredWrappers().remove(this);
+ m_deferred.clear();
+}
+
+void DeferredWrapper::contextDestroyed()
+{
+ clear();
+}
+
JSC::JSValue DeferredWrapper::promise() const
{
ASSERT(m_deferred);
@@ -55,6 +70,9 @@
void DeferredWrapper::callFunction(ExecState& exec, JSValue function, JSValue resolution)
{
+ if (!canInvokeCallback())
+ return;
+
CallData callData;
CallType callType = getCallData(function, callData);
ASSERT(callType != CallType::None);
@@ -64,12 +82,14 @@
call(&exec, function, callType, callData, jsUndefined(), arguments);
- m_globalObject.clear();
- m_deferred.clear();
+ clear();
}
void DeferredWrapper::reject(ExceptionCode ec, const String& message)
{
+ if (isSuspended())
+ return;
+
ASSERT(m_deferred);
ASSERT(m_globalObject);
JSC::ExecState* state = m_globalObject->globalExec();
@@ -85,7 +105,7 @@
JSValue error = state.exception()->value();
state.clearException();
- DeferredWrapper(&state, &globalObject, &promiseDeferred).reject(error);
+ DeferredWrapper::create(&state, &globalObject, &promiseDeferred)->reject(error);
}
static inline JSC::JSValue parseAsJSON(JSC::ExecState* state, const String& data)
@@ -94,27 +114,27 @@
return JSC::JSONParse(state, data);
}
-void fulfillPromiseWithJSON(DeferredWrapper& promise, const String& data)
+void fulfillPromiseWithJSON(Ref<DeferredWrapper>&& promise, const String& data)
{
- JSC::JSValue value = parseAsJSON(promise.globalObject().globalExec(), data);
+ JSC::JSValue value = parseAsJSON(promise->globalObject()->globalExec(), data);
if (!value)
- promise.reject(SYNTAX_ERR);
+ promise->reject(SYNTAX_ERR);
else
- promise.resolve(value);
+ promise->resolve(value);
}
-void fulfillPromiseWithArrayBuffer(DeferredWrapper& promise, ArrayBuffer* arrayBuffer)
+void fulfillPromiseWithArrayBuffer(Ref<DeferredWrapper>&& promise, ArrayBuffer* arrayBuffer)
{
if (!arrayBuffer) {
- promise.reject<JSValue>(createOutOfMemoryError(promise.globalObject().globalExec()));
+ promise->reject<JSValue>(createOutOfMemoryError(promise->globalObject()->globalExec()));
return;
}
- promise.resolve(arrayBuffer);
+ promise->resolve(arrayBuffer);
}
-void fulfillPromiseWithArrayBuffer(DeferredWrapper& promise, const void* data, size_t length)
+void fulfillPromiseWithArrayBuffer(Ref<DeferredWrapper>&& promise, const void* data, size_t length)
{
- fulfillPromiseWithArrayBuffer(promise, ArrayBuffer::tryCreate(data, length).get());
+ fulfillPromiseWithArrayBuffer(WTFMove(promise), ArrayBuffer::tryCreate(data, length).get());
}
}
Modified: trunk/Source/WebCore/bindings/js/JSDOMPromise.h (205256 => 205257)
--- trunk/Source/WebCore/bindings/js/JSDOMPromise.h 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromise.h 2016-08-31 18:36:46 UTC (rev 205257)
@@ -26,6 +26,7 @@
#ifndef JSDOMPromise_h
#define JSDOMPromise_h
+#include "ActiveDOMCallback.h"
#include "JSDOMBinding.h"
#include <heap/StrongInlines.h>
#include <runtime/JSPromiseDeferred.h>
@@ -95,10 +96,15 @@
static constexpr bool passByConstRef = false;
};
-class DeferredWrapper {
+class DeferredWrapper : public RefCounted<DeferredWrapper>, public ActiveDOMCallback {
public:
- DeferredWrapper(JSC::ExecState*, JSDOMGlobalObject*, JSC::JSPromiseDeferred*);
+ static Ref<DeferredWrapper> create(JSC::ExecState* state, JSDOMGlobalObject* globalObject, JSC::JSPromiseDeferred* deferred)
+ {
+ return adoptRef(*new DeferredWrapper(state, globalObject, deferred));
+ }
+ ~DeferredWrapper();
+
template<class ResolveResultType> typename std::enable_if<PromiseResultInspector<ResolveResultType>::passByValue, void>::type
resolve(ResolveResultType result) { resolveWithValue(result); }
template<class ResolveResultType> typename std::enable_if<PromiseResultInspector<ResolveResultType>::passByRef, void>::type
@@ -121,10 +127,19 @@
void reject(ExceptionCode, const String& = { });
- JSDOMGlobalObject& globalObject() const;
JSC::JSValue promise() const;
+ bool isSuspended() { return !m_deferred || !canInvokeCallback(); } // The wrapper world has gone away or active DOM objects have been suspended.
+ JSDOMGlobalObject* globalObject() { return m_globalObject.get(); }
+
+ void visitAggregate(JSC::SlotVisitor& visitor) { visitor.appendUnbarrieredWeak(&m_deferred); }
+
private:
+ DeferredWrapper(JSC::ExecState*, JSDOMGlobalObject*, JSC::JSPromiseDeferred*);
+
+ void clear();
+ void contextDestroyed() override;
+
void callFunction(JSC::ExecState&, JSC::JSValue function, JSC::JSValue resolution);
void resolve(JSC::ExecState& state, JSC::JSValue resolution) { callFunction(state, m_deferred->resolve(), resolution); }
void reject(JSC::ExecState& state, JSC::JSValue resolution) { callFunction(state, m_deferred->reject(), resolution); }
@@ -132,13 +147,13 @@
template<class RejectResultType> void rejectWithValue(RejectResultType&&);
template<class ResolveResultType> void resolveWithValue(ResolveResultType&&);
- JSC::Strong<JSDOMGlobalObject> m_globalObject;
- JSC::Strong<JSC::JSPromiseDeferred> m_deferred;
+ JSC::Weak<JSC::JSPromiseDeferred> m_deferred;
+ JSC::Weak<JSDOMGlobalObject> m_globalObject;
};
-void fulfillPromiseWithJSON(DeferredWrapper&, const String&);
-void fulfillPromiseWithArrayBuffer(DeferredWrapper&, ArrayBuffer*);
-void fulfillPromiseWithArrayBuffer(DeferredWrapper&, const void*, size_t);
+void fulfillPromiseWithJSON(Ref<DeferredWrapper>&&, const String&);
+void fulfillPromiseWithArrayBuffer(Ref<DeferredWrapper>&&, ArrayBuffer*);
+void fulfillPromiseWithArrayBuffer(Ref<DeferredWrapper>&&, const void*, size_t);
void rejectPromiseWithExceptionIfAny(JSC::ExecState&, JSDOMGlobalObject&, JSC::JSPromiseDeferred&);
inline JSC::JSValue callPromiseFunction(JSC::ExecState& state, JSC::EncodedJSValue promiseFunction(JSC::ExecState*, JSC::JSPromiseDeferred*))
@@ -156,26 +171,31 @@
template <typename Value>
class DOMPromise {
public:
- DOMPromise(DeferredWrapper&& wrapper) : m_wrapper(WTFMove(wrapper)) { }
+ DOMPromise(Ref<DeferredWrapper>&& wrapper)
+ : m_wrapper(WTFMove(wrapper))
+ {
+ }
+
DOMPromise(DOMPromise&& promise) : m_wrapper(WTFMove(promise.m_wrapper)) { }
DOMPromise(const DOMPromise&) = default;
DOMPromise& operator=(DOMPromise const&) = default;
- void resolve(typename PromiseResultInspector<Value>::Type value) { m_wrapper.resolve(value); }
+ void resolve(typename PromiseResultInspector<Value>::Type value) { m_wrapper->resolve(value); }
- template<typename... ErrorType> void reject(ErrorType&&... error) { m_wrapper.reject(std::forward<ErrorType>(error)...); }
+ template<typename... ErrorType> void reject(ErrorType&&... error) { m_wrapper->reject(std::forward<ErrorType>(error)...); }
DeferredWrapper& deferredWrapper() { return m_wrapper; }
private:
- DeferredWrapper m_wrapper;
+ Ref<DeferredWrapper> m_wrapper;
};
template<class ResolveResultType>
inline void DeferredWrapper::resolveWithValue(ResolveResultType&& result)
{
- ASSERT(m_deferred);
+ if (isSuspended())
+ return;
ASSERT(m_globalObject);
JSC::ExecState* exec = m_globalObject->globalExec();
JSC::JSLockHolder locker(exec);
@@ -185,6 +205,8 @@
template<class ResolveResultType>
inline void DeferredWrapper::resolveWithNewlyCreated(Ref<ResolveResultType>&& result)
{
+ if (isSuspended())
+ return;
ASSERT(m_deferred);
ASSERT(m_globalObject);
JSC::ExecState* exec = m_globalObject->globalExec();
@@ -195,6 +217,8 @@
template<class RejectResultType>
inline void DeferredWrapper::rejectWithValue(RejectResultType&& result)
{
+ if (isSuspended())
+ return;
ASSERT(m_deferred);
ASSERT(m_globalObject);
JSC::ExecState* exec = m_globalObject->globalExec();
@@ -205,6 +229,8 @@
template<>
inline void DeferredWrapper::resolve(bool result)
{
+ if (isSuspended())
+ return;
ASSERT(m_deferred);
ASSERT(m_globalObject);
JSC::ExecState* exec = m_globalObject->globalExec();
@@ -215,6 +241,8 @@
template<>
inline void DeferredWrapper::resolve(JSC::JSValue value)
{
+ if (isSuspended())
+ return;
ASSERT(m_deferred);
ASSERT(m_globalObject);
JSC::ExecState* exec = m_globalObject->globalExec();
@@ -225,6 +253,8 @@
template<>
inline void DeferredWrapper::reject(JSC::JSValue value)
{
+ if (isSuspended())
+ return;
ASSERT(m_deferred);
ASSERT(m_globalObject);
JSC::ExecState* exec = m_globalObject->globalExec();
@@ -235,6 +265,8 @@
template<>
inline void DeferredWrapper::resolve(std::nullptr_t)
{
+ if (isSuspended())
+ return;
ASSERT(m_deferred);
ASSERT(m_globalObject);
JSC::ExecState* exec = m_globalObject->globalExec();
@@ -245,6 +277,8 @@
template<>
inline void DeferredWrapper::reject(std::nullptr_t)
{
+ if (isSuspended())
+ return;
ASSERT(m_deferred);
ASSERT(m_globalObject);
JSC::ExecState* exec = m_globalObject->globalExec();
@@ -255,6 +289,8 @@
template<>
inline void DeferredWrapper::resolve(const String& result)
{
+ if (isSuspended())
+ return;
ASSERT(m_deferred);
ASSERT(m_globalObject);
JSC::ExecState* exec = m_globalObject->globalExec();
@@ -265,6 +301,8 @@
template<>
inline void DeferredWrapper::reject(const String& result)
{
+ if (isSuspended())
+ return;
ASSERT(m_deferred);
ASSERT(m_globalObject);
JSC::ExecState* exec = m_globalObject->globalExec();
Modified: trunk/Source/WebCore/bindings/js/JSFontFaceCustom.cpp (205256 => 205257)
--- trunk/Source/WebCore/bindings/js/JSFontFaceCustom.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/bindings/js/JSFontFaceCustom.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -39,8 +39,8 @@
{
if (!m_loaded) {
if (!wrapped().promise()) {
- DeferredWrapper promise(&state, globalObject(), JSC::JSPromiseDeferred::create(&state, globalObject()));
- m_loaded.set(state.vm(), this, promise.promise());
+ Ref<DeferredWrapper> promise = DeferredWrapper::create(&state, globalObject(), JSC::JSPromiseDeferred::create(&state, globalObject()));
+ m_loaded.set(state.vm(), this, promise->promise());
wrapped().registerLoaded(WTFMove(promise));
} else
m_loaded.set(state.vm(), this, wrapped().promise().value().deferredWrapper().promise());
Modified: trunk/Source/WebCore/bindings/js/JSFontFaceSetCustom.cpp (205256 => 205257)
--- trunk/Source/WebCore/bindings/js/JSFontFaceSetCustom.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/bindings/js/JSFontFaceSetCustom.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -34,8 +34,8 @@
JSC::JSValue JSFontFaceSet::ready(JSC::ExecState& state) const
{
if (!m_ready) {
- DeferredWrapper promise(&state, globalObject(), JSC::JSPromiseDeferred::create(&state, globalObject()));
- m_ready.set(state.vm(), this, promise.promise());
+ Ref<DeferredWrapper> promise = DeferredWrapper::create(&state, globalObject(), JSC::JSPromiseDeferred::create(&state, globalObject()));
+ m_ready.set(state.vm(), this, promise->promise());
wrapped().registerReady(WTFMove(promise));
}
return m_ready.get();
Modified: trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp (205256 => 205257)
--- trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -391,7 +391,7 @@
auto audioConstraints = MediaConstraintsImpl::create(WTFMove(mandatoryAudioConstraints), WTFMove(advancedAudioConstraints), areAudioConstraintsValid);
auto videoConstraints = MediaConstraintsImpl::create(WTFMove(mandatoryVideoConstraints), WTFMove(advancedVideoConstraints), areVideoConstraintsValid);
JSC::JSPromiseDeferred* promiseDeferred = JSC::JSPromiseDeferred::create(&state, globalObject());
- wrapped().getUserMedia(WTFMove(audioConstraints), WTFMove(videoConstraints), DeferredWrapper(&state, globalObject(), promiseDeferred), ec);
+ wrapped().getUserMedia(WTFMove(audioConstraints), WTFMove(videoConstraints), DeferredWrapper::create(&state, globalObject(), promiseDeferred), ec);
setDOMException(&state, ec);
return promiseDeferred->promise();
}
Modified: trunk/Source/WebCore/bindings/js/JSReadableStreamSourceCustom.cpp (205256 => 205257)
--- trunk/Source/WebCore/bindings/js/JSReadableStreamSourceCustom.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/bindings/js/JSReadableStreamSourceCustom.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -44,7 +44,7 @@
m_controller.set(state.vm(), jsSource, state.argument(0));
JSC::JSPromiseDeferred* promiseDeferred = JSC::JSPromiseDeferred::create(&state, globalObject());
- wrapped().start(ReadableStreamDefaultController(controller), DeferredWrapper(&state, globalObject(), promiseDeferred));
+ wrapped().start(ReadableStreamDefaultController(controller), DeferredWrapper::create(&state, globalObject(), promiseDeferred));
return promiseDeferred->promise();
}
Modified: trunk/Source/WebCore/bindings/js/JSWebKitSubtleCryptoCustom.cpp (205256 => 205257)
--- trunk/Source/WebCore/bindings/js/JSWebKitSubtleCryptoCustom.cpp 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/bindings/js/JSWebKitSubtleCryptoCustom.cpp 2016-08-31 18:36:46 UTC (rev 205257)
@@ -174,12 +174,12 @@
JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(&state, globalObject());
- DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
+ RefPtr<DeferredWrapper> wrapper = DeferredWrapper::create(&state, globalObject(), promiseDeferred);
auto successCallback = [wrapper](const Vector<uint8_t>& result) mutable {
- fulfillPromiseWithArrayBuffer(wrapper, result.data(), result.size());
+ fulfillPromiseWithArrayBuffer(wrapper.releaseNonNull(), result.data(), result.size());
};
auto failureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
ExceptionCode ec = 0;
@@ -229,12 +229,12 @@
}
JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(&state, globalObject());
- DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
+ RefPtr<DeferredWrapper> wrapper = DeferredWrapper::create(&state, globalObject(), promiseDeferred);
auto successCallback = [wrapper](const Vector<uint8_t>& result) mutable {
- fulfillPromiseWithArrayBuffer(wrapper, result.data(), result.size());
+ fulfillPromiseWithArrayBuffer(wrapper.releaseNonNull(), result.data(), result.size());
};
auto failureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
ExceptionCode ec = 0;
@@ -284,12 +284,12 @@
}
JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(&state, globalObject());
- DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
+ RefPtr<DeferredWrapper> wrapper = DeferredWrapper::create(&state, globalObject(), promiseDeferred);
auto successCallback = [wrapper](const Vector<uint8_t>& result) mutable {
- fulfillPromiseWithArrayBuffer(wrapper, result.data(), result.size());
+ fulfillPromiseWithArrayBuffer(wrapper.releaseNonNull(), result.data(), result.size());
};
auto failureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
ExceptionCode ec = 0;
@@ -345,12 +345,12 @@
}
JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(&state, globalObject());
- DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
+ RefPtr<DeferredWrapper> wrapper = DeferredWrapper::create(&state, globalObject(), promiseDeferred);
auto successCallback = [wrapper](bool result) mutable {
- wrapper.resolve(result);
+ wrapper->resolve(result);
};
auto failureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
ExceptionCode ec = 0;
@@ -390,12 +390,12 @@
}
JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(&state, globalObject());
- DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
+ RefPtr<DeferredWrapper> wrapper = DeferredWrapper::create(&state, globalObject(), promiseDeferred);
auto successCallback = [wrapper](const Vector<uint8_t>& result) mutable {
- fulfillPromiseWithArrayBuffer(wrapper, result.data(), result.size());
+ fulfillPromiseWithArrayBuffer(wrapper.releaseNonNull(), result.data(), result.size());
};
auto failureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
ExceptionCode ec = 0;
@@ -444,17 +444,17 @@
}
JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(&state, globalObject());
- DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
+ RefPtr<DeferredWrapper> wrapper = DeferredWrapper::create(&state, globalObject(), promiseDeferred);
auto successCallback = [wrapper](CryptoKey* key, CryptoKeyPair* keyPair) mutable {
ASSERT(key || keyPair);
ASSERT(!key || !keyPair);
if (key)
- wrapper.resolve(key);
+ wrapper->resolve(key);
else
- wrapper.resolve(keyPair);
+ wrapper->resolve(keyPair);
};
auto failureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
ExceptionCode ec = 0;
@@ -581,12 +581,12 @@
}
JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(&state, globalObject());
- DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
+ RefPtr<DeferredWrapper> wrapper = DeferredWrapper::create(&state, globalObject(), promiseDeferred);
auto successCallback = [wrapper](CryptoKey& result) mutable {
- wrapper.resolve(result);
+ wrapper->resolve(result);
};
auto failureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
WebCore::importKey(state, keyFormat, data, WTFMove(algorithm), WTFMove(parameters), extractable, keyUsages, WTFMove(successCallback), WTFMove(failureCallback));
@@ -650,12 +650,12 @@
return throwTypeError(&state, scope);
JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(&state, globalObject());
- DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
+ RefPtr<DeferredWrapper> wrapper = DeferredWrapper::create(&state, globalObject(), promiseDeferred);
auto successCallback = [wrapper](const Vector<uint8_t>& result) mutable {
- fulfillPromiseWithArrayBuffer(wrapper, result.data(), result.size());
+ fulfillPromiseWithArrayBuffer(wrapper.releaseNonNull(), result.data(), result.size());
};
auto failureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
WebCore::exportKey(state, keyFormat, *key, WTFMove(successCallback), WTFMove(failureCallback));
@@ -706,25 +706,25 @@
}
JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(&state, globalObject());
- DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
+ RefPtr<DeferredWrapper> wrapper = DeferredWrapper::create(&state, globalObject(), promiseDeferred);
auto exportSuccessCallback = [keyFormat, algorithm, parameters, wrappingKey, wrapper](const Vector<uint8_t>& exportedKeyData) mutable {
auto encryptSuccessCallback = [wrapper](const Vector<uint8_t>& encryptedData) mutable {
- fulfillPromiseWithArrayBuffer(wrapper, encryptedData.data(), encryptedData.size());
+ fulfillPromiseWithArrayBuffer(wrapper.releaseNonNull(), encryptedData.data(), encryptedData.size());
};
auto encryptFailureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
ExceptionCode ec = 0;
algorithm->encryptForWrapKey(*parameters, *wrappingKey, std::make_pair(exportedKeyData.data(), exportedKeyData.size()), WTFMove(encryptSuccessCallback), WTFMove(encryptFailureCallback), ec);
if (ec) {
// FIXME: Report failure details to console, and possibly to calling script once there is a standardized way to pass errors to WebCrypto promise reject functions.
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
}
};
auto exportFailureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
ExceptionCode ec = 0;
@@ -809,15 +809,15 @@
}
JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(&state, globalObject());
- DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
+ RefPtr<DeferredWrapper> wrapper = DeferredWrapper::create(&state, globalObject(), promiseDeferred);
Strong<JSDOMGlobalObject> domGlobalObject(state.vm(), globalObject());
auto decryptSuccessCallback = [domGlobalObject, keyFormat, unwrappedKeyAlgorithm, unwrappedKeyAlgorithmParameters, extractable, keyUsages, wrapper](const Vector<uint8_t>& result) mutable {
auto importSuccessCallback = [wrapper](CryptoKey& key) mutable {
- wrapper.resolve(key);
+ wrapper->resolve(key);
};
auto importFailureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
ExecState& state = *domGlobalObject->globalExec();
WebCore::importKey(state, keyFormat, std::make_pair(result.data(), result.size()), unwrappedKeyAlgorithm, unwrappedKeyAlgorithmParameters, extractable, keyUsages, WTFMove(importSuccessCallback), WTFMove(importFailureCallback));
@@ -824,12 +824,12 @@
if (state.hadException()) {
// FIXME: Report exception details to console, and possibly to calling script once there is a standardized way to pass errors to WebCrypto promise reject functions.
state.clearException();
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
}
};
auto decryptFailureCallback = [wrapper]() mutable {
- wrapper.reject(nullptr);
+ wrapper->reject(nullptr);
};
ExceptionCode ec = 0;
Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (205256 => 205257)
--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2016-08-31 18:36:46 UTC (rev 205257)
@@ -4114,9 +4114,9 @@
if (IsReturningPromise($function)) {
if ($function->isStatic) {
- push(@arguments, "DeferredWrapper(state, jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject()), promiseDeferred)");
+ push(@arguments, "DeferredWrapper::create(state, jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject()), promiseDeferred)");
} else {
- push(@arguments, "DeferredWrapper(state, castedThis->globalObject(), promiseDeferred)");
+ push(@arguments, "DeferredWrapper::create(state, castedThis->globalObject(), promiseDeferred)");
}
}
push(@arguments, "ec") if $function->signature->extendedAttributes->{"RaisesException"} || $function->signature->extendedAttributes->{"RaisesExceptionWithMessage"};
Modified: trunk/Source/WebKit2/CMakeLists.txt (205256 => 205257)
--- trunk/Source/WebKit2/CMakeLists.txt 2016-08-31 17:44:22 UTC (rev 205256)
+++ trunk/Source/WebKit2/CMakeLists.txt 2016-08-31 18:36:46 UTC (rev 205257)
@@ -88,6 +88,7 @@
"${WEBCORE_DIR}/Modules/vibration"
"${WEBCORE_DIR}/Modules/webdatabase"
"${WEBCORE_DIR}/accessibility"
+ "${WEBCORE_DIR}/bindings/generic"
"${WEBCORE_DIR}/bindings/js"
"${WEBCORE_DIR}/bindings"
"${WEBCORE_DIR}/bridge"