| 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 18 matching lines...) Expand all Loading... |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "bindings/core/v8/SerializedScriptValue.h" | 31 #include "bindings/core/v8/SerializedScriptValue.h" |
| 32 | 32 |
| 33 #include "bindings/core/v8/DOMDataStore.h" | 33 #include "bindings/core/v8/DOMDataStore.h" |
| 34 #include "bindings/core/v8/DOMWrapperWorld.h" | 34 #include "bindings/core/v8/DOMWrapperWorld.h" |
| 35 #include "bindings/core/v8/ExceptionState.h" | 35 #include "bindings/core/v8/ExceptionState.h" |
| 36 #include "bindings/core/v8/ScriptState.h" | 36 #include "bindings/core/v8/ScriptState.h" |
| 37 #include "bindings/core/v8/ScriptValueSerializer.h" | 37 #include "bindings/core/v8/ScriptValueSerializer.h" |
| 38 #include "bindings/core/v8/SerializedScriptValueFactory.h" | 38 #include "bindings/core/v8/SerializedScriptValueFactory.h" |
| 39 #include "bindings/core/v8/TransferableArrayBuffer.h" | 39 #include "bindings/core/v8/Transferables.h" |
| 40 #include "bindings/core/v8/TransferableImageBitmap.h" | |
| 41 #include "bindings/core/v8/TransferableMessagePort.h" | |
| 42 #include "bindings/core/v8/V8ArrayBuffer.h" | 40 #include "bindings/core/v8/V8ArrayBuffer.h" |
| 43 #include "bindings/core/v8/V8ImageBitmap.h" | 41 #include "bindings/core/v8/V8ImageBitmap.h" |
| 44 #include "bindings/core/v8/V8MessagePort.h" | 42 #include "bindings/core/v8/V8MessagePort.h" |
| 45 #include "bindings/core/v8/V8SharedArrayBuffer.h" | 43 #include "bindings/core/v8/V8SharedArrayBuffer.h" |
| 44 #include "core/dom/DOMArrayBuffer.h" |
| 45 #include "core/dom/DOMSharedArrayBuffer.h" |
| 46 #include "core/dom/ExceptionCode.h" | 46 #include "core/dom/ExceptionCode.h" |
| 47 #include "core/dom/MessagePort.h" |
| 48 #include "core/frame/ImageBitmap.h" |
| 47 #include "platform/SharedBuffer.h" | 49 #include "platform/SharedBuffer.h" |
| 48 #include "platform/blob/BlobData.h" | 50 #include "platform/blob/BlobData.h" |
| 49 #include "platform/heap/Handle.h" | 51 #include "platform/heap/Handle.h" |
| 50 #include "wtf/Assertions.h" | 52 #include "wtf/Assertions.h" |
| 51 #include "wtf/ByteOrder.h" | 53 #include "wtf/ByteOrder.h" |
| 52 #include "wtf/Vector.h" | 54 #include "wtf/Vector.h" |
| 53 #include "wtf/text/StringBuffer.h" | 55 #include "wtf/text/StringBuffer.h" |
| 54 #include "wtf/text/StringHash.h" | 56 #include "wtf/text/StringHash.h" |
| 55 | 57 |
| 56 namespace blink { | 58 namespace blink { |
| 57 | 59 |
| 60 SerializedScriptValue::SerializedScriptValue() |
| 61 : m_externallyAllocatedMemory(0) |
| 62 { |
| 63 } |
| 64 |
| 65 SerializedScriptValue::~SerializedScriptValue() |
| 66 { |
| 67 // If the allocated memory was not registered before, then this class is lik
ely |
| 68 // used in a context other than Worker's onmessage environment and the prese
nce of |
| 69 // current v8 context is not guaranteed. Avoid calling v8 then. |
| 70 if (m_externallyAllocatedMemory) { |
| 71 ASSERT(v8::Isolate::GetCurrent()); |
| 72 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte
rnallyAllocatedMemory); |
| 73 } |
| 74 } |
| 75 |
| 58 PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue() | 76 PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue() |
| 59 { | 77 { |
| 60 SerializedScriptValueWriter writer; | 78 SerializedScriptValueWriter writer; |
| 61 writer.writeNull(); | 79 writer.writeNull(); |
| 62 String wireData = writer.takeWireString(); | 80 String wireData = writer.takeWireString(); |
| 63 return adoptRef(new SerializedScriptValue(wireData)); | 81 return adoptRef(new SerializedScriptValue(wireData)); |
| 64 } | 82 } |
| 65 | 83 |
| 66 // Convert serialized string to big endian wire data. | 84 // Convert serialized string to big endian wire data. |
| 67 void SerializedScriptValue::toWireBytes(Vector<char>& result) const | 85 void SerializedScriptValue::toWireBytes(Vector<char>& result) const |
| 68 { | 86 { |
| 69 ASSERT(result.isEmpty()); | 87 ASSERT(result.isEmpty()); |
| 70 size_t length = m_data.length(); | 88 size_t length = m_data.length(); |
| 71 result.resize(length * sizeof(UChar)); | 89 result.resize(length * sizeof(UChar)); |
| 72 UChar* dst = reinterpret_cast<UChar*>(result.data()); | 90 UChar* dst = reinterpret_cast<UChar*>(result.data()); |
| 73 | 91 |
| 74 if (m_data.is8Bit()) { | 92 if (m_data.is8Bit()) { |
| 75 const LChar* src = m_data.characters8(); | 93 const LChar* src = m_data.characters8(); |
| 76 for (size_t i = 0; i < length; i++) | 94 for (size_t i = 0; i < length; i++) |
| 77 dst[i] = htons(static_cast<UChar>(src[i])); | 95 dst[i] = htons(static_cast<UChar>(src[i])); |
| 78 } else { | 96 } else { |
| 79 const UChar* src = m_data.characters16(); | 97 const UChar* src = m_data.characters16(); |
| 80 for (size_t i = 0; i < length; i++) | 98 for (size_t i = 0; i < length; i++) |
| 81 dst[i] = htons(src[i]); | 99 dst[i] = htons(src[i]); |
| 82 } | 100 } |
| 83 } | 101 } |
| 84 | 102 |
| 85 SerializedScriptValue::SerializedScriptValue() | |
| 86 : m_externallyAllocatedMemory(0) | |
| 87 { | |
| 88 } | |
| 89 | |
| 90 static void acculumateArrayBuffersForAllWorlds(v8::Isolate* isolate, DOMArrayBuf
fer* object, Vector<v8::Local<v8::ArrayBuffer>, 4>& buffers) | 103 static void acculumateArrayBuffersForAllWorlds(v8::Isolate* isolate, DOMArrayBuf
fer* object, Vector<v8::Local<v8::ArrayBuffer>, 4>& buffers) |
| 91 { | 104 { |
| 92 if (isMainThread()) { | 105 if (isMainThread()) { |
| 93 Vector<RefPtr<DOMWrapperWorld>> worlds; | 106 Vector<RefPtr<DOMWrapperWorld>> worlds; |
| 94 DOMWrapperWorld::allWorldsInMainThread(worlds); | 107 DOMWrapperWorld::allWorldsInMainThread(worlds); |
| 95 for (size_t i = 0; i < worlds.size(); i++) { | 108 for (size_t i = 0; i < worlds.size(); i++) { |
| 96 v8::Local<v8::Object> wrapper = worlds[i]->domDataStore().get(object
, isolate); | 109 v8::Local<v8::Object> wrapper = worlds[i]->domDataStore().get(object
, isolate); |
| 97 if (!wrapper.IsEmpty()) | 110 if (!wrapper.IsEmpty()) |
| 98 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); | 111 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); |
| 99 } | 112 } |
| 100 } else { | 113 } else { |
| 101 v8::Local<v8::Object> wrapper = DOMWrapperWorld::current(isolate).domDat
aStore().get(object, isolate); | 114 v8::Local<v8::Object> wrapper = DOMWrapperWorld::current(isolate).domDat
aStore().get(object, isolate); |
| 102 if (!wrapper.IsEmpty()) | 115 if (!wrapper.IsEmpty()) |
| 103 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); | 116 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); |
| 104 } | 117 } |
| 105 } | 118 } |
| 106 | 119 |
| 107 PassOwnPtr<SerializedScriptValue::ImageBitmapContentsArray> SerializedScriptValu
e::createImageBitmaps(v8::Isolate* isolate, TransferableImageBitmap* transferabl
eImageBitmaps, ExceptionState& exceptionState) | 120 void SerializedScriptValue::transferImageBitmaps(v8::Isolate* isolate, const Ima
geBitmapArray& imageBitmaps, ExceptionState& exceptionState) |
| 108 { | 121 { |
| 109 HeapVector<Member<ImageBitmap>, 1> imageBitmaps = transferableImageBitmaps->
getArray(); | 122 if (!imageBitmaps.size()) |
| 110 ASSERT(imageBitmaps.size()); | 123 return; |
| 111 | 124 |
| 112 for (size_t i = 0; i < imageBitmaps.size(); i++) { | 125 for (size_t i = 0; i < imageBitmaps.size(); ++i) { |
| 113 if (imageBitmaps[i]->isNeutered()) { | 126 if (imageBitmaps[i]->isNeutered()) { |
| 114 exceptionState.throwDOMException(DataCloneError, "ImageBitmap at ind
ex " + String::number(i) + " is already neutered."); | 127 exceptionState.throwDOMException(DataCloneError, "ImageBitmap at ind
ex " + String::number(i) + " is already neutered."); |
| 115 return nullptr; | 128 return; |
| 116 } | 129 } |
| 117 } | 130 } |
| 118 | 131 |
| 119 OwnPtr<ImageBitmapContentsArray> contents = adoptPtr(new ImageBitmapContents
Array); | 132 OwnPtr<ImageBitmapContentsArray> contents = adoptPtr(new ImageBitmapContents
Array); |
| 120 HeapHashSet<Member<ImageBitmap>> visited; | 133 HeapHashSet<Member<ImageBitmap>> visited; |
| 121 for (size_t i = 0; i < imageBitmaps.size(); i++) { | 134 for (size_t i = 0; i < imageBitmaps.size(); ++i) { |
| 122 if (visited.contains(imageBitmaps[i].get())) | 135 if (visited.contains(imageBitmaps[i])) |
| 123 continue; | 136 continue; |
| 124 visited.add(imageBitmaps[i].get()); | 137 visited.add(imageBitmaps[i]); |
| 125 contents->append(imageBitmaps[i]->transfer()); | 138 contents->append(imageBitmaps[i]->transfer()); |
| 126 } | 139 } |
| 127 return contents.release(); | 140 m_imageBitmapContentsArray = contents.release(); |
| 128 } | 141 } |
| 129 | 142 |
| 130 | 143 |
| 131 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu
e::createArrayBuffers(v8::Isolate* isolate, TransferableArrayBuffer* transferabl
eArrayBuffers, ExceptionState& exceptionState) | 144 void SerializedScriptValue::transferArrayBuffers(v8::Isolate* isolate, const Arr
ayBufferArray& arrayBuffers, ExceptionState& exceptionState) |
| 132 { | 145 { |
| 133 HeapVector<Member<DOMArrayBufferBase>, 1> arrayBuffers = transferableArrayBu
ffers->getArray(); | 146 if (!arrayBuffers.size()) |
| 134 ASSERT(arrayBuffers.size()); | 147 return; |
| 135 | 148 |
| 136 for (size_t i = 0; i < arrayBuffers.size(); i++) { | 149 for (size_t i = 0; i < arrayBuffers.size(); ++i) { |
| 137 if (arrayBuffers[i]->isNeutered()) { | 150 if (arrayBuffers[i]->isNeutered()) { |
| 138 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind
ex " + String::number(i) + " is already neutered."); | 151 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind
ex " + String::number(i) + " is already neutered."); |
| 139 return nullptr; | 152 return; |
| 140 } | 153 } |
| 141 } | 154 } |
| 142 | 155 |
| 143 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents
Array(arrayBuffers.size())); | 156 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents
Array(arrayBuffers.size())); |
| 144 | 157 |
| 145 HeapHashSet<Member<DOMArrayBufferBase>> visited; | 158 HeapHashSet<Member<DOMArrayBufferBase>> visited; |
| 146 for (size_t i = 0; i < arrayBuffers.size(); i++) { | 159 for (size_t i = 0; i < arrayBuffers.size(); ++i) { |
| 147 if (visited.contains(arrayBuffers[i].get())) | 160 if (visited.contains(arrayBuffers[i])) |
| 148 continue; | 161 continue; |
| 149 visited.add(arrayBuffers[i].get()); | 162 visited.add(arrayBuffers[i]); |
| 150 | 163 |
| 151 if (arrayBuffers[i]->isShared()) { | 164 if (arrayBuffers[i]->isShared()) { |
| 152 bool result = arrayBuffers[i]->shareContentsWith(contents->at(i)); | 165 bool result = arrayBuffers[i]->shareContentsWith(contents->at(i)); |
| 153 if (!result) { | 166 if (!result) { |
| 154 exceptionState.throwDOMException(DataCloneError, "SharedArrayBuf
fer at index " + String::number(i) + " could not be transferred."); | 167 exceptionState.throwDOMException(DataCloneError, "SharedArrayBuf
fer at index " + String::number(i) + " could not be transferred."); |
| 155 return nullptr; | 168 return; |
| 156 } | 169 } |
| 157 } else { | 170 } else { |
| 158 Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles; | 171 Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles; |
| 159 v8::HandleScope handleScope(isolate); | 172 v8::HandleScope handleScope(isolate); |
| 160 acculumateArrayBuffersForAllWorlds(isolate, static_cast<DOMArrayBuff
er*>(arrayBuffers[i].get()), bufferHandles); | 173 acculumateArrayBuffersForAllWorlds(isolate, static_cast<DOMArrayBuff
er*>(arrayBuffers[i].get()), bufferHandles); |
| 161 bool isNeuterable = true; | 174 bool isNeuterable = true; |
| 162 for (size_t j = 0; j < bufferHandles.size(); j++) | 175 for (size_t j = 0; j < bufferHandles.size(); ++j) |
| 163 isNeuterable &= bufferHandles[j]->IsNeuterable(); | 176 isNeuterable &= bufferHandles[j]->IsNeuterable(); |
| 164 | 177 |
| 165 DOMArrayBufferBase* toTransfer = arrayBuffers[i]; | 178 DOMArrayBufferBase* toTransfer = arrayBuffers[i]; |
| 166 if (!isNeuterable) | 179 if (!isNeuterable) |
| 167 toTransfer = DOMArrayBuffer::create(arrayBuffers[i]->buffer()); | 180 toTransfer = DOMArrayBuffer::create(arrayBuffers[i]->buffer()); |
| 168 bool result = toTransfer->transfer(contents->at(i)); | 181 bool result = toTransfer->transfer(contents->at(i)); |
| 169 if (!result) { | 182 if (!result) { |
| 170 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at
index " + String::number(i) + " could not be transferred."); | 183 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at
index " + String::number(i) + " could not be transferred."); |
| 171 return nullptr; | 184 return; |
| 172 } | 185 } |
| 173 | 186 |
| 174 if (isNeuterable) | 187 if (isNeuterable) |
| 175 for (size_t j = 0; j < bufferHandles.size(); j++) | 188 for (size_t j = 0; j < bufferHandles.size(); ++j) |
| 176 bufferHandles[j]->Neuter(); | 189 bufferHandles[j]->Neuter(); |
| 177 } | 190 } |
| 178 | 191 |
| 179 } | 192 } |
| 180 | 193 m_arrayBufferContentsArray = contents.release(); |
| 181 return contents.release(); | |
| 182 } | 194 } |
| 183 | 195 |
| 184 SerializedScriptValue::SerializedScriptValue(const String& wireData) | 196 SerializedScriptValue::SerializedScriptValue(const String& wireData) |
| 185 : m_externallyAllocatedMemory(0) | 197 : m_externallyAllocatedMemory(0) |
| 186 { | 198 { |
| 187 m_data = wireData.isolatedCopy(); | 199 m_data = wireData.isolatedCopy(); |
| 188 } | 200 } |
| 189 | 201 |
| 190 v8::Local<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messag
ePorts) | 202 v8::Local<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messag
ePorts) |
| 191 { | 203 { |
| 192 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0); | 204 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0); |
| 193 } | 205 } |
| 194 | 206 |
| 195 v8::Local<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, Me
ssagePortArray* messagePorts, const WebBlobInfoArray* blobInfo) | 207 v8::Local<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, Me
ssagePortArray* messagePorts, const WebBlobInfoArray* blobInfo) |
| 196 { | 208 { |
| 197 return SerializedScriptValueFactory::instance().deserialize(this, isolate, m
essagePorts, blobInfo); | 209 return SerializedScriptValueFactory::instance().deserialize(this, isolate, m
essagePorts, blobInfo); |
| 198 } | 210 } |
| 199 | 211 |
| 200 bool SerializedScriptValue::extractTransferables(v8::Isolate* isolate, v8::Local
<v8::Value> value, int argumentIndex, TransferableArray& transferables, Exceptio
nState& exceptionState) | 212 bool SerializedScriptValue::extractTransferables(v8::Isolate* isolate, v8::Local
<v8::Value> value, int argumentIndex, Transferables& transferables, ExceptionSta
te& exceptionState) |
| 201 { | 213 { |
| 202 if (isUndefinedOrNull(value)) { | 214 if (isUndefinedOrNull(value)) |
| 203 transferables.resize(0); | |
| 204 return true; | 215 return true; |
| 205 } | |
| 206 | 216 |
| 207 uint32_t length = 0; | 217 uint32_t length = 0; |
| 208 if (value->IsArray()) { | 218 if (value->IsArray()) { |
| 209 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value); | 219 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value); |
| 210 length = array->Length(); | 220 length = array->Length(); |
| 211 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { | 221 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
| 212 if (!exceptionState.hadException()) | 222 if (!exceptionState.hadException()) |
| 213 exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgum
entOrValue(argumentIndex + 1)); | 223 exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgum
entOrValue(argumentIndex + 1)); |
| 214 return false; | 224 return false; |
| 215 } | 225 } |
| 216 | 226 |
| 217 v8::Local<v8::Object> transferrables = v8::Local<v8::Object>::Cast(value); | 227 v8::Local<v8::Object> transferableArray = v8::Local<v8::Object>::Cast(value)
; |
| 218 | 228 |
| 219 // Validate the passed array of transferrables. | 229 // Validate the passed array of transferables. |
| 220 for (unsigned i = 0; i < length; ++i) { | 230 for (unsigned i = 0; i < length; ++i) { |
| 221 v8::Local<v8::Value> transferrable; | 231 v8::Local<v8::Value> transferableObject; |
| 222 if (!transferrables->Get(isolate->GetCurrentContext(), i).ToLocal(&trans
ferrable)) | 232 if (!transferableArray->Get(isolate->GetCurrentContext(), i).ToLocal(&tr
ansferableObject)) |
| 223 return false; | 233 return false; |
| 224 // Validation of non-null objects, per HTML5 spec 10.3.3. | 234 // Validation of non-null objects, per HTML5 spec 10.3.3. |
| 225 if (isUndefinedOrNull(transferrable)) { | 235 if (isUndefinedOrNull(transferableObject)) { |
| 226 exceptionState.throwTypeError("Value at index " + String::number(i)
+ " is an untransferable " + (transferrable->IsUndefined() ? "'undefined'" : "'n
ull'") + " value."); | 236 exceptionState.throwTypeError("Value at index " + String::number(i)
+ " is an untransferable " + (transferableObject->IsUndefined() ? "'undefined'"
: "'null'") + " value."); |
| 227 return false; | 237 return false; |
| 228 } | 238 } |
| 229 // Validation of Objects implementing an interface, per WebIDL spec 4.1.
15. | 239 // Validation of Objects implementing an interface, per WebIDL spec 4.1.
15. |
| 230 if (V8MessagePort::hasInstance(transferrable, isolate)) { | 240 if (V8MessagePort::hasInstance(transferableObject, isolate)) { |
| 231 MessagePort* port = V8MessagePort::toImpl(v8::Local<v8::Object>::Cas
t(transferrable)); | 241 MessagePort* port = V8MessagePort::toImpl(v8::Local<v8::Object>::Cas
t(transferableObject)); |
| 232 TransferableMessagePort* ports = TransferableMessagePort::ensure(tra
nsferables); | |
| 233 // Check for duplicate MessagePorts. | 242 // Check for duplicate MessagePorts. |
| 234 if (ports->contains(port)) { | 243 if (transferables.messagePorts.contains(port)) { |
| 235 exceptionState.throwDOMException(DataCloneError, "Message port a
t index " + String::number(i) + " is a duplicate of an earlier port."); | 244 exceptionState.throwDOMException(DataCloneError, "Message port a
t index " + String::number(i) + " is a duplicate of an earlier port."); |
| 236 return false; | 245 return false; |
| 237 } | 246 } |
| 238 ports->append(port); | 247 transferables.messagePorts.append(port); |
| 239 } else if (V8ArrayBuffer::hasInstance(transferrable, isolate)) { | 248 } else if (V8ArrayBuffer::hasInstance(transferableObject, isolate)) { |
| 240 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(v8::Local<v8::Ob
ject>::Cast(transferrable)); | 249 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(v8::Local<v8::Ob
ject>::Cast(transferableObject)); |
| 241 TransferableArrayBuffer* arrayBuffers = TransferableArrayBuffer::ens
ure(transferables); | 250 if (transferables.arrayBuffers.contains(arrayBuffer)) { |
| 242 if (arrayBuffers->contains(arrayBuffer)) { | |
| 243 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at
index " + String::number(i) + " is a duplicate of an earlier ArrayBuffer."); | 251 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at
index " + String::number(i) + " is a duplicate of an earlier ArrayBuffer."); |
| 244 return false; | 252 return false; |
| 245 } | 253 } |
| 246 arrayBuffers->append(arrayBuffer); | 254 transferables.arrayBuffers.append(arrayBuffer); |
| 247 } else if (V8SharedArrayBuffer::hasInstance(transferrable, isolate)) { | 255 } else if (V8SharedArrayBuffer::hasInstance(transferableObject, isolate)
) { |
| 248 DOMSharedArrayBuffer* sharedArrayBuffer = V8SharedArrayBuffer::toImp
l(v8::Local<v8::Object>::Cast(transferrable)); | 256 DOMSharedArrayBuffer* sharedArrayBuffer = V8SharedArrayBuffer::toImp
l(v8::Local<v8::Object>::Cast(transferableObject)); |
| 249 TransferableArrayBuffer* arrayBuffers = TransferableArrayBuffer::ens
ure(transferables); | 257 if (transferables.arrayBuffers.contains(sharedArrayBuffer)) { |
| 250 if (arrayBuffers->contains(sharedArrayBuffer)) { | |
| 251 exceptionState.throwDOMException(DataCloneError, "SharedArrayBuf
fer at index " + String::number(i) + " is a duplicate of an earlier SharedArrayB
uffer."); | 258 exceptionState.throwDOMException(DataCloneError, "SharedArrayBuf
fer at index " + String::number(i) + " is a duplicate of an earlier SharedArrayB
uffer."); |
| 252 return false; | 259 return false; |
| 253 } | 260 } |
| 254 arrayBuffers->append(sharedArrayBuffer); | 261 transferables.arrayBuffers.append(sharedArrayBuffer); |
| 255 } else if (V8ImageBitmap::hasInstance(transferrable, isolate)) { | 262 } else if (V8ImageBitmap::hasInstance(transferableObject, isolate)) { |
| 256 ImageBitmap* imageBitmap = V8ImageBitmap::toImpl(v8::Local<v8::Objec
t>::Cast(transferrable)); | 263 ImageBitmap* imageBitmap = V8ImageBitmap::toImpl(v8::Local<v8::Objec
t>::Cast(transferableObject)); |
| 257 TransferableImageBitmap* imageBitmaps = TransferableImageBitmap::ens
ure(transferables); | 264 if (transferables.imageBitmaps.contains(imageBitmap)) { |
| 258 if (imageBitmaps->contains(imageBitmap)) { | |
| 259 exceptionState.throwDOMException(DataCloneError, "ImageBitmap at
index " + String::number(i) + " is a duplicate of an earlier ImageBitmap."); | 265 exceptionState.throwDOMException(DataCloneError, "ImageBitmap at
index " + String::number(i) + " is a duplicate of an earlier ImageBitmap."); |
| 260 return false; | 266 return false; |
| 261 } | 267 } |
| 262 imageBitmaps->append(imageBitmap); | 268 transferables.imageBitmaps.append(imageBitmap); |
| 263 } else { | 269 } else { |
| 264 exceptionState.throwTypeError("Value at index " + String::number(i)
+ " does not have a transferable type."); | 270 exceptionState.throwTypeError("Value at index " + String::number(i)
+ " does not have a transferable type."); |
| 265 return false; | 271 return false; |
| 266 } | 272 } |
| 267 } | 273 } |
| 268 return true; | 274 return true; |
| 269 } | 275 } |
| 270 | 276 |
| 271 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() | 277 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() |
| 272 { | 278 { |
| 273 if (m_externallyAllocatedMemory) | 279 if (m_externallyAllocatedMemory) |
| 274 return; | 280 return; |
| 275 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); | 281 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); |
| 276 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externall
yAllocatedMemory); | 282 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externall
yAllocatedMemory); |
| 277 } | 283 } |
| 278 | 284 |
| 279 bool SerializedScriptValue::containsTransferableArrayBuffer() const | 285 bool SerializedScriptValue::containsTransferableArrayBuffer() const |
| 280 { | 286 { |
| 281 return m_arrayBufferContentsArray && !m_arrayBufferContentsArray->isEmpty(); | 287 return m_arrayBufferContentsArray && !m_arrayBufferContentsArray->isEmpty(); |
| 282 } | 288 } |
| 283 | 289 |
| 284 SerializedScriptValue::~SerializedScriptValue() | |
| 285 { | |
| 286 // If the allocated memory was not registered before, then this class is lik
ely | |
| 287 // used in a context other then Worker's onmessage environment and the prese
nce of | |
| 288 // current v8 context is not guaranteed. Avoid calling v8 then. | |
| 289 if (m_externallyAllocatedMemory) { | |
| 290 ASSERT(v8::Isolate::GetCurrent()); | |
| 291 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte
rnallyAllocatedMemory); | |
| 292 } | |
| 293 } | |
| 294 | |
| 295 void SerializedScriptValue::transferArrayBuffers(v8::Isolate* isolate, Transfera
bleArrayBuffer* transferableArrayBuffers, ExceptionState& exceptionState) | |
| 296 { | |
| 297 m_arrayBufferContentsArray = createArrayBuffers(isolate, transferableArrayBu
ffers, exceptionState); | |
| 298 } | |
| 299 | |
| 300 void SerializedScriptValue::transferImageBitmaps(v8::Isolate* isolate, Transfera
bleImageBitmap* transferableImageBitmaps, ExceptionState& exceptionState) | |
| 301 { | |
| 302 m_imageBitmapContentsArray = createImageBitmaps(isolate, transferableImageBi
tmaps, exceptionState); | |
| 303 } | |
| 304 | |
| 305 } // namespace blink | 290 } // namespace blink |
| OLD | NEW |