Chromium Code Reviews| 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> uncompiledBytes = wasmModule->GetWasmWireBytes(); | |
| 1273 DCHECK(uncompiledBytes->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 uncompiledBytesLength = | |
| 1278 static_cast<uint32_t>(uncompiledBytes->Length()); | |
| 1279 // We place a tag so we may evolve the format in which we store the | |
| 1280 // uncompiled bytes. We plan to move them to a blob. | |
| 1281 // We want to control how we write the string, though, so we explicitly | |
| 1282 // call writeRawStringBytes. | |
| 1283 m_writer.append(RawBytesTag); | |
| 1284 m_writer.doWriteUint32(uncompiledBytesLength); | |
| 1285 m_writer.ensureSpace(uncompiledBytesLength); | |
| 1286 m_writer.writeRawStringBytes(uncompiledBytes); | |
| 1261 m_writer.doWriteUint32(static_cast<uint32_t>(data.second)); | 1287 m_writer.doWriteUint32(static_cast<uint32_t>(data.second)); |
| 1262 m_writer.append(data.first.get(), static_cast<int>(data.second)); | 1288 m_writer.append(data.first.get(), static_cast<int>(data.second)); |
| 1263 return nullptr; | 1289 return nullptr; |
| 1264 } | 1290 } |
| 1265 | 1291 |
| 1266 ScriptValueSerializer::StateBase* | 1292 ScriptValueSerializer::StateBase* |
| 1267 ScriptValueSerializer::writeAndGreyArrayBuffer(v8::Local<v8::Object> object, | 1293 ScriptValueSerializer::writeAndGreyArrayBuffer(v8::Local<v8::Object> object, |
| 1268 StateBase* next) { | 1294 StateBase* next) { |
| 1269 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(object); | 1295 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(object); |
| 1270 if (!arrayBuffer) | 1296 if (!arrayBuffer) |
| (...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1946 if (m_position + byteLength > m_length) | 1972 if (m_position + byteLength > m_length) |
| 1947 return nullptr; | 1973 return nullptr; |
| 1948 const void* bufferStart = m_buffer + m_position; | 1974 const void* bufferStart = m_buffer + m_position; |
| 1949 m_position += byteLength; | 1975 m_position += byteLength; |
| 1950 return DOMArrayBuffer::create(bufferStart, byteLength); | 1976 return DOMArrayBuffer::create(bufferStart, byteLength); |
| 1951 } | 1977 } |
| 1952 | 1978 |
| 1953 bool SerializedScriptValueReader::readWasmCompiledModule( | 1979 bool SerializedScriptValueReader::readWasmCompiledModule( |
| 1954 v8::Local<v8::Value>* value) { | 1980 v8::Local<v8::Value>* value) { |
| 1955 CHECK(RuntimeEnabledFeatures::webAssemblySerializationEnabled()); | 1981 CHECK(RuntimeEnabledFeatures::webAssemblySerializationEnabled()); |
| 1956 uint32_t size = 0; | 1982 // First, read the tag of the uncompiled bytes. |
| 1957 if (!doReadUint32(&size)) | 1983 SerializationTag uncompiledBytesFormat = InvalidTag; |
|
titzer
2016/10/19 14:27:35
wireBytesFormat?
| |
| 1984 if (!readTag(&uncompiledBytesFormat)) | |
| 1958 return false; | 1985 return false; |
| 1959 if (m_position + size > m_length) | 1986 DCHECK(uncompiledBytesFormat == RawBytesTag); |
| 1987 // Just like when writing, we don't rely on the default string serialization | |
| 1988 // mechanics for the uncompiled bytes. We don't even want a string, because | |
| 1989 // that would lead to a memory copying API implementation on the V8 side. | |
| 1990 uint32_t uncompiledBytesSize = 0; | |
| 1991 uint32_t compiledBytesSize = 0; | |
| 1992 if (!doReadUint32(&uncompiledBytesSize)) | |
| 1960 return false; | 1993 return false; |
| 1961 const uint8_t* buf = m_buffer + m_position; | 1994 if (m_position + uncompiledBytesSize > m_length) |
| 1962 // TODO(mtrofin): simplify deserializer API. const uint8_t* + size_t should | 1995 return false; |
| 1963 // be sufficient. | 1996 const uint8_t* uncompiledBytesStart = m_buffer + m_position; |
| 1964 v8::WasmCompiledModule::SerializedModule data = { | 1997 m_position += uncompiledBytesSize; |
| 1965 std::unique_ptr<const uint8_t[]>(buf), static_cast<size_t>(size)}; | 1998 |
| 1999 if (!doReadUint32(&compiledBytesSize)) | |
| 2000 return false; | |
| 2001 if (m_position + compiledBytesSize > m_length) | |
| 2002 return false; | |
| 2003 const uint8_t* compiledBytesStart = m_buffer + m_position; | |
| 2004 m_position += compiledBytesSize; | |
| 2005 | |
| 2006 v8::WasmCompiledModule::CallerOwnedBuffer uncompiledBytes = { | |
| 2007 uncompiledBytesStart, static_cast<size_t>(uncompiledBytesSize)}; | |
| 2008 | |
| 2009 v8::WasmCompiledModule::CallerOwnedBuffer compiledBytes = { | |
| 2010 compiledBytesStart, static_cast<size_t>(compiledBytesSize)}; | |
| 2011 | |
| 1966 v8::MaybeLocal<v8::WasmCompiledModule> retval = | 2012 v8::MaybeLocal<v8::WasmCompiledModule> retval = |
| 1967 v8::WasmCompiledModule::Deserialize(isolate(), data); | 2013 v8::WasmCompiledModule::DeserializeOrCompile(isolate(), compiledBytes, |
| 1968 data.first.release(); | 2014 uncompiledBytes); |
| 1969 m_position += size; | |
| 1970 | 2015 |
| 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); | 2016 return retval.ToLocal(value); |
| 1975 } | 2017 } |
| 1976 | 2018 |
| 1977 bool SerializedScriptValueReader::readArrayBuffer(v8::Local<v8::Value>* value) { | 2019 bool SerializedScriptValueReader::readArrayBuffer(v8::Local<v8::Value>* value) { |
| 1978 DOMArrayBuffer* arrayBuffer = doReadArrayBuffer(); | 2020 DOMArrayBuffer* arrayBuffer = doReadArrayBuffer(); |
| 1979 if (!arrayBuffer) | 2021 if (!arrayBuffer) |
| 1980 return false; | 2022 return false; |
| 1981 *value = toV8(arrayBuffer, m_scriptState->context()->Global(), isolate()); | 2023 *value = toV8(arrayBuffer, m_scriptState->context()->Global(), isolate()); |
| 1982 return !value->IsEmpty(); | 2024 return !value->IsEmpty(); |
| 1983 } | 2025 } |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2635 m_openCompositeReferenceStack[m_openCompositeReferenceStack.size() - 1]; | 2677 m_openCompositeReferenceStack[m_openCompositeReferenceStack.size() - 1]; |
| 2636 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - | 2678 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - |
| 2637 1); | 2679 1); |
| 2638 if (objectReference >= m_objectPool.size()) | 2680 if (objectReference >= m_objectPool.size()) |
| 2639 return false; | 2681 return false; |
| 2640 *object = m_objectPool[objectReference]; | 2682 *object = m_objectPool[objectReference]; |
| 2641 return true; | 2683 return true; |
| 2642 } | 2684 } |
| 2643 | 2685 |
| 2644 } // namespace blink | 2686 } // namespace blink |
| OLD | NEW |