Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp

Issue 2386173002: reflow comments in Source/bindings/core/v8 (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 const int maxDepth = 20000; 69 const int maxDepth = 20000;
70 70
71 bool shouldCheckForCycles(int depth) { 71 bool shouldCheckForCycles(int depth) {
72 ASSERT(depth >= 0); 72 ASSERT(depth >= 0);
73 // Since we are not required to spot the cycle as soon as it 73 // Since we are not required to spot the cycle as soon as it
74 // happens we can check for cycles only when the current depth 74 // happens we can check for cycles only when the current depth
75 // is a power of two. 75 // is a power of two.
76 return !(depth & (depth - 1)); 76 return !(depth & (depth - 1));
77 } 77 }
78 78
79 // Returns true if the provided object is to be considered a 'host object', as u sed in the 79 // Returns true if the provided object is to be considered a 'host object', as
80 // HTML5 structured clone algorithm. 80 // used in the HTML5 structured clone algorithm.
81 bool isHostObject(v8::Local<v8::Object> object) { 81 bool isHostObject(v8::Local<v8::Object> object) {
82 // If the object has any internal fields, then we won't be able to serialize o r deserialize 82 // If the object has any internal fields, then we won't be able to serialize
83 // them; conveniently, this is also a quick way to detect DOM wrapper objects, because 83 // or deserialize them; conveniently, this is also a quick way to detect DOM
84 // the mechanism for these relies on data stored in these fields. We should 84 // wrapper objects, because the mechanism for these relies on data stored in
85 // catch external array data as a special case. 85 // these fields. We should catch external array data as a special case.
86 return object->InternalFieldCount(); 86 return object->InternalFieldCount();
87 } 87 }
88 88
89 } // namespace 89 } // namespace
90 90
91 void SerializedScriptValueWriter::writeUndefined() { 91 void SerializedScriptValueWriter::writeUndefined() {
92 append(UndefinedTag); 92 append(UndefinedTag);
93 } 93 }
94 94
95 void SerializedScriptValueWriter::writeNull() { 95 void SerializedScriptValueWriter::writeNull() {
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 hasProperty = v8CallBoolean(composite()->HasRealIndexedProperty( 568 hasProperty = v8CallBoolean(composite()->HasRealIndexedProperty(
569 serializer.context(), propertyName.As<v8::Uint32>()->Value())); 569 serializer.context(), propertyName.As<v8::Uint32>()->Value()));
570 } 570 }
571 if (StateBase* newState = serializer.checkException(this)) 571 if (StateBase* newState = serializer.checkException(this))
572 return newState; 572 return newState;
573 if (!hasProperty) { 573 if (!hasProperty) {
574 ++m_index; 574 ++m_index;
575 continue; 575 continue;
576 } 576 }
577 577
578 // |propertyName| is v8::String or v8::Uint32, so its serialization cannot b e recursive. 578 // |propertyName| is v8::String or v8::Uint32, so its serialization cannot
579 // be recursive.
579 serializer.doSerialize(propertyName, nullptr); 580 serializer.doSerialize(propertyName, nullptr);
580 581
581 v8::Local<v8::Value> value; 582 v8::Local<v8::Value> value;
582 if (!composite()->Get(serializer.context(), propertyName).ToLocal(&value)) 583 if (!composite()->Get(serializer.context(), propertyName).ToLocal(&value))
583 return serializer.handleError( 584 return serializer.handleError(
584 Status::JSException, 585 Status::JSException,
585 "Failed to get a property while cloning an object.", this); 586 "Failed to get a property while cloning an object.", this);
586 ++m_index; 587 ++m_index;
587 ++m_numSerializedProperties; 588 ++m_numSerializedProperties;
588 // If we return early here, it's either because we have pushed a new state o nto the 589 // If we return early here, it's either because we have pushed a new state
589 // serialization state stack or because we have encountered an error (and in both cases 590 // onto the serialization state stack or because we have encountered an
590 // we are unwinding the native stack). 591 // error (and in both cases we are unwinding the native stack).
591 if (StateBase* newState = serializer.doSerialize(value, this)) 592 if (StateBase* newState = serializer.doSerialize(value, this))
592 return newState; 593 return newState;
593 } 594 }
594 return objectDone(m_numSerializedProperties, serializer); 595 return objectDone(m_numSerializedProperties, serializer);
595 } 596 }
596 597
597 ScriptValueSerializer::StateBase* ScriptValueSerializer::ObjectState::advance( 598 ScriptValueSerializer::StateBase* ScriptValueSerializer::ObjectState::advance(
598 ScriptValueSerializer& serializer) { 599 ScriptValueSerializer& serializer) {
599 if (m_propertyNames.IsEmpty()) { 600 if (m_propertyNames.IsEmpty()) {
600 if (!composite() 601 if (!composite()
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 return nullptr; 963 return nullptr;
963 } 964 }
964 if (object->IsRegExp()) { 965 if (object->IsRegExp()) {
965 writeRegExp(object); 966 writeRegExp(object);
966 return nullptr; 967 return nullptr;
967 } 968 }
968 if (V8CompositorProxy::hasInstance(object, isolate())) { 969 if (V8CompositorProxy::hasInstance(object, isolate())) {
969 return writeCompositorProxy(object, next); 970 return writeCompositorProxy(object, next);
970 } 971 }
971 972
972 // Since IsNativeError is expensive, this check should always be the last chec k. 973 // Since IsNativeError is expensive, this check should always be the last
974 // check.
973 if (isHostObject(object) || object->IsCallable() || object->IsNativeError()) { 975 if (isHostObject(object) || object->IsCallable() || object->IsNativeError()) {
974 return handleError(Status::DataCloneError, "An object could not be cloned.", 976 return handleError(Status::DataCloneError, "An object could not be cloned.",
975 next); 977 next);
976 } 978 }
977 979
978 return startObjectState(object, next); 980 return startObjectState(object, next);
979 } 981 }
980 982
981 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeArrayBuffer( 983 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeArrayBuffer(
982 v8::Local<v8::Value> arrayBuffer, 984 v8::Local<v8::Value> arrayBuffer,
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 v8::Local<v8::Value> underlyingBuffer = 1226 v8::Local<v8::Value> underlyingBuffer =
1225 toV8(arrayBufferView->bufferBase(), m_scriptState->context()->Global(), 1227 toV8(arrayBufferView->bufferBase(), m_scriptState->context()->Global(),
1226 isolate()); 1228 isolate());
1227 if (underlyingBuffer.IsEmpty()) 1229 if (underlyingBuffer.IsEmpty())
1228 return handleError(Status::DataCloneError, 1230 return handleError(Status::DataCloneError,
1229 "An ArrayBuffer could not be cloned.", next); 1231 "An ArrayBuffer could not be cloned.", next);
1230 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); 1232 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next);
1231 if (stateOut) 1233 if (stateOut)
1232 return stateOut; 1234 return stateOut;
1233 m_writer.writeArrayBufferView(*arrayBufferView); 1235 m_writer.writeArrayBufferView(*arrayBufferView);
1234 // This should be safe: we serialize something that we know to be a wrapper (s ee 1236 // This should be safe: we serialize something that we know to be a wrapper
1235 // the toV8 call above), so the call to doSerializeArrayBuffer should neither 1237 // (see the toV8 call above), so the call to doSerializeArrayBuffer should
1236 // cause the system stack to overflow nor should it have potential to reach 1238 // neither cause the system stack to overflow nor should it have potential to
1237 // this ArrayBufferView again. 1239 // reach this ArrayBufferView again.
1238 // 1240 //
1239 // We do need to grey the underlying buffer before we grey its view, however; 1241 // We do need to grey the underlying buffer before we grey its view, however;
1240 // ArrayBuffers may be shared, so they need to be given reference IDs, and an 1242 // ArrayBuffers may be shared, so they need to be given reference IDs, and an
1241 // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer 1243 // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer
1242 // (or without an additional tag that would allow us to do two-stage construct ion 1244 // (or without an additional tag that would allow us to do two-stage
1243 // like we do for Objects and Arrays). 1245 // construction like we do for Objects and Arrays).
1244 greyObject(object); 1246 greyObject(object);
1245 return nullptr; 1247 return nullptr;
1246 } 1248 }
1247 1249
1248 ScriptValueSerializer::StateBase* 1250 ScriptValueSerializer::StateBase*
1249 ScriptValueSerializer::writeWasmCompiledModule(v8::Local<v8::Object> object, 1251 ScriptValueSerializer::writeWasmCompiledModule(v8::Local<v8::Object> object,
1250 StateBase* next) { 1252 StateBase* next) {
1251 CHECK(RuntimeEnabledFeatures::webAssemblySerializationEnabled()); 1253 CHECK(RuntimeEnabledFeatures::webAssemblySerializationEnabled());
1252 // TODO (mtrofin): explore mechanism avoiding data copying / buffer resizing. 1254 // TODO (mtrofin): explore mechanism avoiding data copying / buffer resizing.
1253 v8::Local<v8::WasmCompiledModule> wasmModule = 1255 v8::Local<v8::WasmCompiledModule> wasmModule =
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 V8SharedArrayBuffer::toImpl(value.As<v8::Object>()); 1315 V8SharedArrayBuffer::toImpl(value.As<v8::Object>());
1314 if (!sharedArrayBuffer) 1316 if (!sharedArrayBuffer)
1315 return 0; 1317 return 0;
1316 m_writer.writeTransferredSharedArrayBuffer(index); 1318 m_writer.writeTransferredSharedArrayBuffer(index);
1317 return nullptr; 1319 return nullptr;
1318 } 1320 }
1319 1321
1320 bool ScriptValueSerializer::shouldSerializeDensely(uint32_t length, 1322 bool ScriptValueSerializer::shouldSerializeDensely(uint32_t length,
1321 uint32_t propertyCount) { 1323 uint32_t propertyCount) {
1322 // Let K be the cost of serializing all property values that are there 1324 // Let K be the cost of serializing all property values that are there
1323 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t key ) 1325 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t
1324 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for all properties that are not there) 1326 // key)
1327 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for all
1328 // properties that are not there)
1325 // so densely is better than sparsly whenever 6*propertyCount > length 1329 // so densely is better than sparsly whenever 6*propertyCount > length
1326 return 6 * propertyCount >= length; 1330 return 6 * propertyCount >= length;
1327 } 1331 }
1328 1332
1329 ScriptValueSerializer::StateBase* ScriptValueSerializer::startArrayState( 1333 ScriptValueSerializer::StateBase* ScriptValueSerializer::startArrayState(
1330 v8::Local<v8::Array> array, 1334 v8::Local<v8::Array> array,
1331 StateBase* next) { 1335 StateBase* next) {
1332 v8::Local<v8::Array> propertyNames; 1336 v8::Local<v8::Array> propertyNames;
1333 if (!array->GetOwnPropertyNames(context()).ToLocal(&propertyNames)) 1337 if (!array->GetOwnPropertyNames(context()).ToLocal(&propertyNames))
1334 return checkException(next); 1338 return checkException(next);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 } 1373 }
1370 1374
1371 ScriptValueSerializer::StateBase* ScriptValueSerializer::startObjectState( 1375 ScriptValueSerializer::StateBase* ScriptValueSerializer::startObjectState(
1372 v8::Local<v8::Object> object, 1376 v8::Local<v8::Object> object,
1373 StateBase* next) { 1377 StateBase* next) {
1374 m_writer.writeGenerateFreshObject(); 1378 m_writer.writeGenerateFreshObject();
1375 // FIXME: check not a wrapper 1379 // FIXME: check not a wrapper
1376 return push(new ObjectState(object, next)); 1380 return push(new ObjectState(object, next));
1377 } 1381 }
1378 1382
1379 // Marks object as having been visited by the serializer and assigns it a unique object reference ID. 1383 // Marks object as having been visited by the serializer and assigns it a unique
1380 // An object may only be greyed once. 1384 // object reference ID. An object may only be greyed once.
1381 void ScriptValueSerializer::greyObject(const v8::Local<v8::Object>& object) { 1385 void ScriptValueSerializer::greyObject(const v8::Local<v8::Object>& object) {
1382 ASSERT(!m_objectPool.contains(object)); 1386 ASSERT(!m_objectPool.contains(object));
1383 uint32_t objectReference = m_nextObjectReference++; 1387 uint32_t objectReference = m_nextObjectReference++;
1384 m_objectPool.set(object, objectReference); 1388 m_objectPool.set(object, objectReference);
1385 } 1389 }
1386 1390
1387 bool ScriptValueSerializer::appendBlobInfo(const String& uuid, 1391 bool ScriptValueSerializer::appendBlobInfo(const String& uuid,
1388 const String& type, 1392 const String& type,
1389 unsigned long long size, 1393 unsigned long long size,
1390 int* index) { 1394 int* index) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 SerializationTag tag, 1426 SerializationTag tag,
1423 v8::Local<v8::Value>* value, 1427 v8::Local<v8::Value>* value,
1424 ScriptValueDeserializer& deserializer) { 1428 ScriptValueDeserializer& deserializer) {
1425 switch (tag) { 1429 switch (tag) {
1426 case ReferenceCountTag: { 1430 case ReferenceCountTag: {
1427 if (!m_version) 1431 if (!m_version)
1428 return false; 1432 return false;
1429 uint32_t referenceTableSize; 1433 uint32_t referenceTableSize;
1430 if (!doReadUint32(&referenceTableSize)) 1434 if (!doReadUint32(&referenceTableSize))
1431 return false; 1435 return false;
1432 // If this test fails, then the serializer and deserializer disagree about the assignment 1436 // If this test fails, then the serializer and deserializer disagree about
1433 // of object reference IDs. On the deserialization side, this means there are too many or too few 1437 // the assignment of object reference IDs. On the deserialization side,
1434 // calls to pushObjectReference. 1438 // this means there are too many or too few calls to pushObjectReference.
1435 if (referenceTableSize != deserializer.objectReferenceCount()) 1439 if (referenceTableSize != deserializer.objectReferenceCount())
1436 return false; 1440 return false;
1437 return true; 1441 return true;
1438 } 1442 }
1439 case InvalidTag: 1443 case InvalidTag:
1440 return false; 1444 return false;
1441 case PaddingTag: 1445 case PaddingTag:
1442 return true; 1446 return true;
1443 case UndefinedTag: 1447 case UndefinedTag:
1444 *value = v8::Undefined(isolate()); 1448 *value = v8::Undefined(isolate());
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after
2258 for (unsigned i = 0; i < sizeof(double); ++i) 2262 for (unsigned i = 0; i < sizeof(double); ++i)
2259 numberAsByteArray[i] = m_buffer[m_position++]; 2263 numberAsByteArray[i] = m_buffer[m_position++];
2260 return true; 2264 return true;
2261 } 2265 }
2262 2266
2263 PassRefPtr<BlobDataHandle> 2267 PassRefPtr<BlobDataHandle>
2264 SerializedScriptValueReader::getOrCreateBlobDataHandle(const String& uuid, 2268 SerializedScriptValueReader::getOrCreateBlobDataHandle(const String& uuid,
2265 const String& type, 2269 const String& type,
2266 long long size) { 2270 long long size) {
2267 // The containing ssv may have a BDH for this uuid if this ssv is just being 2271 // The containing ssv may have a BDH for this uuid if this ssv is just being
2268 // passed from main to worker thread (for example). We use those values when c reating 2272 // passed from main to worker thread (for example). We use those values when
2269 // the new blob instead of cons'ing up a new BDH. 2273 // creating the new blob instead of cons'ing up a new BDH.
2270 // 2274 //
2271 // FIXME: Maybe we should require that it work that way where the ssv must hav e a BDH for any 2275 // FIXME: Maybe we should require that it work that way where the ssv must
2272 // blobs it comes across during deserialization. Would require callers to expl icitly populate 2276 // have a BDH for any blobs it comes across during deserialization. Would
2273 // the collection of BDH's for blobs to work, which would encourage lifetimes to be considered 2277 // require callers to explicitly populate the collection of BDH's for blobs to
2274 // when passing ssv's around cross process. At present, we get 'lucky' in some cases because 2278 // work, which would encourage lifetimes to be considered when passing ssv's
2275 // the blob in the src process happens to still exist at the time the dest pro cess is deserializing. 2279 // around cross process. At present, we get 'lucky' in some cases because the
2280 // blob in the src process happens to still exist at the time the dest process
2281 // is deserializing.
2276 // For example in sharedWorker.postMessage(...). 2282 // For example in sharedWorker.postMessage(...).
2277 BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid); 2283 BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid);
2278 if (it != m_blobDataHandles.end()) { 2284 if (it != m_blobDataHandles.end()) {
2279 // make assertions about type and size? 2285 // make assertions about type and size?
2280 return it->value; 2286 return it->value;
2281 } 2287 }
2282 return BlobDataHandle::create(uuid, type, size); 2288 return BlobDataHandle::create(uuid, type, size);
2283 } 2289 }
2284 2290
2285 v8::Local<v8::Value> ScriptValueDeserializer::deserialize() { 2291 v8::Local<v8::Value> ScriptValueDeserializer::deserialize() {
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
2623 m_openCompositeReferenceStack[m_openCompositeReferenceStack.size() - 1]; 2629 m_openCompositeReferenceStack[m_openCompositeReferenceStack.size() - 1];
2624 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 2630 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() -
2625 1); 2631 1);
2626 if (objectReference >= m_objectPool.size()) 2632 if (objectReference >= m_objectPool.size())
2627 return false; 2633 return false;
2628 *object = m_objectPool[objectReference]; 2634 *object = m_objectPool[objectReference];
2629 return true; 2635 return true;
2630 } 2636 }
2631 2637
2632 } // namespace blink 2638 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698