| 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 19 matching lines...) Expand all Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |