Index: Source/modules/crypto/CryptoResultImpl.cpp |
diff --git a/Source/modules/crypto/CryptoResultImpl.cpp b/Source/modules/crypto/CryptoResultImpl.cpp |
index 2360727a13a91f34ae1e4352523c2068b1c2c2e2..cdf1f2243020600dc19cac340e29a3f4e627789f 100644 |
--- a/Source/modules/crypto/CryptoResultImpl.cpp |
+++ b/Source/modules/crypto/CryptoResultImpl.cpp |
@@ -47,6 +47,7 @@ |
#include "modules/crypto/NormalizeAlgorithm.h" |
#include "public/platform/Platform.h" |
#include "public/platform/WebCryptoAlgorithm.h" |
+#include "wtf/Atomics.h" |
namespace blink { |
@@ -63,7 +64,7 @@ static void rejectWithTypeError(const String& errorDetails, ScriptPromiseResolve |
class CryptoResultImpl::Resolver final : public ScriptPromiseResolver { |
public: |
- static PassRefPtrWillBeRawPtr<ScriptPromiseResolver> create(ScriptState* scriptState, CryptoResultImpl* result) |
+ static PassRefPtrWillBeRawPtr<Resolver> create(ScriptState* scriptState, CryptoResultImpl* result) |
{ |
RefPtrWillBeRawPtr<Resolver> resolver = adoptRefWillBeNoop(new Resolver(scriptState, result)); |
resolver->suspendIfNeeded(); |
@@ -74,18 +75,39 @@ public: |
void stop() override |
{ |
m_result->cancel(); |
- m_result->clearResolver(); |
m_result = nullptr; |
ScriptPromiseResolver::stop(); |
} |
+ DEFINE_INLINE_VIRTUAL_TRACE() |
+ { |
+ visitor->trace(m_result); |
+ ScriptPromiseResolver::trace(visitor); |
+ } |
+ |
private: |
Resolver(ScriptState* scriptState, CryptoResultImpl* result) |
: ScriptPromiseResolver(scriptState) |
, m_result(result) { } |
- RefPtr<CryptoResultImpl> m_result; |
+ |
+ RefPtrWillBeMember<CryptoResultImpl> m_result; |
}; |
+CryptoResultImpl::ResultCancel::ResultCancel() |
+ : m_cancelled(0) |
+{ |
+} |
+ |
+bool CryptoResultImpl::ResultCancel::cancelled() const |
+{ |
+ return acquireLoad(&m_cancelled); |
+} |
+ |
+void CryptoResultImpl::ResultCancel::cancel() |
+{ |
+ releaseStore(&m_cancelled, 1); |
+} |
+ |
ExceptionCode webCryptoErrorToExceptionCode(WebCryptoErrorType errorType) |
{ |
switch (errorType) { |
@@ -107,11 +129,31 @@ ExceptionCode webCryptoErrorToExceptionCode(WebCryptoErrorType errorType) |
return 0; |
} |
+CryptoResultImpl::CryptoResultImpl(ScriptState* scriptState) |
+ : m_cancel(ResultCancel::create()) |
+{ |
+ ASSERT(scriptState->contextIsValid()); |
+ if (scriptState->executionContext()->activeDOMObjectsAreStopped()) { |
+ // If active dom objects have been stopped, avoid creating |
+ // CryptoResultImpl::Resolver. |
+ m_resolver = nullptr; |
+ m_cancel->cancel(); |
+ return; |
+ } |
+ m_resolver = Resolver::create(scriptState, this).get(); |
+} |
+ |
CryptoResultImpl::~CryptoResultImpl() |
{ |
ASSERT(!m_resolver); |
} |
+DEFINE_TRACE(CryptoResultImpl) |
+{ |
+ visitor->trace(m_resolver); |
+ CryptoResult::trace(visitor); |
+} |
+ |
void CryptoResultImpl::clearResolver() |
{ |
m_resolver = nullptr; |
@@ -124,96 +166,89 @@ PassRefPtrWillBeRawPtr<CryptoResultImpl> CryptoResultImpl::create(ScriptState* s |
void CryptoResultImpl::completeWithError(WebCryptoErrorType errorType, const WebString& errorDetails) |
{ |
- if (m_resolver) { |
- ExceptionCode ec = webCryptoErrorToExceptionCode(errorType); |
+ if (!m_resolver) |
+ return; |
- // Handle TypeError separately, as it cannot be created using |
- // DOMException. |
- if (ec == V8TypeError) |
- rejectWithTypeError(errorDetails, m_resolver); |
- else |
- m_resolver->reject(DOMException::create(ec, errorDetails)); |
- } |
+ ExceptionCode ec = webCryptoErrorToExceptionCode(errorType); |
+ |
+ // Handle TypeError separately, as it cannot be created using |
+ // DOMException. |
+ if (ec == V8TypeError) |
+ rejectWithTypeError(errorDetails, m_resolver); |
+ else |
+ m_resolver->reject(DOMException::create(ec, errorDetails)); |
clearResolver(); |
} |
void CryptoResultImpl::completeWithBuffer(const void* bytes, unsigned bytesSize) |
{ |
- if (m_resolver) |
- m_resolver->resolve(DOMArrayBuffer::create(bytes, bytesSize)); |
+ if (!m_resolver) |
+ return; |
+ |
+ m_resolver->resolve(DOMArrayBuffer::create(bytes, bytesSize)); |
clearResolver(); |
} |
void CryptoResultImpl::completeWithJson(const char* utf8Data, unsigned length) |
{ |
- if (m_resolver) { |
- ScriptPromiseResolver* resolver = m_resolver; |
- ScriptState* scriptState = resolver->scriptState(); |
- ScriptState::Scope scope(scriptState); |
+ if (!m_resolver) |
+ return; |
- v8::Local<v8::String> jsonString = v8AtomicString(scriptState->isolate(), utf8Data, length); |
+ ScriptState* scriptState = m_resolver->scriptState(); |
+ ScriptState::Scope scope(scriptState); |
- v8::TryCatch exceptionCatcher; |
- v8::Local<v8::Value> jsonDictionary; |
- if (v8Call(v8::JSON::Parse(scriptState->isolate(), jsonString), jsonDictionary, exceptionCatcher)) |
- resolver->resolve(jsonDictionary); |
- else |
- resolver->reject(exceptionCatcher.Exception()); |
- } |
+ v8::Local<v8::String> jsonString = v8AtomicString(scriptState->isolate(), utf8Data, length); |
+ |
+ v8::TryCatch exceptionCatcher; |
+ v8::Local<v8::Value> jsonDictionary; |
+ if (v8Call(v8::JSON::Parse(scriptState->isolate(), jsonString), jsonDictionary, exceptionCatcher)) |
+ m_resolver->resolve(jsonDictionary); |
+ else |
+ m_resolver->reject(exceptionCatcher.Exception()); |
clearResolver(); |
} |
void CryptoResultImpl::completeWithBoolean(bool b) |
{ |
- if (m_resolver) |
- m_resolver->resolve(b); |
+ if (!m_resolver) |
+ return; |
+ |
+ m_resolver->resolve(b); |
clearResolver(); |
} |
void CryptoResultImpl::completeWithKey(const WebCryptoKey& key) |
{ |
- if (m_resolver) |
- m_resolver->resolve(CryptoKey::create(key)); |
+ if (!m_resolver) |
+ return; |
+ |
+ m_resolver->resolve(CryptoKey::create(key)); |
clearResolver(); |
} |
void CryptoResultImpl::completeWithKeyPair(const WebCryptoKey& publicKey, const WebCryptoKey& privateKey) |
{ |
- if (m_resolver) { |
- ScriptState* scriptState = m_resolver->scriptState(); |
- ScriptState::Scope scope(scriptState); |
+ if (!m_resolver) |
+ return; |
- V8ObjectBuilder keyPair(scriptState); |
+ ScriptState* scriptState = m_resolver->scriptState(); |
+ ScriptState::Scope scope(scriptState); |
- keyPair.add("publicKey", ScriptValue::from(scriptState, CryptoKey::create(publicKey))); |
- keyPair.add("privateKey", ScriptValue::from(scriptState, CryptoKey::create(privateKey))); |
+ V8ObjectBuilder keyPair(scriptState); |
- m_resolver->resolve(keyPair.v8Value()); |
- } |
- clearResolver(); |
-} |
+ keyPair.add("publicKey", ScriptValue::from(scriptState, CryptoKey::create(publicKey))); |
+ keyPair.add("privateKey", ScriptValue::from(scriptState, CryptoKey::create(privateKey))); |
-bool CryptoResultImpl::cancelled() const |
-{ |
- return acquireLoad(&m_cancelled); |
+ m_resolver->resolve(keyPair.v8Value()); |
+ clearResolver(); |
} |
void CryptoResultImpl::cancel() |
{ |
- releaseStore(&m_cancelled, 1); |
-} |
- |
-CryptoResultImpl::CryptoResultImpl(ScriptState* scriptState) |
- : m_cancelled(0) |
-{ |
- ASSERT(scriptState->contextIsValid()); |
- if (scriptState->executionContext()->activeDOMObjectsAreStopped()) { |
- // If active dom objects have been stopped, avoid creating |
- // CryptoResultResolver. |
- m_resolver = nullptr; |
- } else { |
- m_resolver = Resolver::create(scriptState, this).get(); |
- } |
+ ASSERT(m_cancel); |
+ m_cancel->cancel(); |
+ m_cancel.clear(); |
+ clearResolver(); |
} |
ScriptPromise CryptoResultImpl::promise() |