Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/Dictionary.cpp

Issue 2509713002: binding: Makes Dictionary throw an exception (constructor). (Closed)
Patch Set: Addressed review comments. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 // http://crbug.com/666661
58 } 67 return v8CallBoolean(
59 68 m_dictionaryObject->Has(v8Context(), v8String(m_isolate, key)));
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 } 69 }
65 70
66 DictionaryIterator Dictionary::getIterator( 71 DictionaryIterator Dictionary::getIterator(
67 ExecutionContext* executionContext) const { 72 ExecutionContext* executionContext) const {
68 v8::Local<v8::Value> iteratorGetter; 73 v8::Local<v8::Value> iteratorGetter;
69 if (!getInternal(v8::Symbol::GetIterator(m_isolate), iteratorGetter) || 74 if (!getInternal(v8::Symbol::GetIterator(m_isolate), iteratorGetter) ||
70 !iteratorGetter->IsFunction()) 75 !iteratorGetter->IsFunction())
71 return nullptr; 76 return nullptr;
72 v8::Local<v8::Value> iterator; 77 v8::Local<v8::Value> iterator;
73 if (!v8Call(V8ScriptRunner::callFunction( 78 if (!v8Call(V8ScriptRunner::callFunction(
74 v8::Local<v8::Function>::Cast(iteratorGetter), 79 v8::Local<v8::Function>::Cast(iteratorGetter),
75 executionContext, m_options, 0, nullptr, m_isolate), 80 executionContext, m_dictionaryObject, 0, nullptr, m_isolate),
76 iterator)) 81 iterator))
77 return nullptr; 82 return nullptr;
78 if (!iterator->IsObject()) 83 if (!iterator->IsObject())
79 return nullptr; 84 return nullptr;
80 return DictionaryIterator(v8::Local<v8::Object>::Cast(iterator), m_isolate); 85 return DictionaryIterator(v8::Local<v8::Object>::Cast(iterator), m_isolate);
81 } 86 }
82 87
83 bool Dictionary::get(const StringView& key, Dictionary& value) const { 88 bool Dictionary::get(const StringView& key, Dictionary& value) const {
84 v8::Local<v8::Value> v8Value; 89 v8::Local<v8::Value> v8Value;
85 if (!get(key, v8Value)) 90 if (!get(key, v8Value))
86 return false; 91 return false;
87 92
88 if (v8Value->IsObject()) { 93 if (v8Value->IsObject()) {
89 ASSERT(m_isolate); 94 ASSERT(m_isolate);
90 ASSERT(m_isolate == v8::Isolate::GetCurrent()); 95 ASSERT(m_isolate == v8::Isolate::GetCurrent());
91 value = Dictionary(m_isolate, v8Value); 96 // TODO(bashi,yukishiino): Should rethrow the exception.
97 // http://crbug.com/666661
98 TrackExceptionState exceptionState;
99 value = Dictionary(m_isolate, v8Value, exceptionState);
92 } 100 }
93 101
94 return true; 102 return true;
95 } 103 }
96 104
97 bool Dictionary::getInternal(const v8::Local<v8::Value>& key, 105 bool Dictionary::getInternal(const v8::Local<v8::Value>& key,
98 v8::Local<v8::Value>& result) const { 106 v8::Local<v8::Value>& result) const {
99 v8::Local<v8::Object> object; 107 if (m_dictionaryObject.IsEmpty())
100 if (!toObject(object))
101 return false; 108 return false;
102 109
103 DCHECK(m_isolate); 110 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; 111 return false;
107 112
108 // Swallow a possible exception in v8::Object::Get(). 113 // Swallow a possible exception in v8::Object::Get().
109 // TODO(bashi,yukishiino): Should rethrow the exception. 114 // TODO(bashi,yukishiino): Should rethrow the exception.
115 // http://crbug.com/666661
110 v8::TryCatch tryCatch(isolate()); 116 v8::TryCatch tryCatch(isolate());
111 return object->Get(v8Context(), key).ToLocal(&result); 117 return m_dictionaryObject->Get(v8Context(), key).ToLocal(&result);
112 } 118 }
113 119
114 static inline bool propertyKey(v8::Local<v8::Context> v8Context, 120 static inline bool propertyKey(v8::Local<v8::Context> v8Context,
115 v8::Local<v8::Array> properties, 121 v8::Local<v8::Array> properties,
116 uint32_t index, 122 uint32_t index,
117 v8::Local<v8::String>& key) { 123 v8::Local<v8::String>& key) {
118 v8::Local<v8::Value> property; 124 v8::Local<v8::Value> property;
119 if (!properties->Get(v8Context, index).ToLocal(&property)) 125 if (!properties->Get(v8Context, index).ToLocal(&property))
120 return false; 126 return false;
121 return property->ToString(v8Context).ToLocal(&key); 127 return property->ToString(v8Context).ToLocal(&key);
122 } 128 }
123 129
124 bool Dictionary::getOwnPropertiesAsStringHashMap( 130 bool Dictionary::getOwnPropertiesAsStringHashMap(
125 HashMap<String, String>& hashMap) const { 131 HashMap<String, String>& hashMap) const {
126 v8::Local<v8::Object> object; 132 if (m_dictionaryObject.IsEmpty())
127 if (!toObject(object))
128 return false; 133 return false;
129 134
130 v8::Local<v8::Array> properties; 135 v8::Local<v8::Array> properties;
131 if (!object->GetOwnPropertyNames(v8Context()).ToLocal(&properties)) 136 if (!m_dictionaryObject->GetOwnPropertyNames(v8Context())
137 .ToLocal(&properties))
132 return false; 138 return false;
133 // Swallow a possible exception in v8::Object::Get(). 139 // Swallow a possible exception in v8::Object::Get().
134 // TODO(bashi,yukishiino): Should rethrow the exception. 140 // TODO(bashi,yukishiino): Should rethrow the exception.
135 // Note that propertyKey() may throw an exception. 141 // Note that propertyKey() may throw an exception.
142 // http://crbug.com/666661
136 v8::TryCatch tryCatch(isolate()); 143 v8::TryCatch tryCatch(isolate());
137 for (uint32_t i = 0; i < properties->Length(); ++i) { 144 for (uint32_t i = 0; i < properties->Length(); ++i) {
138 v8::Local<v8::String> key; 145 v8::Local<v8::String> key;
139 if (!propertyKey(v8Context(), properties, i, key)) 146 if (!propertyKey(v8Context(), properties, i, key))
140 continue; 147 continue;
141 if (!v8CallBoolean(object->Has(v8Context(), key))) 148 if (!v8CallBoolean(m_dictionaryObject->Has(v8Context(), key)))
142 continue; 149 continue;
143 150
144 v8::Local<v8::Value> value; 151 v8::Local<v8::Value> value;
145 if (!object->Get(v8Context(), key).ToLocal(&value)) { 152 if (!m_dictionaryObject->Get(v8Context(), key).ToLocal(&value)) {
146 tryCatch.Reset(); 153 tryCatch.Reset();
147 continue; 154 continue;
148 } 155 }
149 TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false); 156 TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false);
150 TOSTRING_DEFAULT(V8StringResource<>, stringValue, value, false); 157 TOSTRING_DEFAULT(V8StringResource<>, stringValue, value, false);
151 if (!static_cast<const String&>(stringKey).isEmpty()) 158 if (!static_cast<const String&>(stringKey).isEmpty())
152 hashMap.set(stringKey, stringValue); 159 hashMap.set(stringKey, stringValue);
153 } 160 }
154 161
155 return true; 162 return true;
156 } 163 }
157 164
158 bool Dictionary::getPropertyNames(Vector<String>& names) const { 165 bool Dictionary::getPropertyNames(Vector<String>& names) const {
159 v8::Local<v8::Object> object; 166 if (m_dictionaryObject.IsEmpty())
160 if (!toObject(object))
161 return false; 167 return false;
162 168
163 v8::Local<v8::Array> properties; 169 v8::Local<v8::Array> properties;
164 if (!object->GetPropertyNames(v8Context()).ToLocal(&properties)) 170 if (!m_dictionaryObject->GetPropertyNames(v8Context()).ToLocal(&properties))
165 return false; 171 return false;
166 for (uint32_t i = 0; i < properties->Length(); ++i) { 172 for (uint32_t i = 0; i < properties->Length(); ++i) {
167 v8::Local<v8::String> key; 173 v8::Local<v8::String> key;
168 if (!propertyKey(v8Context(), properties, i, key)) 174 if (!propertyKey(v8Context(), properties, i, key))
169 continue; 175 continue;
170 if (!v8CallBoolean(object->Has(v8Context(), key))) 176 if (!v8CallBoolean(m_dictionaryObject->Has(v8Context(), key)))
171 continue; 177 continue;
172 TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false); 178 TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false);
173 names.append(stringKey); 179 names.append(stringKey);
174 } 180 }
175 181
176 return true; 182 return true;
177 } 183 }
178 184
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 185 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698