<!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  &lt;msaboff@apple.com&gt;
+
+        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  &lt;zalan@apple.com&gt;
</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 &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+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) &lt; 0 is true
+PASS view.getInt8(0,true) &lt; 0 is true
+PASS view.getInt16(0) &lt; 0 is true
+PASS view.getInt16(0,true) &lt; 0 is false
+PASS view.getInt32(0) &lt; 0 is true
+PASS view.getInt32(0,true) &lt; 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) &lt; 0.0000001 is true
+PASS Math.abs(view.getFloat32(0,true) - Math.SQRT2) &gt; 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) &lt; 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) &lt; 0 is true
+PASS view.getInt8(1,true) &lt; 0 is true
+PASS view.getInt16(1) &lt; 0 is true
+PASS view.getInt16(1,true) &lt; 0 is false
+PASS view.getInt32(1) &lt; 0 is true
+PASS view.getInt32(1,true) &lt; 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) &lt; 0.0000001 is true
+PASS Math.abs(view.getFloat32(1,true) - Math.SQRT2) &gt; 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) &lt; 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) &lt; 0 is true
+PASS view.getInt8(2,true) &lt; 0 is true
+PASS view.getInt16(2) &lt; 0 is true
+PASS view.getInt16(2,true) &lt; 0 is false
+PASS view.getInt32(2) &lt; 0 is true
+PASS view.getInt32(2,true) &lt; 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) &lt; 0.0000001 is true
+PASS Math.abs(view.getFloat32(2,true) - Math.SQRT2) &gt; 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) &lt; 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) &lt; 0 is true
+PASS view.getInt8(3,true) &lt; 0 is true
+PASS view.getInt16(3) &lt; 0 is true
+PASS view.getInt16(3,true) &lt; 0 is false
+PASS view.getInt32(3) &lt; 0 is true
+PASS view.getInt32(3,true) &lt; 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) &lt; 0.0000001 is true
+PASS Math.abs(view.getFloat32(3,true) - Math.SQRT2) &gt; 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) &lt; 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) &lt; 0 is true
+PASS view.getInt8(4,true) &lt; 0 is true
+PASS view.getInt16(4) &lt; 0 is true
+PASS view.getInt16(4,true) &lt; 0 is false
+PASS view.getInt32(4) &lt; 0 is true
+PASS view.getInt32(4,true) &lt; 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) &lt; 0.0000001 is true
+PASS Math.abs(view.getFloat32(4,true) - Math.SQRT2) &gt; 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) &lt; 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) &lt; 0 is true
+PASS view.getInt8(5,true) &lt; 0 is true
+PASS view.getInt16(5) &lt; 0 is true
+PASS view.getInt16(5,true) &lt; 0 is false
+PASS view.getInt32(5) &lt; 0 is true
+PASS view.getInt32(5,true) &lt; 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) &lt; 0.0000001 is true
+PASS Math.abs(view.getFloat32(5,true) - Math.SQRT2) &gt; 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) &lt; 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) &lt; 0 is true
+PASS view.getInt8(6,true) &lt; 0 is true
+PASS view.getInt16(6) &lt; 0 is true
+PASS view.getInt16(6,true) &lt; 0 is false
+PASS view.getInt32(6) &lt; 0 is true
+PASS view.getInt32(6,true) &lt; 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) &lt; 0.0000001 is true
+PASS Math.abs(view.getFloat32(6,true) - Math.SQRT2) &gt; 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) &lt; 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) &lt; 0 is true
+PASS view.getInt8(7,true) &lt; 0 is true
+PASS view.getInt16(7) &lt; 0 is true
+PASS view.getInt16(7,true) &lt; 0 is false
+PASS view.getInt32(7) &lt; 0 is true
+PASS view.getInt32(7,true) &lt; 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) &lt; 0.0000001 is true
+PASS Math.abs(view.getFloat32(7,true) - Math.SQRT2) &gt; 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) &lt; 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>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;script-tests/arraybuffer-dataview.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</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(
+    &quot;This test checks that DataView methods work at different alignments and with both endians.&quot;
+);
+
+function paddedHex(v)
+{
+    var result = &quot;&quot;
+
+    if (v &lt; 16)
+        result = &quot;0&quot;
+    result += v.toString(16);
+
+    return result
+}
+
+function byteString(view, start, len)
+{
+    if (start &lt; 0 || len &lt; 0 || start + len &gt; view.byteLength)
+        return &quot;Undefined&quot;
+
+    result = &quot;&quot;
+    for (var i = 0; i &lt; len; i++) {
+        if (i)
+            result += &quot; &quot;
+        result += paddedHex(view.getUint8(start + i))
+    }
+
+    return result
+}
+
+function clearView(view)
+{
+    for (var i = 0; i &lt; view.byteLength; i++)
+        view.setUint8(i, 0);
+}
+
+var buffer = new ArrayBuffer(16);
+var view = new DataView(buffer, 0);
+
+for (var i = 0; i &lt; 8; i++) {
+    clearView(view)
+    view.setInt8(i, 22)
+    view.setUint32(i + 1, 0x1badface)
+    shouldBe(&quot;byteString(view, &quot; + i + &quot;, 5)&quot;, &quot;'16 1b ad fa ce'&quot;)
+
+    clearView(view)
+    view.setInt8(i, 0x12)
+    view.setInt8(i + 1, 0x34)
+    view.setInt8(i + 2, 0x56)
+    view.setInt8(i + 3, 0x78)
+    shouldBe(&quot;byteString(view, &quot; + i + &quot;, 4)&quot;, &quot;'12 34 56 78'&quot;)
+    shouldBe(&quot;view.getInt16(&quot; + i + &quot;).toString(16)&quot;, &quot;'1234'&quot;)
+    shouldBe(&quot;view.getInt16(i, true).toString(16)&quot;, &quot;'3412'&quot;)
+    shouldBe(&quot;view.getInt32(&quot; + i + &quot;).toString(16)&quot;, &quot;'12345678'&quot;)
+    shouldBe(&quot;view.getInt32(i, true).toString(16)&quot;, &quot;'78563412'&quot;)
+
+    clearView(view)
+    view.setInt32(i, -1 | 0)
+    shouldBe(&quot;byteString(view, &quot; + i + &quot;, 4)&quot;, &quot;'ff ff ff ff'&quot;)
+    shouldBe(&quot;view.getInt8(&quot; + i + &quot;)&quot;, &quot;-1&quot;)
+    shouldBe(&quot;view.getUint8(&quot; + i + &quot;)&quot;, &quot;255&quot;)
+    shouldBe(&quot;view.getInt16(&quot; + i + &quot;)&quot;, &quot;-1&quot;)
+    shouldBe(&quot;view.getUint16(&quot; + i + &quot;)&quot;, &quot;65535&quot;)
+    shouldBe(&quot;view.getInt32(&quot; + i + &quot;)&quot;, &quot;-1&quot;)
+    shouldBe(&quot;view.getUint32(&quot; + i + &quot;)&quot;, &quot;4294967295&quot;)
+
+    clearView(view)
+    view.setInt8(i, -1 | 0)
+    shouldBeTrue(&quot;view.getInt8(&quot; + i + &quot;) &lt; 0&quot;)
+    shouldBeTrue(&quot;view.getInt8(&quot; + i + &quot;,true) &lt; 0&quot;)
+    shouldBeTrue(&quot;view.getInt16(&quot; + i + &quot;) &lt; 0&quot;)
+    shouldBeFalse(&quot;view.getInt16(&quot; + i + &quot;,true) &lt; 0&quot;)
+    shouldBeTrue(&quot;view.getInt32(&quot; + i + &quot;) &lt; 0&quot;)
+    shouldBeFalse(&quot;view.getInt32(&quot; + i + &quot;,true) &lt; 0&quot;)
+
+    clearView(view)
+    view.setUint16(i, 0x4000)
+    shouldBe(&quot;view.getFloat32(&quot; + i + &quot;)&quot;, &quot;2&quot;)
+    shouldBeTrue(&quot;view.getFloat32(&quot; + i + &quot;,true) != 2.0&quot;)
+
+    clearView(view)
+    view.setUint16(i, 0xc000)
+    shouldBe(&quot;view.getFloat32(&quot; + i + &quot;)&quot;, &quot;-2&quot;)
+    shouldBeTrue(&quot;view.getFloat32(&quot; + i + &quot;,true) != -2.0&quot;)
+
+    clearView(view)
+    view.setUint32(i, 0x3fb504f3)
+    shouldBeTrue(&quot;Math.abs(view.getFloat32(&quot; + i + &quot;) - Math.SQRT2) &lt; 0.0000001&quot;)
+    shouldBeTrue(&quot;Math.abs(view.getFloat32(&quot; + i + &quot;,true) - Math.SQRT2) &gt; 0.0000001&quot;)
+
+    clearView(view)
+    view.setUint8(i, 0x7f)
+    view.setUint8(i + 1, 0x80)
+    view.setUint8(i + 3, 0x01)
+    shouldBeNaN(&quot;view.getFloat32(&quot; + i + &quot;)&quot;)
+    shouldBeFalse(&quot;isNaN(view.getFloat32(&quot; + i + &quot;,true))&quot;)
+
+    clearView(view)
+    view.setUint8(i, 0xff)
+    view.setUint8(i + 1, 0xc0)
+    shouldBeNaN(&quot;view.getFloat32(&quot; + i + &quot;)&quot;)
+    shouldBeFalse(&quot;isNaN(view.getFloat32(&quot; + i + &quot;,true))&quot;)
+
+    clearView(view)
+    view.setUint16(i, 0x3ff0)
+    shouldBe(&quot;view.getFloat64(&quot; + i + &quot;)&quot;, &quot;1&quot;)
+    shouldBeTrue(&quot;view.getFloat64(&quot; + i + &quot;,true) != 1&quot;)
+
+    clearView(view)
+    view.setUint16(i, 0xbff0)
+    shouldBe(&quot;view.getFloat64(&quot; + i + &quot;)&quot;, &quot;-1&quot;)
+    shouldBeTrue(&quot;view.getFloat64(&quot; + i + &quot;,true) != -1&quot;)
+
+    clearView(view)
+    view.setUint16(i, 0x4009)
+    view.setUint16(i + 2, 0x21fb)
+    view.setUint16(i + 4, 0x5444)
+    view.setUint16(i + 6, 0x2d18)
+    shouldBeTrue(&quot;Math.abs(view.getFloat64(&quot; + i + &quot;) - Math.PI) &lt; 0.000000001&quot;)
+}
</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  &lt;msaboff@apple.com&gt;
+
+        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  &lt;fpizlo@apple.com&gt;
</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-&gt;length();
</span><span class="cx">     if (elementSize &gt; byteLength || byteOffset &gt; byteLength - elementSize)
</span><span class="cx">         return throwVMError(exec, createRangeError(exec, &quot;Out of bounds access&quot;));
</span><del>-    
-    typename Adaptor::Type value = *reinterpret_cast&lt;typename Adaptor::Type*&gt;(static_cast&lt;uint8_t*&gt;(dataView-&gt;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&lt;uint8_t*&gt;(dataView-&gt;vector()) + byteOffset;
+
+    if (needToFlipBytesIfLittleEndian(littleEndian)) {
+        for (unsigned i = dataSize; i--;)
+            u.rawBytes[i] = *dataPtr++;
+    } else {
+        for (unsigned i = 0; i &lt; 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&lt;typename Adaptor&gt;
</span><span class="lines">@@ -138,8 +149,14 @@
</span><span class="cx">     unsigned byteOffset = exec-&gt;uncheckedArgument(0).toUInt32(exec);
</span><span class="cx">     if (exec-&gt;hadException())
</span><span class="cx">         return JSValue::encode(jsUndefined());
</span><del>-    
-    typename Adaptor::Type value = toNativeFromValue&lt;Adaptor&gt;(exec, exec-&gt;uncheckedArgument(1));
</del><ins>+
+    const unsigned dataSize = sizeof(typename Adaptor::Type);
+    union {
+        typename Adaptor::Type value;
+        uint8_t rawBytes[dataSize];
+    } u;
+
+    u.value = toNativeFromValue&lt;Adaptor&gt;(exec, exec-&gt;uncheckedArgument(1));
</ins><span class="cx">     if (exec-&gt;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-&gt;length();
</span><span class="cx">     if (elementSize &gt; byteLength || byteOffset &gt; byteLength - elementSize)
</span><span class="cx">         return throwVMError(exec, createRangeError(exec, &quot;Out of bounds access&quot;));
</span><del>-    
-    if (needToFlipBytesIfLittleEndian(littleEndian))
-        value = flipBytes(value);
-    
-    *reinterpret_cast&lt;typename Adaptor::Type*&gt;(static_cast&lt;uint8_t*&gt;(dataView-&gt;vector()) + byteOffset) = value;
-    
</del><ins>+
+    uint8_t* dataPtr = static_cast&lt;uint8_t*&gt;(dataView-&gt;vector()) + byteOffset;
+
+    if (needToFlipBytesIfLittleEndian(littleEndian)) {
+        for (unsigned i = dataSize; i--;)
+            *dataPtr++ = u.rawBytes[i];
+    } else {
+        for (unsigned i = 0; i &lt; 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>