| 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 const LChar* src = m_data.characters8(); | 142 const LChar* src = m_data.characters8(); |
| 143 for (size_t i = 0; i < length; i++) | 143 for (size_t i = 0; i < length; i++) |
| 144 dst[i] = htons(static_cast<UChar>(src[i])); | 144 dst[i] = htons(static_cast<UChar>(src[i])); |
| 145 } else { | 145 } else { |
| 146 const UChar* src = m_data.characters16(); | 146 const UChar* src = m_data.characters16(); |
| 147 for (size_t i = 0; i < length; i++) | 147 for (size_t i = 0; i < length; i++) |
| 148 dst[i] = htons(src[i]); | 148 dst[i] = htons(src[i]); |
| 149 } | 149 } |
| 150 } | 150 } |
| 151 | 151 |
| 152 static void acculumateArrayBuffersForAllWorlds( | 152 static void accumulateArrayBuffersForAllWorlds( |
| 153 v8::Isolate* isolate, | 153 v8::Isolate* isolate, |
| 154 DOMArrayBuffer* object, | 154 DOMArrayBuffer* object, |
| 155 Vector<v8::Local<v8::ArrayBuffer>, 4>& buffers) { | 155 Vector<v8::Local<v8::ArrayBuffer>, 4>& buffers) { |
| 156 if (isMainThread()) { | 156 if (isMainThread()) { |
| 157 Vector<RefPtr<DOMWrapperWorld>> worlds; | 157 Vector<RefPtr<DOMWrapperWorld>> worlds; |
| 158 DOMWrapperWorld::allWorldsInMainThread(worlds); | 158 DOMWrapperWorld::allWorldsInMainThread(worlds); |
| 159 for (size_t i = 0; i < worlds.size(); i++) { | 159 for (size_t i = 0; i < worlds.size(); i++) { |
| 160 v8::Local<v8::Object> wrapper = | 160 v8::Local<v8::Object> wrapper = |
| 161 worlds[i]->domDataStore().get(object, isolate); | 161 worlds[i]->domDataStore().get(object, isolate); |
| 162 if (!wrapper.IsEmpty()) | 162 if (!wrapper.IsEmpty()) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 } | 223 } |
| 224 visited.add(offscreenCanvases[i].get()); | 224 visited.add(offscreenCanvases[i].get()); |
| 225 offscreenCanvases[i].get()->setNeutered(); | 225 offscreenCanvases[i].get()->setNeutered(); |
| 226 } | 226 } |
| 227 } | 227 } |
| 228 | 228 |
| 229 void SerializedScriptValue::transferArrayBuffers( | 229 void SerializedScriptValue::transferArrayBuffers( |
| 230 v8::Isolate* isolate, | 230 v8::Isolate* isolate, |
| 231 const ArrayBufferArray& arrayBuffers, | 231 const ArrayBufferArray& arrayBuffers, |
| 232 ExceptionState& exceptionState) { | 232 ExceptionState& exceptionState) { |
| 233 if (!arrayBuffers.size()) | 233 m_arrayBufferContentsArray = |
| 234 return; | 234 transferArrayBufferContents(isolate, arrayBuffers, exceptionState); |
| 235 | |
| 236 for (size_t i = 0; i < arrayBuffers.size(); ++i) { | |
| 237 if (arrayBuffers[i]->isNeutered()) { | |
| 238 exceptionState.throwDOMException( | |
| 239 DataCloneError, "ArrayBuffer at index " + String::number(i) + | |
| 240 " is already neutered."); | |
| 241 return; | |
| 242 } | |
| 243 } | |
| 244 | |
| 245 std::unique_ptr<ArrayBufferContentsArray> contents = | |
| 246 wrapUnique(new ArrayBufferContentsArray(arrayBuffers.size())); | |
| 247 | |
| 248 HeapHashSet<Member<DOMArrayBufferBase>> visited; | |
| 249 for (size_t i = 0; i < arrayBuffers.size(); ++i) { | |
| 250 if (visited.contains(arrayBuffers[i])) | |
| 251 continue; | |
| 252 visited.add(arrayBuffers[i]); | |
| 253 | |
| 254 if (arrayBuffers[i]->isShared()) { | |
| 255 bool result = arrayBuffers[i]->shareContentsWith(contents->at(i)); | |
| 256 if (!result) { | |
| 257 exceptionState.throwDOMException( | |
| 258 DataCloneError, "SharedArrayBuffer at index " + String::number(i) + | |
| 259 " could not be transferred."); | |
| 260 return; | |
| 261 } | |
| 262 } else { | |
| 263 Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles; | |
| 264 v8::HandleScope handleScope(isolate); | |
| 265 acculumateArrayBuffersForAllWorlds( | |
| 266 isolate, static_cast<DOMArrayBuffer*>(arrayBuffers[i].get()), | |
| 267 bufferHandles); | |
| 268 bool isNeuterable = true; | |
| 269 for (size_t j = 0; j < bufferHandles.size(); ++j) | |
| 270 isNeuterable &= bufferHandles[j]->IsNeuterable(); | |
| 271 | |
| 272 DOMArrayBufferBase* toTransfer = arrayBuffers[i]; | |
| 273 if (!isNeuterable) | |
| 274 toTransfer = | |
| 275 DOMArrayBuffer::create(arrayBuffers[i]->buffer()->data(), | |
| 276 arrayBuffers[i]->buffer()->byteLength()); | |
| 277 bool result = toTransfer->transfer(contents->at(i)); | |
| 278 if (!result) { | |
| 279 exceptionState.throwDOMException( | |
| 280 DataCloneError, "ArrayBuffer at index " + String::number(i) + | |
| 281 " could not be transferred."); | |
| 282 return; | |
| 283 } | |
| 284 | |
| 285 if (isNeuterable) | |
| 286 for (size_t j = 0; j < bufferHandles.size(); ++j) | |
| 287 bufferHandles[j]->Neuter(); | |
| 288 } | |
| 289 } | |
| 290 m_arrayBufferContentsArray = std::move(contents); | |
| 291 } | 235 } |
| 292 | 236 |
| 293 v8::Local<v8::Value> SerializedScriptValue::deserialize( | 237 v8::Local<v8::Value> SerializedScriptValue::deserialize( |
| 294 MessagePortArray* messagePorts) { | 238 MessagePortArray* messagePorts) { |
| 295 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0); | 239 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0); |
| 296 } | 240 } |
| 297 | 241 |
| 298 v8::Local<v8::Value> SerializedScriptValue::deserialize( | 242 v8::Local<v8::Value> SerializedScriptValue::deserialize( |
| 299 v8::Isolate* isolate, | 243 v8::Isolate* isolate, |
| 300 MessagePortArray* messagePorts, | 244 MessagePortArray* messagePorts, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 transferables.offscreenCanvases.append(offscreenCanvas); | 339 transferables.offscreenCanvases.append(offscreenCanvas); |
| 396 } else { | 340 } else { |
| 397 exceptionState.throwTypeError("Value at index " + String::number(i) + | 341 exceptionState.throwTypeError("Value at index " + String::number(i) + |
| 398 " does not have a transferable type."); | 342 " does not have a transferable type."); |
| 399 return false; | 343 return false; |
| 400 } | 344 } |
| 401 } | 345 } |
| 402 return true; | 346 return true; |
| 403 } | 347 } |
| 404 | 348 |
| 349 std::unique_ptr<ArrayBufferContentsArray> |
| 350 SerializedScriptValue::transferArrayBufferContents( |
| 351 v8::Isolate* isolate, |
| 352 const ArrayBufferArray& arrayBuffers, |
| 353 ExceptionState& exceptionState) { |
| 354 if (!arrayBuffers.size()) |
| 355 return nullptr; |
| 356 |
| 357 for (auto it = arrayBuffers.begin(); it != arrayBuffers.end(); ++it) { |
| 358 DOMArrayBufferBase* arrayBuffer = *it; |
| 359 if (arrayBuffer->isNeutered()) { |
| 360 size_t index = std::distance(arrayBuffers.begin(), it); |
| 361 exceptionState.throwDOMException( |
| 362 DataCloneError, "ArrayBuffer at index " + String::number(index) + |
| 363 " is already neutered."); |
| 364 return nullptr; |
| 365 } |
| 366 } |
| 367 |
| 368 std::unique_ptr<ArrayBufferContentsArray> contents = |
| 369 wrapUnique(new ArrayBufferContentsArray(arrayBuffers.size())); |
| 370 |
| 371 HeapHashSet<Member<DOMArrayBufferBase>> visited; |
| 372 for (auto it = arrayBuffers.begin(); it != arrayBuffers.end(); ++it) { |
| 373 DOMArrayBufferBase* arrayBuffer = *it; |
| 374 if (visited.contains(arrayBuffer)) |
| 375 continue; |
| 376 visited.add(arrayBuffer); |
| 377 |
| 378 size_t index = std::distance(arrayBuffers.begin(), it); |
| 379 if (arrayBuffer->isShared()) { |
| 380 if (!arrayBuffer->shareContentsWith(contents->at(index))) { |
| 381 exceptionState.throwDOMException(DataCloneError, |
| 382 "SharedArrayBuffer at index " + |
| 383 String::number(index) + |
| 384 " could not be transferred."); |
| 385 return nullptr; |
| 386 } |
| 387 } else { |
| 388 Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles; |
| 389 v8::HandleScope handleScope(isolate); |
| 390 accumulateArrayBuffersForAllWorlds( |
| 391 isolate, static_cast<DOMArrayBuffer*>(it->get()), bufferHandles); |
| 392 bool isNeuterable = true; |
| 393 for (const auto& bufferHandle : bufferHandles) |
| 394 isNeuterable &= bufferHandle->IsNeuterable(); |
| 395 |
| 396 DOMArrayBufferBase* toTransfer = arrayBuffer; |
| 397 if (!isNeuterable) { |
| 398 toTransfer = DOMArrayBuffer::create( |
| 399 arrayBuffer->buffer()->data(), arrayBuffer->buffer()->byteLength()); |
| 400 } |
| 401 if (!toTransfer->transfer(contents->at(index))) { |
| 402 exceptionState.throwDOMException( |
| 403 DataCloneError, "ArrayBuffer at index " + String::number(index) + |
| 404 " could not be transferred."); |
| 405 return nullptr; |
| 406 } |
| 407 |
| 408 if (isNeuterable) { |
| 409 for (const auto& bufferHandle : bufferHandles) |
| 410 bufferHandle->Neuter(); |
| 411 } |
| 412 } |
| 413 } |
| 414 return contents; |
| 415 } |
| 416 |
| 405 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() { | 417 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() { |
| 406 if (m_externallyAllocatedMemory) | 418 if (m_externallyAllocatedMemory) |
| 407 return; | 419 return; |
| 408 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); | 420 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); |
| 409 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( | 421 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( |
| 410 m_externallyAllocatedMemory); | 422 m_externallyAllocatedMemory); |
| 411 } | 423 } |
| 412 | 424 |
| 413 bool SerializedScriptValue::containsTransferableArrayBuffer() const { | |
| 414 return m_arrayBufferContentsArray && !m_arrayBufferContentsArray->isEmpty(); | |
| 415 } | |
| 416 | |
| 417 } // namespace blink | 425 } // namespace blink |
| OLD | NEW |