Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "bindings/core/v8/Dictionary.h" | 26 #include "bindings/core/v8/Dictionary.h" |
| 27 | 27 |
| 28 #include "bindings/core/v8/V8ScriptRunner.h" | 28 #include "bindings/core/v8/V8ScriptRunner.h" |
| 29 #include "bindings/core/v8/V8StringResource.h" | 29 #include "bindings/core/v8/V8StringResource.h" |
| 30 #include "core/dom/ExecutionContext.h" | 30 #include "core/dom/ExecutionContext.h" |
| 31 | 31 |
| 32 namespace blink { | 32 namespace blink { |
| 33 | 33 |
| 34 Dictionary& Dictionary::operator=(const Dictionary& optionsObject) { | 34 Dictionary::Dictionary(v8::Isolate* isolate, |
| 35 m_options = optionsObject.m_options; | 35 v8::Local<v8::Value> dictionaryObject, |
| 36 m_isolate = optionsObject.m_isolate; | 36 ExceptionState& exceptionState) |
| 37 return *this; | 37 : m_isolate(isolate) { |
| 38 } | 38 DCHECK(isolate); |
| 39 | 39 |
| 40 bool Dictionary::isObject() const { | 40 // https://heycam.github.io/webidl/#es-dictionary |
|
bashi
2016/11/18 15:03:55
I'm not sure "Dictionary" class is a "WebIDL dicti
Yuki
2016/11/21 12:40:27
Well, ... but you said that the call sites of Dict
| |
| 41 return !isUndefinedOrNull() && m_options->IsObject(); | 41 // Type of an ECMAScript value must be Undefined, Null or Object. |
| 42 } | 42 if (dictionaryObject.IsEmpty() || dictionaryObject->IsUndefined()) { |
| 43 m_valueType = ValueType::Undefined; | |
| 44 return; | |
| 45 } | |
| 46 if (dictionaryObject->IsNull()) { | |
| 47 m_valueType = ValueType::Null; | |
| 48 return; | |
| 49 } | |
| 50 if (dictionaryObject->IsObject()) { | |
| 51 m_valueType = ValueType::Object; | |
| 52 m_dictionaryObject = dictionaryObject.As<v8::Object>(); | |
| 53 return; | |
| 54 } | |
| 43 | 55 |
| 44 bool Dictionary::isUndefinedOrNull() const { | 56 exceptionState.throwTypeError( |
| 45 if (m_options.IsEmpty()) | 57 "The dictionary provided is neither undefined, null nor an Object."); |
| 46 return true; | |
| 47 return blink::isUndefinedOrNull(m_options); | |
| 48 } | 58 } |
| 49 | 59 |
| 50 bool Dictionary::hasProperty(const StringView& key) const { | 60 bool Dictionary::hasProperty(const StringView& key) const { |
| 51 v8::Local<v8::Object> object; | 61 if (m_dictionaryObject.IsEmpty()) |
| 52 if (!toObject(object)) | |
| 53 return false; | 62 return false; |
| 54 | 63 |
| 55 DCHECK(m_isolate); | 64 // TODO(bashi,yukishiino): Should rethrow the exception. |
| 56 DCHECK_EQ(m_isolate, v8::Isolate::GetCurrent()); | 65 // Has() on a revoked proxy will throw an exception. |
| 57 return v8CallBoolean(object->Has(v8Context(), v8String(m_isolate, key))); | 66 return v8CallBoolean( |
| 58 } | 67 m_dictionaryObject->Has(v8Context(), v8String(m_isolate, key))); |
| 59 | |
| 60 bool Dictionary::get(const StringView& key, v8::Local<v8::Value>& value) const { | |
| 61 if (!m_isolate) | |
| 62 return false; | |
| 63 return getInternal(v8String(m_isolate, key), value); | |
| 64 } | 68 } |
| 65 | 69 |
| 66 DictionaryIterator Dictionary::getIterator( | 70 DictionaryIterator Dictionary::getIterator( |
| 67 ExecutionContext* executionContext) const { | 71 ExecutionContext* executionContext) const { |
| 68 v8::Local<v8::Value> iteratorGetter; | 72 v8::Local<v8::Value> iteratorGetter; |
| 69 if (!getInternal(v8::Symbol::GetIterator(m_isolate), iteratorGetter) || | 73 if (!getInternal(v8::Symbol::GetIterator(m_isolate), iteratorGetter) || |
| 70 !iteratorGetter->IsFunction()) | 74 !iteratorGetter->IsFunction()) |
| 71 return nullptr; | 75 return nullptr; |
| 72 v8::Local<v8::Value> iterator; | 76 v8::Local<v8::Value> iterator; |
| 73 if (!v8Call(V8ScriptRunner::callFunction( | 77 if (!v8Call(V8ScriptRunner::callFunction( |
| 74 v8::Local<v8::Function>::Cast(iteratorGetter), | 78 v8::Local<v8::Function>::Cast(iteratorGetter), |
| 75 executionContext, m_options, 0, nullptr, m_isolate), | 79 executionContext, m_dictionaryObject, 0, nullptr, m_isolate), |
| 76 iterator)) | 80 iterator)) |
| 77 return nullptr; | 81 return nullptr; |
| 78 if (!iterator->IsObject()) | 82 if (!iterator->IsObject()) |
| 79 return nullptr; | 83 return nullptr; |
| 80 return DictionaryIterator(v8::Local<v8::Object>::Cast(iterator), m_isolate); | 84 return DictionaryIterator(v8::Local<v8::Object>::Cast(iterator), m_isolate); |
| 81 } | 85 } |
| 82 | 86 |
| 83 bool Dictionary::get(const StringView& key, Dictionary& value) const { | 87 bool Dictionary::get(const StringView& key, Dictionary& value) const { |
| 84 v8::Local<v8::Value> v8Value; | 88 v8::Local<v8::Value> v8Value; |
| 85 if (!get(key, v8Value)) | 89 if (!get(key, v8Value)) |
| 86 return false; | 90 return false; |
| 87 | 91 |
| 88 if (v8Value->IsObject()) { | 92 if (v8Value->IsObject()) { |
| 89 ASSERT(m_isolate); | 93 ASSERT(m_isolate); |
| 90 ASSERT(m_isolate == v8::Isolate::GetCurrent()); | 94 ASSERT(m_isolate == v8::Isolate::GetCurrent()); |
| 91 value = Dictionary(m_isolate, v8Value); | 95 // TODO(bashi,yukishiino): Should rethrow the exception. |
|
bashi
2016/11/18 15:03:55
nit: wouldn't it worth referring a bug entry ?
Yuki
2016/11/21 12:40:27
Done.
| |
| 96 TrackExceptionState exceptionState; | |
| 97 value = Dictionary(m_isolate, v8Value, exceptionState); | |
| 92 } | 98 } |
| 93 | 99 |
| 94 return true; | 100 return true; |
| 95 } | 101 } |
| 96 | 102 |
| 97 bool Dictionary::getInternal(const v8::Local<v8::Value>& key, | 103 bool Dictionary::getInternal(const v8::Local<v8::Value>& key, |
| 98 v8::Local<v8::Value>& result) const { | 104 v8::Local<v8::Value>& result) const { |
| 99 v8::Local<v8::Object> object; | 105 if (m_dictionaryObject.IsEmpty()) |
| 100 if (!toObject(object)) | |
| 101 return false; | 106 return false; |
| 102 | 107 |
| 103 DCHECK(m_isolate); | 108 if (!v8CallBoolean(m_dictionaryObject->Has(v8Context(), key))) |
| 104 DCHECK_EQ(m_isolate, v8::Isolate::GetCurrent()); | |
| 105 if (!v8CallBoolean(object->Has(v8Context(), key))) | |
| 106 return false; | 109 return false; |
| 107 | 110 |
| 108 // Swallow a possible exception in v8::Object::Get(). | 111 // Swallow a possible exception in v8::Object::Get(). |
| 109 // TODO(bashi,yukishiino): Should rethrow the exception. | 112 // TODO(bashi,yukishiino): Should rethrow the exception. |
| 110 v8::TryCatch tryCatch(isolate()); | 113 v8::TryCatch tryCatch(isolate()); |
| 111 return object->Get(v8Context(), key).ToLocal(&result); | 114 return m_dictionaryObject->Get(v8Context(), key).ToLocal(&result); |
| 112 } | 115 } |
| 113 | 116 |
| 114 static inline bool propertyKey(v8::Local<v8::Context> v8Context, | 117 static inline bool propertyKey(v8::Local<v8::Context> v8Context, |
| 115 v8::Local<v8::Array> properties, | 118 v8::Local<v8::Array> properties, |
| 116 uint32_t index, | 119 uint32_t index, |
| 117 v8::Local<v8::String>& key) { | 120 v8::Local<v8::String>& key) { |
| 118 v8::Local<v8::Value> property; | 121 v8::Local<v8::Value> property; |
| 119 if (!properties->Get(v8Context, index).ToLocal(&property)) | 122 if (!properties->Get(v8Context, index).ToLocal(&property)) |
| 120 return false; | 123 return false; |
| 121 return property->ToString(v8Context).ToLocal(&key); | 124 return property->ToString(v8Context).ToLocal(&key); |
| 122 } | 125 } |
| 123 | 126 |
| 124 bool Dictionary::getOwnPropertiesAsStringHashMap( | 127 bool Dictionary::getOwnPropertiesAsStringHashMap( |
| 125 HashMap<String, String>& hashMap) const { | 128 HashMap<String, String>& hashMap) const { |
| 126 v8::Local<v8::Object> object; | 129 if (m_dictionaryObject.IsEmpty()) |
| 127 if (!toObject(object)) | |
| 128 return false; | 130 return false; |
| 129 | 131 |
| 130 v8::Local<v8::Array> properties; | 132 v8::Local<v8::Array> properties; |
| 131 if (!object->GetOwnPropertyNames(v8Context()).ToLocal(&properties)) | 133 if (!m_dictionaryObject->GetOwnPropertyNames(v8Context()) |
| 134 .ToLocal(&properties)) | |
| 132 return false; | 135 return false; |
| 133 // Swallow a possible exception in v8::Object::Get(). | 136 // Swallow a possible exception in v8::Object::Get(). |
| 134 // TODO(bashi,yukishiino): Should rethrow the exception. | 137 // TODO(bashi,yukishiino): Should rethrow the exception. |
| 135 // Note that propertyKey() may throw an exception. | 138 // Note that propertyKey() may throw an exception. |
| 136 v8::TryCatch tryCatch(isolate()); | 139 v8::TryCatch tryCatch(isolate()); |
| 137 for (uint32_t i = 0; i < properties->Length(); ++i) { | 140 for (uint32_t i = 0; i < properties->Length(); ++i) { |
| 138 v8::Local<v8::String> key; | 141 v8::Local<v8::String> key; |
| 139 if (!propertyKey(v8Context(), properties, i, key)) | 142 if (!propertyKey(v8Context(), properties, i, key)) |
| 140 continue; | 143 continue; |
| 141 if (!v8CallBoolean(object->Has(v8Context(), key))) | 144 if (!v8CallBoolean(m_dictionaryObject->Has(v8Context(), key))) |
| 142 continue; | 145 continue; |
| 143 | 146 |
| 144 v8::Local<v8::Value> value; | 147 v8::Local<v8::Value> value; |
| 145 if (!object->Get(v8Context(), key).ToLocal(&value)) { | 148 if (!m_dictionaryObject->Get(v8Context(), key).ToLocal(&value)) { |
| 146 tryCatch.Reset(); | 149 tryCatch.Reset(); |
| 147 continue; | 150 continue; |
| 148 } | 151 } |
| 149 TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false); | 152 TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false); |
| 150 TOSTRING_DEFAULT(V8StringResource<>, stringValue, value, false); | 153 TOSTRING_DEFAULT(V8StringResource<>, stringValue, value, false); |
| 151 if (!static_cast<const String&>(stringKey).isEmpty()) | 154 if (!static_cast<const String&>(stringKey).isEmpty()) |
| 152 hashMap.set(stringKey, stringValue); | 155 hashMap.set(stringKey, stringValue); |
| 153 } | 156 } |
| 154 | 157 |
| 155 return true; | 158 return true; |
| 156 } | 159 } |
| 157 | 160 |
| 158 bool Dictionary::getPropertyNames(Vector<String>& names) const { | 161 bool Dictionary::getPropertyNames(Vector<String>& names) const { |
| 159 v8::Local<v8::Object> object; | 162 if (m_dictionaryObject.IsEmpty()) |
| 160 if (!toObject(object)) | |
| 161 return false; | 163 return false; |
| 162 | 164 |
| 163 v8::Local<v8::Array> properties; | 165 v8::Local<v8::Array> properties; |
| 164 if (!object->GetPropertyNames(v8Context()).ToLocal(&properties)) | 166 if (!m_dictionaryObject->GetPropertyNames(v8Context()).ToLocal(&properties)) |
| 165 return false; | 167 return false; |
| 166 for (uint32_t i = 0; i < properties->Length(); ++i) { | 168 for (uint32_t i = 0; i < properties->Length(); ++i) { |
| 167 v8::Local<v8::String> key; | 169 v8::Local<v8::String> key; |
| 168 if (!propertyKey(v8Context(), properties, i, key)) | 170 if (!propertyKey(v8Context(), properties, i, key)) |
| 169 continue; | 171 continue; |
| 170 if (!v8CallBoolean(object->Has(v8Context(), key))) | 172 if (!v8CallBoolean(m_dictionaryObject->Has(v8Context(), key))) |
| 171 continue; | 173 continue; |
| 172 TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false); | 174 TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false); |
| 173 names.append(stringKey); | 175 names.append(stringKey); |
| 174 } | 176 } |
| 175 | 177 |
| 176 return true; | 178 return true; |
| 177 } | 179 } |
| 178 | 180 |
| 179 bool Dictionary::toObject(v8::Local<v8::Object>& object) const { | |
| 180 return !isUndefinedOrNull() && | |
| 181 m_options->ToObject(v8Context()).ToLocal(&object); | |
| 182 } | |
| 183 | |
| 184 } // namespace blink | 181 } // namespace blink |
| OLD | NEW |