Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: Source/bindings/v8/SerializedScriptValue.cpp

Issue 114363002: Structured cloning: improve DataCloneError reporting. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased + reset V8TestInterfaceConstructor.cpp result Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/bindings/v8/SerializedScriptValue.h ('k') | Source/bindings/v8/V8Utilities.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 19 matching lines...) Expand all
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "bindings/v8/SerializedScriptValue.h" 32 #include "bindings/v8/SerializedScriptValue.h"
33 33
34 #include "V8Blob.h" 34 #include "V8Blob.h"
35 #include "V8DOMFileSystem.h" 35 #include "V8DOMFileSystem.h"
36 #include "V8File.h" 36 #include "V8File.h"
37 #include "V8FileList.h" 37 #include "V8FileList.h"
38 #include "V8ImageData.h" 38 #include "V8ImageData.h"
39 #include "V8MessagePort.h" 39 #include "V8MessagePort.h"
40 #include "bindings/v8/ExceptionState.h"
40 #include "bindings/v8/ScriptScope.h" 41 #include "bindings/v8/ScriptScope.h"
41 #include "bindings/v8/ScriptState.h" 42 #include "bindings/v8/ScriptState.h"
42 #include "bindings/v8/V8Binding.h" 43 #include "bindings/v8/V8Binding.h"
43 #include "bindings/v8/V8Utilities.h" 44 #include "bindings/v8/V8Utilities.h"
44 #include "bindings/v8/custom/V8ArrayBufferCustom.h" 45 #include "bindings/v8/custom/V8ArrayBufferCustom.h"
45 #include "bindings/v8/custom/V8ArrayBufferViewCustom.h" 46 #include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
46 #include "bindings/v8/custom/V8DataViewCustom.h" 47 #include "bindings/v8/custom/V8DataViewCustom.h"
47 #include "bindings/v8/custom/V8Float32ArrayCustom.h" 48 #include "bindings/v8/custom/V8Float32ArrayCustom.h"
48 #include "bindings/v8/custom/V8Float64ArrayCustom.h" 49 #include "bindings/v8/custom/V8Float64ArrayCustom.h"
49 #include "bindings/v8/custom/V8Int16ArrayCustom.h" 50 #include "bindings/v8/custom/V8Int16ArrayCustom.h"
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 return wrapper.As<v8::ArrayBuffer>(); 697 return wrapper.As<v8::ArrayBuffer>();
697 } 698 }
698 699
699 class Serializer { 700 class Serializer {
700 class StateBase; 701 class StateBase;
701 public: 702 public:
702 enum Status { 703 enum Status {
703 Success, 704 Success,
704 InputError, 705 InputError,
705 DataCloneError, 706 DataCloneError,
706 InvalidStateError, 707 JSException
707 JSException,
708 JSFailure
709 }; 708 };
710 709
711 Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::I solate* isolate) 710 Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::I solate* isolate)
712 : m_writer(writer) 711 : m_writer(writer)
713 , m_tryCatch(tryCatch) 712 , m_tryCatch(tryCatch)
714 , m_depth(0) 713 , m_depth(0)
715 , m_status(Success) 714 , m_status(Success)
716 , m_nextObjectReference(0) 715 , m_nextObjectReference(0)
717 , m_blobDataHandles(blobDataHandles) 716 , m_blobDataHandles(blobDataHandles)
718 , m_isolate(isolate) 717 , m_isolate(isolate)
(...skipping 16 matching lines...) Expand all
735 Status serialize(v8::Handle<v8::Value> value) 734 Status serialize(v8::Handle<v8::Value> value)
736 { 735 {
737 v8::HandleScope scope(m_isolate); 736 v8::HandleScope scope(m_isolate);
738 m_writer.writeVersion(); 737 m_writer.writeVersion();
739 StateBase* state = doSerialize(value, 0); 738 StateBase* state = doSerialize(value, 0);
740 while (state) 739 while (state)
741 state = state->advance(*this); 740 state = state->advance(*this);
742 return m_status; 741 return m_status;
743 } 742 }
744 743
744 String errorMessage() { return m_errorMessage; }
745
745 // Functions used by serialization states. 746 // Functions used by serialization states.
746 StateBase* doSerialize(v8::Handle<v8::Value>, StateBase* next); 747 StateBase* doSerialize(v8::Handle<v8::Value>, StateBase* next);
747 748
748 StateBase* doSerializeArrayBuffer(v8::Handle<v8::Value> arrayBuffer, StateBa se* next) 749 StateBase* doSerializeArrayBuffer(v8::Handle<v8::Value> arrayBuffer, StateBa se* next)
749 { 750 {
750 return doSerialize(arrayBuffer, next); 751 return doSerialize(arrayBuffer, next);
751 } 752 }
752 753
753 StateBase* checkException(StateBase* state) 754 StateBase* checkException(StateBase* state)
754 { 755 {
755 return m_tryCatch.HasCaught() ? handleError(JSException, state) : 0; 756 return m_tryCatch.HasCaught() ? handleError(JSException, "", state) : 0;
756 }
757
758 StateBase* reportFailure(StateBase* state)
759 {
760 return handleError(JSFailure, state);
761 } 757 }
762 758
763 StateBase* writeObject(uint32_t numProperties, StateBase* state) 759 StateBase* writeObject(uint32_t numProperties, StateBase* state)
764 { 760 {
765 m_writer.writeObject(numProperties); 761 m_writer.writeObject(numProperties);
766 return pop(state); 762 return pop(state);
767 } 763 }
768 764
769 StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBa se* state) 765 StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBa se* state)
770 { 766 {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0; 849 virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0;
854 850
855 StateBase* serializeProperties(bool ignoreIndexed, Serializer& serialize r) 851 StateBase* serializeProperties(bool ignoreIndexed, Serializer& serialize r)
856 { 852 {
857 while (m_index < m_propertyNames->Length()) { 853 while (m_index < m_propertyNames->Length()) {
858 if (!m_nameDone) { 854 if (!m_nameDone) {
859 v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_i ndex); 855 v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_i ndex);
860 if (StateBase* newState = serializer.checkException(this)) 856 if (StateBase* newState = serializer.checkException(this))
861 return newState; 857 return newState;
862 if (propertyName.IsEmpty()) 858 if (propertyName.IsEmpty())
863 return serializer.reportFailure(this); 859 return serializer.handleError(InputError, "Empty propert y names cannot be cloned.", this);
864 bool hasStringProperty = propertyName->IsString() && composi te()->HasRealNamedProperty(propertyName.As<v8::String>()); 860 bool hasStringProperty = propertyName->IsString() && composi te()->HasRealNamedProperty(propertyName.As<v8::String>());
865 if (StateBase* newState = serializer.checkException(this)) 861 if (StateBase* newState = serializer.checkException(this))
866 return newState; 862 return newState;
867 bool hasIndexedProperty = !hasStringProperty && propertyName ->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()) ; 863 bool hasIndexedProperty = !hasStringProperty && propertyName ->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()) ;
868 if (StateBase* newState = serializer.checkException(this)) 864 if (StateBase* newState = serializer.checkException(this))
869 return newState; 865 return newState;
870 if (hasStringProperty || (hasIndexedProperty && !ignoreIndex ed)) 866 if (hasStringProperty || (hasIndexedProperty && !ignoreIndex ed))
871 m_propertyName = propertyName; 867 m_propertyName = propertyName;
872 else { 868 else {
873 ++m_index; 869 ++m_index;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 { 908 {
913 } 909 }
914 910
915 virtual StateBase* advance(Serializer& serializer) 911 virtual StateBase* advance(Serializer& serializer)
916 { 912 {
917 if (m_propertyNames.IsEmpty()) { 913 if (m_propertyNames.IsEmpty()) {
918 m_propertyNames = composite()->GetPropertyNames(); 914 m_propertyNames = composite()->GetPropertyNames();
919 if (StateBase* newState = serializer.checkException(this)) 915 if (StateBase* newState = serializer.checkException(this))
920 return newState; 916 return newState;
921 if (m_propertyNames.IsEmpty()) 917 if (m_propertyNames.IsEmpty())
922 return serializer.reportFailure(this); 918 return serializer.handleError(InputError, "Empty property na mes cannot be cloned.", nextState());
923 } 919 }
924 return serializeProperties(false, serializer); 920 return serializeProperties(false, serializer);
925 } 921 }
926 922
927 protected: 923 protected:
928 virtual StateBase* objectDone(unsigned numProperties, Serializer& serial izer) 924 virtual StateBase* objectDone(unsigned numProperties, Serializer& serial izer)
929 { 925 {
930 return serializer.writeObject(numProperties, this); 926 return serializer.writeObject(numProperties, this);
931 } 927 }
932 }; 928 };
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 virtual StateBase* objectDone(unsigned numProperties, Serializer& serial izer) 978 virtual StateBase* objectDone(unsigned numProperties, Serializer& serial izer)
983 { 979 {
984 return serializer.writeSparseArray(numProperties, composite().As<v8: :Array>()->Length(), this); 980 return serializer.writeSparseArray(numProperties, composite().As<v8: :Array>()->Length(), this);
985 } 981 }
986 }; 982 };
987 983
988 StateBase* push(StateBase* state) 984 StateBase* push(StateBase* state)
989 { 985 {
990 ASSERT(state); 986 ASSERT(state);
991 ++m_depth; 987 ++m_depth;
992 return checkComposite(state) ? state : handleError(InputError, state); 988 return checkComposite(state) ? state : handleError(InputError, "Value be ing cloned is either cyclic or too deeply nested.", state);
993 } 989 }
994 990
995 StateBase* pop(StateBase* state) 991 StateBase* pop(StateBase* state)
996 { 992 {
997 ASSERT(state); 993 ASSERT(state);
998 --m_depth; 994 --m_depth;
999 StateBase* next = state->nextState(); 995 StateBase* next = state->nextState();
1000 delete state; 996 delete state;
1001 return next; 997 return next;
1002 } 998 }
1003 999
1004 StateBase* handleError(Status errorStatus, StateBase* state) 1000 StateBase* handleError(Status errorStatus, const String& message, StateBase* state)
1005 { 1001 {
1006 ASSERT(errorStatus != Success); 1002 ASSERT(errorStatus != Success);
1007 m_status = errorStatus; 1003 m_status = errorStatus;
1004 m_errorMessage = message;
1008 while (state) { 1005 while (state) {
1009 StateBase* tmp = state->nextState(); 1006 StateBase* tmp = state->nextState();
1010 delete state; 1007 delete state;
1011 state = tmp; 1008 state = tmp;
1012 } 1009 }
1013 return new ErrorState; 1010 return new ErrorState;
1014 } 1011 }
1015 1012
1016 bool checkComposite(StateBase* top) 1013 bool checkComposite(StateBase* top)
1017 { 1014 {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size()); 1061 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size());
1065 m_blobDataHandles.add(blob->uuid(), blob->blobDataHandle()); 1062 m_blobDataHandles.add(blob->uuid(), blob->blobDataHandle());
1066 } 1063 }
1067 1064
1068 StateBase* writeDOMFileSystem(v8::Handle<v8::Value> value, StateBase* next) 1065 StateBase* writeDOMFileSystem(v8::Handle<v8::Value> value, StateBase* next)
1069 { 1066 {
1070 DOMFileSystem* fs = V8DOMFileSystem::toNative(value.As<v8::Object>()); 1067 DOMFileSystem* fs = V8DOMFileSystem::toNative(value.As<v8::Object>());
1071 if (!fs) 1068 if (!fs)
1072 return 0; 1069 return 0;
1073 if (!fs->clonable()) 1070 if (!fs->clonable())
1074 return handleError(DataCloneError, next); 1071 return handleError(DataCloneError, "A FileSystem object could not be cloned.", next);
1075 m_writer.writeDOMFileSystem(fs->type(), fs->name(), fs->rootURL().string ()); 1072 m_writer.writeDOMFileSystem(fs->type(), fs->name(), fs->rootURL().string ());
1076 return 0; 1073 return 0;
1077 } 1074 }
1078 1075
1079 void writeFile(v8::Handle<v8::Value> value) 1076 void writeFile(v8::Handle<v8::Value> value)
1080 { 1077 {
1081 File* file = V8File::toNative(value.As<v8::Object>()); 1078 File* file = V8File::toNative(value.As<v8::Object>());
1082 if (!file) 1079 if (!file)
1083 return; 1080 return;
1084 m_writer.writeFile(*file); 1081 m_writer.writeFile(*file);
(...skipping 26 matching lines...) Expand all
1111 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); 1108 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags());
1112 } 1109 }
1113 1110
1114 StateBase* writeAndGreyArrayBufferView(v8::Handle<v8::Object> object, StateB ase* next) 1111 StateBase* writeAndGreyArrayBufferView(v8::Handle<v8::Object> object, StateB ase* next)
1115 { 1112 {
1116 ASSERT(!object.IsEmpty()); 1113 ASSERT(!object.IsEmpty());
1117 ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(object); 1114 ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(object);
1118 if (!arrayBufferView) 1115 if (!arrayBufferView)
1119 return 0; 1116 return 0;
1120 if (!arrayBufferView->buffer()) 1117 if (!arrayBufferView->buffer())
1121 return handleError(DataCloneError, next); 1118 return handleError(DataCloneError, "An ArrayBuffer could not be clon ed.", next);
1122 v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), v8::Handle<v8::Object>(), m_writer.getIsolate()); 1119 v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), v8::Handle<v8::Object>(), m_writer.getIsolate());
1123 if (underlyingBuffer.IsEmpty()) 1120 if (underlyingBuffer.IsEmpty())
1124 return handleError(DataCloneError, next); 1121 return handleError(DataCloneError, "An ArrayBuffer could not be clon ed.", next);
1125 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); 1122 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next);
1126 if (stateOut) 1123 if (stateOut)
1127 return stateOut; 1124 return stateOut;
1128 m_writer.writeArrayBufferView(*arrayBufferView); 1125 m_writer.writeArrayBufferView(*arrayBufferView);
1129 // This should be safe: we serialize something that we know to be a wrap per (see 1126 // This should be safe: we serialize something that we know to be a wrap per (see
1130 // the toV8 call above), so the call to doSerializeArrayBuffer should ne ither 1127 // the toV8 call above), so the call to doSerializeArrayBuffer should ne ither
1131 // cause the system stack to overflow nor should it have potential to re ach 1128 // cause the system stack to overflow nor should it have potential to re ach
1132 // this ArrayBufferView again. 1129 // this ArrayBufferView again.
1133 // 1130 //
1134 // We do need to grey the underlying buffer before we grey its view, how ever; 1131 // We do need to grey the underlying buffer before we grey its view, how ever;
1135 // ArrayBuffers may be shared, so they need to be given reference IDs, a nd an 1132 // ArrayBuffers may be shared, so they need to be given reference IDs, a nd an
1136 // ArrayBufferView cannot be constructed without a corresponding ArrayBu ffer 1133 // ArrayBufferView cannot be constructed without a corresponding ArrayBu ffer
1137 // (or without an additional tag that would allow us to do two-stage con struction 1134 // (or without an additional tag that would allow us to do two-stage con struction
1138 // like we do for Objects and Arrays). 1135 // like we do for Objects and Arrays).
1139 greyObject(object); 1136 greyObject(object);
1140 return 0; 1137 return 0;
1141 } 1138 }
1142 1139
1143 StateBase* writeArrayBuffer(v8::Handle<v8::Value> value, StateBase* next) 1140 StateBase* writeArrayBuffer(v8::Handle<v8::Value> value, StateBase* next)
1144 { 1141 {
1145 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>( )); 1142 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>( ));
1146 if (!arrayBuffer) 1143 if (!arrayBuffer)
1147 return 0; 1144 return 0;
1148 if (arrayBuffer->isNeutered()) 1145 if (arrayBuffer->isNeutered())
1149 return handleError(InvalidStateError, next); 1146 return handleError(DataCloneError, "An ArrayBuffer is neutered and c ould not be cloned.", next);
1150 ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>())); 1147 ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>()));
1151 m_writer.writeArrayBuffer(*arrayBuffer); 1148 m_writer.writeArrayBuffer(*arrayBuffer);
1152 return 0; 1149 return 0;
1153 } 1150 }
1154 1151
1155 StateBase* writeTransferredArrayBuffer(v8::Handle<v8::Value> value, uint32_t index, StateBase* next) 1152 StateBase* writeTransferredArrayBuffer(v8::Handle<v8::Value> value, uint32_t index, StateBase* next)
1156 { 1153 {
1157 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>( )); 1154 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>( ));
1158 if (!arrayBuffer) 1155 if (!arrayBuffer)
1159 return 0; 1156 return 0;
1160 if (arrayBuffer->isNeutered()) 1157 if (arrayBuffer->isNeutered())
1161 return handleError(DataCloneError, next); 1158 return handleError(DataCloneError, "An ArrayBuffer is neutered and c ould not be cloned.", next);
1162 m_writer.writeTransferredArrayBuffer(index); 1159 m_writer.writeTransferredArrayBuffer(index);
1163 return 0; 1160 return 0;
1164 } 1161 }
1165 1162
1166 static bool shouldSerializeDensely(uint32_t length, uint32_t propertyCount) 1163 static bool shouldSerializeDensely(uint32_t length, uint32_t propertyCount)
1167 { 1164 {
1168 // Let K be the cost of serializing all property values that are there 1165 // Let K be the cost of serializing all property values that are there
1169 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32 _t key) 1166 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32 _t key)
1170 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte f or all properties that are not there) 1167 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte f or all properties that are not there)
1171 // so densely is better than sparsly whenever 6*propertyCount > length 1168 // so densely is better than sparsly whenever 6*propertyCount > length
(...skipping 29 matching lines...) Expand all
1201 { 1198 {
1202 ASSERT(!m_objectPool.contains(object)); 1199 ASSERT(!m_objectPool.contains(object));
1203 uint32_t objectReference = m_nextObjectReference++; 1200 uint32_t objectReference = m_nextObjectReference++;
1204 m_objectPool.set(object, objectReference); 1201 m_objectPool.set(object, objectReference);
1205 } 1202 }
1206 1203
1207 Writer& m_writer; 1204 Writer& m_writer;
1208 v8::TryCatch& m_tryCatch; 1205 v8::TryCatch& m_tryCatch;
1209 int m_depth; 1206 int m_depth;
1210 Status m_status; 1207 Status m_status;
1208 String m_errorMessage;
1211 typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool; 1209 typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool;
1212 ObjectPool m_objectPool; 1210 ObjectPool m_objectPool;
1213 ObjectPool m_transferredMessagePorts; 1211 ObjectPool m_transferredMessagePorts;
1214 ObjectPool m_transferredArrayBuffers; 1212 ObjectPool m_transferredArrayBuffers;
1215 uint32_t m_nextObjectReference; 1213 uint32_t m_nextObjectReference;
1216 BlobDataHandleMap& m_blobDataHandles; 1214 BlobDataHandleMap& m_blobDataHandles;
1217 v8::Isolate* m_isolate; 1215 v8::Isolate* m_isolate;
1218 }; 1216 };
1219 1217
1220 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Stat eBase* next) 1218 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Stat eBase* next)
1221 { 1219 {
1222 m_writer.writeReferenceCount(m_nextObjectReference); 1220 m_writer.writeReferenceCount(m_nextObjectReference);
1223 uint32_t objectReference; 1221 uint32_t objectReference;
1224 uint32_t arrayBufferIndex; 1222 uint32_t arrayBufferIndex;
1225 WrapperWorldType currentWorldType = worldType(m_isolate); 1223 WrapperWorldType currentWorldType = worldType(m_isolate);
1226 if ((value->IsObject() || value->IsDate() || value->IsRegExp()) 1224 if ((value->IsObject() || value->IsDate() || value->IsRegExp())
1227 && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) { 1225 && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) {
1228 // Note that IsObject() also detects wrappers (eg, it will catch the thi ngs 1226 // Note that IsObject() also detects wrappers (eg, it will catch the thi ngs
1229 // that we grey and write below). 1227 // that we grey and write below).
1230 ASSERT(!value->IsString()); 1228 ASSERT(!value->IsString());
1231 m_writer.writeObjectReference(objectReference); 1229 m_writer.writeObjectReference(objectReference);
1232 } else if (value.IsEmpty()) 1230 } else if (value.IsEmpty()) {
1233 return reportFailure(next); 1231 return handleError(InputError, "The empty property name cannot be cloned .", next);
1234 else if (value->IsUndefined()) 1232 } else if (value->IsUndefined())
1235 m_writer.writeUndefined(); 1233 m_writer.writeUndefined();
1236 else if (value->IsNull()) 1234 else if (value->IsNull())
1237 m_writer.writeNull(); 1235 m_writer.writeNull();
1238 else if (value->IsTrue()) 1236 else if (value->IsTrue())
1239 m_writer.writeTrue(); 1237 m_writer.writeTrue();
1240 else if (value->IsFalse()) 1238 else if (value->IsFalse())
1241 m_writer.writeFalse(); 1239 m_writer.writeFalse();
1242 else if (value->IsInt32()) 1240 else if (value->IsInt32())
1243 m_writer.writeInt32(value->Int32Value()); 1241 m_writer.writeInt32(value->Int32Value());
1244 else if (value->IsUint32()) 1242 else if (value->IsUint32())
1245 m_writer.writeUint32(value->Uint32Value()); 1243 m_writer.writeUint32(value->Uint32Value());
1246 else if (value->IsNumber()) 1244 else if (value->IsNumber())
1247 m_writer.writeNumber(value.As<v8::Number>()->Value()); 1245 m_writer.writeNumber(value.As<v8::Number>()->Value());
1248 else if (V8ArrayBufferView::hasInstance(value, m_isolate, currentWorldType)) 1246 else if (V8ArrayBufferView::hasInstance(value, m_isolate, currentWorldType))
1249 return writeAndGreyArrayBufferView(value.As<v8::Object>(), next); 1247 return writeAndGreyArrayBufferView(value.As<v8::Object>(), next);
1250 else if (value->IsString()) 1248 else if (value->IsString())
1251 writeString(value); 1249 writeString(value);
1252 else if (V8MessagePort::hasInstance(value, m_isolate, currentWorldType)) { 1250 else if (V8MessagePort::hasInstance(value, m_isolate, currentWorldType)) {
1253 uint32_t messagePortIndex; 1251 uint32_t messagePortIndex;
1254 if (m_transferredMessagePorts.tryGet(value.As<v8::Object>(), &messagePor tIndex)) 1252 if (m_transferredMessagePorts.tryGet(value.As<v8::Object>(), &messagePor tIndex))
1255 m_writer.writeTransferredMessagePort(messagePortIndex); 1253 m_writer.writeTransferredMessagePort(messagePortIndex);
1256 else 1254 else
1257 return handleError(DataCloneError, next); 1255 return handleError(DataCloneError, "A MessagePort could not be c loned.", next);
1258 } else if (V8ArrayBuffer::hasInstance(value, m_isolate, currentWorldType) && m_transferredArrayBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex)) 1256 } else if (V8ArrayBuffer::hasInstance(value, m_isolate, currentWorldType) && m_transferredArrayBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex))
1259 return writeTransferredArrayBuffer(value, arrayBufferIndex, next); 1257 return writeTransferredArrayBuffer(value, arrayBufferIndex, next);
1260 else { 1258 else {
1261 v8::Handle<v8::Object> jsObject = value.As<v8::Object>(); 1259 v8::Handle<v8::Object> jsObject = value.As<v8::Object>();
1262 if (jsObject.IsEmpty()) 1260 if (jsObject.IsEmpty())
1263 return handleError(DataCloneError, next); 1261 return handleError(DataCloneError, "An object could not be cloned.", next);
1264 greyObject(jsObject); 1262 greyObject(jsObject);
1265 if (value->IsDate()) 1263 if (value->IsDate())
1266 m_writer.writeDate(value->NumberValue()); 1264 m_writer.writeDate(value->NumberValue());
1267 else if (value->IsStringObject()) 1265 else if (value->IsStringObject())
1268 writeStringObject(value); 1266 writeStringObject(value);
1269 else if (value->IsNumberObject()) 1267 else if (value->IsNumberObject())
1270 writeNumberObject(value); 1268 writeNumberObject(value);
1271 else if (value->IsBooleanObject()) 1269 else if (value->IsBooleanObject())
1272 writeBooleanObject(value); 1270 writeBooleanObject(value);
1273 else if (value->IsArray()) { 1271 else if (value->IsArray()) {
1274 return startArrayState(value.As<v8::Array>(), next); 1272 return startArrayState(value.As<v8::Array>(), next);
1275 } else if (V8File::hasInstance(value, m_isolate, currentWorldType)) 1273 } else if (V8File::hasInstance(value, m_isolate, currentWorldType))
1276 writeFile(value); 1274 writeFile(value);
1277 else if (V8Blob::hasInstance(value, m_isolate, currentWorldType)) 1275 else if (V8Blob::hasInstance(value, m_isolate, currentWorldType))
1278 writeBlob(value); 1276 writeBlob(value);
1279 else if (V8DOMFileSystem::hasInstance(value, m_isolate, currentWorldType )) 1277 else if (V8DOMFileSystem::hasInstance(value, m_isolate, currentWorldType ))
1280 return writeDOMFileSystem(value, next); 1278 return writeDOMFileSystem(value, next);
1281 else if (V8FileList::hasInstance(value, m_isolate, currentWorldType)) 1279 else if (V8FileList::hasInstance(value, m_isolate, currentWorldType))
1282 writeFileList(value); 1280 writeFileList(value);
1283 else if (V8ImageData::hasInstance(value, m_isolate, currentWorldType)) 1281 else if (V8ImageData::hasInstance(value, m_isolate, currentWorldType))
1284 writeImageData(value); 1282 writeImageData(value);
1285 else if (value->IsRegExp()) 1283 else if (value->IsRegExp())
1286 writeRegExp(value); 1284 writeRegExp(value);
1287 else if (V8ArrayBuffer::hasInstance(value, m_isolate, currentWorldType)) 1285 else if (V8ArrayBuffer::hasInstance(value, m_isolate, currentWorldType))
1288 return writeArrayBuffer(value, next); 1286 return writeArrayBuffer(value, next);
1289 else if (value->IsObject()) { 1287 else if (value->IsObject()) {
1290 if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNat iveError()) 1288 if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNat iveError())
1291 return handleError(DataCloneError, next); 1289 return handleError(DataCloneError, "An object could not be clone d.", next);
1292 return startObjectState(jsObject, next); 1290 return startObjectState(jsObject, next);
1293 } else 1291 } else
1294 return handleError(DataCloneError, next); 1292 return handleError(DataCloneError, "A value could not be cloned.", n ext);
1295 } 1293 }
1296 return 0; 1294 return 0;
1297 } 1295 }
1298 1296
1299 // Interface used by Reader to create objects of composite types. 1297 // Interface used by Reader to create objects of composite types.
1300 class CompositeCreator { 1298 class CompositeCreator {
1301 public: 1299 public:
1302 virtual ~CompositeCreator() { } 1300 virtual ~CompositeCreator() { }
1303 1301
1304 virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0; 1302 virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0;
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
2246 Vector<v8::Handle<v8::Value> > m_objectPool; 2244 Vector<v8::Handle<v8::Value> > m_objectPool;
2247 Vector<uint32_t> m_openCompositeReferenceStack; 2245 Vector<uint32_t> m_openCompositeReferenceStack;
2248 MessagePortArray* m_transferredMessagePorts; 2246 MessagePortArray* m_transferredMessagePorts;
2249 ArrayBufferContentsArray* m_arrayBufferContents; 2247 ArrayBufferContentsArray* m_arrayBufferContents;
2250 Vector<v8::Handle<v8::Object> > m_arrayBuffers; 2248 Vector<v8::Handle<v8::Object> > m_arrayBuffers;
2251 uint32_t m_version; 2249 uint32_t m_version;
2252 }; 2250 };
2253 2251
2254 } // namespace 2252 } // namespace
2255 2253
2256 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::V alue> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, boo l& didThrow, v8::Isolate* isolate) 2254 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::V alue> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Exc eptionState& exceptionState, v8::Isolate* isolate)
2257 { 2255 {
2258 return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, didThrow, isolate)); 2256 return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, exceptionState, isolate));
2259 } 2257 }
2260 2258
2261 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExcepti ons(v8::Handle<v8::Value> value, v8::Isolate* isolate) 2259 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExcepti ons(v8::Handle<v8::Value> value, v8::Isolate* isolate)
2262 { 2260 {
2263 bool didThrow; 2261 TrackExceptionState exceptionState;
2264 return adoptRef(new SerializedScriptValue(value, 0, 0, didThrow, isolate, Do NotThrowExceptions)); 2262 return adoptRef(new SerializedScriptValue(value, 0, 0, exceptionState, isola te));
2265 } 2263 }
2266 2264
2267 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValu e& value, bool& didThrow, ScriptState* state) 2265 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValu e& value, ExceptionState& exceptionState, ScriptState* state)
2268 { 2266 {
2269 ScriptScope scope(state); 2267 ScriptScope scope(state);
2270 return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, didThrow, s tate->isolate())); 2268 return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, exceptionSt ate, state->isolate()));
2271 } 2269 }
2272 2270
2273 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const St ring& data) 2271 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const St ring& data)
2274 { 2272 {
2275 return adoptRef(new SerializedScriptValue(data)); 2273 return adoptRef(new SerializedScriptValue(data));
2276 } 2274 }
2277 2275
2278 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(con st Vector<uint8_t>& data) 2276 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(con st Vector<uint8_t>& data)
2279 { 2277 {
2280 // Decode wire data from big endian to host byte order. 2278 // Decode wire data from big endian to host byte order.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2361 { 2359 {
2362 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 2360 v8::Isolate* isolate = v8::Isolate::GetCurrent();
2363 Vector<DOMDataStore*>& allStores = V8PerIsolateData::from(isolate)->allStore s(); 2361 Vector<DOMDataStore*>& allStores = V8PerIsolateData::from(isolate)->allStore s();
2364 for (size_t i = 0; i < allStores.size(); i++) { 2362 for (size_t i = 0; i < allStores.size(); i++) {
2365 v8::Handle<v8::Object> wrapper = allStores[i]->get<V8ArrayBufferView>(ob ject, isolate); 2363 v8::Handle<v8::Object> wrapper = allStores[i]->get<V8ArrayBufferView>(ob ject, isolate);
2366 if (!wrapper.IsEmpty()) 2364 if (!wrapper.IsEmpty())
2367 wrapper->SetIndexedPropertiesToExternalArrayData(0, v8::kExternalByt eArray, 0); 2365 wrapper->SetIndexedPropertiesToExternalArrayData(0, v8::kExternalByt eArray, 0);
2368 } 2366 }
2369 } 2367 }
2370 2368
2371 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu e::transferArrayBuffers(ArrayBufferArray& arrayBuffers, bool& didThrow, v8::Isol ate* isolate) 2369 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu e::transferArrayBuffers(ArrayBufferArray& arrayBuffers, ExceptionState& exceptio nState, v8::Isolate* isolate)
2372 { 2370 {
2373 ASSERT(arrayBuffers.size()); 2371 ASSERT(arrayBuffers.size());
2374 2372
2375 for (size_t i = 0; i < arrayBuffers.size(); i++) { 2373 for (size_t i = 0; i < arrayBuffers.size(); i++) {
2376 if (arrayBuffers[i]->isNeutered()) { 2374 if (arrayBuffers[i]->isNeutered()) {
2377 setDOMException(InvalidStateError, isolate); 2375 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind ex " + String::number(i) + " is already neutered.");
2378 didThrow = true;
2379 return nullptr; 2376 return nullptr;
2380 } 2377 }
2381 } 2378 }
2382 2379
2383 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents Array(arrayBuffers.size())); 2380 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents Array(arrayBuffers.size()));
2384 2381
2385 HashSet<ArrayBuffer*> visited; 2382 HashSet<ArrayBuffer*> visited;
2386 for (size_t i = 0; i < arrayBuffers.size(); i++) { 2383 for (size_t i = 0; i < arrayBuffers.size(); i++) {
2387 Vector<RefPtr<ArrayBufferView> > neuteredViews; 2384 Vector<RefPtr<ArrayBufferView> > neuteredViews;
2388 2385
2389 if (visited.contains(arrayBuffers[i].get())) 2386 if (visited.contains(arrayBuffers[i].get()))
2390 continue; 2387 continue;
2391 visited.add(arrayBuffers[i].get()); 2388 visited.add(arrayBuffers[i].get());
2392 2389
2393 bool result = arrayBuffers[i]->transfer(contents->at(i), neuteredViews); 2390 bool result = arrayBuffers[i]->transfer(contents->at(i), neuteredViews);
2394 if (!result) { 2391 if (!result) {
2395 setDOMException(InvalidStateError, isolate); 2392 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind ex " + String::number(i) + " could not be transferred.");
2396 didThrow = true;
2397 return nullptr; 2393 return nullptr;
2398 } 2394 }
2399 2395
2400 neuterBinding(arrayBuffers[i].get()); 2396 neuterBinding(arrayBuffers[i].get());
2401 for (size_t j = 0; j < neuteredViews.size(); j++) 2397 for (size_t j = 0; j < neuteredViews.size(); j++)
2402 neuterBinding(neuteredViews[j].get()); 2398 neuterBinding(neuteredViews[j].get());
2403 } 2399 }
2404 return contents.release(); 2400 return contents.release();
2405 } 2401 }
2406 2402
2407 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, Messag ePortArray* messagePorts, ArrayBufferArray* arrayBuffers, bool& didThrow, v8::Is olate* isolate, ExceptionPolicy policy) 2403 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, Messag ePortArray* messagePorts, ArrayBufferArray* arrayBuffers, ExceptionState& except ionState, v8::Isolate* isolate)
2408 : m_externallyAllocatedMemory(0) 2404 : m_externallyAllocatedMemory(0)
2409 { 2405 {
2410 didThrow = false;
2411 Writer writer(isolate); 2406 Writer writer(isolate);
2412 Serializer::Status status; 2407 Serializer::Status status;
2408 String errorMessage;
2413 { 2409 {
2414 v8::TryCatch tryCatch; 2410 v8::TryCatch tryCatch;
2415 Serializer serializer(writer, messagePorts, arrayBuffers, m_blobDataHand les, tryCatch, isolate); 2411 Serializer serializer(writer, messagePorts, arrayBuffers, m_blobDataHand les, tryCatch, isolate);
2416 status = serializer.serialize(value); 2412 status = serializer.serialize(value);
2417 if (status == Serializer::JSException) { 2413 if (status == Serializer::JSException) {
2418 didThrow = true;
2419 // If there was a JS exception thrown, re-throw it. 2414 // If there was a JS exception thrown, re-throw it.
2420 if (policy == ThrowExceptions) 2415 exceptionState.rethrowV8Exception(tryCatch.Exception());
2421 tryCatch.ReThrow();
2422 return; 2416 return;
2423 } 2417 }
2418 errorMessage = serializer.errorMessage();
2424 } 2419 }
2425 switch (status) { 2420 switch (status) {
2426 case Serializer::InputError: 2421 case Serializer::InputError:
2427 case Serializer::DataCloneError: 2422 case Serializer::DataCloneError:
2428 // If there was an input error, throw a new exception outside 2423 exceptionState.throwDOMException(DataCloneError, errorMessage);
2429 // of the TryCatch scope.
2430 didThrow = true;
2431 if (policy == ThrowExceptions)
2432 setDOMException(DataCloneError, isolate);
2433 return;
2434 case Serializer::InvalidStateError:
2435 didThrow = true;
2436 if (policy == ThrowExceptions)
2437 setDOMException(InvalidStateError, isolate);
2438 return;
2439 case Serializer::JSFailure:
2440 // If there was a JS failure (but no exception), there's not
2441 // much we can do except for unwinding the C++ stack by
2442 // pretending there was a JS exception.
2443 didThrow = true;
2444 return; 2424 return;
2445 case Serializer::Success: 2425 case Serializer::Success:
2446 m_data = writer.takeWireString(); 2426 m_data = writer.takeWireString();
2447 ASSERT(m_data.impl()->hasOneRef()); 2427 ASSERT(m_data.impl()->hasOneRef());
2448 if (arrayBuffers && arrayBuffers->size()) 2428 if (arrayBuffers && arrayBuffers->size())
2449 m_arrayBufferContentsArray = transferArrayBuffers(*arrayBuffers, did Throw, isolate); 2429 m_arrayBufferContentsArray = transferArrayBuffers(*arrayBuffers, exc eptionState, isolate);
2450 return; 2430 return;
2451 case Serializer::JSException: 2431 case Serializer::JSException:
2452 // We should never get here because this case was handled above. 2432 ASSERT_NOT_REACHED();
2453 break; 2433 break;
2454 } 2434 }
2455 ASSERT_NOT_REACHED(); 2435 ASSERT_NOT_REACHED();
2456 } 2436 }
2457 2437
2458 SerializedScriptValue::SerializedScriptValue(const String& wireData) 2438 SerializedScriptValue::SerializedScriptValue(const String& wireData)
2459 : m_externallyAllocatedMemory(0) 2439 : m_externallyAllocatedMemory(0)
2460 { 2440 {
2461 m_data = wireData.isolatedCopy(); 2441 m_data = wireData.isolatedCopy();
2462 } 2442 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2498 // If the allocated memory was not registered before, then this class is lik ely 2478 // If the allocated memory was not registered before, then this class is lik ely
2499 // used in a context other then Worker's onmessage environment and the prese nce of 2479 // used in a context other then Worker's onmessage environment and the prese nce of
2500 // current v8 context is not guaranteed. Avoid calling v8 then. 2480 // current v8 context is not guaranteed. Avoid calling v8 then.
2501 if (m_externallyAllocatedMemory) { 2481 if (m_externallyAllocatedMemory) {
2502 ASSERT(v8::Isolate::GetCurrent()); 2482 ASSERT(v8::Isolate::GetCurrent());
2503 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte rnallyAllocatedMemory); 2483 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte rnallyAllocatedMemory);
2504 } 2484 }
2505 } 2485 }
2506 2486
2507 } // namespace WebCore 2487 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/bindings/v8/SerializedScriptValue.h ('k') | Source/bindings/v8/V8Utilities.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698