Commit e28e1e56 authored by jbroman's avatar jbroman Committed by Commit bot

Support structured clone atop v8::ValueSerializer behind a RuntimeEnabledFeature.

There is further refactoring to be done to clean this up, but this is sufficient
to make things mostly work. Notably this still does a copy into a 16-bit WTF::String
because at present there is a significant amount of other code that assumes this.

BUG=148757

Review-Url: https://codereview.chromium.org/2277403002
Cr-Commit-Position: refs/heads/master@{#415195}
parent f1b0eb09
......@@ -735,6 +735,29 @@ static void recordValueCounts(int primitiveCount, int jsObjectCount, int domWrap
PassRefPtr<SerializedScriptValue> ScriptValueSerializer::serialize(v8::Local<v8::Value> value, Transferables* transferables, ExceptionState& exceptionState)
{
if (RuntimeEnabledFeatures::v8BasedStructuredCloneEnabled()) {
v8::HandleScope scope(isolate());
v8::ValueSerializer serializer(isolate());
serializer.WriteHeader();
bool wroteValue;
if (!serializer.WriteValue(context(), value).To(&wroteValue)) {
// TODO(jbroman): Revisit how DataCloneError is thrown.
// https://crbug.com/641964
if (m_tryCatch.HasCaught()) {
exceptionState.rethrowV8Exception(m_tryCatch.Exception());
} else {
exceptionState.throwDOMException(DataCloneError, "An object could not be cloned.");
}
return nullptr;
}
DCHECK(wroteValue);
std::vector<uint8_t> buffer = serializer.ReleaseBuffer();
// TODO(jbroman): Remove this old conversion to WTF::String.
if (buffer.size() % 2)
buffer.push_back(0);
return SerializedScriptValue::create(String(reinterpret_cast<const UChar*>(&buffer[0]), buffer.size() / 2));
}
m_primitiveCount = m_jsObjectCount = m_domWrapperCount = 0;
DCHECK(!m_blobDataHandles);
......@@ -2127,6 +2150,23 @@ PassRefPtr<BlobDataHandle> SerializedScriptValueReader::getOrCreateBlobDataHandl
v8::Local<v8::Value> ScriptValueDeserializer::deserialize()
{
v8::Isolate* isolate = m_reader.getScriptState()->isolate();
if (RuntimeEnabledFeatures::v8BasedStructuredCloneEnabled()) {
v8::EscapableHandleScope scope(isolate);
v8::TryCatch tryCatch(isolate);
v8::ValueDeserializer deserializer(isolate, m_reader.buffer(), m_reader.length());
deserializer.SetSupportsLegacyWireFormat(true);
bool readHeader;
if (!deserializer.ReadHeader().To(&readHeader))
return v8::Null(isolate);
DCHECK(readHeader);
v8::Local<v8::Context> context = m_reader.getScriptState()->context();
v8::Local<v8::Value> value;
if (!deserializer.ReadValue(context).ToLocal(&value))
return v8::Null(isolate);
return scope.Escape(value);
}
if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::wireFormatVersion)
return v8::Null(isolate);
m_reader.setVersion(m_version);
......
......@@ -483,10 +483,14 @@ public:
bool readVersion(uint32_t& version);
void setVersion(uint32_t);
// Used to extract the underlying buffer, in order to bypass
// SerializedScriptValueReader.
const uint8_t* buffer() const { return m_buffer; }
unsigned length() const { return m_length; }
protected:
v8::Isolate* isolate() const { return m_scriptState->isolate(); }
v8::Local<v8::Context> context() const { return m_scriptState->context(); }
unsigned length() const { return m_length; }
unsigned position() const { return m_position; }
const uint8_t* allocate(uint32_t size)
......
......@@ -232,6 +232,7 @@ WebGLImageChromium
WebUSB status=experimental, origin_trial_feature_name=WebUSB
WebVR
WebVTTRegions status=experimental
V8BasedStructuredClone
V8IdleTasks
VisibilityChangeOnUnload status=experimental
XSLT status=stable
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment