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 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 21 matching lines...) Expand all Loading... |
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/ScriptState.h" |
38 #include "bindings/core/v8/ScriptValueSerializer.h" | 38 #include "bindings/core/v8/ScriptValueSerializer.h" |
39 #include "bindings/core/v8/SerializedScriptValueFactory.h" | 39 #include "bindings/core/v8/SerializedScriptValueFactory.h" |
40 #include "bindings/core/v8/V8ArrayBuffer.h" | 40 #include "bindings/core/v8/V8ArrayBuffer.h" |
41 #include "bindings/core/v8/V8MessagePort.h" | 41 #include "bindings/core/v8/V8MessagePort.h" |
| 42 #include "bindings/core/v8/V8SharedArrayBuffer.h" |
42 #include "core/dom/ExceptionCode.h" | 43 #include "core/dom/ExceptionCode.h" |
43 #include "platform/SharedBuffer.h" | 44 #include "platform/SharedBuffer.h" |
44 #include "platform/blob/BlobData.h" | 45 #include "platform/blob/BlobData.h" |
45 #include "platform/heap/Handle.h" | 46 #include "platform/heap/Handle.h" |
46 #include "wtf/Assertions.h" | 47 #include "wtf/Assertions.h" |
47 #include "wtf/ByteOrder.h" | 48 #include "wtf/ByteOrder.h" |
48 #include "wtf/Vector.h" | 49 #include "wtf/Vector.h" |
49 #include "wtf/text/StringBuffer.h" | 50 #include "wtf/text/StringBuffer.h" |
50 #include "wtf/text/StringHash.h" | 51 #include "wtf/text/StringHash.h" |
51 | 52 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 if (!wrapper.IsEmpty()) | 94 if (!wrapper.IsEmpty()) |
94 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); | 95 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); |
95 } | 96 } |
96 } else { | 97 } else { |
97 v8::Local<v8::Object> wrapper = DOMWrapperWorld::current(isolate).domDat
aStore().get(object, isolate); | 98 v8::Local<v8::Object> wrapper = DOMWrapperWorld::current(isolate).domDat
aStore().get(object, isolate); |
98 if (!wrapper.IsEmpty()) | 99 if (!wrapper.IsEmpty()) |
99 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); | 100 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); |
100 } | 101 } |
101 } | 102 } |
102 | 103 |
103 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu
e::createArrayBuffers(v8::Isolate* isolate, ArrayBufferArray& arrayBuffers, Exce
ptionState& exceptionState) | 104 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu
e::createArrayBuffers(v8::Isolate* isolate, ArrayBufferArray& arrayBuffers, Shar
edArrayBufferArray& sharedArrayBuffers, ExceptionState& exceptionState) |
104 { | 105 { |
105 ASSERT(arrayBuffers.size()); | 106 size_t bufferCount = arrayBuffers.size() + sharedArrayBuffers.size(); |
| 107 ASSERT(bufferCount > 0); |
106 | 108 |
107 for (size_t i = 0; i < arrayBuffers.size(); i++) { | 109 for (size_t i = 0; i < arrayBuffers.size(); i++) { |
108 if (arrayBuffers[i]->isNeutered()) { | 110 if (arrayBuffers[i]->isNeutered()) { |
109 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind
ex " + String::number(i) + " is already neutered."); | 111 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind
ex " + String::number(i) + " is already neutered."); |
110 return nullptr; | 112 return nullptr; |
111 } | 113 } |
112 } | 114 } |
113 | 115 |
114 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents
Array(arrayBuffers.size())); | 116 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents
Array(bufferCount)); |
115 | 117 |
116 HashSet<DOMArrayBuffer*> visited; | 118 HashSet<DOMArrayBuffer*> visited; |
117 for (size_t i = 0; i < arrayBuffers.size(); i++) { | 119 for (size_t i = 0; i < arrayBuffers.size(); i++) { |
118 if (visited.contains(arrayBuffers[i].get())) | 120 if (visited.contains(arrayBuffers[i].get())) |
119 continue; | 121 continue; |
120 visited.add(arrayBuffers[i].get()); | 122 visited.add(arrayBuffers[i].get()); |
121 | 123 |
122 Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles; | 124 Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles; |
123 v8::HandleScope handleScope(isolate); | 125 v8::HandleScope handleScope(isolate); |
124 acculumateArrayBuffersForAllWorlds(isolate, arrayBuffers[i].get(), buffe
rHandles); | 126 acculumateArrayBuffersForAllWorlds(isolate, arrayBuffers[i].get(), buffe
rHandles); |
125 bool isNeuterable = true; | 127 bool isNeuterable = true; |
126 for (size_t j = 0; j < bufferHandles.size(); j++) | 128 for (size_t j = 0; j < bufferHandles.size(); j++) |
127 isNeuterable &= bufferHandles[j]->IsNeuterable(); | 129 isNeuterable &= bufferHandles[j]->IsNeuterable(); |
128 | 130 |
129 RefPtr<DOMArrayBuffer> toTransfer = arrayBuffers[i]; | 131 RefPtr<DOMArrayBuffer> toTransfer = arrayBuffers[i]; |
130 if (!isNeuterable) | 132 if (!isNeuterable) |
131 toTransfer = DOMArrayBuffer::create(arrayBuffers[i]->buffer()); | 133 toTransfer = DOMArrayBuffer::create(arrayBuffers[i]->buffer()); |
132 bool result = toTransfer->transfer(contents->at(i)); | 134 bool result = toTransfer->transfer(contents->at(i)); |
133 if (!result) { | 135 if (!result) { |
134 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind
ex " + String::number(i) + " could not be transferred."); | 136 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind
ex " + String::number(i) + " could not be transferred."); |
135 return nullptr; | 137 return nullptr; |
136 } | 138 } |
137 | 139 |
138 if (isNeuterable) | 140 if (isNeuterable) |
139 for (size_t j = 0; j < bufferHandles.size(); j++) | 141 for (size_t j = 0; j < bufferHandles.size(); j++) |
140 bufferHandles[j]->Neuter(); | 142 bufferHandles[j]->Neuter(); |
141 } | 143 } |
| 144 |
| 145 HashSet<DOMSharedArrayBuffer*> sharedVisited; |
| 146 size_t offset = arrayBuffers.size(); |
| 147 for (size_t i = 0; i < sharedArrayBuffers.size(); i++) { |
| 148 if (sharedVisited.contains(sharedArrayBuffers[i].get())) |
| 149 continue; |
| 150 sharedVisited.add(sharedArrayBuffers[i].get()); |
| 151 |
| 152 bool result = sharedArrayBuffers[i]->transfer(contents->at(i + offset)); |
| 153 if (!result) { |
| 154 exceptionState.throwDOMException(DataCloneError, "SharedArrayBuffer
at index " + String::number(i) + " could not be transferred."); |
| 155 return nullptr; |
| 156 } |
| 157 } |
| 158 |
142 return contents.release(); | 159 return contents.release(); |
143 } | 160 } |
144 | 161 |
145 SerializedScriptValue::SerializedScriptValue(const String& wireData) | 162 SerializedScriptValue::SerializedScriptValue(const String& wireData) |
146 : m_externallyAllocatedMemory(0) | 163 : m_externallyAllocatedMemory(0) |
147 { | 164 { |
148 m_data = wireData.isolatedCopy(); | 165 m_data = wireData.isolatedCopy(); |
149 } | 166 } |
150 | 167 |
151 v8::Local<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messag
ePorts) | 168 v8::Local<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messag
ePorts) |
152 { | 169 { |
153 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0); | 170 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0); |
154 } | 171 } |
155 | 172 |
156 v8::Local<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, Me
ssagePortArray* messagePorts, const WebBlobInfoArray* blobInfo) | 173 v8::Local<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, Me
ssagePortArray* messagePorts, const WebBlobInfoArray* blobInfo) |
157 { | 174 { |
158 return SerializedScriptValueFactory::instance().deserialize(this, isolate, m
essagePorts, blobInfo); | 175 return SerializedScriptValueFactory::instance().deserialize(this, isolate, m
essagePorts, blobInfo); |
159 } | 176 } |
160 | 177 |
161 bool SerializedScriptValue::extractTransferables(v8::Isolate* isolate, v8::Local
<v8::Value> value, int argumentIndex, MessagePortArray& ports, ArrayBufferArray&
arrayBuffers, ExceptionState& exceptionState) | 178 bool SerializedScriptValue::extractTransferables(v8::Isolate* isolate, v8::Local
<v8::Value> value, int argumentIndex, MessagePortArray& ports, ArrayBufferArray&
arrayBuffers, SharedArrayBufferArray& sharedArrayBuffers, ExceptionState& excep
tionState) |
162 { | 179 { |
163 if (isUndefinedOrNull(value)) { | 180 if (isUndefinedOrNull(value)) { |
164 ports.resize(0); | 181 ports.resize(0); |
165 arrayBuffers.resize(0); | 182 arrayBuffers.resize(0); |
| 183 sharedArrayBuffers.resize(0); |
166 return true; | 184 return true; |
167 } | 185 } |
168 | 186 |
169 uint32_t length = 0; | 187 uint32_t length = 0; |
170 if (value->IsArray()) { | 188 if (value->IsArray()) { |
171 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value); | 189 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value); |
172 length = array->Length(); | 190 length = array->Length(); |
173 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { | 191 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
174 if (!exceptionState.hadException()) | 192 if (!exceptionState.hadException()) |
175 exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgum
entOrValue(argumentIndex + 1)); | 193 exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgum
entOrValue(argumentIndex + 1)); |
(...skipping 21 matching lines...) Expand all Loading... |
197 return false; | 215 return false; |
198 } | 216 } |
199 ports.append(port.release()); | 217 ports.append(port.release()); |
200 } else if (V8ArrayBuffer::hasInstance(transferrable, isolate)) { | 218 } else if (V8ArrayBuffer::hasInstance(transferrable, isolate)) { |
201 RefPtr<DOMArrayBuffer> arrayBuffer = V8ArrayBuffer::toImpl(v8::Local
<v8::Object>::Cast(transferrable)); | 219 RefPtr<DOMArrayBuffer> arrayBuffer = V8ArrayBuffer::toImpl(v8::Local
<v8::Object>::Cast(transferrable)); |
202 if (arrayBuffers.contains(arrayBuffer)) { | 220 if (arrayBuffers.contains(arrayBuffer)) { |
203 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at
index " + String::number(i) + " is a duplicate of an earlier ArrayBuffer."); | 221 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at
index " + String::number(i) + " is a duplicate of an earlier ArrayBuffer."); |
204 return false; | 222 return false; |
205 } | 223 } |
206 arrayBuffers.append(arrayBuffer.release()); | 224 arrayBuffers.append(arrayBuffer.release()); |
| 225 } else if (V8SharedArrayBuffer::hasInstance(transferrable, isolate)) { |
| 226 RefPtr<DOMSharedArrayBuffer> sharedArrayBuffer = V8SharedArrayBuffer
::toImpl(v8::Handle<v8::Object>::Cast(transferrable)); |
| 227 if (sharedArrayBuffers.contains(sharedArrayBuffer)) { |
| 228 exceptionState.throwDOMException(DataCloneError, "SharedArrayBuf
fer at index " + String::number(i) + " is a duplicate of an earlier SharedArrayB
uffer."); |
| 229 return false; |
| 230 } |
| 231 sharedArrayBuffers.append(sharedArrayBuffer.release()); |
207 } else { | 232 } else { |
208 exceptionState.throwTypeError("Value at index " + String::number(i)
+ " does not have a transferable type."); | 233 exceptionState.throwTypeError("Value at index " + String::number(i)
+ " does not have a transferable type."); |
209 return false; | 234 return false; |
210 } | 235 } |
211 } | 236 } |
212 return true; | 237 return true; |
213 } | 238 } |
214 | 239 |
215 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() | 240 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() |
216 { | 241 { |
217 if (m_externallyAllocatedMemory) | 242 if (m_externallyAllocatedMemory) |
218 return; | 243 return; |
219 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); | 244 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); |
220 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externall
yAllocatedMemory); | 245 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externall
yAllocatedMemory); |
221 } | 246 } |
222 | 247 |
223 SerializedScriptValue::~SerializedScriptValue() | 248 SerializedScriptValue::~SerializedScriptValue() |
224 { | 249 { |
225 // If the allocated memory was not registered before, then this class is lik
ely | 250 // If the allocated memory was not registered before, then this class is lik
ely |
226 // used in a context other then Worker's onmessage environment and the prese
nce of | 251 // used in a context other then Worker's onmessage environment and the prese
nce of |
227 // current v8 context is not guaranteed. Avoid calling v8 then. | 252 // current v8 context is not guaranteed. Avoid calling v8 then. |
228 if (m_externallyAllocatedMemory) { | 253 if (m_externallyAllocatedMemory) { |
229 ASSERT(v8::Isolate::GetCurrent()); | 254 ASSERT(v8::Isolate::GetCurrent()); |
230 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte
rnallyAllocatedMemory); | 255 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte
rnallyAllocatedMemory); |
231 } | 256 } |
232 } | 257 } |
233 | 258 |
234 void SerializedScriptValue::transferArrayBuffers(v8::Isolate* isolate, ArrayBuff
erArray& arrayBuffers, ExceptionState& exceptionState) | 259 void SerializedScriptValue::transferArrayBuffers(v8::Isolate* isolate, ArrayBuff
erArray& arrayBuffers, SharedArrayBufferArray& sharedArrayBuffers, ExceptionStat
e& exceptionState) |
235 { | 260 { |
236 m_arrayBufferContentsArray = createArrayBuffers(isolate, arrayBuffers, excep
tionState); | 261 m_arrayBufferContentsArray = createArrayBuffers(isolate, arrayBuffers, share
dArrayBuffers, exceptionState); |
237 } | 262 } |
238 | 263 |
239 } // namespace blink | 264 } // namespace blink |
OLD | NEW |