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 "config.h" | 5 #include "config.h" |
6 #include "bindings/core/v8/ScriptValueSerializer.h" | 6 #include "bindings/core/v8/ScriptValueSerializer.h" |
7 | 7 |
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" |
11 #include "bindings/core/v8/V8CompositorProxy.h" | 11 #include "bindings/core/v8/V8CompositorProxy.h" |
12 #include "bindings/core/v8/V8File.h" | 12 #include "bindings/core/v8/V8File.h" |
13 #include "bindings/core/v8/V8FileList.h" | 13 #include "bindings/core/v8/V8FileList.h" |
| 14 #include "bindings/core/v8/V8ImageBitmap.h" |
14 #include "bindings/core/v8/V8ImageData.h" | 15 #include "bindings/core/v8/V8ImageData.h" |
15 #include "bindings/core/v8/V8MessagePort.h" | 16 #include "bindings/core/v8/V8MessagePort.h" |
16 #include "bindings/core/v8/V8SharedArrayBuffer.h" | 17 #include "bindings/core/v8/V8SharedArrayBuffer.h" |
17 #include "core/dom/CompositorProxy.h" | 18 #include "core/dom/CompositorProxy.h" |
18 #include "core/dom/DOMDataView.h" | 19 #include "core/dom/DOMDataView.h" |
19 #include "core/dom/DOMSharedArrayBuffer.h" | 20 #include "core/dom/DOMSharedArrayBuffer.h" |
20 #include "core/dom/DOMTypedArray.h" | 21 #include "core/dom/DOMTypedArray.h" |
21 #include "core/fileapi/Blob.h" | 22 #include "core/fileapi/Blob.h" |
22 #include "core/fileapi/File.h" | 23 #include "core/fileapi/File.h" |
23 #include "core/fileapi/FileList.h" | 24 #include "core/fileapi/FileList.h" |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 append(MessagePortTag); | 317 append(MessagePortTag); |
317 doWriteUint32(index); | 318 doWriteUint32(index); |
318 } | 319 } |
319 | 320 |
320 void SerializedScriptValueWriter::writeTransferredArrayBuffer(uint32_t index) | 321 void SerializedScriptValueWriter::writeTransferredArrayBuffer(uint32_t index) |
321 { | 322 { |
322 append(ArrayBufferTransferTag); | 323 append(ArrayBufferTransferTag); |
323 doWriteUint32(index); | 324 doWriteUint32(index); |
324 } | 325 } |
325 | 326 |
| 327 void SerializedScriptValueWriter::writeTransferredImageBitmap(uint32_t index) |
| 328 { |
| 329 append(ImageBitmapTransferTag); |
| 330 doWriteUint32(index); |
| 331 } |
| 332 |
326 void SerializedScriptValueWriter::writeTransferredSharedArrayBuffer(uint32_t ind
ex) | 333 void SerializedScriptValueWriter::writeTransferredSharedArrayBuffer(uint32_t ind
ex) |
327 { | 334 { |
328 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); | 335 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); |
329 append(SharedArrayBufferTransferTag); | 336 append(SharedArrayBufferTransferTag); |
330 doWriteUint32(index); | 337 doWriteUint32(index); |
331 } | 338 } |
332 | 339 |
333 void SerializedScriptValueWriter::writeObjectReference(uint32_t reference) | 340 void SerializedScriptValueWriter::writeObjectReference(uint32_t reference) |
334 { | 341 { |
335 append(ObjectReferenceTag); | 342 append(ObjectReferenceTag); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 { | 636 { |
630 if (!impl) | 637 if (!impl) |
631 return v8::Local<v8::Object>(); | 638 return v8::Local<v8::Object>(); |
632 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); | 639 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); |
633 if (wrapper.IsEmpty()) | 640 if (wrapper.IsEmpty()) |
634 return v8::Local<v8::Object>(); | 641 return v8::Local<v8::Object>(); |
635 ASSERT(wrapper->IsObject()); | 642 ASSERT(wrapper->IsObject()); |
636 return wrapper.As<v8::Object>(); | 643 return wrapper.As<v8::Object>(); |
637 } | 644 } |
638 | 645 |
| 646 static v8::Local<v8::Object> toV8Object(ImageBitmap* impl, v8::Local<v8::Object>
creationContext, v8::Isolate* isolate) |
| 647 { |
| 648 if (!impl) |
| 649 return v8::Local<v8::Object>(); |
| 650 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); |
| 651 if (wrapper.IsEmpty()) |
| 652 return v8::Local<v8::Object>(); |
| 653 return wrapper.As<v8::Object>(); |
| 654 } |
| 655 |
639 static v8::Local<v8::Object> toV8Object(DOMArrayBufferBase* impl, v8::Local<v8::
Object> creationContext, v8::Isolate* isolate) | 656 static v8::Local<v8::Object> toV8Object(DOMArrayBufferBase* impl, v8::Local<v8::
Object> creationContext, v8::Isolate* isolate) |
640 { | 657 { |
641 if (!impl) | 658 if (!impl) |
642 return v8::Local<v8::Object>(); | 659 return v8::Local<v8::Object>(); |
643 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); | 660 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); |
644 if (wrapper.IsEmpty()) | 661 if (wrapper.IsEmpty()) |
645 return v8::Local<v8::Object>(); | 662 return v8::Local<v8::Object>(); |
646 return wrapper.As<v8::Object>(); | 663 return wrapper.As<v8::Object>(); |
647 } | 664 } |
648 | 665 |
649 // Returns true if the provided object is to be considered a 'host object', as u
sed in the | 666 // Returns true if the provided object is to be considered a 'host object', as u
sed in the |
650 // HTML5 structured clone algorithm. | 667 // HTML5 structured clone algorithm. |
651 static bool isHostObject(v8::Local<v8::Object> object) | 668 static bool isHostObject(v8::Local<v8::Object> object) |
652 { | 669 { |
653 // If the object has any internal fields, then we won't be able to serialize
or deserialize | 670 // If the object has any internal fields, then we won't be able to serialize
or deserialize |
654 // them; conveniently, this is also a quick way to detect DOM wrapper object
s, because | 671 // them; conveniently, this is also a quick way to detect DOM wrapper object
s, because |
655 // the mechanism for these relies on data stored in these fields. We should | 672 // the mechanism for these relies on data stored in these fields. We should |
656 // catch external array data as a special case. | 673 // catch external array data as a special case. |
657 return object->InternalFieldCount(); | 674 return object->InternalFieldCount(); |
658 } | 675 } |
659 | 676 |
660 ScriptValueSerializer::ScriptValueSerializer(SerializedScriptValueWriter& writer
, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArr
ay* blobInfo, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, Script
State* scriptState) | 677 ScriptValueSerializer::ScriptValueSerializer(SerializedScriptValueWriter& writer
, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, ImageBitmapArr
ay* imageBitmaps, WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles
, v8::TryCatch& tryCatch, ScriptState* scriptState) |
661 : m_scriptState(scriptState) | 678 : m_scriptState(scriptState) |
662 , m_writer(writer) | 679 , m_writer(writer) |
663 , m_tryCatch(tryCatch) | 680 , m_tryCatch(tryCatch) |
664 , m_depth(0) | 681 , m_depth(0) |
665 , m_status(Success) | 682 , m_status(Success) |
666 , m_nextObjectReference(0) | 683 , m_nextObjectReference(0) |
667 , m_blobInfo(blobInfo) | 684 , m_blobInfo(blobInfo) |
668 , m_blobDataHandles(blobDataHandles) | 685 , m_blobDataHandles(blobDataHandles) |
669 { | 686 { |
670 ASSERT(!tryCatch.HasCaught()); | 687 ASSERT(!tryCatch.HasCaught()); |
671 v8::Local<v8::Object> creationContext = m_scriptState->context()->Global(); | 688 v8::Local<v8::Object> creationContext = m_scriptState->context()->Global(); |
672 if (messagePorts) { | 689 if (messagePorts) { |
673 for (size_t i = 0; i < messagePorts->size(); i++) | 690 for (size_t i = 0; i < messagePorts->size(); i++) |
674 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(),
creationContext, isolate()), i); | 691 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(),
creationContext, isolate()), i); |
675 } | 692 } |
676 if (arrayBuffers) { | 693 if (arrayBuffers) { |
677 for (size_t i = 0; i < arrayBuffers->size(); i++) { | 694 for (size_t i = 0; i < arrayBuffers->size(); i++) { |
678 v8::Local<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i)
.get(), creationContext, isolate()); | 695 v8::Local<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i)
.get(), creationContext, isolate()); |
679 // Coalesce multiple occurences of the same buffer to the first inde
x. | 696 // Coalesce multiple occurences of the same buffer to the first inde
x. |
680 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) | 697 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) |
681 m_transferredArrayBuffers.set(v8ArrayBuffer, i); | 698 m_transferredArrayBuffers.set(v8ArrayBuffer, i); |
682 } | 699 } |
683 } | 700 } |
| 701 if (imageBitmaps) { |
| 702 for (size_t i = 0; i < imageBitmaps->size(); i++) { |
| 703 v8::Local<v8::Object> v8ImageBitmap = toV8Object(imageBitmaps->at(i)
.get(), creationContext, isolate()); |
| 704 if (!m_transferredImageBitmaps.contains(v8ImageBitmap)) |
| 705 m_transferredImageBitmaps.set(v8ImageBitmap, i); |
| 706 } |
| 707 } |
684 } | 708 } |
685 | 709 |
686 ScriptValueSerializer::Status ScriptValueSerializer::serialize(v8::Local<v8::Val
ue> value) | 710 ScriptValueSerializer::Status ScriptValueSerializer::serialize(v8::Local<v8::Val
ue> value) |
687 { | 711 { |
688 v8::HandleScope scope(isolate()); | 712 v8::HandleScope scope(isolate()); |
689 m_writer.writeVersion(); | 713 m_writer.writeVersion(); |
690 StateBase* state = doSerialize(value, 0); | 714 StateBase* state = doSerialize(value, 0); |
691 while (state) | 715 while (state) |
692 state = state->advance(*this); | 716 state = state->advance(*this); |
693 return m_status; | 717 return m_status; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 } else if (value->IsUint32()) { | 750 } else if (value->IsUint32()) { |
727 m_writer.writeUint32(value.As<v8::Uint32>()->Value()); | 751 m_writer.writeUint32(value.As<v8::Uint32>()->Value()); |
728 } else if (value->IsNumber()) { | 752 } else if (value->IsNumber()) { |
729 m_writer.writeNumber(value.As<v8::Number>()->Value()); | 753 m_writer.writeNumber(value.As<v8::Number>()->Value()); |
730 } else if (value->IsString()) { | 754 } else if (value->IsString()) { |
731 writeString(value); | 755 writeString(value); |
732 } else if (value->IsObject()) { | 756 } else if (value->IsObject()) { |
733 v8::Local<v8::Object> jsObject = value.As<v8::Object>(); | 757 v8::Local<v8::Object> jsObject = value.As<v8::Object>(); |
734 | 758 |
735 uint32_t arrayBufferIndex; | 759 uint32_t arrayBufferIndex; |
| 760 uint32_t imageBitmapIndex; |
736 if (V8ArrayBufferView::hasInstance(value, isolate())) { | 761 if (V8ArrayBufferView::hasInstance(value, isolate())) { |
737 return writeAndGreyArrayBufferView(jsObject, next); | 762 return writeAndGreyArrayBufferView(jsObject, next); |
738 } else if (V8MessagePort::hasInstance(value, isolate())) { | 763 } else if (V8MessagePort::hasInstance(value, isolate())) { |
739 uint32_t messagePortIndex; | 764 uint32_t messagePortIndex; |
740 if (!m_transferredMessagePorts.tryGet(jsObject, &messagePortIndex)) | 765 if (!m_transferredMessagePorts.tryGet(jsObject, &messagePortIndex)) |
741 return handleError(DataCloneError, "A MessagePort could not be c
loned.", next); | 766 return handleError(DataCloneError, "A MessagePort could not be c
loned.", next); |
742 m_writer.writeTransferredMessagePort(messagePortIndex); | 767 m_writer.writeTransferredMessagePort(messagePortIndex); |
743 return nullptr; | 768 return nullptr; |
744 } else if (V8ArrayBuffer::hasInstance(value, isolate()) && m_transferred
ArrayBuffers.tryGet(jsObject, &arrayBufferIndex)) { | 769 } else if (V8ArrayBuffer::hasInstance(value, isolate()) && m_transferred
ArrayBuffers.tryGet(jsObject, &arrayBufferIndex)) { |
745 return writeTransferredArrayBuffer(value, arrayBufferIndex, next); | 770 return writeTransferredArrayBuffer(value, arrayBufferIndex, next); |
| 771 } else if (V8ImageBitmap::hasInstance(value, isolate()) && m_transferred
ImageBitmaps.tryGet(jsObject, &imageBitmapIndex)) { |
| 772 return writeTransferredImageBitmap(value, imageBitmapIndex, next); |
746 } else if (V8SharedArrayBuffer::hasInstance(value, isolate()) && m_trans
ferredArrayBuffers.tryGet(jsObject, &arrayBufferIndex)) { | 773 } else if (V8SharedArrayBuffer::hasInstance(value, isolate()) && m_trans
ferredArrayBuffers.tryGet(jsObject, &arrayBufferIndex)) { |
747 return writeTransferredSharedArrayBuffer(value, arrayBufferIndex, ne
xt); | 774 return writeTransferredSharedArrayBuffer(value, arrayBufferIndex, ne
xt); |
748 } | 775 } |
749 | 776 |
750 greyObject(jsObject); | 777 greyObject(jsObject); |
751 if (value->IsDate()) { | 778 if (value->IsDate()) { |
752 m_writer.writeDate(value.As<v8::Date>()->ValueOf()); | 779 m_writer.writeDate(value.As<v8::Date>()->ValueOf()); |
753 } else if (value->IsStringObject()) { | 780 } else if (value->IsStringObject()) { |
754 writeStringObject(value); | 781 writeStringObject(value); |
755 } else if (value->IsNumberObject()) { | 782 } else if (value->IsNumberObject()) { |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1016 { | 1043 { |
1017 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); | 1044 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); |
1018 if (!arrayBuffer) | 1045 if (!arrayBuffer) |
1019 return 0; | 1046 return 0; |
1020 if (arrayBuffer->isNeutered()) | 1047 if (arrayBuffer->isNeutered()) |
1021 return handleError(DataCloneError, "An ArrayBuffer is neutered and could
not be cloned.", next); | 1048 return handleError(DataCloneError, "An ArrayBuffer is neutered and could
not be cloned.", next); |
1022 m_writer.writeTransferredArrayBuffer(index); | 1049 m_writer.writeTransferredArrayBuffer(index); |
1023 return 0; | 1050 return 0; |
1024 } | 1051 } |
1025 | 1052 |
| 1053 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredImageBi
tmap(v8::Local<v8::Value> value, uint32_t index, ScriptValueSerializer::StateBas
e* next) |
| 1054 { |
| 1055 ImageBitmap* imageBitmap = V8ImageBitmap::toImpl(value.As<v8::Object>()); |
| 1056 if (!imageBitmap) |
| 1057 return 0; |
| 1058 if (imageBitmap->isNeutered()) |
| 1059 return handleError(DataCloneError, "An ImageBitmap is neutered and could
not be cloned.", next); |
| 1060 m_writer.writeTransferredImageBitmap(index); |
| 1061 return 0; |
| 1062 } |
| 1063 |
1026 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredSharedA
rrayBuffer(v8::Local<v8::Value> value, uint32_t index, ScriptValueSerializer::St
ateBase* next) | 1064 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredSharedA
rrayBuffer(v8::Local<v8::Value> value, uint32_t index, ScriptValueSerializer::St
ateBase* next) |
1027 { | 1065 { |
1028 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); | 1066 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); |
1029 DOMSharedArrayBuffer* sharedArrayBuffer = V8SharedArrayBuffer::toImpl(value.
As<v8::Object>()); | 1067 DOMSharedArrayBuffer* sharedArrayBuffer = V8SharedArrayBuffer::toImpl(value.
As<v8::Object>()); |
1030 if (!sharedArrayBuffer) | 1068 if (!sharedArrayBuffer) |
1031 return 0; | 1069 return 0; |
1032 m_writer.writeTransferredSharedArrayBuffer(index); | 1070 m_writer.writeTransferredSharedArrayBuffer(index); |
1033 return 0; | 1071 return 0; |
1034 } | 1072 } |
1035 | 1073 |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 case ArrayBufferTransferTag: { | 1382 case ArrayBufferTransferTag: { |
1345 if (!m_version) | 1383 if (!m_version) |
1346 return false; | 1384 return false; |
1347 uint32_t index; | 1385 uint32_t index; |
1348 if (!doReadUint32(&index)) | 1386 if (!doReadUint32(&index)) |
1349 return false; | 1387 return false; |
1350 if (!creator.tryGetTransferredArrayBuffer(index, value)) | 1388 if (!creator.tryGetTransferredArrayBuffer(index, value)) |
1351 return false; | 1389 return false; |
1352 break; | 1390 break; |
1353 } | 1391 } |
| 1392 case ImageBitmapTransferTag: { |
| 1393 if (!m_version) |
| 1394 return false; |
| 1395 uint32_t index; |
| 1396 if (!doReadUint32(&index)) |
| 1397 return false; |
| 1398 if (!creator.tryGetTransferredImageBitmap(index, value)) |
| 1399 return false; |
| 1400 break; |
| 1401 } |
1354 case SharedArrayBufferTransferTag: { | 1402 case SharedArrayBufferTransferTag: { |
1355 if (!m_version) | 1403 if (!m_version) |
1356 return false; | 1404 return false; |
1357 uint32_t index; | 1405 uint32_t index; |
1358 if (!doReadUint32(&index)) | 1406 if (!doReadUint32(&index)) |
1359 return false; | 1407 return false; |
1360 if (!creator.tryGetTransferredSharedArrayBuffer(index, value)) | 1408 if (!creator.tryGetTransferredSharedArrayBuffer(index, value)) |
1361 return false; | 1409 return false; |
1362 break; | 1410 break; |
1363 } | 1411 } |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2058 v8::Local<v8::Object> creationContext = m_reader.scriptState()->context(
)->Global(); | 2106 v8::Local<v8::Object> creationContext = m_reader.scriptState()->context(
)->Global(); |
2059 result = toV8(buffer.get(), creationContext, isolate); | 2107 result = toV8(buffer.get(), creationContext, isolate); |
2060 if (result.IsEmpty()) | 2108 if (result.IsEmpty()) |
2061 return false; | 2109 return false; |
2062 m_arrayBuffers[index] = result; | 2110 m_arrayBuffers[index] = result; |
2063 } | 2111 } |
2064 *object = result; | 2112 *object = result; |
2065 return true; | 2113 return true; |
2066 } | 2114 } |
2067 | 2115 |
| 2116 bool ScriptValueDeserializer::tryGetTransferredImageBitmap(uint32_t index, v8::L
ocal<v8::Value>* object) |
| 2117 { |
| 2118 if (!m_imageBitmapContents) |
| 2119 return false; |
| 2120 if (index >= m_imageBitmaps.size()) |
| 2121 return false; |
| 2122 v8::Local<v8::Value> result = m_imageBitmaps.at(index); |
| 2123 if (result.IsEmpty()) { |
| 2124 RefPtrWillBeRawPtr<ImageBitmap> bitmap = ImageBitmap::create(m_imageBitm
apContents->at(index).get()); |
| 2125 v8::Isolate* isolate = m_reader.scriptState()->isolate(); |
| 2126 v8::Local<v8::Object> creationContext = m_reader.scriptState()->context(
)->Global(); |
| 2127 result = toV8(bitmap.get(), creationContext, isolate); |
| 2128 if (result.IsEmpty()) |
| 2129 return false; |
| 2130 m_imageBitmaps[index] = result; |
| 2131 } |
| 2132 *object = result; |
| 2133 return true; |
| 2134 } |
| 2135 |
2068 bool ScriptValueDeserializer::tryGetTransferredSharedArrayBuffer(uint32_t index,
v8::Local<v8::Value>* object) | 2136 bool ScriptValueDeserializer::tryGetTransferredSharedArrayBuffer(uint32_t index,
v8::Local<v8::Value>* object) |
2069 { | 2137 { |
2070 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); | 2138 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); |
2071 if (!m_arrayBufferContents) | 2139 if (!m_arrayBufferContents) |
2072 return false; | 2140 return false; |
2073 if (index >= m_arrayBuffers.size()) | 2141 if (index >= m_arrayBuffers.size()) |
2074 return false; | 2142 return false; |
2075 v8::Local<v8::Value> result = m_arrayBuffers.at(index); | 2143 v8::Local<v8::Value> result = m_arrayBuffers.at(index); |
2076 if (result.IsEmpty()) { | 2144 if (result.IsEmpty()) { |
2077 RefPtr<DOMSharedArrayBuffer> buffer = DOMSharedArrayBuffer::create(m_arr
ayBufferContents->at(index)); | 2145 RefPtr<DOMSharedArrayBuffer> buffer = DOMSharedArrayBuffer::create(m_arr
ayBufferContents->at(index)); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2157 return false; | 2225 return false; |
2158 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe
renceStack.size() - 1]; | 2226 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe
renceStack.size() - 1]; |
2159 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() -
1); | 2227 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() -
1); |
2160 if (objectReference >= m_objectPool.size()) | 2228 if (objectReference >= m_objectPool.size()) |
2161 return false; | 2229 return false; |
2162 *object = m_objectPool[objectReference]; | 2230 *object = m_objectPool[objectReference]; |
2163 return true; | 2231 return true; |
2164 } | 2232 } |
2165 | 2233 |
2166 } // namespace blink | 2234 } // namespace blink |
OLD | NEW |