Modified: trunk/LayoutTests/fast/canvas/webgl/script-tests/array-message-passing.js (113232 => 113233)
--- trunk/LayoutTests/fast/canvas/webgl/script-tests/array-message-passing.js 2012-04-04 20:31:24 UTC (rev 113232)
+++ trunk/LayoutTests/fast/canvas/webgl/script-tests/array-message-passing.js 2012-04-04 20:43:31 UTC (rev 113233)
@@ -69,14 +69,43 @@
testFailed(testName + ": expected BYTES_PER_ELEMENT " + sent.BYTES_PER_ELEMENT + ", saw " + got.BYTES_PER_ELEMENT);
return false;
}
+ return true;
}
function dataViewCompare(testName, got, sent) {
- if (!viewCompare(testName, got, sent)) {
+ return viewCompare(testName, got, sent);
+}
+
+function dataViewCompare2(testName, got, sent) {
+ for (var i = 0; i < 2; ++i) {
+ if (!dataViewCompare(testName, got[i], sent[i])) {
+ return false;
+ }
+ }
+ if (got[0].buffer !== got[1].buffer) {
+ testFailed(testName + ": expected the same ArrayBuffer for both views");
return false;
}
+ return true;
}
+function dataViewCompare3(testName, got, sent) {
+ for (var i = 0; i < 3; i += 2) {
+ if (!dataViewCompare(testName, got[i], sent[i])) {
+ return false;
+ }
+ }
+ if (got[1].x !== sent[1].x || got[1].y !== sent[1].y) {
+ testFailed(testName + ": {x:1, y:1} was not transferred properly");
+ return false;
+ }
+ if (got[0].buffer !== got[2].buffer) {
+ testFailed(testName + ": expected the same ArrayBuffer for both views");
+ return false;
+ }
+ return false;
+}
+
function createBuffer(length) {
var buffer = new ArrayBuffer(length);
var view = new Uint8Array(buffer);
@@ -115,12 +144,16 @@
["Float64", Float64Array, 8]
];
+var arrayBuffer1 = createBuffer(1);
+
var testList = [
['ArrayBuffer0', new ArrayBuffer(0), bufferCompare],
['ArrayBuffer1', createBuffer(1), bufferCompare],
['ArrayBuffer128', createBuffer(128), bufferCompare],
['DataView0', new DataView(new ArrayBuffer(0)), dataViewCompare],
['DataView1', new DataView(createBuffer(1)), dataViewCompare],
+ ['DataView1-dup', [new DataView(arrayBuffer1), new DataView(arrayBuffer1)], dataViewCompare2],
+ ['DataView1-dup2', [new DataView(arrayBuffer1), {x:1, y:1}, new DataView(arrayBuffer1)], dataViewCompare3],
['DataView128', new DataView(createBuffer(128)), dataViewCompare],
['DataView1_offset_at_end', new DataView(createBuffer(1), 1, 0), dataViewCompare],
['DataView128_offset_at_end', new DataView(createBuffer(128), 128, 0), dataViewCompare],
Modified: trunk/Source/WebCore/ChangeLog (113232 => 113233)
--- trunk/Source/WebCore/ChangeLog 2012-04-04 20:31:24 UTC (rev 113232)
+++ trunk/Source/WebCore/ChangeLog 2012-04-04 20:43:31 UTC (rev 113233)
@@ -1,3 +1,32 @@
+2012-04-04 Dmitry Lomov <dslo...@google.com>
+
+ [JSC] ArrayBufferView and its ArrayBuffer are appended to object pool in wrong order
+ https://bugs.webkit.org/show_bug.cgi?id=82090
+ The implementation of structured cloning algorithm (http://www.w3.org/TR/html5/common-dom-interfaces.html#internal-structured-cloning-algorithm)
+ in SerializedScriptValue.cpp assigns numerical identifiers to encontered objects as it traverses
+ the cloned object during serialization.
+ When the cloning encounters an already seen object, it transfers the assigned numerical id
+ instead of cloning the object again. Deserialization process then repeats the process in
+ the mirror fashion, i.e. on deserializing the object it assigns deserialized object a numeric id and if it
+ deserializes the id it substitutes the perviously deserialized objects. It is critical that serialization and deserialization
+ assigns numeric ids in the same order.
+
+ The bug (discovered by Yong Li) is that when serializing ArrayBufferView, the ids were assigned first to
+ the ArrayBufferView and then to underlying ArrayBuffer; however on deserialization the ids were assigned another way round.
+
+ This patch fixes that by assigning the id first to ArrayBuffer and then to ArrayBufferView, and adds corresponding test cases.
+
+ Reviewed by Kenneth Russell.
+
+ New test cases added to fast/canvas/web-gl/array-message-passing.html.
+
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::CloneSerializer::checkForDuplicate):
+ (CloneSerializer):
+ (WebCore::CloneSerializer::recordObject):
+ (WebCore::CloneSerializer::startObjectInternal):
+ (WebCore::CloneSerializer::dumpIfTerminal):
+
2012-04-04 Ian Vollick <voll...@chromium.org>
[chromium] When setting animation started events, should check the root layer
Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (113232 => 113233)
--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2012-04-04 20:31:24 UTC (rev 113232)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2012-04-04 20:43:31 UTC (rev 113233)
@@ -389,20 +389,33 @@
return isJSArray(object) || object->inherits(&JSArray::s_info);
}
- bool startObjectInternal(JSObject* object)
+ bool checkForDuplicate(JSObject* object)
{
// Record object for graph reconstruction
ObjectPool::AddResult addResult = m_objectPool.add(object, m_objectPool.size());
-
+
// Handle duplicate references
if (!addResult.isNewEntry) {
write(ObjectReferenceTag);
ASSERT(static_cast<int32_t>(addResult.iterator->second) < m_objectPool.size());
writeObjectIndex(addResult.iterator->second);
- return false;
+ return true;
}
-
+
+ return false;
+ }
+
+ void recordObject(JSObject* object)
+ {
+ m_objectPool.add(object, m_objectPool.size());
m_gcBuffer.append(object);
+ }
+
+ bool startObjectInternal(JSObject* object)
+ {
+ if (checkForDuplicate(object))
+ return false;
+ recordObject(object);
return true;
}
@@ -643,9 +656,11 @@
return true;
}
if (obj->inherits(&JSArrayBufferView::s_info)) {
- if (!startObjectInternal(obj))
+ if (checkForDuplicate(obj))
return true;
- return dumpArrayBufferView(obj, code);
+ bool success = dumpArrayBufferView(obj, code);
+ recordObject(obj);
+ return success;
}
CallData unusedData;