| 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 16 matching lines...) Expand all Loading... |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "bindings/core/v8/SerializedScriptValue.h" | 32 #include "bindings/core/v8/SerializedScriptValue.h" |
| 33 | 33 |
| 34 #include "bindings/core/v8/ExceptionState.h" | 34 #include "bindings/core/v8/ExceptionState.h" |
| 35 #include "bindings/core/v8/V8Binding.h" | 35 #include "bindings/core/v8/V8Binding.h" |
| 36 #include "bindings/core/v8/V8ImageData.h" | 36 #include "bindings/core/v8/V8ImageData.h" |
| 37 #include "bindings/core/v8/V8MessagePort.h" | |
| 38 #include "bindings/core/v8/custom/V8ArrayBufferCustom.h" | 37 #include "bindings/core/v8/custom/V8ArrayBufferCustom.h" |
| 39 #include "bindings/core/v8/custom/V8ArrayBufferViewCustom.h" | 38 #include "bindings/core/v8/custom/V8ArrayBufferViewCustom.h" |
| 40 #include "bindings/core/v8/custom/V8DataViewCustom.h" | 39 #include "bindings/core/v8/custom/V8DataViewCustom.h" |
| 41 #include "bindings/core/v8/custom/V8Float32ArrayCustom.h" | 40 #include "bindings/core/v8/custom/V8Float32ArrayCustom.h" |
| 42 #include "bindings/core/v8/custom/V8Float64ArrayCustom.h" | 41 #include "bindings/core/v8/custom/V8Float64ArrayCustom.h" |
| 43 #include "bindings/core/v8/custom/V8Int16ArrayCustom.h" | 42 #include "bindings/core/v8/custom/V8Int16ArrayCustom.h" |
| 44 #include "bindings/core/v8/custom/V8Int32ArrayCustom.h" | 43 #include "bindings/core/v8/custom/V8Int32ArrayCustom.h" |
| 45 #include "bindings/core/v8/custom/V8Int8ArrayCustom.h" | 44 #include "bindings/core/v8/custom/V8Int8ArrayCustom.h" |
| 46 #include "bindings/core/v8/custom/V8Uint16ArrayCustom.h" | 45 #include "bindings/core/v8/custom/V8Uint16ArrayCustom.h" |
| 47 #include "bindings/core/v8/custom/V8Uint32ArrayCustom.h" | 46 #include "bindings/core/v8/custom/V8Uint32ArrayCustom.h" |
| 48 #include "bindings/core/v8/custom/V8Uint8ArrayCustom.h" | 47 #include "bindings/core/v8/custom/V8Uint8ArrayCustom.h" |
| 49 #include "bindings/core/v8/custom/V8Uint8ClampedArrayCustom.h" | 48 #include "bindings/core/v8/custom/V8Uint8ClampedArrayCustom.h" |
| 50 #include "core/dom/ExceptionCode.h" | 49 #include "core/dom/ExceptionCode.h" |
| 51 #include "core/dom/MessagePort.h" | |
| 52 #include "core/html/ImageData.h" | 50 #include "core/html/ImageData.h" |
| 53 #include "core/html/canvas/DataView.h" | 51 #include "core/html/canvas/DataView.h" |
| 54 #include "platform/SharedBuffer.h" | 52 #include "platform/SharedBuffer.h" |
| 55 #include "platform/heap/Handle.h" | 53 #include "platform/heap/Handle.h" |
| 56 #include "public/platform/Platform.h" | 54 #include "public/platform/Platform.h" |
| 57 #include "wtf/ArrayBuffer.h" | 55 #include "wtf/ArrayBuffer.h" |
| 58 #include "wtf/ArrayBufferContents.h" | 56 #include "wtf/ArrayBufferContents.h" |
| 59 #include "wtf/ArrayBufferView.h" | 57 #include "wtf/ArrayBufferView.h" |
| 60 #include "wtf/Assertions.h" | 58 #include "wtf/Assertions.h" |
| 61 #include "wtf/ByteOrder.h" | 59 #include "wtf/ByteOrder.h" |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 PaddingTag = '\0', // Is ignored (but consumed). | 174 PaddingTag = '\0', // Is ignored (but consumed). |
| 177 UndefinedTag = '_', // -> <undefined> | 175 UndefinedTag = '_', // -> <undefined> |
| 178 NullTag = '0', // -> <null> | 176 NullTag = '0', // -> <null> |
| 179 TrueTag = 'T', // -> <true> | 177 TrueTag = 'T', // -> <true> |
| 180 FalseTag = 'F', // -> <false> | 178 FalseTag = 'F', // -> <false> |
| 181 StringTag = 'S', // string:RawString -> string | 179 StringTag = 'S', // string:RawString -> string |
| 182 StringUCharTag = 'c', // string:RawUCharString -> string | 180 StringUCharTag = 'c', // string:RawUCharString -> string |
| 183 Int32Tag = 'I', // value:ZigZag-encoded int32 -> Integer | 181 Int32Tag = 'I', // value:ZigZag-encoded int32 -> Integer |
| 184 Uint32Tag = 'U', // value:uint32_t -> Integer | 182 Uint32Tag = 'U', // value:uint32_t -> Integer |
| 185 DateTag = 'D', // value:double -> Date (ref) | 183 DateTag = 'D', // value:double -> Date (ref) |
| 186 MessagePortTag = 'M', // index:int -> MessagePort. Fills the result with tra
nsferred MessagePort. | |
| 187 NumberTag = 'N', // value:double -> Number | 184 NumberTag = 'N', // value:double -> Number |
| 188 ImageDataTag = '#', // width:uint32_t, height:uint32_t, pixelDataLength:uint
32_t, data:byte[pixelDataLength] -> ImageData (ref) | 185 ImageDataTag = '#', // width:uint32_t, height:uint32_t, pixelDataLength:uint
32_t, data:byte[pixelDataLength] -> ImageData (ref) |
| 189 ObjectTag = '{', // numProperties:uint32_t -> pops the last object from the
open stack; | 186 ObjectTag = '{', // numProperties:uint32_t -> pops the last object from the
open stack; |
| 190 // fills it with the last numProp
erties name,value pairs pushed onto the deserialization stack | 187 // fills it with the last numProp
erties name,value pairs pushed onto the deserialization stack |
| 191 SparseArrayTag = '@', // numProperties:uint32_t, length:uint32_t -> pops the
last object from the open stack; | 188 SparseArrayTag = '@', // numProperties:uint32_t, length:uint32_t -> pops the
last object from the open stack; |
| 192 // fills it
with the last numProperties name,value pairs pushed onto the deserialization st
ack | 189 // fills it
with the last numProperties name,value pairs pushed onto the deserialization st
ack |
| 193 DenseArrayTag = '$', // numProperties:uint32_t, length:uint32_t -> pops the
last object from the open stack; | 190 DenseArrayTag = '$', // numProperties:uint32_t, length:uint32_t -> pops the
last object from the open stack; |
| 194 // fills it
with the last length elements and numProperties name,value pairs pushed onto des
erialization stack | 191 // fills it
with the last length elements and numProperties name,value pairs pushed onto des
erialization stack |
| 195 RegExpTag = 'R', // pattern:RawString, flags:uint32_t -> RegExp (ref) | 192 RegExpTag = 'R', // pattern:RawString, flags:uint32_t -> RegExp (ref) |
| 196 ArrayBufferTag = 'B', // byteLength:uint32_t, data:byte[byteLength] -> Array
Buffer (ref) | 193 ArrayBufferTag = 'B', // byteLength:uint32_t, data:byte[byteLength] -> Array
Buffer (ref) |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 } | 427 } |
| 431 | 428 |
| 432 void writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags flags) | 429 void writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags flags) |
| 433 { | 430 { |
| 434 append(RegExpTag); | 431 append(RegExpTag); |
| 435 v8::String::Utf8Value patternUtf8Value(pattern); | 432 v8::String::Utf8Value patternUtf8Value(pattern); |
| 436 doWriteString(*patternUtf8Value, patternUtf8Value.length()); | 433 doWriteString(*patternUtf8Value, patternUtf8Value.length()); |
| 437 doWriteUint32(static_cast<uint32_t>(flags)); | 434 doWriteUint32(static_cast<uint32_t>(flags)); |
| 438 } | 435 } |
| 439 | 436 |
| 440 void writeTransferredMessagePort(uint32_t index) | |
| 441 { | |
| 442 append(MessagePortTag); | |
| 443 doWriteUint32(index); | |
| 444 } | |
| 445 | |
| 446 void writeTransferredArrayBuffer(uint32_t index) | 437 void writeTransferredArrayBuffer(uint32_t index) |
| 447 { | 438 { |
| 448 append(ArrayBufferTransferTag); | 439 append(ArrayBufferTransferTag); |
| 449 doWriteUint32(index); | 440 doWriteUint32(index); |
| 450 } | 441 } |
| 451 | 442 |
| 452 void writeObjectReference(uint32_t reference) | 443 void writeObjectReference(uint32_t reference) |
| 453 { | 444 { |
| 454 append(ObjectReferenceTag); | 445 append(ObjectReferenceTag); |
| 455 doWriteUint32(reference); | 446 doWriteUint32(reference); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 | 600 |
| 610 int v8StringWriteOptions() | 601 int v8StringWriteOptions() |
| 611 { | 602 { |
| 612 return v8::String::NO_NULL_TERMINATION; | 603 return v8::String::NO_NULL_TERMINATION; |
| 613 } | 604 } |
| 614 | 605 |
| 615 Vector<BufferValueType> m_buffer; | 606 Vector<BufferValueType> m_buffer; |
| 616 unsigned m_position; | 607 unsigned m_position; |
| 617 }; | 608 }; |
| 618 | 609 |
| 619 static v8::Handle<v8::Object> toV8Object(MessagePort* impl, v8::Handle<v8::Objec
t> creationContext, v8::Isolate* isolate) | |
| 620 { | |
| 621 if (!impl) | |
| 622 return v8::Handle<v8::Object>(); | |
| 623 v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate); | |
| 624 ASSERT(wrapper->IsObject()); | |
| 625 return wrapper.As<v8::Object>(); | |
| 626 } | |
| 627 | |
| 628 static v8::Handle<v8::ArrayBuffer> toV8Object(ArrayBuffer* impl, v8::Handle<v8::
Object> creationContext, v8::Isolate* isolate) | 610 static v8::Handle<v8::ArrayBuffer> toV8Object(ArrayBuffer* impl, v8::Handle<v8::
Object> creationContext, v8::Isolate* isolate) |
| 629 { | 611 { |
| 630 if (!impl) | 612 if (!impl) |
| 631 return v8::Handle<v8::ArrayBuffer>(); | 613 return v8::Handle<v8::ArrayBuffer>(); |
| 632 v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate); | 614 v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate); |
| 633 ASSERT(wrapper->IsArrayBuffer()); | 615 ASSERT(wrapper->IsArrayBuffer()); |
| 634 return wrapper.As<v8::ArrayBuffer>(); | 616 return wrapper.As<v8::ArrayBuffer>(); |
| 635 } | 617 } |
| 636 | 618 |
| 637 class Serializer { | 619 class Serializer { |
| 638 class StateBase; | 620 class StateBase; |
| 639 public: | 621 public: |
| 640 enum Status { | 622 enum Status { |
| 641 Success, | 623 Success, |
| 642 InputError, | 624 InputError, |
| 643 DataCloneError, | 625 DataCloneError, |
| 644 JSException | 626 JSException |
| 645 }; | 627 }; |
| 646 | 628 |
| 647 Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray*
arrayBuffers, v8::TryCatch& tryCatch, ScriptState* scriptState) | 629 Serializer(Writer& writer, ArrayBufferArray* arrayBuffers, v8::TryCatch& try
Catch, ScriptState* scriptState) |
| 648 : m_scriptState(scriptState) | 630 : m_scriptState(scriptState) |
| 649 , m_writer(writer) | 631 , m_writer(writer) |
| 650 , m_tryCatch(tryCatch) | 632 , m_tryCatch(tryCatch) |
| 651 , m_depth(0) | 633 , m_depth(0) |
| 652 , m_status(Success) | 634 , m_status(Success) |
| 653 , m_nextObjectReference(0) | 635 , m_nextObjectReference(0) |
| 654 { | 636 { |
| 655 ASSERT(!tryCatch.HasCaught()); | 637 ASSERT(!tryCatch.HasCaught()); |
| 656 v8::Handle<v8::Object> creationContext = m_scriptState->context()->Globa
l(); | 638 v8::Handle<v8::Object> creationContext = m_scriptState->context()->Globa
l(); |
| 657 if (messagePorts) { | |
| 658 for (size_t i = 0; i < messagePorts->size(); i++) | |
| 659 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get
(), creationContext, isolate()), i); | |
| 660 } | |
| 661 if (arrayBuffers) { | 639 if (arrayBuffers) { |
| 662 for (size_t i = 0; i < arrayBuffers->size(); i++) { | 640 for (size_t i = 0; i < arrayBuffers->size(); i++) { |
| 663 v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->
at(i).get(), creationContext, isolate()); | 641 v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->
at(i).get(), creationContext, isolate()); |
| 664 // Coalesce multiple occurences of the same buffer to the first
index. | 642 // Coalesce multiple occurences of the same buffer to the first
index. |
| 665 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) | 643 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) |
| 666 m_transferredArrayBuffers.set(v8ArrayBuffer, i); | 644 m_transferredArrayBuffers.set(v8ArrayBuffer, i); |
| 667 } | 645 } |
| 668 } | 646 } |
| 669 } | 647 } |
| 670 | 648 |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1097 } | 1075 } |
| 1098 | 1076 |
| 1099 RefPtr<ScriptState> m_scriptState; | 1077 RefPtr<ScriptState> m_scriptState; |
| 1100 Writer& m_writer; | 1078 Writer& m_writer; |
| 1101 v8::TryCatch& m_tryCatch; | 1079 v8::TryCatch& m_tryCatch; |
| 1102 int m_depth; | 1080 int m_depth; |
| 1103 Status m_status; | 1081 Status m_status; |
| 1104 String m_errorMessage; | 1082 String m_errorMessage; |
| 1105 typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool; | 1083 typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool; |
| 1106 ObjectPool m_objectPool; | 1084 ObjectPool m_objectPool; |
| 1107 ObjectPool m_transferredMessagePorts; | |
| 1108 ObjectPool m_transferredArrayBuffers; | 1085 ObjectPool m_transferredArrayBuffers; |
| 1109 uint32_t m_nextObjectReference; | 1086 uint32_t m_nextObjectReference; |
| 1110 }; | 1087 }; |
| 1111 | 1088 |
| 1112 // Returns true if the provided object is to be considered a 'host object', as u
sed in the | 1089 // Returns true if the provided object is to be considered a 'host object', as u
sed in the |
| 1113 // HTML5 structured clone algorithm. | 1090 // HTML5 structured clone algorithm. |
| 1114 static bool isHostObject(v8::Handle<v8::Object> object) | 1091 static bool isHostObject(v8::Handle<v8::Object> object) |
| 1115 { | 1092 { |
| 1116 // If the object has any internal fields, then we won't be able to serialize
or deserialize | 1093 // If the object has any internal fields, then we won't be able to serialize
or deserialize |
| 1117 // them; conveniently, this is also a quick way to detect DOM wrapper object
s, because | 1094 // them; conveniently, this is also a quick way to detect DOM wrapper object
s, because |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1144 } else if (value->IsInt32()) { | 1121 } else if (value->IsInt32()) { |
| 1145 m_writer.writeInt32(value->Int32Value()); | 1122 m_writer.writeInt32(value->Int32Value()); |
| 1146 } else if (value->IsUint32()) { | 1123 } else if (value->IsUint32()) { |
| 1147 m_writer.writeUint32(value->Uint32Value()); | 1124 m_writer.writeUint32(value->Uint32Value()); |
| 1148 } else if (value->IsNumber()) { | 1125 } else if (value->IsNumber()) { |
| 1149 m_writer.writeNumber(value.As<v8::Number>()->Value()); | 1126 m_writer.writeNumber(value.As<v8::Number>()->Value()); |
| 1150 } else if (V8ArrayBufferView::hasInstance(value, isolate())) { | 1127 } else if (V8ArrayBufferView::hasInstance(value, isolate())) { |
| 1151 return writeAndGreyArrayBufferView(value.As<v8::Object>(), next); | 1128 return writeAndGreyArrayBufferView(value.As<v8::Object>(), next); |
| 1152 } else if (value->IsString()) { | 1129 } else if (value->IsString()) { |
| 1153 writeString(value); | 1130 writeString(value); |
| 1154 } else if (V8MessagePort::hasInstance(value, isolate())) { | |
| 1155 uint32_t messagePortIndex; | |
| 1156 if (m_transferredMessagePorts.tryGet(value.As<v8::Object>(), &messagePor
tIndex)) { | |
| 1157 m_writer.writeTransferredMessagePort(messagePortIndex); | |
| 1158 } else { | |
| 1159 return handleError(DataCloneError, "A MessagePort could not be clone
d.", next); | |
| 1160 } | |
| 1161 } else if (V8ArrayBuffer::hasInstance(value, isolate()) && m_transferredArra
yBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex)) { | 1131 } else if (V8ArrayBuffer::hasInstance(value, isolate()) && m_transferredArra
yBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex)) { |
| 1162 return writeTransferredArrayBuffer(value, arrayBufferIndex, next); | 1132 return writeTransferredArrayBuffer(value, arrayBufferIndex, next); |
| 1163 } else { | 1133 } else { |
| 1164 v8::Handle<v8::Object> jsObject = value.As<v8::Object>(); | 1134 v8::Handle<v8::Object> jsObject = value.As<v8::Object>(); |
| 1165 if (jsObject.IsEmpty()) | 1135 if (jsObject.IsEmpty()) |
| 1166 return handleError(DataCloneError, "An object could not be cloned.",
next); | 1136 return handleError(DataCloneError, "An object could not be cloned.",
next); |
| 1167 greyObject(jsObject); | 1137 greyObject(jsObject); |
| 1168 if (value->IsDate()) { | 1138 if (value->IsDate()) { |
| 1169 m_writer.writeDate(value->NumberValue()); | 1139 m_writer.writeDate(value->NumberValue()); |
| 1170 } else if (value->IsStringObject()) { | 1140 } else if (value->IsStringObject()) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1195 // Interface used by Reader to create objects of composite types. | 1165 // Interface used by Reader to create objects of composite types. |
| 1196 class CompositeCreator { | 1166 class CompositeCreator { |
| 1197 STACK_ALLOCATED(); | 1167 STACK_ALLOCATED(); |
| 1198 public: | 1168 public: |
| 1199 virtual ~CompositeCreator() { } | 1169 virtual ~CompositeCreator() { } |
| 1200 | 1170 |
| 1201 virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0; | 1171 virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0; |
| 1202 virtual uint32_t objectReferenceCount() = 0; | 1172 virtual uint32_t objectReferenceCount() = 0; |
| 1203 virtual void pushObjectReference(const v8::Handle<v8::Value>&) = 0; | 1173 virtual void pushObjectReference(const v8::Handle<v8::Value>&) = 0; |
| 1204 virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<
v8::Value>*) = 0; | 1174 virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<
v8::Value>*) = 0; |
| 1205 virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Val
ue>*) = 0; | |
| 1206 virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Val
ue>*) = 0; | 1175 virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Val
ue>*) = 0; |
| 1207 virtual bool newSparseArray(uint32_t length) = 0; | 1176 virtual bool newSparseArray(uint32_t length) = 0; |
| 1208 virtual bool newDenseArray(uint32_t length) = 0; | 1177 virtual bool newDenseArray(uint32_t length) = 0; |
| 1209 virtual bool newObject() = 0; | 1178 virtual bool newObject() = 0; |
| 1210 virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*)
= 0; | 1179 virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*)
= 0; |
| 1211 virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8
::Handle<v8::Value>*) = 0; | 1180 virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8
::Handle<v8::Value>*) = 0; |
| 1212 virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8:
:Handle<v8::Value>*) = 0; | 1181 virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8:
:Handle<v8::Value>*) = 0; |
| 1213 }; | 1182 }; |
| 1214 | 1183 |
| 1215 // Reader is responsible for deserializing primitive types and | 1184 // Reader is responsible for deserializing primitive types and |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1390 case GenerateFreshDenseArrayTag: { | 1359 case GenerateFreshDenseArrayTag: { |
| 1391 if (!m_version) | 1360 if (!m_version) |
| 1392 return false; | 1361 return false; |
| 1393 uint32_t length; | 1362 uint32_t length; |
| 1394 if (!doReadUint32(&length)) | 1363 if (!doReadUint32(&length)) |
| 1395 return false; | 1364 return false; |
| 1396 if (!creator.newDenseArray(length)) | 1365 if (!creator.newDenseArray(length)) |
| 1397 return false; | 1366 return false; |
| 1398 return true; | 1367 return true; |
| 1399 } | 1368 } |
| 1400 case MessagePortTag: { | |
| 1401 if (!m_version) | |
| 1402 return false; | |
| 1403 uint32_t index; | |
| 1404 if (!doReadUint32(&index)) | |
| 1405 return false; | |
| 1406 if (!creator.tryGetTransferredMessagePort(index, value)) | |
| 1407 return false; | |
| 1408 break; | |
| 1409 } | |
| 1410 case ArrayBufferTransferTag: { | 1369 case ArrayBufferTransferTag: { |
| 1411 if (!m_version) | 1370 if (!m_version) |
| 1412 return false; | 1371 return false; |
| 1413 uint32_t index; | 1372 uint32_t index; |
| 1414 if (!doReadUint32(&index)) | 1373 if (!doReadUint32(&index)) |
| 1415 return false; | 1374 return false; |
| 1416 if (!creator.tryGetTransferredArrayBuffer(index, value)) | 1375 if (!creator.tryGetTransferredArrayBuffer(index, value)) |
| 1417 return false; | 1376 return false; |
| 1418 break; | 1377 break; |
| 1419 } | 1378 } |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1756 const unsigned m_length; | 1715 const unsigned m_length; |
| 1757 unsigned m_position; | 1716 unsigned m_position; |
| 1758 uint32_t m_version; | 1717 uint32_t m_version; |
| 1759 }; | 1718 }; |
| 1760 | 1719 |
| 1761 | 1720 |
| 1762 typedef Vector<WTF::ArrayBufferContents, 1> ArrayBufferContentsArray; | 1721 typedef Vector<WTF::ArrayBufferContents, 1> ArrayBufferContentsArray; |
| 1763 | 1722 |
| 1764 class Deserializer FINAL : public CompositeCreator { | 1723 class Deserializer FINAL : public CompositeCreator { |
| 1765 public: | 1724 public: |
| 1766 Deserializer(Reader& reader, MessagePortArray* messagePorts, ArrayBufferCont
entsArray* arrayBufferContents) | 1725 Deserializer(Reader& reader, ArrayBufferContentsArray* arrayBufferContents) |
| 1767 : m_reader(reader) | 1726 : m_reader(reader) |
| 1768 , m_transferredMessagePorts(messagePorts) | |
| 1769 , m_arrayBufferContents(arrayBufferContents) | 1727 , m_arrayBufferContents(arrayBufferContents) |
| 1770 , m_arrayBuffers(arrayBufferContents ? arrayBufferContents->size() : 0) | 1728 , m_arrayBuffers(arrayBufferContents ? arrayBufferContents->size() : 0) |
| 1771 , m_version(0) | 1729 , m_version(0) |
| 1772 { | 1730 { |
| 1773 } | 1731 } |
| 1774 | 1732 |
| 1775 v8::Handle<v8::Value> deserialize() | 1733 v8::Handle<v8::Value> deserialize() |
| 1776 { | 1734 { |
| 1777 v8::Isolate* isolate = m_reader.scriptState()->isolate(); | 1735 v8::Isolate* isolate = m_reader.scriptState()->isolate(); |
| 1778 if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValu
e::wireFormatVersion) | 1736 if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValu
e::wireFormatVersion) |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1875 } | 1833 } |
| 1876 pop(length); | 1834 pop(length); |
| 1877 return true; | 1835 return true; |
| 1878 } | 1836 } |
| 1879 | 1837 |
| 1880 virtual void pushObjectReference(const v8::Handle<v8::Value>& object) OVERRI
DE | 1838 virtual void pushObjectReference(const v8::Handle<v8::Value>& object) OVERRI
DE |
| 1881 { | 1839 { |
| 1882 m_objectPool.append(object); | 1840 m_objectPool.append(object); |
| 1883 } | 1841 } |
| 1884 | 1842 |
| 1885 virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Val
ue>* object) OVERRIDE | |
| 1886 { | |
| 1887 if (!m_transferredMessagePorts) | |
| 1888 return false; | |
| 1889 if (index >= m_transferredMessagePorts->size()) | |
| 1890 return false; | |
| 1891 v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context
()->Global(); | |
| 1892 *object = toV8(m_transferredMessagePorts->at(index).get(), creationConte
xt, m_reader.scriptState()->isolate()); | |
| 1893 return true; | |
| 1894 } | |
| 1895 | |
| 1896 virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Val
ue>* object) OVERRIDE | 1843 virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Val
ue>* object) OVERRIDE |
| 1897 { | 1844 { |
| 1898 if (!m_arrayBufferContents) | 1845 if (!m_arrayBufferContents) |
| 1899 return false; | 1846 return false; |
| 1900 if (index >= m_arrayBuffers.size()) | 1847 if (index >= m_arrayBuffers.size()) |
| 1901 return false; | 1848 return false; |
| 1902 v8::Handle<v8::Object> result = m_arrayBuffers.at(index); | 1849 v8::Handle<v8::Object> result = m_arrayBuffers.at(index); |
| 1903 if (result.IsEmpty()) { | 1850 if (result.IsEmpty()) { |
| 1904 RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(m_arrayBufferConten
ts->at(index)); | 1851 RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(m_arrayBufferConten
ts->at(index)); |
| 1905 buffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::i
nstanceTemplate()); | 1852 buffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::i
nstanceTemplate()); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1984 if (objectReference >= m_objectPool.size()) | 1931 if (objectReference >= m_objectPool.size()) |
| 1985 return false; | 1932 return false; |
| 1986 *object = m_objectPool[objectReference]; | 1933 *object = m_objectPool[objectReference]; |
| 1987 return true; | 1934 return true; |
| 1988 } | 1935 } |
| 1989 | 1936 |
| 1990 Reader& m_reader; | 1937 Reader& m_reader; |
| 1991 Vector<v8::Local<v8::Value> > m_stack; | 1938 Vector<v8::Local<v8::Value> > m_stack; |
| 1992 Vector<v8::Handle<v8::Value> > m_objectPool; | 1939 Vector<v8::Handle<v8::Value> > m_objectPool; |
| 1993 Vector<uint32_t> m_openCompositeReferenceStack; | 1940 Vector<uint32_t> m_openCompositeReferenceStack; |
| 1994 RawPtrWillBeMember<MessagePortArray> m_transferredMessagePorts; | |
| 1995 ArrayBufferContentsArray* m_arrayBufferContents; | 1941 ArrayBufferContentsArray* m_arrayBufferContents; |
| 1996 Vector<v8::Handle<v8::Object> > m_arrayBuffers; | 1942 Vector<v8::Handle<v8::Object> > m_arrayBuffers; |
| 1997 uint32_t m_version; | 1943 uint32_t m_version; |
| 1998 }; | 1944 }; |
| 1999 | 1945 |
| 2000 } // namespace | 1946 } // namespace |
| 2001 | 1947 |
| 2002 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::V
alue> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Exc
eptionState& exceptionState, v8::Isolate* isolate) | 1948 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::V
alue> value, ArrayBufferArray* arrayBuffers, ExceptionState& exceptionState, v8:
:Isolate* isolate) |
| 2003 { | 1949 { |
| 2004 return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers,
exceptionState, isolate)); | 1950 return adoptRef(new SerializedScriptValue(value, arrayBuffers, exceptionStat
e, isolate)); |
| 2005 } | 1951 } |
| 2006 | 1952 |
| 2007 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExcepti
ons(v8::Handle<v8::Value> value, v8::Isolate* isolate) | 1953 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExcepti
ons(v8::Handle<v8::Value> value, v8::Isolate* isolate) |
| 2008 { | 1954 { |
| 2009 TrackExceptionState exceptionState; | 1955 TrackExceptionState exceptionState; |
| 2010 return adoptRef(new SerializedScriptValue(value, 0, 0, exceptionState, isola
te)); | 1956 return adoptRef(new SerializedScriptValue(value, 0, exceptionState, isolate)
); |
| 2011 } | 1957 } |
| 2012 | 1958 |
| 2013 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValu
e& value, ExceptionState& exceptionState, v8::Isolate* isolate) | 1959 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValu
e& value, ExceptionState& exceptionState, v8::Isolate* isolate) |
| 2014 { | 1960 { |
| 2015 ASSERT(isolate->InContext()); | 1961 ASSERT(isolate->InContext()); |
| 2016 return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, exceptionSt
ate, isolate)); | 1962 return adoptRef(new SerializedScriptValue(value.v8Value(), 0, exceptionState
, isolate)); |
| 2017 } | 1963 } |
| 2018 | 1964 |
| 2019 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const St
ring& data) | 1965 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const St
ring& data) |
| 2020 { | 1966 { |
| 2021 return adoptRef(new SerializedScriptValue(data)); | 1967 return adoptRef(new SerializedScriptValue(data)); |
| 2022 } | 1968 } |
| 2023 | 1969 |
| 2024 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(con
st Vector<uint8_t>& data) | 1970 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(con
st Vector<uint8_t>& data) |
| 2025 { | 1971 { |
| 2026 // Decode wire data from big endian to host byte order. | 1972 // Decode wire data from big endian to host byte order. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2130 if (!result) { | 2076 if (!result) { |
| 2131 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind
ex " + String::number(i) + " could not be transferred."); | 2077 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind
ex " + String::number(i) + " could not be transferred."); |
| 2132 return nullptr; | 2078 return nullptr; |
| 2133 } | 2079 } |
| 2134 | 2080 |
| 2135 neuterArrayBufferInAllWorlds(arrayBuffers[i].get()); | 2081 neuterArrayBufferInAllWorlds(arrayBuffers[i].get()); |
| 2136 } | 2082 } |
| 2137 return contents.release(); | 2083 return contents.release(); |
| 2138 } | 2084 } |
| 2139 | 2085 |
| 2140 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, Messag
ePortArray* messagePorts, ArrayBufferArray* arrayBuffers, ExceptionState& except
ionState, v8::Isolate* isolate) | 2086 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, ArrayB
ufferArray* arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate) |
| 2141 : m_externallyAllocatedMemory(0) | 2087 : m_externallyAllocatedMemory(0) |
| 2142 { | 2088 { |
| 2143 Writer writer; | 2089 Writer writer; |
| 2144 Serializer::Status status; | 2090 Serializer::Status status; |
| 2145 String errorMessage; | 2091 String errorMessage; |
| 2146 { | 2092 { |
| 2147 v8::TryCatch tryCatch; | 2093 v8::TryCatch tryCatch; |
| 2148 Serializer serializer(writer, messagePorts, arrayBuffers, tryCatch, Scri
ptState::current(isolate)); | 2094 Serializer serializer(writer, arrayBuffers, tryCatch, ScriptState::curre
nt(isolate)); |
| 2149 status = serializer.serialize(value); | 2095 status = serializer.serialize(value); |
| 2150 if (status == Serializer::JSException) { | 2096 if (status == Serializer::JSException) { |
| 2151 // If there was a JS exception thrown, re-throw it. | 2097 // If there was a JS exception thrown, re-throw it. |
| 2152 exceptionState.rethrowV8Exception(tryCatch.Exception()); | 2098 exceptionState.rethrowV8Exception(tryCatch.Exception()); |
| 2153 return; | 2099 return; |
| 2154 } | 2100 } |
| 2155 errorMessage = serializer.errorMessage(); | 2101 errorMessage = serializer.errorMessage(); |
| 2156 } | 2102 } |
| 2157 switch (status) { | 2103 switch (status) { |
| 2158 case Serializer::InputError: | 2104 case Serializer::InputError: |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2171 } | 2117 } |
| 2172 ASSERT_NOT_REACHED(); | 2118 ASSERT_NOT_REACHED(); |
| 2173 } | 2119 } |
| 2174 | 2120 |
| 2175 SerializedScriptValue::SerializedScriptValue(const String& wireData) | 2121 SerializedScriptValue::SerializedScriptValue(const String& wireData) |
| 2176 : m_externallyAllocatedMemory(0) | 2122 : m_externallyAllocatedMemory(0) |
| 2177 { | 2123 { |
| 2178 m_data = wireData.isolatedCopy(); | 2124 m_data = wireData.isolatedCopy(); |
| 2179 } | 2125 } |
| 2180 | 2126 |
| 2181 v8::Handle<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messa
gePorts) | 2127 v8::Handle<v8::Value> SerializedScriptValue::deserialize() |
| 2182 { | 2128 { |
| 2183 return deserialize(v8::Isolate::GetCurrent(), messagePorts); | 2129 return deserialize(v8::Isolate::GetCurrent()); |
| 2184 } | 2130 } |
| 2185 | 2131 |
| 2186 v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, M
essagePortArray* messagePorts) | 2132 v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate) |
| 2187 { | 2133 { |
| 2188 if (!m_data.impl()) | 2134 if (!m_data.impl()) |
| 2189 return v8::Null(isolate); | 2135 return v8::Null(isolate); |
| 2190 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); | 2136 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); |
| 2191 m_data.ensure16Bit(); | 2137 m_data.ensure16Bit(); |
| 2192 // FIXME: SerializedScriptValue shouldn't use String for its underlying | 2138 // FIXME: SerializedScriptValue shouldn't use String for its underlying |
| 2193 // storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The | 2139 // storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The |
| 2194 // information stored in m_data isn't even encoded in UTF-16. Instead, | 2140 // information stored in m_data isn't even encoded in UTF-16. Instead, |
| 2195 // unicode characters are encoded as UTF-8 with two code units per UChar. | 2141 // unicode characters are encoded as UTF-8 with two code units per UChar. |
| 2196 Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16()
), 2 * m_data.length(), ScriptState::current(isolate)); | 2142 Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16()
), 2 * m_data.length(), ScriptState::current(isolate)); |
| 2197 Deserializer deserializer(reader, messagePorts, m_arrayBufferContentsArray.g
et()); | 2143 Deserializer deserializer(reader, m_arrayBufferContentsArray.get()); |
| 2198 | 2144 |
| 2199 // deserialize() can run arbitrary script (e.g., setters), which could resul
t in |this| being destroyed. | 2145 // deserialize() can run arbitrary script (e.g., setters), which could resul
t in |this| being destroyed. |
| 2200 // Holding a RefPtr ensures we are alive (along with our internal data) thro
ughout the operation. | 2146 // Holding a RefPtr ensures we are alive (along with our internal data) thro
ughout the operation. |
| 2201 RefPtr<SerializedScriptValue> protect(this); | 2147 RefPtr<SerializedScriptValue> protect(this); |
| 2202 return deserializer.deserialize(); | 2148 return deserializer.deserialize(); |
| 2203 } | 2149 } |
| 2204 | 2150 |
| 2205 bool SerializedScriptValue::extractTransferables(v8::Local<v8::Value> value, int
argumentIndex, MessagePortArray& ports, ArrayBufferArray& arrayBuffers, Excepti
onState& exceptionState, v8::Isolate* isolate) | |
| 2206 { | |
| 2207 if (isUndefinedOrNull(value)) { | |
| 2208 ports.resize(0); | |
| 2209 arrayBuffers.resize(0); | |
| 2210 return true; | |
| 2211 } | |
| 2212 | |
| 2213 uint32_t length = 0; | |
| 2214 if (value->IsArray()) { | |
| 2215 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value); | |
| 2216 length = array->Length(); | |
| 2217 } else if (toV8Sequence(value, length, isolate).IsEmpty()) { | |
| 2218 exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgumentO
rValue(argumentIndex + 1)); | |
| 2219 return false; | |
| 2220 } | |
| 2221 | |
| 2222 v8::Local<v8::Object> transferrables = v8::Local<v8::Object>::Cast(value); | |
| 2223 | |
| 2224 // Validate the passed array of transferrables. | |
| 2225 for (unsigned i = 0; i < length; ++i) { | |
| 2226 v8::Local<v8::Value> transferrable = transferrables->Get(i); | |
| 2227 // Validation of non-null objects, per HTML5 spec 10.3.3. | |
| 2228 if (isUndefinedOrNull(transferrable)) { | |
| 2229 exceptionState.throwDOMException(DataCloneError, "Value at index " +
String::number(i) + " is an untransferable " + (transferrable->IsUndefined() ?
"'undefined'" : "'null'") + " value."); | |
| 2230 return false; | |
| 2231 } | |
| 2232 // Validation of Objects implementing an interface, per WebIDL spec 4.1.
15. | |
| 2233 if (V8MessagePort::hasInstance(transferrable, isolate)) { | |
| 2234 RefPtrWillBeRawPtr<MessagePort> port = V8MessagePort::toNative(v8::H
andle<v8::Object>::Cast(transferrable)); | |
| 2235 // Check for duplicate MessagePorts. | |
| 2236 if (ports.contains(port)) { | |
| 2237 exceptionState.throwDOMException(DataCloneError, "Message port a
t index " + String::number(i) + " is a duplicate of an earlier port."); | |
| 2238 return false; | |
| 2239 } | |
| 2240 ports.append(port.release()); | |
| 2241 } else if (V8ArrayBuffer::hasInstance(transferrable, isolate)) { | |
| 2242 RefPtr<ArrayBuffer> arrayBuffer = V8ArrayBuffer::toNative(v8::Handle
<v8::Object>::Cast(transferrable)); | |
| 2243 if (arrayBuffers.contains(arrayBuffer)) { | |
| 2244 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at
index " + String::number(i) + " is a duplicate of an earlier ArrayBuffer."); | |
| 2245 return false; | |
| 2246 } | |
| 2247 arrayBuffers.append(arrayBuffer.release()); | |
| 2248 } else { | |
| 2249 exceptionState.throwDOMException(DataCloneError, "Value at index " +
String::number(i) + " does not have a transferable type."); | |
| 2250 return false; | |
| 2251 } | |
| 2252 } | |
| 2253 return true; | |
| 2254 } | |
| 2255 | |
| 2256 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() | |
| 2257 { | |
| 2258 if (m_externallyAllocatedMemory) | |
| 2259 return; | |
| 2260 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); | |
| 2261 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externall
yAllocatedMemory); | |
| 2262 } | |
| 2263 | |
| 2264 SerializedScriptValue::~SerializedScriptValue() | 2151 SerializedScriptValue::~SerializedScriptValue() |
| 2265 { | 2152 { |
| 2266 // If the allocated memory was not registered before, then this class is lik
ely | 2153 // If the allocated memory was not registered before, then this class is lik
ely |
| 2267 // used in a context other then Worker's onmessage environment and the prese
nce of | 2154 // used in a context other then Worker's onmessage environment and the prese
nce of |
| 2268 // current v8 context is not guaranteed. Avoid calling v8 then. | 2155 // current v8 context is not guaranteed. Avoid calling v8 then. |
| 2269 if (m_externallyAllocatedMemory) { | 2156 if (m_externallyAllocatedMemory) { |
| 2270 ASSERT(v8::Isolate::GetCurrent()); | 2157 ASSERT(v8::Isolate::GetCurrent()); |
| 2271 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte
rnallyAllocatedMemory); | 2158 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte
rnallyAllocatedMemory); |
| 2272 } | 2159 } |
| 2273 } | 2160 } |
| 2274 | 2161 |
| 2275 } // namespace blink | 2162 } // namespace blink |
| OLD | NEW |