OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2009, 2010 Google Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
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. | |
29 */ | |
30 | |
31 #ifndef SerializedScriptValue_h | |
32 #define SerializedScriptValue_h | |
33 | |
34 #include <memory> | |
35 | |
36 #include "bindings/core/v8/NativeValueTraits.h" | |
37 #include "bindings/core/v8/ScriptValue.h" | |
38 #include "bindings/core/v8/Transferables.h" | |
39 #include "core/CoreExport.h" | |
40 #include "platform/wtf/Allocator.h" | |
41 #include "platform/wtf/HashMap.h" | |
42 #include "platform/wtf/ThreadSafeRefCounted.h" | |
43 #include "platform/wtf/allocator/Partitions.h" | |
44 #include "platform/wtf/typed_arrays/ArrayBufferContents.h" | |
45 #include "v8/include/v8.h" | |
46 | |
47 namespace blink { | |
48 | |
49 class BlobDataHandle; | |
50 class Transferables; | |
51 class ExceptionState; | |
52 class StaticBitmapImage; | |
53 class WebBlobInfo; | |
54 | |
55 typedef HashMap<String, RefPtr<BlobDataHandle>> BlobDataHandleMap; | |
56 typedef Vector<WebBlobInfo> WebBlobInfoArray; | |
57 | |
58 class CORE_EXPORT SerializedScriptValue | |
59 : public ThreadSafeRefCounted<SerializedScriptValue> { | |
60 public: | |
61 using ArrayBufferContentsArray = Vector<WTF::ArrayBufferContents, 1>; | |
62 using ImageBitmapContentsArray = Vector<RefPtr<StaticBitmapImage>, 1>; | |
63 using TransferredWasmModulesArray = | |
64 WTF::Vector<v8::WasmCompiledModule::TransferrableModule>; | |
65 | |
66 // Increment this for each incompatible change to the wire format. | |
67 // Version 2: Added StringUCharTag for UChar v8 strings. | |
68 // Version 3: Switched to using uuids as blob data identifiers. | |
69 // Version 4: Extended File serialization to be complete. | |
70 // Version 5: Added CryptoKeyTag for Key objects. | |
71 // Version 6: Added indexed serialization for File, Blob, and FileList. | |
72 // Version 7: Extended File serialization with user visibility. | |
73 // Version 8: File.lastModified in milliseconds (seconds-based in earlier | |
74 // versions.) | |
75 // Version 9: Added Map and Set support. | |
76 // [versions skipped] | |
77 // Version 16: Separate versioning between V8 and Blink. | |
78 // Version 17: Remove unnecessary byte swapping. | |
79 // | |
80 // The following versions cannot be used, in order to be able to | |
81 // deserialize version 0 SSVs. The class implementation has details. | |
82 // DO NOT USE: 35, 64, 68, 73, 78, 82, 83, 85, 91, 98, 102, 108, 123. | |
83 // | |
84 // WARNING: Increasing this value is a change which cannot safely be rolled | |
85 // back without breaking compatibility with data stored on disk. It is | |
86 // strongly recommended that you do not make such changes near a release | |
87 // milestone branch point. | |
88 // | |
89 // Recent changes are routinely reverted in preparation for branch, and this | |
90 // has been the cause of at least one bug in the past. | |
91 static constexpr uint32_t kWireFormatVersion = 17; | |
92 | |
93 struct SerializeOptions { | |
94 STACK_ALLOCATED(); | |
95 Transferables* transferables = nullptr; | |
96 WebBlobInfoArray* blob_info = nullptr; | |
97 bool write_wasm_to_stream = false; | |
98 // Set when serializing a value for storage; e.g. when writing to | |
99 // IndexedDB. | |
100 bool for_storage = false; | |
101 }; | |
102 static PassRefPtr<SerializedScriptValue> Serialize(v8::Isolate*, | |
103 v8::Local<v8::Value>, | |
104 const SerializeOptions&, | |
105 ExceptionState&); | |
106 static PassRefPtr<SerializedScriptValue> SerializeAndSwallowExceptions( | |
107 v8::Isolate*, | |
108 v8::Local<v8::Value>); | |
109 | |
110 static PassRefPtr<SerializedScriptValue> Create(); | |
111 static PassRefPtr<SerializedScriptValue> Create(const String&); | |
112 static PassRefPtr<SerializedScriptValue> Create(const char* data, | |
113 size_t length); | |
114 | |
115 ~SerializedScriptValue(); | |
116 | |
117 static PassRefPtr<SerializedScriptValue> NullValue(); | |
118 | |
119 String ToWireString() const; | |
120 void ToWireBytes(Vector<char>&) const; | |
121 | |
122 // Deserializes the value (in the current context). Returns a null value in | |
123 // case of failure. | |
124 struct DeserializeOptions { | |
125 STACK_ALLOCATED(); | |
126 MessagePortArray* message_ports = nullptr; | |
127 const WebBlobInfoArray* blob_info = nullptr; | |
128 bool read_wasm_from_stream = false; | |
129 }; | |
130 v8::Local<v8::Value> Deserialize(v8::Isolate* isolate) { | |
131 return Deserialize(isolate, DeserializeOptions()); | |
132 } | |
133 v8::Local<v8::Value> Deserialize(v8::Isolate*, const DeserializeOptions&); | |
134 | |
135 // Helper function which pulls the values out of a JS sequence and into a | |
136 // MessagePortArray. Also validates the elements per sections 4.1.13 and | |
137 // 4.1.15 of the WebIDL spec and section 8.3.3 of the HTML5 spec and generates | |
138 // exceptions as appropriate. | |
139 // Returns true if the array was filled, or false if the passed value was not | |
140 // of an appropriate type. | |
141 static bool ExtractTransferables(v8::Isolate*, | |
142 v8::Local<v8::Value>, | |
143 int, | |
144 Transferables&, | |
145 ExceptionState&); | |
146 | |
147 // Helper function which pulls ArrayBufferContents out of an ArrayBufferArray | |
148 // and neuters the ArrayBufferArray. Returns nullptr if there is an | |
149 // exception. | |
150 static std::unique_ptr<ArrayBufferContentsArray> TransferArrayBufferContents( | |
151 v8::Isolate*, | |
152 const ArrayBufferArray&, | |
153 ExceptionState&); | |
154 | |
155 static std::unique_ptr<ImageBitmapContentsArray> TransferImageBitmapContents( | |
156 v8::Isolate*, | |
157 const ImageBitmapArray&, | |
158 ExceptionState&); | |
159 | |
160 // Informs V8 about external memory allocated and owned by this object. | |
161 // Large values should contribute to GC counters to eventually trigger a GC, | |
162 // otherwise flood of postMessage() can cause OOM. | |
163 // Ok to invoke multiple times (only adds memory once). | |
164 // The memory registration is revoked automatically in destructor. | |
165 void RegisterMemoryAllocatedWithCurrentScriptContext(); | |
166 | |
167 // The dual, unregistering / subtracting the external memory allocation costs | |
168 // of this SerializedScriptValue with the current context. This includes | |
169 // discounting the cost of the transferables. | |
170 // | |
171 // The value is updated and marked as having no allocations registered, | |
172 // hence subsequent calls will be no-ops. | |
173 void UnregisterMemoryAllocatedWithCurrentScriptContext(); | |
174 | |
175 const uint8_t* Data() const { return data_buffer_.get(); } | |
176 size_t DataLengthInBytes() const { return data_buffer_size_; } | |
177 | |
178 BlobDataHandleMap& BlobDataHandles() { return blob_data_handles_; } | |
179 ArrayBufferContentsArray* GetArrayBufferContentsArray() { | |
180 return array_buffer_contents_array_.get(); | |
181 } | |
182 ImageBitmapContentsArray* GetImageBitmapContentsArray() { | |
183 return image_bitmap_contents_array_.get(); | |
184 } | |
185 | |
186 TransferredWasmModulesArray& WasmModules() { return wasm_modules_; } | |
187 | |
188 private: | |
189 friend class ScriptValueSerializer; | |
190 friend class V8ScriptValueSerializer; | |
191 | |
192 struct BufferDeleter { | |
193 void operator()(uint8_t* buffer) { WTF::Partitions::BufferFree(buffer); } | |
194 }; | |
195 using DataBufferPtr = std::unique_ptr<uint8_t[], BufferDeleter>; | |
196 | |
197 SerializedScriptValue(); | |
198 explicit SerializedScriptValue(const String& wire_data); | |
199 | |
200 void SetData(DataBufferPtr data, size_t size) { | |
201 data_buffer_ = std::move(data); | |
202 data_buffer_size_ = size; | |
203 } | |
204 | |
205 void TransferArrayBuffers(v8::Isolate*, | |
206 const ArrayBufferArray&, | |
207 ExceptionState&); | |
208 void TransferImageBitmaps(v8::Isolate*, | |
209 const ImageBitmapArray&, | |
210 ExceptionState&); | |
211 void TransferOffscreenCanvas(v8::Isolate*, | |
212 const OffscreenCanvasArray&, | |
213 ExceptionState&); | |
214 | |
215 DataBufferPtr data_buffer_; | |
216 size_t data_buffer_size_ = 0; | |
217 | |
218 std::unique_ptr<ArrayBufferContentsArray> array_buffer_contents_array_; | |
219 std::unique_ptr<ImageBitmapContentsArray> image_bitmap_contents_array_; | |
220 TransferredWasmModulesArray wasm_modules_; | |
221 | |
222 BlobDataHandleMap blob_data_handles_; | |
223 | |
224 bool has_registered_external_allocation_; | |
225 bool transferables_need_external_allocation_registration_; | |
226 }; | |
227 | |
228 template <> | |
229 struct NativeValueTraits<SerializedScriptValue> | |
230 : public NativeValueTraitsBase<SerializedScriptValue> { | |
231 CORE_EXPORT static inline PassRefPtr<SerializedScriptValue> NativeValue( | |
232 v8::Isolate* isolate, | |
233 v8::Local<v8::Value> value, | |
234 ExceptionState& exception_state) { | |
235 return SerializedScriptValue::Serialize( | |
236 isolate, value, SerializedScriptValue::SerializeOptions(), | |
237 exception_state); | |
238 } | |
239 }; | |
240 | |
241 } // namespace blink | |
242 | |
243 #endif // SerializedScriptValue_h | |
OLD | NEW |