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

Side by Side Diff: Source/bindings/core/v8/SerializedScriptValue.cpp

Issue 718383003: bindings: fixed incorrect dependency of SerializedScriptValue. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Added fast/js/structured-clone.html Created 6 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 are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * 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 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 16 matching lines...) Expand all
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "bindings/core/v8/SerializedScriptValue.h" 32 #include "bindings/core/v8/SerializedScriptValue.h"
33 33
34 #include "bindings/core/v8/DOMDataStore.h" 34 #include "bindings/core/v8/DOMDataStore.h"
35 #include "bindings/core/v8/DOMWrapperWorld.h" 35 #include "bindings/core/v8/DOMWrapperWorld.h"
36 #include "bindings/core/v8/ExceptionState.h" 36 #include "bindings/core/v8/ExceptionState.h"
37 #include "bindings/core/v8/ScriptState.h"
37 #include "bindings/core/v8/ScriptValueSerializer.h" 38 #include "bindings/core/v8/ScriptValueSerializer.h"
39 #include "bindings/core/v8/SerializedScriptValueFactory.h"
38 #include "bindings/core/v8/V8ArrayBuffer.h" 40 #include "bindings/core/v8/V8ArrayBuffer.h"
39 #include "bindings/core/v8/V8ArrayBufferView.h"
40 #include "bindings/core/v8/V8Binding.h"
41 #include "bindings/core/v8/V8MessagePort.h" 41 #include "bindings/core/v8/V8MessagePort.h"
42 #include "core/dom/DOMArrayBuffer.h"
43 #include "core/dom/ExceptionCode.h" 42 #include "core/dom/ExceptionCode.h"
44 #include "platform/SharedBuffer.h" 43 #include "platform/SharedBuffer.h"
45 #include "platform/blob/BlobData.h" 44 #include "platform/blob/BlobData.h"
46 #include "platform/heap/Handle.h" 45 #include "platform/heap/Handle.h"
47 #include "public/platform/Platform.h"
48 #include "wtf/ArrayBufferContents.h"
49 #include "wtf/Assertions.h" 46 #include "wtf/Assertions.h"
50 #include "wtf/ByteOrder.h" 47 #include "wtf/ByteOrder.h"
51 #include "wtf/Uint8ClampedArray.h"
52 #include "wtf/Vector.h" 48 #include "wtf/Vector.h"
53 #include "wtf/text/StringBuffer.h" 49 #include "wtf/text/StringBuffer.h"
54 #include "wtf/text/StringHash.h" 50 #include "wtf/text/StringHash.h"
55 #include "wtf/text/StringUTF8Adaptor.h"
56 51
57 namespace blink { 52 namespace blink {
58 53
59 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::V alue> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Exc eptionState& exceptionState, v8::Isolate* isolate)
60 {
61 return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, 0, exceptionState, isolate));
62 }
63
64 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExcepti ons(v8::Isolate* isolate, v8::Handle<v8::Value> value)
65 {
66 TrackExceptionState exceptionState;
67 return adoptRef(new SerializedScriptValue(value, 0, 0, 0, exceptionState, is olate));
68 }
69
70 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValu e& value, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState, v8::Isolat e* isolate)
71 {
72 ASSERT(isolate->InContext());
73 return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, blobInfo, e xceptionState, isolate));
74 }
75
76 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const St ring& data)
77 {
78 return adoptRef(new SerializedScriptValue(data));
79 }
80
81 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(con st Vector<uint8_t>& data)
82 {
83 // Decode wire data from big endian to host byte order.
84 ASSERT(!(data.size() % sizeof(UChar)));
85 size_t length = data.size() / sizeof(UChar);
86 StringBuffer<UChar> buffer(length);
87 const UChar* src = reinterpret_cast<const UChar*>(data.data());
88 UChar* dst = buffer.characters();
89 for (size_t i = 0; i < length; i++)
90 dst[i] = ntohs(src[i]);
91
92 return createFromWire(String::adopt(buffer));
93 }
94
95 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& da ta)
96 {
97 return create(data, v8::Isolate::GetCurrent());
98 }
99
100 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& da ta, v8::Isolate* isolate)
101 {
102 SerializedScriptValueInternal::Writer writer;
103 writer.writeWebCoreString(data);
104 String wireData = writer.takeWireString();
105 return adoptRef(new SerializedScriptValue(wireData));
106 }
107
108 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create()
109 {
110 return adoptRef(new SerializedScriptValue());
111 }
112
113 PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue() 54 PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue()
114 { 55 {
115 SerializedScriptValueInternal::Writer writer; 56 SerializedScriptValueWriter writer;
116 writer.writeNull(); 57 writer.writeNull();
117 String wireData = writer.takeWireString(); 58 String wireData = writer.takeWireString();
118 return adoptRef(new SerializedScriptValue(wireData)); 59 return adoptRef(new SerializedScriptValue(wireData));
119 } 60 }
120 61
121 // Convert serialized string to big endian wire data. 62 // Convert serialized string to big endian wire data.
122 void SerializedScriptValue::toWireBytes(Vector<char>& result) const 63 void SerializedScriptValue::toWireBytes(Vector<char>& result) const
123 { 64 {
124 ASSERT(result.isEmpty()); 65 ASSERT(result.isEmpty());
125 size_t length = m_data.length(); 66 size_t length = m_data.length();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 } 98 }
158 } else { 99 } else {
159 v8::Handle<v8::Object> wrapper = DOMWrapperWorld::current(isolate).domDa taStore().get(object, isolate); 100 v8::Handle<v8::Object> wrapper = DOMWrapperWorld::current(isolate).domDa taStore().get(object, isolate);
160 if (!wrapper.IsEmpty()) { 101 if (!wrapper.IsEmpty()) {
161 ASSERT(wrapper->IsArrayBuffer()); 102 ASSERT(wrapper->IsArrayBuffer());
162 v8::Handle<v8::ArrayBuffer>::Cast(wrapper)->Neuter(); 103 v8::Handle<v8::ArrayBuffer>::Cast(wrapper)->Neuter();
163 } 104 }
164 } 105 }
165 } 106 }
166 107
167 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu e::transferArrayBuffers(v8::Isolate* isolate, ArrayBufferArray& arrayBuffers, Ex ceptionState& exceptionState) 108 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu e::createArrayBuffers(v8::Isolate* isolate, ArrayBufferArray& arrayBuffers, Exce ptionState& exceptionState)
168 { 109 {
169 ASSERT(arrayBuffers.size()); 110 ASSERT(arrayBuffers.size());
170 111
171 for (size_t i = 0; i < arrayBuffers.size(); i++) { 112 for (size_t i = 0; i < arrayBuffers.size(); i++) {
172 if (arrayBuffers[i]->isNeutered()) { 113 if (arrayBuffers[i]->isNeutered()) {
173 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind ex " + String::number(i) + " is already neutered."); 114 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind ex " + String::number(i) + " is already neutered.");
174 return nullptr; 115 return nullptr;
175 } 116 }
176 } 117 }
177 118
178 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents Array(arrayBuffers.size())); 119 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents Array(arrayBuffers.size()));
179 120
180 HashSet<DOMArrayBuffer*> visited; 121 HashSet<DOMArrayBuffer*> visited;
181 for (size_t i = 0; i < arrayBuffers.size(); i++) { 122 for (size_t i = 0; i < arrayBuffers.size(); i++) {
182 if (visited.contains(arrayBuffers[i].get())) 123 if (visited.contains(arrayBuffers[i].get()))
183 continue; 124 continue;
184 visited.add(arrayBuffers[i].get()); 125 visited.add(arrayBuffers[i].get());
185 126
186 bool result = arrayBuffers[i]->transfer(contents->at(i)); 127 bool result = arrayBuffers[i]->transfer(contents->at(i));
187 if (!result) { 128 if (!result) {
188 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind ex " + String::number(i) + " could not be transferred."); 129 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind ex " + String::number(i) + " could not be transferred.");
189 return nullptr; 130 return nullptr;
190 } 131 }
191 132
192 neuterArrayBufferInAllWorlds(arrayBuffers[i].get()); 133 neuterArrayBufferInAllWorlds(arrayBuffers[i].get());
193 } 134 }
194 return contents.release(); 135 return contents.release();
195 } 136 }
196 137
197 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, Messag ePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArray* blob Info, ExceptionState& exceptionState, v8::Isolate* isolate)
198 : m_externallyAllocatedMemory(0)
199 {
200 SerializedScriptValueInternal::Writer writer;
201 SerializedScriptValueInternal::Serializer::Status status;
202 String errorMessage;
203 {
204 v8::TryCatch tryCatch;
205 SerializedScriptValueInternal::Serializer serializer(writer, messagePort s, arrayBuffers, blobInfo, m_blobDataHandles, tryCatch, ScriptState::current(iso late));
206 status = serializer.serialize(value);
207 if (status == SerializedScriptValueInternal::Serializer::JSException) {
208 // If there was a JS exception thrown, re-throw it.
209 exceptionState.rethrowV8Exception(tryCatch.Exception());
210 return;
211 }
212 errorMessage = serializer.errorMessage();
213 }
214 switch (status) {
215 case SerializedScriptValueInternal::Serializer::InputError:
216 case SerializedScriptValueInternal::Serializer::DataCloneError:
217 exceptionState.throwDOMException(DataCloneError, errorMessage);
218 return;
219 case SerializedScriptValueInternal::Serializer::Success:
220 m_data = writer.takeWireString();
221 ASSERT(m_data.impl()->hasOneRef());
222 if (arrayBuffers && arrayBuffers->size())
223 m_arrayBufferContentsArray = transferArrayBuffers(isolate, *arrayBuf fers, exceptionState);
224 return;
225 case SerializedScriptValueInternal::Serializer::JSException:
226 ASSERT_NOT_REACHED();
227 break;
228 }
229 ASSERT_NOT_REACHED();
230 }
231
232 SerializedScriptValue::SerializedScriptValue(const String& wireData) 138 SerializedScriptValue::SerializedScriptValue(const String& wireData)
233 : m_externallyAllocatedMemory(0) 139 : m_externallyAllocatedMemory(0)
234 { 140 {
235 m_data = wireData.isolatedCopy(); 141 m_data = wireData.isolatedCopy();
236 } 142 }
237 143
238 v8::Handle<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messa gePorts) 144 v8::Handle<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messa gePorts)
239 { 145 {
240 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0); 146 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0);
241 } 147 }
242 148
243 v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, M essagePortArray* messagePorts, const WebBlobInfoArray* blobInfo) 149 v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, M essagePortArray* messagePorts, const WebBlobInfoArray* blobInfo)
244 { 150 {
245 if (!m_data.impl()) 151 return SerializedScriptValueFactory::instance().deserialize(this, isolate, m essagePorts, blobInfo);
246 return v8::Null(isolate);
247 COMPILE_ASSERT(sizeof(SerializedScriptValueInternal::Writer::BufferValueType ) == 2, BufferValueTypeIsTwoBytes);
248 m_data.ensure16Bit();
249 // FIXME: SerializedScriptValue shouldn't use String for its underlying
250 // storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The
251 // information stored in m_data isn't even encoded in UTF-16. Instead,
252 // unicode characters are encoded as UTF-8 with two code units per UChar.
253 SerializedScriptValueInternal::Reader reader(reinterpret_cast<const uint8_t* >(m_data.impl()->characters16()), 2 * m_data.length(), blobInfo, m_blobDataHandl es, ScriptState::current(isolate));
254 SerializedScriptValueInternal::Deserializer deserializer(reader, messagePort s, m_arrayBufferContentsArray.get());
255
256 // deserialize() can run arbitrary script (e.g., setters), which could resul t in |this| being destroyed.
257 // Holding a RefPtr ensures we are alive (along with our internal data) thro ughout the operation.
258 RefPtr<SerializedScriptValue> protect(this);
259 return deserializer.deserialize();
260 } 152 }
261 153
262 bool SerializedScriptValue::extractTransferables(v8::Isolate* isolate, v8::Local <v8::Value> value, int argumentIndex, MessagePortArray& ports, ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState) 154 bool SerializedScriptValue::extractTransferables(v8::Isolate* isolate, v8::Local <v8::Value> value, int argumentIndex, MessagePortArray& ports, ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState)
263 { 155 {
264 if (isUndefinedOrNull(value)) { 156 if (isUndefinedOrNull(value)) {
265 ports.resize(0); 157 ports.resize(0);
266 arrayBuffers.resize(0); 158 arrayBuffers.resize(0);
267 return true; 159 return true;
268 } 160 }
269 161
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 { 215 {
324 // If the allocated memory was not registered before, then this class is lik ely 216 // If the allocated memory was not registered before, then this class is lik ely
325 // used in a context other then Worker's onmessage environment and the prese nce of 217 // used in a context other then Worker's onmessage environment and the prese nce of
326 // current v8 context is not guaranteed. Avoid calling v8 then. 218 // current v8 context is not guaranteed. Avoid calling v8 then.
327 if (m_externallyAllocatedMemory) { 219 if (m_externallyAllocatedMemory) {
328 ASSERT(v8::Isolate::GetCurrent()); 220 ASSERT(v8::Isolate::GetCurrent());
329 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte rnallyAllocatedMemory); 221 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte rnallyAllocatedMemory);
330 } 222 }
331 } 223 }
332 224
225 void SerializedScriptValue::transferArrayBuffers(v8::Isolate* isolate, ArrayBuff erArray& arrayBuffers, ExceptionState& exceptionState)
226 {
227 m_arrayBufferContentsArray = createArrayBuffers(isolate, arrayBuffers, excep tionState);
228 }
229
333 } // namespace blink 230 } // namespace blink
OLDNEW
« no previous file with comments | « Source/bindings/core/v8/SerializedScriptValue.h ('k') | Source/bindings/core/v8/SerializedScriptValueFactory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698