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 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 (size_t i = 0; i < arrayBuffers.size(); ++i) { | |
|
haraken
2016/10/19 09:49:28
Can we use an iterator? An index-based access is s
nhiroki
2016/10/20 07:44:02
Done.
(Just to confirm: The out-of-range check in
| |
| 358 if (arrayBuffers[i]->isNeutered()) { | |
| 359 exceptionState.throwDOMException( | |
| 360 DataCloneError, "ArrayBuffer at index " + String::number(i) + | |
| 361 " is already neutered."); | |
| 362 return nullptr; | |
| 363 } | |
| 364 } | |
| 365 | |
| 366 std::unique_ptr<ArrayBufferContentsArray> contents = | |
| 367 wrapUnique(new ArrayBufferContentsArray(arrayBuffers.size())); | |
| 368 | |
| 369 HeapHashSet<Member<DOMArrayBufferBase>> visited; | |
| 370 for (size_t i = 0; i < arrayBuffers.size(); ++i) { | |
|
haraken
2016/10/19 09:49:28
Ditto.
nhiroki
2016/10/20 07:44:02
Done.
| |
| 371 if (visited.contains(arrayBuffers[i])) | |
| 372 continue; | |
| 373 visited.add(arrayBuffers[i]); | |
| 374 | |
| 375 if (arrayBuffers[i]->isShared()) { | |
| 376 bool result = arrayBuffers[i]->shareContentsWith(contents->at(i)); | |
| 377 if (!result) { | |
| 378 exceptionState.throwDOMException( | |
| 379 DataCloneError, "SharedArrayBuffer at index " + String::number(i) + | |
| 380 " could not be transferred."); | |
| 381 return nullptr; | |
| 382 } | |
| 383 } else { | |
| 384 Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles; | |
| 385 v8::HandleScope handleScope(isolate); | |
| 386 accumulateArrayBuffersForAllWorlds( | |
| 387 isolate, static_cast<DOMArrayBuffer*>(arrayBuffers[i].get()), | |
| 388 bufferHandles); | |
| 389 bool isNeuterable = true; | |
| 390 for (size_t j = 0; j < bufferHandles.size(); ++j) | |
|
haraken
2016/10/19 09:49:28
Ditto.
nhiroki
2016/10/20 07:44:02
Done.
| |
| 391 isNeuterable &= bufferHandles[j]->IsNeuterable(); | |
| 392 | |
| 393 DOMArrayBufferBase* toTransfer = arrayBuffers[i]; | |
| 394 if (!isNeuterable) { | |
| 395 toTransfer = | |
| 396 DOMArrayBuffer::create(arrayBuffers[i]->buffer()->data(), | |
| 397 arrayBuffers[i]->buffer()->byteLength()); | |
| 398 } | |
| 399 bool result = toTransfer->transfer(contents->at(i)); | |
| 400 if (!result) { | |
| 401 exceptionState.throwDOMException( | |
| 402 DataCloneError, "ArrayBuffer at index " + String::number(i) + | |
| 403 " could not be transferred."); | |
| 404 return nullptr; | |
| 405 } | |
| 406 | |
| 407 if (isNeuterable) | |
| 408 for (size_t j = 0; j < bufferHandles.size(); ++j) | |
|
haraken
2016/10/19 09:49:28
Ditto.
nhiroki
2016/10/20 07:44:02
Done.
| |
| 409 bufferHandles[j]->Neuter(); | |
| 410 } | |
| 411 } | |
| 412 return contents; | |
| 413 } | |
| 414 | |
| 405 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() { | 415 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() { |
| 406 if (m_externallyAllocatedMemory) | 416 if (m_externallyAllocatedMemory) |
| 407 return; | 417 return; |
| 408 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); | 418 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); |
| 409 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( | 419 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( |
| 410 m_externallyAllocatedMemory); | 420 m_externallyAllocatedMemory); |
| 411 } | 421 } |
| 412 | 422 |
| 413 bool SerializedScriptValue::containsTransferableArrayBuffer() const { | |
| 414 return m_arrayBufferContentsArray && !m_arrayBufferContentsArray->isEmpty(); | |
| 415 } | |
| 416 | |
| 417 } // namespace blink | 423 } // namespace blink |
| OLD | NEW |