Title: [165121] trunk
Revision
165121
Author
[email protected]
Date
2014-03-05 13:01:35 -0800 (Wed, 05 Mar 2014)

Log Message

JSDataViewPrototype::getData() and setData() crash on platforms that don't allow unaligned accesses
https://bugs.webkit.org/show_bug.cgi?id=129746

Reviewed by Filip Pizlo.

Source/_javascript_Core: 

Changed to use a union to manually assemble or disassemble the various types
from / to the corresponding bytes.  All memory access is now done using
byte accesses.

* runtime/JSDataViewPrototype.cpp:
(JSC::getData):
(JSC::setData):

LayoutTests: 

New test to validate proper operation of DataView operations at
various byte offsets using both little and big endian.

* js/arraybuffer-dataview-expected.txt: Added.
* js/arraybuffer-dataview.html: Added.
* js/script-tests/arraybuffer-dataview.js: Added.
(paddedHex):
(byteString):
(clearView):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (165120 => 165121)


--- trunk/LayoutTests/ChangeLog	2014-03-05 20:34:45 UTC (rev 165120)
+++ trunk/LayoutTests/ChangeLog	2014-03-05 21:01:35 UTC (rev 165121)
@@ -1,3 +1,20 @@
+2014-03-05  Michael Saboff  <[email protected]>
+
+        JSDataViewPrototype::getData() and setData() crash on platforms that don't allow unaligned accesses
+        https://bugs.webkit.org/show_bug.cgi?id=129746
+
+        Reviewed by Filip Pizlo.
+
+        New test to validate proper operation of DataView operations at
+        various byte offsets using both little and big endian.
+
+        * js/arraybuffer-dataview-expected.txt: Added.
+        * js/arraybuffer-dataview.html: Added.
+        * js/script-tests/arraybuffer-dataview.js: Added.
+        (paddedHex):
+        (byteString):
+        (clearView):
+
 2014-03-05  Zalan Bujtas  <[email protected]>
 
         Subpixel rendering: Wrong cliprect on absolute positioned elements.

Added: trunk/LayoutTests/js/arraybuffer-dataview-expected.txt (0 => 165121)


--- trunk/LayoutTests/js/arraybuffer-dataview-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/arraybuffer-dataview-expected.txt	2014-03-05 21:01:35 UTC (rev 165121)
@@ -0,0 +1,281 @@
+This test checks that DataView methods work at different alignments and with both endians.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS byteString(view, 0, 5) is '16 1b ad fa ce'
+PASS byteString(view, 0, 4) is '12 34 56 78'
+PASS view.getInt16(0).toString(16) is '1234'
+PASS view.getInt16(i, true).toString(16) is '3412'
+PASS view.getInt32(0).toString(16) is '12345678'
+PASS view.getInt32(i, true).toString(16) is '78563412'
+PASS byteString(view, 0, 4) is 'ff ff ff ff'
+PASS view.getInt8(0) is -1
+PASS view.getUint8(0) is 255
+PASS view.getInt16(0) is -1
+PASS view.getUint16(0) is 65535
+PASS view.getInt32(0) is -1
+PASS view.getUint32(0) is 4294967295
+PASS view.getInt8(0) < 0 is true
+PASS view.getInt8(0,true) < 0 is true
+PASS view.getInt16(0) < 0 is true
+PASS view.getInt16(0,true) < 0 is false
+PASS view.getInt32(0) < 0 is true
+PASS view.getInt32(0,true) < 0 is false
+PASS view.getFloat32(0) is 2
+PASS view.getFloat32(0,true) != 2.0 is true
+PASS view.getFloat32(0) is -2
+PASS view.getFloat32(0,true) != -2.0 is true
+PASS Math.abs(view.getFloat32(0) - Math.SQRT2) < 0.0000001 is true
+PASS Math.abs(view.getFloat32(0,true) - Math.SQRT2) > 0.0000001 is true
+PASS view.getFloat32(0) is NaN
+PASS isNaN(view.getFloat32(0,true)) is false
+PASS view.getFloat32(0) is NaN
+PASS isNaN(view.getFloat32(0,true)) is false
+PASS view.getFloat64(0) is 1
+PASS view.getFloat64(0,true) != 1 is true
+PASS view.getFloat64(0) is -1
+PASS view.getFloat64(0,true) != -1 is true
+PASS Math.abs(view.getFloat64(0) - Math.PI) < 0.000000001 is true
+PASS byteString(view, 1, 5) is '16 1b ad fa ce'
+PASS byteString(view, 1, 4) is '12 34 56 78'
+PASS view.getInt16(1).toString(16) is '1234'
+PASS view.getInt16(i, true).toString(16) is '3412'
+PASS view.getInt32(1).toString(16) is '12345678'
+PASS view.getInt32(i, true).toString(16) is '78563412'
+PASS byteString(view, 1, 4) is 'ff ff ff ff'
+PASS view.getInt8(1) is -1
+PASS view.getUint8(1) is 255
+PASS view.getInt16(1) is -1
+PASS view.getUint16(1) is 65535
+PASS view.getInt32(1) is -1
+PASS view.getUint32(1) is 4294967295
+PASS view.getInt8(1) < 0 is true
+PASS view.getInt8(1,true) < 0 is true
+PASS view.getInt16(1) < 0 is true
+PASS view.getInt16(1,true) < 0 is false
+PASS view.getInt32(1) < 0 is true
+PASS view.getInt32(1,true) < 0 is false
+PASS view.getFloat32(1) is 2
+PASS view.getFloat32(1,true) != 2.0 is true
+PASS view.getFloat32(1) is -2
+PASS view.getFloat32(1,true) != -2.0 is true
+PASS Math.abs(view.getFloat32(1) - Math.SQRT2) < 0.0000001 is true
+PASS Math.abs(view.getFloat32(1,true) - Math.SQRT2) > 0.0000001 is true
+PASS view.getFloat32(1) is NaN
+PASS isNaN(view.getFloat32(1,true)) is false
+PASS view.getFloat32(1) is NaN
+PASS isNaN(view.getFloat32(1,true)) is false
+PASS view.getFloat64(1) is 1
+PASS view.getFloat64(1,true) != 1 is true
+PASS view.getFloat64(1) is -1
+PASS view.getFloat64(1,true) != -1 is true
+PASS Math.abs(view.getFloat64(1) - Math.PI) < 0.000000001 is true
+PASS byteString(view, 2, 5) is '16 1b ad fa ce'
+PASS byteString(view, 2, 4) is '12 34 56 78'
+PASS view.getInt16(2).toString(16) is '1234'
+PASS view.getInt16(i, true).toString(16) is '3412'
+PASS view.getInt32(2).toString(16) is '12345678'
+PASS view.getInt32(i, true).toString(16) is '78563412'
+PASS byteString(view, 2, 4) is 'ff ff ff ff'
+PASS view.getInt8(2) is -1
+PASS view.getUint8(2) is 255
+PASS view.getInt16(2) is -1
+PASS view.getUint16(2) is 65535
+PASS view.getInt32(2) is -1
+PASS view.getUint32(2) is 4294967295
+PASS view.getInt8(2) < 0 is true
+PASS view.getInt8(2,true) < 0 is true
+PASS view.getInt16(2) < 0 is true
+PASS view.getInt16(2,true) < 0 is false
+PASS view.getInt32(2) < 0 is true
+PASS view.getInt32(2,true) < 0 is false
+PASS view.getFloat32(2) is 2
+PASS view.getFloat32(2,true) != 2.0 is true
+PASS view.getFloat32(2) is -2
+PASS view.getFloat32(2,true) != -2.0 is true
+PASS Math.abs(view.getFloat32(2) - Math.SQRT2) < 0.0000001 is true
+PASS Math.abs(view.getFloat32(2,true) - Math.SQRT2) > 0.0000001 is true
+PASS view.getFloat32(2) is NaN
+PASS isNaN(view.getFloat32(2,true)) is false
+PASS view.getFloat32(2) is NaN
+PASS isNaN(view.getFloat32(2,true)) is false
+PASS view.getFloat64(2) is 1
+PASS view.getFloat64(2,true) != 1 is true
+PASS view.getFloat64(2) is -1
+PASS view.getFloat64(2,true) != -1 is true
+PASS Math.abs(view.getFloat64(2) - Math.PI) < 0.000000001 is true
+PASS byteString(view, 3, 5) is '16 1b ad fa ce'
+PASS byteString(view, 3, 4) is '12 34 56 78'
+PASS view.getInt16(3).toString(16) is '1234'
+PASS view.getInt16(i, true).toString(16) is '3412'
+PASS view.getInt32(3).toString(16) is '12345678'
+PASS view.getInt32(i, true).toString(16) is '78563412'
+PASS byteString(view, 3, 4) is 'ff ff ff ff'
+PASS view.getInt8(3) is -1
+PASS view.getUint8(3) is 255
+PASS view.getInt16(3) is -1
+PASS view.getUint16(3) is 65535
+PASS view.getInt32(3) is -1
+PASS view.getUint32(3) is 4294967295
+PASS view.getInt8(3) < 0 is true
+PASS view.getInt8(3,true) < 0 is true
+PASS view.getInt16(3) < 0 is true
+PASS view.getInt16(3,true) < 0 is false
+PASS view.getInt32(3) < 0 is true
+PASS view.getInt32(3,true) < 0 is false
+PASS view.getFloat32(3) is 2
+PASS view.getFloat32(3,true) != 2.0 is true
+PASS view.getFloat32(3) is -2
+PASS view.getFloat32(3,true) != -2.0 is true
+PASS Math.abs(view.getFloat32(3) - Math.SQRT2) < 0.0000001 is true
+PASS Math.abs(view.getFloat32(3,true) - Math.SQRT2) > 0.0000001 is true
+PASS view.getFloat32(3) is NaN
+PASS isNaN(view.getFloat32(3,true)) is false
+PASS view.getFloat32(3) is NaN
+PASS isNaN(view.getFloat32(3,true)) is false
+PASS view.getFloat64(3) is 1
+PASS view.getFloat64(3,true) != 1 is true
+PASS view.getFloat64(3) is -1
+PASS view.getFloat64(3,true) != -1 is true
+PASS Math.abs(view.getFloat64(3) - Math.PI) < 0.000000001 is true
+PASS byteString(view, 4, 5) is '16 1b ad fa ce'
+PASS byteString(view, 4, 4) is '12 34 56 78'
+PASS view.getInt16(4).toString(16) is '1234'
+PASS view.getInt16(i, true).toString(16) is '3412'
+PASS view.getInt32(4).toString(16) is '12345678'
+PASS view.getInt32(i, true).toString(16) is '78563412'
+PASS byteString(view, 4, 4) is 'ff ff ff ff'
+PASS view.getInt8(4) is -1
+PASS view.getUint8(4) is 255
+PASS view.getInt16(4) is -1
+PASS view.getUint16(4) is 65535
+PASS view.getInt32(4) is -1
+PASS view.getUint32(4) is 4294967295
+PASS view.getInt8(4) < 0 is true
+PASS view.getInt8(4,true) < 0 is true
+PASS view.getInt16(4) < 0 is true
+PASS view.getInt16(4,true) < 0 is false
+PASS view.getInt32(4) < 0 is true
+PASS view.getInt32(4,true) < 0 is false
+PASS view.getFloat32(4) is 2
+PASS view.getFloat32(4,true) != 2.0 is true
+PASS view.getFloat32(4) is -2
+PASS view.getFloat32(4,true) != -2.0 is true
+PASS Math.abs(view.getFloat32(4) - Math.SQRT2) < 0.0000001 is true
+PASS Math.abs(view.getFloat32(4,true) - Math.SQRT2) > 0.0000001 is true
+PASS view.getFloat32(4) is NaN
+PASS isNaN(view.getFloat32(4,true)) is false
+PASS view.getFloat32(4) is NaN
+PASS isNaN(view.getFloat32(4,true)) is false
+PASS view.getFloat64(4) is 1
+PASS view.getFloat64(4,true) != 1 is true
+PASS view.getFloat64(4) is -1
+PASS view.getFloat64(4,true) != -1 is true
+PASS Math.abs(view.getFloat64(4) - Math.PI) < 0.000000001 is true
+PASS byteString(view, 5, 5) is '16 1b ad fa ce'
+PASS byteString(view, 5, 4) is '12 34 56 78'
+PASS view.getInt16(5).toString(16) is '1234'
+PASS view.getInt16(i, true).toString(16) is '3412'
+PASS view.getInt32(5).toString(16) is '12345678'
+PASS view.getInt32(i, true).toString(16) is '78563412'
+PASS byteString(view, 5, 4) is 'ff ff ff ff'
+PASS view.getInt8(5) is -1
+PASS view.getUint8(5) is 255
+PASS view.getInt16(5) is -1
+PASS view.getUint16(5) is 65535
+PASS view.getInt32(5) is -1
+PASS view.getUint32(5) is 4294967295
+PASS view.getInt8(5) < 0 is true
+PASS view.getInt8(5,true) < 0 is true
+PASS view.getInt16(5) < 0 is true
+PASS view.getInt16(5,true) < 0 is false
+PASS view.getInt32(5) < 0 is true
+PASS view.getInt32(5,true) < 0 is false
+PASS view.getFloat32(5) is 2
+PASS view.getFloat32(5,true) != 2.0 is true
+PASS view.getFloat32(5) is -2
+PASS view.getFloat32(5,true) != -2.0 is true
+PASS Math.abs(view.getFloat32(5) - Math.SQRT2) < 0.0000001 is true
+PASS Math.abs(view.getFloat32(5,true) - Math.SQRT2) > 0.0000001 is true
+PASS view.getFloat32(5) is NaN
+PASS isNaN(view.getFloat32(5,true)) is false
+PASS view.getFloat32(5) is NaN
+PASS isNaN(view.getFloat32(5,true)) is false
+PASS view.getFloat64(5) is 1
+PASS view.getFloat64(5,true) != 1 is true
+PASS view.getFloat64(5) is -1
+PASS view.getFloat64(5,true) != -1 is true
+PASS Math.abs(view.getFloat64(5) - Math.PI) < 0.000000001 is true
+PASS byteString(view, 6, 5) is '16 1b ad fa ce'
+PASS byteString(view, 6, 4) is '12 34 56 78'
+PASS view.getInt16(6).toString(16) is '1234'
+PASS view.getInt16(i, true).toString(16) is '3412'
+PASS view.getInt32(6).toString(16) is '12345678'
+PASS view.getInt32(i, true).toString(16) is '78563412'
+PASS byteString(view, 6, 4) is 'ff ff ff ff'
+PASS view.getInt8(6) is -1
+PASS view.getUint8(6) is 255
+PASS view.getInt16(6) is -1
+PASS view.getUint16(6) is 65535
+PASS view.getInt32(6) is -1
+PASS view.getUint32(6) is 4294967295
+PASS view.getInt8(6) < 0 is true
+PASS view.getInt8(6,true) < 0 is true
+PASS view.getInt16(6) < 0 is true
+PASS view.getInt16(6,true) < 0 is false
+PASS view.getInt32(6) < 0 is true
+PASS view.getInt32(6,true) < 0 is false
+PASS view.getFloat32(6) is 2
+PASS view.getFloat32(6,true) != 2.0 is true
+PASS view.getFloat32(6) is -2
+PASS view.getFloat32(6,true) != -2.0 is true
+PASS Math.abs(view.getFloat32(6) - Math.SQRT2) < 0.0000001 is true
+PASS Math.abs(view.getFloat32(6,true) - Math.SQRT2) > 0.0000001 is true
+PASS view.getFloat32(6) is NaN
+PASS isNaN(view.getFloat32(6,true)) is false
+PASS view.getFloat32(6) is NaN
+PASS isNaN(view.getFloat32(6,true)) is false
+PASS view.getFloat64(6) is 1
+PASS view.getFloat64(6,true) != 1 is true
+PASS view.getFloat64(6) is -1
+PASS view.getFloat64(6,true) != -1 is true
+PASS Math.abs(view.getFloat64(6) - Math.PI) < 0.000000001 is true
+PASS byteString(view, 7, 5) is '16 1b ad fa ce'
+PASS byteString(view, 7, 4) is '12 34 56 78'
+PASS view.getInt16(7).toString(16) is '1234'
+PASS view.getInt16(i, true).toString(16) is '3412'
+PASS view.getInt32(7).toString(16) is '12345678'
+PASS view.getInt32(i, true).toString(16) is '78563412'
+PASS byteString(view, 7, 4) is 'ff ff ff ff'
+PASS view.getInt8(7) is -1
+PASS view.getUint8(7) is 255
+PASS view.getInt16(7) is -1
+PASS view.getUint16(7) is 65535
+PASS view.getInt32(7) is -1
+PASS view.getUint32(7) is 4294967295
+PASS view.getInt8(7) < 0 is true
+PASS view.getInt8(7,true) < 0 is true
+PASS view.getInt16(7) < 0 is true
+PASS view.getInt16(7,true) < 0 is false
+PASS view.getInt32(7) < 0 is true
+PASS view.getInt32(7,true) < 0 is false
+PASS view.getFloat32(7) is 2
+PASS view.getFloat32(7,true) != 2.0 is true
+PASS view.getFloat32(7) is -2
+PASS view.getFloat32(7,true) != -2.0 is true
+PASS Math.abs(view.getFloat32(7) - Math.SQRT2) < 0.0000001 is true
+PASS Math.abs(view.getFloat32(7,true) - Math.SQRT2) > 0.0000001 is true
+PASS view.getFloat32(7) is NaN
+PASS isNaN(view.getFloat32(7,true)) is false
+PASS view.getFloat32(7) is NaN
+PASS isNaN(view.getFloat32(7,true)) is false
+PASS view.getFloat64(7) is 1
+PASS view.getFloat64(7,true) != 1 is true
+PASS view.getFloat64(7) is -1
+PASS view.getFloat64(7,true) != -1 is true
+PASS Math.abs(view.getFloat64(7) - Math.PI) < 0.000000001 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/arraybuffer-dataview.html (0 => 165121)


--- trunk/LayoutTests/js/arraybuffer-dataview.html	                        (rev 0)
+++ trunk/LayoutTests/js/arraybuffer-dataview.html	2014-03-05 21:01:35 UTC (rev 165121)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/script-tests/arraybuffer-dataview.js (0 => 165121)


--- trunk/LayoutTests/js/script-tests/arraybuffer-dataview.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/arraybuffer-dataview.js	2014-03-05 21:01:35 UTC (rev 165121)
@@ -0,0 +1,120 @@
+description(
+    "This test checks that DataView methods work at different alignments and with both endians."
+);
+
+function paddedHex(v)
+{
+    var result = ""
+
+    if (v < 16)
+        result = "0"
+    result += v.toString(16);
+
+    return result
+}
+
+function byteString(view, start, len)
+{
+    if (start < 0 || len < 0 || start + len > view.byteLength)
+        return "Undefined"
+
+    result = ""
+    for (var i = 0; i < len; i++) {
+	if (i)
+	    result += " "
+        result += paddedHex(view.getUint8(start + i))
+    }
+
+    return result
+}
+
+function clearView(view)
+{
+    for (var i = 0; i < view.byteLength; i++)
+	view.setUint8(i, 0);
+}
+
+var buffer = new ArrayBuffer(16);
+var view = new DataView(buffer, 0);
+
+for (var i = 0; i < 8; i++) {
+    clearView(view)
+    view.setInt8(i, 22)
+    view.setUint32(i + 1, 0x1badface)
+    shouldBe("byteString(view, " + i + ", 5)", "'16 1b ad fa ce'")
+
+    clearView(view)
+    view.setInt8(i, 0x12)
+    view.setInt8(i + 1, 0x34)
+    view.setInt8(i + 2, 0x56)
+    view.setInt8(i + 3, 0x78)
+    shouldBe("byteString(view, " + i + ", 4)", "'12 34 56 78'")
+    shouldBe("view.getInt16(" + i + ").toString(16)", "'1234'")
+    shouldBe("view.getInt16(i, true).toString(16)", "'3412'")
+    shouldBe("view.getInt32(" + i + ").toString(16)", "'12345678'")
+    shouldBe("view.getInt32(i, true).toString(16)", "'78563412'")
+
+    clearView(view)
+    view.setInt32(i, -1 | 0)
+    shouldBe("byteString(view, " + i + ", 4)", "'ff ff ff ff'")
+    shouldBe("view.getInt8(" + i + ")", "-1")
+    shouldBe("view.getUint8(" + i + ")", "255")
+    shouldBe("view.getInt16(" + i + ")", "-1")
+    shouldBe("view.getUint16(" + i + ")", "65535")
+    shouldBe("view.getInt32(" + i + ")", "-1")
+    shouldBe("view.getUint32(" + i + ")", "4294967295")
+
+    clearView(view)
+    view.setInt8(i, -1 | 0)
+    shouldBeTrue("view.getInt8(" + i + ") < 0")
+    shouldBeTrue("view.getInt8(" + i + ",true) < 0")
+    shouldBeTrue("view.getInt16(" + i + ") < 0")
+    shouldBeFalse("view.getInt16(" + i + ",true) < 0")
+    shouldBeTrue("view.getInt32(" + i + ") < 0")
+    shouldBeFalse("view.getInt32(" + i + ",true) < 0")
+
+    clearView(view)
+    view.setUint16(i, 0x4000)
+    shouldBe("view.getFloat32(" + i + ")", "2")
+    shouldBeTrue("view.getFloat32(" + i + ",true) != 2.0")
+
+    clearView(view)
+    view.setUint16(i, 0xc000)
+    shouldBe("view.getFloat32(" + i + ")", "-2")
+    shouldBeTrue("view.getFloat32(" + i + ",true) != -2.0")
+
+    clearView(view)
+    view.setUint32(i, 0x3fb504f3)
+    shouldBeTrue("Math.abs(view.getFloat32(" + i + ") - Math.SQRT2) < 0.0000001")
+    shouldBeTrue("Math.abs(view.getFloat32(" + i + ",true) - Math.SQRT2) > 0.0000001")
+
+    clearView(view)
+    view.setUint8(i, 0x7f)
+    view.setUint8(i + 1, 0x80)
+    view.setUint8(i + 3, 0x01)
+    shouldBeNaN("view.getFloat32(" + i + ")")
+    shouldBeFalse("isNaN(view.getFloat32(" + i + ",true))")
+
+    clearView(view)
+    view.setUint8(i, 0xff)
+    view.setUint8(i + 1, 0xc0)
+    shouldBeNaN("view.getFloat32(" + i + ")")
+    shouldBeFalse("isNaN(view.getFloat32(" + i + ",true))")
+
+    clearView(view)
+    view.setUint16(i, 0x3ff0)
+    shouldBe("view.getFloat64(" + i + ")", "1")
+    shouldBeTrue("view.getFloat64(" + i + ",true) != 1")
+
+    clearView(view)
+    view.setUint16(i, 0xbff0)
+    shouldBe("view.getFloat64(" + i + ")", "-1")
+    shouldBeTrue("view.getFloat64(" + i + ",true) != -1")
+
+    clearView(view)
+    view.setUint16(i, 0x4009)
+    view.setUint16(i + 2, 0x21fb)
+    view.setUint16(i + 4, 0x5444)
+    view.setUint16(i + 6, 0x2d18)
+    shouldBeTrue("Math.abs(view.getFloat64(" + i + ") - Math.PI) < 0.000000001")
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (165120 => 165121)


--- trunk/Source/_javascript_Core/ChangeLog	2014-03-05 20:34:45 UTC (rev 165120)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-03-05 21:01:35 UTC (rev 165121)
@@ -1,3 +1,18 @@
+2014-03-05  Michael Saboff  <[email protected]>
+
+        JSDataViewPrototype::getData() and setData() crash on platforms that don't allow unaligned accesses
+        https://bugs.webkit.org/show_bug.cgi?id=129746
+
+        Reviewed by Filip Pizlo.
+
+        Changed to use a union to manually assemble or disassemble the various types
+        from / to the corresponding bytes.  All memory access is now done using
+        byte accesses.
+
+        * runtime/JSDataViewPrototype.cpp:
+        (JSC::getData):
+        (JSC::setData):
+
 2014-03-05  Filip Pizlo  <[email protected]>
 
         FTL loadStructure always generates invalid IR

Modified: trunk/Source/_javascript_Core/runtime/JSDataViewPrototype.cpp (165120 => 165121)


--- trunk/Source/_javascript_Core/runtime/JSDataViewPrototype.cpp	2014-03-05 20:34:45 UTC (rev 165120)
+++ trunk/Source/_javascript_Core/runtime/JSDataViewPrototype.cpp	2014-03-05 21:01:35 UTC (rev 165121)
@@ -116,13 +116,24 @@
     unsigned byteLength = dataView->length();
     if (elementSize > byteLength || byteOffset > byteLength - elementSize)
         return throwVMError(exec, createRangeError(exec, "Out of bounds access"));
-    
-    typename Adaptor::Type value = *reinterpret_cast<typename Adaptor::Type*>(static_cast<uint8_t*>(dataView->vector()) + byteOffset);
-    
-    if (needToFlipBytesIfLittleEndian(littleEndian))
-        value = flipBytes(value);
-    
-    return JSValue::encode(Adaptor::toJSValue(value));
+
+    const unsigned dataSize = sizeof(typename Adaptor::Type);
+    union {
+        typename Adaptor::Type value;
+        uint8_t rawBytes[dataSize];
+    } u;
+
+    uint8_t* dataPtr = static_cast<uint8_t*>(dataView->vector()) + byteOffset;
+
+    if (needToFlipBytesIfLittleEndian(littleEndian)) {
+        for (unsigned i = dataSize; i--;)
+            u.rawBytes[i] = *dataPtr++;
+    } else {
+        for (unsigned i = 0; i < dataSize; i++)
+            u.rawBytes[i] = *dataPtr++;
+    }
+
+    return JSValue::encode(Adaptor::toJSValue(u.value));
 }
 
 template<typename Adaptor>
@@ -138,8 +149,14 @@
     unsigned byteOffset = exec->uncheckedArgument(0).toUInt32(exec);
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
-    
-    typename Adaptor::Type value = toNativeFromValue<Adaptor>(exec, exec->uncheckedArgument(1));
+
+    const unsigned dataSize = sizeof(typename Adaptor::Type);
+    union {
+        typename Adaptor::Type value;
+        uint8_t rawBytes[dataSize];
+    } u;
+
+    u.value = toNativeFromValue<Adaptor>(exec, exec->uncheckedArgument(1));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     
@@ -154,12 +171,17 @@
     unsigned byteLength = dataView->length();
     if (elementSize > byteLength || byteOffset > byteLength - elementSize)
         return throwVMError(exec, createRangeError(exec, "Out of bounds access"));
-    
-    if (needToFlipBytesIfLittleEndian(littleEndian))
-        value = flipBytes(value);
-    
-    *reinterpret_cast<typename Adaptor::Type*>(static_cast<uint8_t*>(dataView->vector()) + byteOffset) = value;
-    
+
+    uint8_t* dataPtr = static_cast<uint8_t*>(dataView->vector()) + byteOffset;
+
+    if (needToFlipBytesIfLittleEndian(littleEndian)) {
+        for (unsigned i = dataSize; i--;)
+            *dataPtr++ = u.rawBytes[i];
+    } else {
+        for (unsigned i = 0; i < dataSize; i++)
+            *dataPtr++ = u.rawBytes[i];
+    }
+
     return JSValue::encode(jsUndefined());
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to