| Index: Source/bindings/core/v8/Dictionary.cpp
|
| diff --git a/Source/bindings/core/v8/Dictionary.cpp b/Source/bindings/core/v8/Dictionary.cpp
|
| index 91b09a48d1f3e5ddc70a0b17a746f658336fead6..1efca2be8f06e9a7371606689a8da4f13fb47e63 100644
|
| --- a/Source/bindings/core/v8/Dictionary.cpp
|
| +++ b/Source/bindings/core/v8/Dictionary.cpp
|
| @@ -46,6 +46,15 @@
|
|
|
| namespace blink {
|
|
|
| +#define TO_OBJECT_WITH_CHECK(context, value, object) \
|
| +{ \
|
| + v8::MaybeLocal<v8::Object> maybeObject = value->ToObject(m_context); \
|
| + if (maybeObject.IsEmpty()) \
|
| + return false; \
|
| + if (!maybeObject.ToLocal(&object)) \
|
| + return false; \
|
| +}
|
| +
|
| static ExceptionState& emptyExceptionState()
|
| {
|
| AtomicallyInitializedStaticReference(WTF::ThreadSpecific<NonThrowableExceptionState>, exceptionState, new ThreadSpecific<NonThrowableExceptionState>);
|
| @@ -65,6 +74,7 @@ Dictionary::Dictionary(const v8::Handle<v8::Value>& options, v8::Isolate* isolat
|
| {
|
| ASSERT(m_isolate);
|
| ASSERT(m_exceptionState);
|
| + subscribeScriptStateDisposal();
|
| #if ENABLE(ASSERT)
|
| m_exceptionState->onStackObjectChecker().add(this);
|
| #endif
|
| @@ -72,6 +82,7 @@ Dictionary::Dictionary(const v8::Handle<v8::Value>& options, v8::Isolate* isolat
|
|
|
| Dictionary::~Dictionary()
|
| {
|
| + unsubscribeScriptStateDisposal();
|
| #if ENABLE(ASSERT)
|
| if (m_exceptionState)
|
| m_exceptionState->onStackObjectChecker().remove(this);
|
| @@ -80,8 +91,10 @@ Dictionary::~Dictionary()
|
|
|
| Dictionary& Dictionary::operator=(const Dictionary& optionsObject)
|
| {
|
| + unsubscribeScriptStateDisposal();
|
| m_options = optionsObject.m_options;
|
| m_isolate = optionsObject.m_isolate;
|
| + subscribeScriptStateDisposal();
|
| #if ENABLE(ASSERT)
|
| if (m_exceptionState)
|
| m_exceptionState->onStackObjectChecker().remove(this);
|
| @@ -115,14 +128,14 @@ bool Dictionary::hasProperty(const String& key) const
|
| {
|
| if (isUndefinedOrNull())
|
| return false;
|
| - v8::Local<v8::Object> options = m_options->ToObject(m_isolate);
|
| - ASSERT(!options.IsEmpty());
|
| + v8::Local<v8::Object> object;
|
| + TO_OBJECT_WITH_CHECK(m_context, m_options, object);
|
|
|
| ASSERT(m_isolate);
|
| ASSERT(m_isolate == v8::Isolate::GetCurrent());
|
| ASSERT(m_exceptionState);
|
| v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
|
| - if (!options->Has(v8Key))
|
| + if (v8Key.IsEmpty() || !object->Has(v8Key))
|
| return false;
|
|
|
| return true;
|
| @@ -132,19 +145,17 @@ bool Dictionary::getKey(const String& key, v8::Local<v8::Value>& value) const
|
| {
|
| if (isUndefinedOrNull())
|
| return false;
|
| - v8::Local<v8::Object> options = m_options->ToObject(m_isolate);
|
| - ASSERT(!options.IsEmpty());
|
| + v8::Local<v8::Object> object;
|
| + TO_OBJECT_WITH_CHECK(m_context, m_options, object);
|
|
|
| ASSERT(m_isolate);
|
| ASSERT(m_isolate == v8::Isolate::GetCurrent());
|
| ASSERT(m_exceptionState);
|
| v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
|
| - if (!options->Has(v8Key))
|
| - return false;
|
| - value = options->Get(v8Key);
|
| - if (value.IsEmpty())
|
| + if (v8Key.IsEmpty() || !object->Has(v8Key))
|
| return false;
|
| - return true;
|
| + value = object->Get(v8Key);
|
| + return !value.IsEmpty();
|
| }
|
|
|
| bool Dictionary::get(const String& key, v8::Local<v8::Value>& value) const
|
| @@ -171,11 +182,11 @@ bool Dictionary::set(const String& key, const v8::Handle<v8::Value>& value)
|
| {
|
| if (isUndefinedOrNull())
|
| return false;
|
| - v8::Local<v8::Object> options = m_options->ToObject(m_isolate);
|
| - ASSERT(!options.IsEmpty());
|
| + v8::Local<v8::Object> object;
|
| + TO_OBJECT_WITH_CHECK(m_context, m_options, object);
|
| ASSERT(m_exceptionState);
|
|
|
| - return options->Set(v8String(m_isolate, key), value);
|
| + return object->Set(v8String(m_isolate, key), value);
|
| }
|
|
|
| bool Dictionary::set(const String& key, const String& value)
|
| @@ -216,19 +227,24 @@ bool Dictionary::getOwnPropertiesAsStringHashMap(HashMap<String, String>& hashMa
|
| if (!isObject())
|
| return false;
|
|
|
| - v8::Handle<v8::Object> options = m_options->ToObject(m_isolate);
|
| - if (options.IsEmpty())
|
| - return false;
|
| + v8::Local<v8::Object> object;
|
| + TO_OBJECT_WITH_CHECK(m_context, m_options, object);
|
|
|
| - v8::Local<v8::Array> properties = options->GetOwnPropertyNames();
|
| + v8::Local<v8::Array> properties = object->GetOwnPropertyNames();
|
| if (properties.IsEmpty())
|
| return true;
|
| for (uint32_t i = 0; i < properties->Length(); ++i) {
|
| - v8::Local<v8::String> key = properties->Get(i)->ToString(m_isolate);
|
| - if (!options->Has(key))
|
| + v8::Local<v8::Value> property = properties->Get(i);
|
| + if (property.IsEmpty())
|
| + continue;
|
| + v8::MaybeLocal<v8::String> maybeKey = properties->Get(i)->ToString(m_context);
|
| + v8::Local<v8::String> key;
|
| + if (!maybeKey.ToLocal(&key) || !object->Has(key))
|
| continue;
|
|
|
| - v8::Local<v8::Value> value = options->Get(key);
|
| + v8::Local<v8::Value> value = object->Get(key);
|
| + if (value.IsEmpty())
|
| + continue;
|
| TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false);
|
| TOSTRING_DEFAULT(V8StringResource<>, stringValue, value, false);
|
| if (!static_cast<const String&>(stringKey).isEmpty())
|
| @@ -243,16 +259,19 @@ bool Dictionary::getPropertyNames(Vector<String>& names) const
|
| if (!isObject())
|
| return false;
|
|
|
| - v8::Handle<v8::Object> options = m_options->ToObject(m_isolate);
|
| - if (options.IsEmpty())
|
| - return false;
|
| + v8::Local<v8::Object> object;
|
| + TO_OBJECT_WITH_CHECK(m_context, m_options, object);
|
|
|
| - v8::Local<v8::Array> properties = options->GetPropertyNames();
|
| + v8::Local<v8::Array> properties = object->GetPropertyNames();
|
| if (properties.IsEmpty())
|
| return true;
|
| for (uint32_t i = 0; i < properties->Length(); ++i) {
|
| - v8::Local<v8::String> key = properties->Get(i)->ToString(m_isolate);
|
| - if (!options->Has(key))
|
| + v8::Local<v8::Value> property = properties->Get(i);
|
| + if (property.IsEmpty())
|
| + continue;
|
| + v8::MaybeLocal<v8::String> maybeKey = properties->Get(i)->ToString(m_context);
|
| + v8::Local<v8::String> key;
|
| + if (!maybeKey.ToLocal(&key) || !object->Has(key))
|
| continue;
|
| TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false);
|
| names.append(stringKey);
|
| @@ -285,4 +304,27 @@ void Dictionary::ConversionContext::throwTypeError(const String& detail)
|
| exceptionState().throwTypeError(detail);
|
| }
|
|
|
| +void Dictionary::willDisposeScriptState(ScriptState*)
|
| +{
|
| + m_context.Clear();
|
| +}
|
| +
|
| +void Dictionary::subscribeScriptStateDisposal()
|
| +{
|
| + if (m_isolate) {
|
| + ScriptState* scriptState = ScriptState::current(m_isolate);
|
| + scriptState->addObserver(this);
|
| + m_context = scriptState->context();
|
| + ASSERT(!m_context.IsEmpty());
|
| + }
|
| +}
|
| +
|
| +void Dictionary::unsubscribeScriptStateDisposal()
|
| +{
|
| + if (m_isolate) {
|
| + ScriptState* scriptState = ScriptState::current(m_isolate);
|
| + scriptState->removeObserver(this);
|
| + }
|
| +}
|
| +
|
| } // namespace blink
|
|
|