| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "bindings/core/v8/ScriptValueSerializer.h" | 5 #include "bindings/core/v8/ScriptValueSerializer.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/Transferables.h" | 7 #include "bindings/core/v8/Transferables.h" |
| 8 #include "bindings/core/v8/V8ArrayBuffer.h" | 8 #include "bindings/core/v8/V8ArrayBuffer.h" |
| 9 #include "bindings/core/v8/V8ArrayBufferView.h" | 9 #include "bindings/core/v8/V8ArrayBufferView.h" |
| 10 #include "bindings/core/v8/V8Blob.h" | 10 #include "bindings/core/v8/V8Blob.h" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 } | 101 } |
| 102 | 102 |
| 103 void SerializedScriptValueWriter::writeFalse() { | 103 void SerializedScriptValueWriter::writeFalse() { |
| 104 append(FalseTag); | 104 append(FalseTag); |
| 105 } | 105 } |
| 106 | 106 |
| 107 void SerializedScriptValueWriter::writeBooleanObject(bool value) { | 107 void SerializedScriptValueWriter::writeBooleanObject(bool value) { |
| 108 append(value ? TrueObjectTag : FalseObjectTag); | 108 append(value ? TrueObjectTag : FalseObjectTag); |
| 109 } | 109 } |
| 110 | 110 |
| 111 void SerializedScriptValueWriter::writeRawStringBytes( |
| 112 v8::Local<v8::String>& string) { |
| 113 int rawLength = string->Length(); |
| 114 string->WriteOneByte(byteAt(m_position), 0, rawLength, |
| 115 v8StringWriteOptions()); |
| 116 m_position += rawLength; |
| 117 } |
| 118 |
| 119 void SerializedScriptValueWriter::writeUtf8String( |
| 120 v8::Local<v8::String>& string) { |
| 121 int utf8Length = string->Utf8Length(); |
| 122 char* buffer = reinterpret_cast<char*>(byteAt(m_position)); |
| 123 string->WriteUtf8(buffer, utf8Length, 0, v8StringWriteOptions()); |
| 124 m_position += utf8Length; |
| 125 } |
| 126 |
| 111 void SerializedScriptValueWriter::writeOneByteString( | 127 void SerializedScriptValueWriter::writeOneByteString( |
| 112 v8::Local<v8::String>& string) { | 128 v8::Local<v8::String>& string) { |
| 113 int stringLength = string->Length(); | 129 int stringLength = string->Length(); |
| 114 int utf8Length = string->Utf8Length(); | 130 int utf8Length = string->Utf8Length(); |
| 115 ASSERT(stringLength >= 0 && utf8Length >= 0); | 131 ASSERT(stringLength >= 0 && utf8Length >= 0); |
| 116 | 132 |
| 117 append(StringTag); | 133 append(StringTag); |
| 118 doWriteUint32(static_cast<uint32_t>(utf8Length)); | 134 doWriteUint32(static_cast<uint32_t>(utf8Length)); |
| 119 ensureSpace(utf8Length); | 135 ensureSpace(utf8Length); |
| 120 | 136 |
| 121 // ASCII fast path. | 137 // ASCII fast path. |
| 122 if (stringLength == utf8Length) { | 138 if (stringLength == utf8Length) { |
| 123 string->WriteOneByte(byteAt(m_position), 0, utf8Length, | 139 writeRawStringBytes(string); |
| 124 v8StringWriteOptions()); | |
| 125 } else { | 140 } else { |
| 126 char* buffer = reinterpret_cast<char*>(byteAt(m_position)); | 141 writeUtf8String(string); |
| 127 string->WriteUtf8(buffer, utf8Length, 0, v8StringWriteOptions()); | |
| 128 } | 142 } |
| 129 m_position += utf8Length; | |
| 130 } | 143 } |
| 131 | 144 |
| 132 void SerializedScriptValueWriter::writeUCharString( | 145 void SerializedScriptValueWriter::writeUCharString( |
| 133 v8::Local<v8::String>& string) { | 146 v8::Local<v8::String>& string) { |
| 134 int length = string->Length(); | 147 int length = string->Length(); |
| 135 ASSERT(length >= 0); | 148 ASSERT(length >= 0); |
| 136 | 149 |
| 137 int size = length * sizeof(UChar); | 150 int size = length * sizeof(UChar); |
| 138 int bytes = bytesNeededToWireEncode(static_cast<uint32_t>(size)); | 151 int bytes = bytesNeededToWireEncode(static_cast<uint32_t>(size)); |
| 139 if ((m_position + 1 + bytes) & 1) | 152 if ((m_position + 1 + bytes) & 1) |
| (...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 return nullptr; | 1262 return nullptr; |
| 1250 } | 1263 } |
| 1251 | 1264 |
| 1252 ScriptValueSerializer::StateBase* | 1265 ScriptValueSerializer::StateBase* |
| 1253 ScriptValueSerializer::writeWasmCompiledModule(v8::Local<v8::Object> object, | 1266 ScriptValueSerializer::writeWasmCompiledModule(v8::Local<v8::Object> object, |
| 1254 StateBase* next) { | 1267 StateBase* next) { |
| 1255 CHECK(RuntimeEnabledFeatures::webAssemblySerializationEnabled()); | 1268 CHECK(RuntimeEnabledFeatures::webAssemblySerializationEnabled()); |
| 1256 // TODO (mtrofin): explore mechanism avoiding data copying / buffer resizing. | 1269 // TODO (mtrofin): explore mechanism avoiding data copying / buffer resizing. |
| 1257 v8::Local<v8::WasmCompiledModule> wasmModule = | 1270 v8::Local<v8::WasmCompiledModule> wasmModule = |
| 1258 object.As<v8::WasmCompiledModule>(); | 1271 object.As<v8::WasmCompiledModule>(); |
| 1272 v8::Local<v8::String> wireBytes = wasmModule->GetWasmWireBytes(); |
| 1273 DCHECK(wireBytes->IsOneByte()); |
| 1274 |
| 1259 v8::WasmCompiledModule::SerializedModule data = wasmModule->Serialize(); | 1275 v8::WasmCompiledModule::SerializedModule data = wasmModule->Serialize(); |
| 1260 m_writer.append(WasmModuleTag); | 1276 m_writer.append(WasmModuleTag); |
| 1277 uint32_t wireBytesLength = static_cast<uint32_t>(wireBytes->Length()); |
| 1278 // We place a tag so we may evolve the format in which we store the |
| 1279 // wire bytes. We plan to move them to a blob. |
| 1280 // We want to control how we write the string, though, so we explicitly |
| 1281 // call writeRawStringBytes. |
| 1282 m_writer.append(RawBytesTag); |
| 1283 m_writer.doWriteUint32(wireBytesLength); |
| 1284 m_writer.ensureSpace(wireBytesLength); |
| 1285 m_writer.writeRawStringBytes(wireBytes); |
| 1261 m_writer.doWriteUint32(static_cast<uint32_t>(data.second)); | 1286 m_writer.doWriteUint32(static_cast<uint32_t>(data.second)); |
| 1262 m_writer.append(data.first.get(), static_cast<int>(data.second)); | 1287 m_writer.append(data.first.get(), static_cast<int>(data.second)); |
| 1263 return nullptr; | 1288 return nullptr; |
| 1264 } | 1289 } |
| 1265 | 1290 |
| 1266 ScriptValueSerializer::StateBase* | 1291 ScriptValueSerializer::StateBase* |
| 1267 ScriptValueSerializer::writeAndGreyArrayBuffer(v8::Local<v8::Object> object, | 1292 ScriptValueSerializer::writeAndGreyArrayBuffer(v8::Local<v8::Object> object, |
| 1268 StateBase* next) { | 1293 StateBase* next) { |
| 1269 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(object); | 1294 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(object); |
| 1270 if (!arrayBuffer) | 1295 if (!arrayBuffer) |
| (...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1946 if (m_position + byteLength > m_length) | 1971 if (m_position + byteLength > m_length) |
| 1947 return nullptr; | 1972 return nullptr; |
| 1948 const void* bufferStart = m_buffer + m_position; | 1973 const void* bufferStart = m_buffer + m_position; |
| 1949 m_position += byteLength; | 1974 m_position += byteLength; |
| 1950 return DOMArrayBuffer::create(bufferStart, byteLength); | 1975 return DOMArrayBuffer::create(bufferStart, byteLength); |
| 1951 } | 1976 } |
| 1952 | 1977 |
| 1953 bool SerializedScriptValueReader::readWasmCompiledModule( | 1978 bool SerializedScriptValueReader::readWasmCompiledModule( |
| 1954 v8::Local<v8::Value>* value) { | 1979 v8::Local<v8::Value>* value) { |
| 1955 CHECK(RuntimeEnabledFeatures::webAssemblySerializationEnabled()); | 1980 CHECK(RuntimeEnabledFeatures::webAssemblySerializationEnabled()); |
| 1956 uint32_t size = 0; | 1981 // First, read the tag of the wire bytes. |
| 1957 if (!doReadUint32(&size)) | 1982 SerializationTag wireBytesFormat = InvalidTag; |
| 1983 if (!readTag(&wireBytesFormat)) |
| 1958 return false; | 1984 return false; |
| 1959 if (m_position + size > m_length) | 1985 DCHECK(wireBytesFormat == RawBytesTag); |
| 1986 // Just like when writing, we don't rely on the default string serialization |
| 1987 // mechanics for the wire bytes. We don't even want a string, because |
| 1988 // that would lead to a memory copying API implementation on the V8 side. |
| 1989 uint32_t wireBytesSize = 0; |
| 1990 uint32_t compiledBytesSize = 0; |
| 1991 if (!doReadUint32(&wireBytesSize)) |
| 1960 return false; | 1992 return false; |
| 1961 const uint8_t* buf = m_buffer + m_position; | 1993 if (m_position + wireBytesSize > m_length) |
| 1962 // TODO(mtrofin): simplify deserializer API. const uint8_t* + size_t should | 1994 return false; |
| 1963 // be sufficient. | 1995 const uint8_t* wireBytesStart = m_buffer + m_position; |
| 1964 v8::WasmCompiledModule::SerializedModule data = { | 1996 m_position += wireBytesSize; |
| 1965 std::unique_ptr<const uint8_t[]>(buf), static_cast<size_t>(size)}; | 1997 |
| 1998 if (!doReadUint32(&compiledBytesSize)) |
| 1999 return false; |
| 2000 if (m_position + compiledBytesSize > m_length) |
| 2001 return false; |
| 2002 const uint8_t* compiledBytesStart = m_buffer + m_position; |
| 2003 m_position += compiledBytesSize; |
| 2004 |
| 2005 v8::WasmCompiledModule::CallerOwnedBuffer wireBytes = { |
| 2006 wireBytesStart, static_cast<size_t>(wireBytesSize)}; |
| 2007 |
| 2008 v8::WasmCompiledModule::CallerOwnedBuffer compiledBytes = { |
| 2009 compiledBytesStart, static_cast<size_t>(compiledBytesSize)}; |
| 2010 |
| 1966 v8::MaybeLocal<v8::WasmCompiledModule> retval = | 2011 v8::MaybeLocal<v8::WasmCompiledModule> retval = |
| 1967 v8::WasmCompiledModule::Deserialize(isolate(), data); | 2012 v8::WasmCompiledModule::DeserializeOrCompile(isolate(), compiledBytes, |
| 1968 data.first.release(); | 2013 wireBytes); |
| 1969 m_position += size; | |
| 1970 | 2014 |
| 1971 // TODO(mtrofin): right now, we'll return undefined if the deserialization | |
| 1972 // fails, which is what may happen when v8's version changes. Update when | |
| 1973 // spec settles. crbug.com/639090 | |
| 1974 return retval.ToLocal(value); | 2015 return retval.ToLocal(value); |
| 1975 } | 2016 } |
| 1976 | 2017 |
| 1977 bool SerializedScriptValueReader::readArrayBuffer(v8::Local<v8::Value>* value) { | 2018 bool SerializedScriptValueReader::readArrayBuffer(v8::Local<v8::Value>* value) { |
| 1978 DOMArrayBuffer* arrayBuffer = doReadArrayBuffer(); | 2019 DOMArrayBuffer* arrayBuffer = doReadArrayBuffer(); |
| 1979 if (!arrayBuffer) | 2020 if (!arrayBuffer) |
| 1980 return false; | 2021 return false; |
| 1981 *value = toV8(arrayBuffer, m_scriptState->context()->Global(), isolate()); | 2022 *value = toV8(arrayBuffer, m_scriptState->context()->Global(), isolate()); |
| 1982 return !value->IsEmpty(); | 2023 return !value->IsEmpty(); |
| 1983 } | 2024 } |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2635 m_openCompositeReferenceStack[m_openCompositeReferenceStack.size() - 1]; | 2676 m_openCompositeReferenceStack[m_openCompositeReferenceStack.size() - 1]; |
| 2636 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - | 2677 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - |
| 2637 1); | 2678 1); |
| 2638 if (objectReference >= m_objectPool.size()) | 2679 if (objectReference >= m_objectPool.size()) |
| 2639 return false; | 2680 return false; |
| 2640 *object = m_objectPool[objectReference]; | 2681 *object = m_objectPool[objectReference]; |
| 2641 return true; | 2682 return true; |
| 2642 } | 2683 } |
| 2643 | 2684 |
| 2644 } // namespace blink | 2685 } // namespace blink |
| OLD | NEW |