<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[165121] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/165121">165121</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2014-03-05 13:01:35 -0800 (Wed, 05 Mar 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>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/JavaScriptCore:
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):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSDataViewPrototypecpp">trunk/Source/JavaScriptCore/runtime/JSDataViewPrototype.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsarraybufferdataviewexpectedtxt">trunk/LayoutTests/js/arraybuffer-dataview-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsarraybufferdataviewhtml">trunk/LayoutTests/js/arraybuffer-dataview.html</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsarraybufferdataviewjs">trunk/LayoutTests/js/script-tests/arraybuffer-dataview.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (165120 => 165121)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-03-05 20:34:45 UTC (rev 165120)
+++ trunk/LayoutTests/ChangeLog        2014-03-05 21:01:35 UTC (rev 165121)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2014-03-05 Michael Saboff <msaboff@apple.com>
+
+ 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):
+
</ins><span class="cx"> 2014-03-05 Zalan Bujtas <zalan@apple.com>
</span><span class="cx">
</span><span class="cx"> Subpixel rendering: Wrong cliprect on absolute positioned elements.
</span></span></pre></div>
<a id="trunkLayoutTestsjsarraybufferdataviewexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/arraybuffer-dataview-expected.txt (0 => 165121)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,281 @@
</span><ins>+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
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsarraybufferdataviewhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/arraybuffer-dataview.html (0 => 165121)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/arraybuffer-dataview.html         (rev 0)
+++ trunk/LayoutTests/js/arraybuffer-dataview.html        2014-03-05 21:01:35 UTC (rev 165121)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="script-tests/arraybuffer-dataview.js"></script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsarraybufferdataviewjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/script-tests/arraybuffer-dataview.js (0 => 165121)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,120 @@
</span><ins>+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")
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (165120 => 165121)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-03-05 20:34:45 UTC (rev 165120)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-03-05 21:01:35 UTC (rev 165121)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2014-03-05 Michael Saboff <msaboff@apple.com>
+
+ 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):
+
</ins><span class="cx"> 2014-03-05 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> FTL loadStructure always generates invalid IR
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSDataViewPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSDataViewPrototype.cpp (165120 => 165121)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSDataViewPrototype.cpp        2014-03-05 20:34:45 UTC (rev 165120)
+++ trunk/Source/JavaScriptCore/runtime/JSDataViewPrototype.cpp        2014-03-05 21:01:35 UTC (rev 165121)
</span><span class="lines">@@ -116,13 +116,24 @@
</span><span class="cx"> unsigned byteLength = dataView->length();
</span><span class="cx"> if (elementSize > byteLength || byteOffset > byteLength - elementSize)
</span><span class="cx"> return throwVMError(exec, createRangeError(exec, "Out of bounds access"));
</span><del>-
- 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));
</del><ins>+
+ 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));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template<typename Adaptor>
</span><span class="lines">@@ -138,8 +149,14 @@
</span><span class="cx"> unsigned byteOffset = exec->uncheckedArgument(0).toUInt32(exec);
</span><span class="cx"> if (exec->hadException())
</span><span class="cx"> return JSValue::encode(jsUndefined());
</span><del>-
- typename Adaptor::Type value = toNativeFromValue<Adaptor>(exec, exec->uncheckedArgument(1));
</del><ins>+
+ 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));
</ins><span class="cx"> if (exec->hadException())
</span><span class="cx"> return JSValue::encode(jsUndefined());
</span><span class="cx">
</span><span class="lines">@@ -154,12 +171,17 @@
</span><span class="cx"> unsigned byteLength = dataView->length();
</span><span class="cx"> if (elementSize > byteLength || byteOffset > byteLength - elementSize)
</span><span class="cx"> return throwVMError(exec, createRangeError(exec, "Out of bounds access"));
</span><del>-
- if (needToFlipBytesIfLittleEndian(littleEndian))
- value = flipBytes(value);
-
- *reinterpret_cast<typename Adaptor::Type*>(static_cast<uint8_t*>(dataView->vector()) + byteOffset) = value;
-
</del><ins>+
+ 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];
+ }
+
</ins><span class="cx"> return JSValue::encode(jsUndefined());
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre>
</div>
</div>
</body>
</html>