title: Can anyone confirm this iOS 10 beta 3 Safari bug?
body: <p>Our JavaScript application fails in very strange ways when running on iOS 10 beta 2 and beta 3 (running on iPhone 6). When looking at logs I can see that arrays contain NaN's and 0x00's in unexpected places. I managed to produce a test program that can quite reliably reproduce the behavior.</p>
  
  <p>I have filled a bug report with Apple but haven't heard back so I am a bit concerned whether this will be fixed or not. So as a first thing, I would like to hear if someone can reproduce it and at least confirm there is a bug (and not just a misunderstanding on my part etc.). I'm fairly sure of this myself, but always good to be on the safe side! Could also be others have encountered it and found a workaround or maybe if some WebKit developers run into it, they might be able to help.</p>
  
  <p><strong>Test program showing bug</strong>
  Here's the test progarm. The problem doesn't occur every time but the JavaScript code in the page can detect when it occurred and will keep refreshing the page until it occurs. On a non-affected browser, this means the page will keep refreshing. On an affected browser (such as Safari on iOS 10 beta 2 and beta 3 running on an iPhone 6) the refreshing will stop after some iterations (typically 5-10) and the display error.</p>
  
  <p>The program operates by creating an uint8array of size 8192 (it seems smaller array sizes causes the error to be more rare). It will fill this array with dummy values, then call "toStr" which first allocates a new plain Array, then copies the contents of the uint8array to the plain array, narrowing each element along the way. While doing this it builds up a string containing the original value and the copied value. When the error occurs, the element in the target array turns out to be NaN which should not be able to occur since it by construction contains only integers. The doTest() function tests for whether such a NaN value is contained in the resulting string which shows that the error has occurred.</p>
  
  <p>Note that within each refresh, the program runs 20 iterations and here it is also random which iteration that fails. However, I have observed that if the error doesn't occur among the first 20 of iterations, it is not likely to occur at all within this page load even if one ran an indefinite number of iterations, and this is the reason why I added the reload page logic.</p>
  
  <p>Note that the program logic itself is completely deterministic so every run should be the same, which is also the case on other browsers. More detail can be seen by removing the comments from the log() statement in the doTest() function so it prints out the array.</p>
  
  <p>Note that the problem seems to go away if the function "narrow" is inlined rather than being a separate function (even though these two programs should of course be semantically equivalent). Also, if one omits the shift from "state >> 8" the error also seemingly goes away so either the exact array values are significant or this rewrite somehow affects how the JIT operates. Hence, it is critical the exact program structure is used when testing for the problem.</p>
  
  <pre><code>&lt;html&gt;
  &lt;head&gt;
  &lt;title&gt;Array test page&lt;/title&gt;
  &lt;script&gt;
      log = function(s) {
          var ta = document.getElementById("ta");
          ta.value += s + "\n";
      }
  
      function narrow(x_0) {
          return x_0 &lt;&lt; 24 &gt;&gt; 24;
      }
  
      function toStr(i8bytes) {
          var bytes, i, str;
          bytes = new Array(i8bytes.length);
          str = '';
          for (i = 0; i &lt; 16; i++) {
              bytes[i] = narrow(i8bytes[i]);
              str += '*** (' + i8bytes[i] + ' - ' + bytes[i] + ')';
          }
          return str;
      }
  
      function doTest() {
          var sz = 8192;
          state = 0;
          var i;
  
          var fnd = false;
          for (i = 0; i &lt; 20; i++) {
              var arr = new ArrayBuffer(sz);
              var i8bytes = new Uint8Array(arr, 0, sz);
              for (j = 0; j &lt; i8bytes.length; j++) {
                  state = state + 1;
                  var v = state &gt;&gt; 8;
                  i8bytes[j] = narrow(v);
              }
              var str = toStr(i8bytes);
              // log(str); &lt;-- REMOVE COMMENT to show results
              if (str.indexOf("NaN") !== -1) {
                  log("Found NaN at iteration" + i);
                  log(str);
                  fnd = true;
                  break;
              }
          }
          return fnd;
  
      }
      function start() {
          log("Starting: " + new Date());
          if (!doTest()) {
              location.reload(true); // &lt;--- REMOVE THIS LINE TO PREVENT RELOAD 
          }
      };
  &lt;/script&gt;
  &lt;/head&gt;
  &lt;body onload="start()"&gt;
  &lt;h1&gt;Array test page&lt;/h1&gt;
  &lt;p&gt;Note that on a non-affected browser this page will reload indefinitely. On an affected browser, it
  will stop reloading once the problem is detected.
  &lt;p&gt;
  &lt;textarea id="ta" rows="10" cols="40"&gt;&lt;/textarea&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>