| 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 |