<!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" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { 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 #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#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>
<title>[27095] trunk</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/27095">27095</a></dd>
<dt>Author</dt> <dd>darin</dd>
<dt>Date</dt> <dd>2007-10-26 00:51:25 -0700 (Fri, 26 Oct 2007)</dd>
</dl>

<h3>Log Message</h3>
<pre>JavaScriptCore:

        Reviewed by Maciej.

        - http://bugs.webkit.org/show_bug.cgi?id=15703
          fix numeric functions -- improve correctness and speed

        Gives about 1% gain on SunSpider.

        * kjs/value.h: Added toIntegerPreserveNan, removed toUInt16.
        (KJS::JSValue::toInt32): Changed to call getTruncatedInt32 in a way that works
        with both immediate and number values.
        (KJS::JSValue::toUInt32): Ditto.
        * kjs/value.cpp:
        (KJS::JSValue::toInteger): Moved the logic from roundValue here, with a couple
        differences. One is that it now correctly returns 0 for NaN, and another is that
        there's no special case for 0 or infinity, since the general case already handles
        those correctly.
        (KJS::JSValue::toIntegerPreserveNaN): Added. Like toInteger, but without the
        check for NaN.
        (KJS::JSValue::toInt32SlowCase): Call toNumber instead of roundValue. The
        truncation done by the typecast already does the necessary truncation that
        roundValue was doing.
        (KJS::JSValue::toUInt32SlowCase): Ditto.
        (KJS::JSValue::toUInt16): Removed.

        * kjs/internal.h: Removed roundValue.
        * kjs/internal.cpp: Ditto.

        * kjs/array_object.cpp: (KJS::ArrayProtoFunc::callAsFunction): Remove unneeded
        code to handle NaN in Array.slice; toInteger now never returns NaN as specified.

        * kjs/date_object.cpp:
        (KJS::fillStructuresUsingTimeArgs): Replaced call to roundValue with a call to
        toNumber as specified.
        (KJS::DateProtoFunc::callAsFunction): In SetTime case, replaced call to roundValue
        with a call to toNumber and timeClip as specified.
        (KJS::DateObjectImp::construct): Removed unnecessary checks of numArgs in cases
        where the default behavior of toInt32 (returning 0) was already correct. Replaced
        call to roundValue with a call to toNumber as specified.
        (KJS::DateObjectFuncImp::callAsFunction): Ditto.

        * kjs/math_object.cpp: (MathFuncImp::callAsFunction): Removed unnecessary special
        cases for the pow function that the library already handles correctly.

        * kjs/number_object.cpp: (NumberProtoFunc::callAsFunction): Changed ToString to
        call toIntegerPreserveNaN, so we can continue to handle the NaN case differently.
        The real toInteger now returns 0 for NaN. Took out unneeded special case in
        ToFixed for undefined; was only needed because our toInteger was wrong. Same
        thing in ToExponential. Changed ToPrecision to call toIntegerPreserveNaN.

        * kjs/string_object.cpp:
        (KJS::StringProtoFunc::callAsFunction): Took out CharAt and CharCodeAt special
        cases for undefined that were only needed because toInteger was wrong. Same in
        IndexOf, and was able to remove some special cases. In LastIndexOf, used
        toIntegerPreserveNaN, but was able to remove some special cases there too.
        Changed Substr implementation to preserve correct behavior with the change
        to toInteger and match the specification. Also made sure we weren't converting
        an out of range double to an int.
        (KJS::StringObjectFuncImp::callAsFunction): Changed constructor to just use
        toUInt32, because truncating toUInt32 to 16 bits is the same thing and there's
        no reason to have toUInt16 as a second, less-optimized function that's only
        called at this one call site.

        * wtf/MathExtras.h: Added trunc function for Windows.

LayoutTests:

        Reviewed by Maciej.

        - test changes for http://bugs.webkit.org/show_bug.cgi?id=15703
          fix numeric functions -- improve correctness and speed

        * fast/js/resources/char-at.js: Updated test to expect that we get the first
        character if we pass NaN to charAt and charCodeAt; it's what the specification
        asks for and matches other browsers too.
        * fast/js/char-at-expected.txt: Updated.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJavaScriptCoreChangeLog">trunk/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkJavaScriptCorekjsarray_objectcpp">trunk/JavaScriptCore/kjs/array_object.cpp</a></li>
<li><a href="#trunkJavaScriptCorekjsdate_objectcpp">trunk/JavaScriptCore/kjs/date_object.cpp</a></li>
<li><a href="#trunkJavaScriptCorekjsinternalcpp">trunk/JavaScriptCore/kjs/internal.cpp</a></li>
<li><a href="#trunkJavaScriptCorekjsinternalh">trunk/JavaScriptCore/kjs/internal.h</a></li>
<li><a href="#trunkJavaScriptCorekjsmath_objectcpp">trunk/JavaScriptCore/kjs/math_object.cpp</a></li>
<li><a href="#trunkJavaScriptCorekjsnumber_objectcpp">trunk/JavaScriptCore/kjs/number_object.cpp</a></li>
<li><a href="#trunkJavaScriptCorekjsstring_objectcpp">trunk/JavaScriptCore/kjs/string_object.cpp</a></li>
<li><a href="#trunkJavaScriptCorekjsvaluecpp">trunk/JavaScriptCore/kjs/value.cpp</a></li>
<li><a href="#trunkJavaScriptCorekjsvalueh">trunk/JavaScriptCore/kjs/value.h</a></li>
<li><a href="#trunkJavaScriptCorewtfMathExtrash">trunk/JavaScriptCore/wtf/MathExtras.h</a></li>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastjscharatexpectedtxt">trunk/LayoutTests/fast/js/char-at-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastjsresourcescharatjs">trunk/LayoutTests/fast/js/resources/char-at.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/ChangeLog (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/ChangeLog        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/JavaScriptCore/ChangeLog        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -1,3 +1,69 @@
</span><ins>+2007-10-25  Darin Adler  &lt;darin@apple.com&gt;
+
+        Reviewed by Maciej.
+
+        - http://bugs.webkit.org/show_bug.cgi?id=15703
+          fix numeric functions -- improve correctness and speed
+
+        Gives about 1% gain on SunSpider.
+
+        * kjs/value.h: Added toIntegerPreserveNan, removed toUInt16.
+        (KJS::JSValue::toInt32): Changed to call getTruncatedInt32 in a way that works
+        with both immediate and number values.
+        (KJS::JSValue::toUInt32): Ditto.
+        * kjs/value.cpp:
+        (KJS::JSValue::toInteger): Moved the logic from roundValue here, with a couple
+        differences. One is that it now correctly returns 0 for NaN, and another is that
+        there's no special case for 0 or infinity, since the general case already handles
+        those correctly.
+        (KJS::JSValue::toIntegerPreserveNaN): Added. Like toInteger, but without the
+        check for NaN.
+        (KJS::JSValue::toInt32SlowCase): Call toNumber instead of roundValue. The
+        truncation done by the typecast already does the necessary truncation that
+        roundValue was doing.
+        (KJS::JSValue::toUInt32SlowCase): Ditto.
+        (KJS::JSValue::toUInt16): Removed.
+
+        * kjs/internal.h: Removed roundValue.
+        * kjs/internal.cpp: Ditto.
+
+        * kjs/array_object.cpp: (KJS::ArrayProtoFunc::callAsFunction): Remove unneeded
+        code to handle NaN in Array.slice; toInteger now never returns NaN as specified.
+
+        * kjs/date_object.cpp:
+        (KJS::fillStructuresUsingTimeArgs): Replaced call to roundValue with a call to
+        toNumber as specified.
+        (KJS::DateProtoFunc::callAsFunction): In SetTime case, replaced call to roundValue
+        with a call to toNumber and timeClip as specified.
+        (KJS::DateObjectImp::construct): Removed unnecessary checks of numArgs in cases
+        where the default behavior of toInt32 (returning 0) was already correct. Replaced
+        call to roundValue with a call to toNumber as specified.
+        (KJS::DateObjectFuncImp::callAsFunction): Ditto.
+
+        * kjs/math_object.cpp: (MathFuncImp::callAsFunction): Removed unnecessary special
+        cases for the pow function that the library already handles correctly.
+
+        * kjs/number_object.cpp: (NumberProtoFunc::callAsFunction): Changed ToString to
+        call toIntegerPreserveNaN, so we can continue to handle the NaN case differently.
+        The real toInteger now returns 0 for NaN. Took out unneeded special case in
+        ToFixed for undefined; was only needed because our toInteger was wrong. Same
+        thing in ToExponential. Changed ToPrecision to call toIntegerPreserveNaN.
+
+        * kjs/string_object.cpp:
+        (KJS::StringProtoFunc::callAsFunction): Took out CharAt and CharCodeAt special
+        cases for undefined that were only needed because toInteger was wrong. Same in
+        IndexOf, and was able to remove some special cases. In LastIndexOf, used
+        toIntegerPreserveNaN, but was able to remove some special cases there too.
+        Changed Substr implementation to preserve correct behavior with the change
+        to toInteger and match the specification. Also made sure we weren't converting
+        an out of range double to an int.
+        (KJS::StringObjectFuncImp::callAsFunction): Changed constructor to just use
+        toUInt32, because truncating toUInt32 to 16 bits is the same thing and there's
+        no reason to have toUInt16 as a second, less-optimized function that's only
+        called at this one call site.
+
+        * wtf/MathExtras.h: Added trunc function for Windows.
+
</ins><span class="cx"> 2007-10-25  Geoffrey Garen  &lt;ggaren@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Reviewed by Maciej Stachowiak.
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsarray_objectcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/array_object.cpp (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/array_object.cpp        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/JavaScriptCore/kjs/array_object.cpp        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -253,32 +253,30 @@
</span><span class="cx">     // We return a new array
</span><span class="cx">     JSObject *resObj = static_cast&lt;JSObject *&gt;(exec-&gt;lexicalInterpreter()-&gt;builtinArray()-&gt;construct(exec,List::empty()));
</span><span class="cx">     result = resObj;
</span><del>-    double begin = 0;
-    if (!args[0]-&gt;isUndefined()) {
-        begin = args[0]-&gt;toInteger(exec);
-        if (begin &gt;= 0) { // false for NaN
-            if (begin &gt; length)
-                begin = length;
-        } else {
-            begin += length;
-            if (!(begin &gt;= 0)) // true for NaN
-                begin = 0;
-        }
</del><ins>+    double begin = args[0]-&gt;toInteger(exec);
+    if (begin &gt;= 0) {
+      if (begin &gt; length)
+        begin = length;
+    } else {
+      begin += length;
+      if (begin &lt; 0)
+        begin = 0;
</ins><span class="cx">     }
</span><del>-    double end = length;
-    if (!args[1]-&gt;isUndefined()) {
</del><ins>+    double end;
+    if (args[1]-&gt;isUndefined())
+      end = length;
+    else {
</ins><span class="cx">       end = args[1]-&gt;toInteger(exec);
</span><del>-      if (end &lt; 0) { // false for NaN
</del><ins>+      if (end &lt; 0) {
</ins><span class="cx">         end += length;
</span><span class="cx">         if (end &lt; 0)
</span><span class="cx">           end = 0;
</span><span class="cx">       } else {
</span><del>-        if (!(end &lt;= length)) // true for NaN
</del><ins>+        if (end &gt; length)
</ins><span class="cx">           end = length;
</span><span class="cx">       }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    //printf( &quot;Slicing from %d to %d \n&quot;, begin, end );
</del><span class="cx">     int n = 0;
</span><span class="cx">     int b = static_cast&lt;int&gt;(begin);
</span><span class="cx">     int e = static_cast&lt;int&gt;(end);
</span><span class="lines">@@ -549,7 +547,7 @@
</span><span class="cx">       // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf 
</span><span class="cx"> 
</span><span class="cx">     int index = length - 1;
</span><del>-    double d = args[1]-&gt;toInteger(exec);
</del><ins>+    double d = args[1]-&gt;toIntegerPreserveNaN(exec);
</ins><span class="cx"> 
</span><span class="cx">     if (d &lt; 0) {
</span><span class="cx">         d += length;
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsdate_objectcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/date_object.cpp (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/date_object.cpp        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/JavaScriptCore/kjs/date_object.cpp        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -275,7 +275,7 @@
</span><span class="cx">     
</span><span class="cx">     // milliseconds
</span><span class="cx">     if (idx &lt; numArgs) {
</span><del>-        milliseconds += roundValue(exec, args[idx]);
</del><ins>+        milliseconds += args[idx]-&gt;toNumber(exec);
</ins><span class="cx">     } else {
</span><span class="cx">         milliseconds += *ms;
</span><span class="cx">     }
</span><span class="lines">@@ -551,7 +551,7 @@
</span><span class="cx">   case GetTimezoneOffset:
</span><span class="cx">     return jsNumber(-gmtoffset(t) / minutesPerHour);
</span><span class="cx">   case SetTime:
</span><del>-    milli = roundValue(exec, args[0]);
</del><ins>+    milli = timeClip(args[0]-&gt;toNumber(exec));
</ins><span class="cx">     result = jsNumber(milli);
</span><span class="cx">     thisDateObj-&gt;setInternalValue(result);
</span><span class="cx">     break;
</span><span class="lines">@@ -648,11 +648,11 @@
</span><span class="cx">       t.year = (year &gt;= 0 &amp;&amp; year &lt;= 99) ? year : year - 1900;
</span><span class="cx">       t.month = args[1]-&gt;toInt32(exec);
</span><span class="cx">       t.monthDay = (numArgs &gt;= 3) ? args[2]-&gt;toInt32(exec) : 1;
</span><del>-      t.hour = (numArgs &gt;= 4) ? args[3]-&gt;toInt32(exec) : 0;
-      t.minute = (numArgs &gt;= 5) ? args[4]-&gt;toInt32(exec) : 0;
-      t.second = (numArgs &gt;= 6) ? args[5]-&gt;toInt32(exec) : 0;
</del><ins>+      t.hour = args[3]-&gt;toInt32(exec);
+      t.minute = args[4]-&gt;toInt32(exec);
+      t.second = args[5]-&gt;toInt32(exec);
</ins><span class="cx">       t.isDST = -1;
</span><del>-      double ms = (numArgs &gt;= 7) ? roundValue(exec, args[6]) : 0;
</del><ins>+      double ms = (numArgs &gt;= 7) ? args[6]-&gt;toNumber(exec) : 0;
</ins><span class="cx">       value = gregorianDateTimeToMS(t, ms, false);
</span><span class="cx">     }
</span><span class="cx">   }
</span><span class="lines">@@ -702,10 +702,10 @@
</span><span class="cx">     t.year = (year &gt;= 0 &amp;&amp; year &lt;= 99) ? year : year - 1900;
</span><span class="cx">     t.month = args[1]-&gt;toInt32(exec);
</span><span class="cx">     t.monthDay = (n &gt;= 3) ? args[2]-&gt;toInt32(exec) : 1;
</span><del>-    t.hour = (n &gt;= 4) ? args[3]-&gt;toInt32(exec) : 0;
-    t.minute = (n &gt;= 5) ? args[4]-&gt;toInt32(exec) : 0;
-    t.second = (n &gt;= 6) ? args[5]-&gt;toInt32(exec) : 0;
-    double ms = (n &gt;= 7) ? roundValue(exec, args[6]) : 0;
</del><ins>+    t.hour = args[3]-&gt;toInt32(exec);
+    t.minute = args[4]-&gt;toInt32(exec);
+    t.second = args[5]-&gt;toInt32(exec);
+    double ms = (n &gt;= 7) ? args[6]-&gt;toNumber(exec) : 0;
</ins><span class="cx">     return jsNumber(gregorianDateTimeToMS(t, ms, true));
</span><span class="cx">   }
</span><span class="cx"> }
</span><span class="lines">@@ -1084,10 +1084,9 @@
</span><span class="cx"> {
</span><span class="cx">     if (!isfinite(t))
</span><span class="cx">         return NaN;
</span><del>-    double at = fabs(t);
-    if (at &gt; 8.64E15)
</del><ins>+    if (fabs(t) &gt; 8.64E15)
</ins><span class="cx">         return NaN;
</span><del>-    return copysign(floor(at), t);
</del><ins>+    return trunc(t);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsinternalcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/internal.cpp (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/internal.cpp        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/JavaScriptCore/kjs/internal.cpp        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -49,10 +49,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace KJS {
</span><span class="cx"> 
</span><del>-#if PLATFORM(WIN_OS)
-#define copysign _copysign
-#endif
-
</del><span class="cx"> // ------------------------------ StringImp ------------------------------------
</span><span class="cx"> 
</span><span class="cx"> JSValue* StringImp::toPrimitive(ExecState*, JSType) const
</span><span class="lines">@@ -250,15 +246,6 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ global functions -----------------------------
</span><span class="cx"> 
</span><del>-double roundValue(ExecState *exec, JSValue *v)
-{
-  double d = v-&gt;toNumber(exec);
-  double ad = fabs(d);
-  if (ad == 0 || isNaN(d) || isInf(d))
-    return d;
-  return copysign(floor(ad), d);
-}
-
</del><span class="cx"> #ifndef NDEBUG
</span><span class="cx"> #include &lt;stdio.h&gt;
</span><span class="cx"> void printInfo(ExecState *exec, const char *s, JSValue *o, int lineno)
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsinternalh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/internal.h (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/internal.h        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/JavaScriptCore/kjs/internal.h        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -145,9 +145,6 @@
</span><span class="cx">     bool isAborted;
</span><span class="cx">   };
</span><span class="cx"> 
</span><del>-  // helper function for toInteger, toInt32, toUInt32 and toUInt16
-  double roundValue(ExecState *, JSValue *);
-
</del><span class="cx"> #ifndef NDEBUG
</span><span class="cx">   void printInfo(ExecState *exec, const char *s, JSValue *, int lineno = -1);
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsmath_objectcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/math_object.cpp (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/math_object.cpp        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/JavaScriptCore/kjs/math_object.cpp        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -202,12 +202,8 @@
</span><span class="cx">     // ECMA 15.8.2.1.13 (::pow takes care of most of the critera)
</span><span class="cx">     if (isNaN(arg2))
</span><span class="cx">       result = NaN;
</span><del>-    else if (isNaN(arg) &amp;&amp; arg2 != 0)
</del><ins>+    else if (isInf(arg2) &amp;&amp; fabs(arg) == 1)
</ins><span class="cx">       result = NaN;
</span><del>-    else if (fabs(arg) == 1 &amp;&amp; isInf(arg2))
-      result = NaN;
-    else if (arg2 == 0 &amp;&amp; arg != 0)
-      result = 1;
</del><span class="cx">     else
</span><span class="cx">       result = ::pow(arg, arg2);
</span><span class="cx">     break;
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsnumber_objectcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/number_object.cpp (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/number_object.cpp        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/JavaScriptCore/kjs/number_object.cpp        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -153,7 +153,7 @@
</span><span class="cx">   case ToString: {
</span><span class="cx">     double dradix = 10;
</span><span class="cx">     if (!args.isEmpty())
</span><del>-      dradix = args[0]-&gt;toInteger(exec);
</del><ins>+      dradix = args[0]-&gt;toIntegerPreserveNaN(exec);
</ins><span class="cx">     if (dradix &gt;= 2 &amp;&amp; dradix &lt;= 36 &amp;&amp; dradix != 10) { // false for NaN
</span><span class="cx">       int radix = static_cast&lt;int&gt;(dradix);
</span><span class="cx">       const char digits[] = &quot;0123456789abcdefghijklmnopqrstuvwxyz&quot;;
</span><span class="lines">@@ -208,9 +208,7 @@
</span><span class="cx">   {
</span><span class="cx">       JSValue *fractionDigits = args[0];
</span><span class="cx">       double df = fractionDigits-&gt;toInteger(exec);
</span><del>-      if (fractionDigits-&gt;isUndefined())
-            df = 0;
-      if (!(df &gt;= 0 &amp;&amp; df &lt;= 20)) // true for NaN
</del><ins>+      if (!(df &gt;= 0 &amp;&amp; df &lt;= 20))
</ins><span class="cx">           return throwError(exec, RangeError, &quot;toFixed() digits argument must be between 0 and 20&quot;);
</span><span class="cx">       int f = (int)df;
</span><span class="cx">       
</span><span class="lines">@@ -255,7 +253,7 @@
</span><span class="cx">       
</span><span class="cx">       JSValue *fractionDigits = args[0];
</span><span class="cx">       double df = fractionDigits-&gt;toInteger(exec);
</span><del>-      if (!fractionDigits-&gt;isUndefined() &amp;&amp; !(df &gt;= 0 &amp;&amp; df &lt;= 20)) // true for NaN
</del><ins>+      if (!(df &gt;= 0 &amp;&amp; df &lt;= 20))
</ins><span class="cx">           return throwError(exec, RangeError, &quot;toExponential() argument must between 0 and 20&quot;);
</span><span class="cx">       int f = (int)df;
</span><span class="cx">       
</span><span class="lines">@@ -342,7 +340,7 @@
</span><span class="cx">       int e = 0;
</span><span class="cx">       UString m;
</span><span class="cx">       
</span><del>-      double dp = args[0]-&gt;toInteger(exec);
</del><ins>+      double dp = args[0]-&gt;toIntegerPreserveNaN(exec);
</ins><span class="cx">       double x = v-&gt;toNumber(exec);
</span><span class="cx">       if (isNaN(dp) || isNaN(x) || isInf(x))
</span><span class="cx">           return jsString(v-&gt;toString(exec));
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsstring_objectcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/string_object.cpp (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/string_object.cpp        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/JavaScriptCore/kjs/string_object.cpp        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -457,20 +457,16 @@
</span><span class="cx">     // handled above
</span><span class="cx">     break;
</span><span class="cx">   case CharAt:
</span><del>-    // Other browsers treat an omitted parameter as 0 rather than NaN.
-    // That doesn't match the ECMA standard, but is needed for site compatibility.
-    dpos = a0-&gt;isUndefined() ? 0 : a0-&gt;toInteger(exec);
-    if (dpos &gt;= 0 &amp;&amp; dpos &lt; len) // false for NaN
</del><ins>+    dpos = a0-&gt;toInteger(exec);
+    if (dpos &gt;= 0 &amp;&amp; dpos &lt; len)
</ins><span class="cx">       u = s.substr(static_cast&lt;int&gt;(dpos), 1);
</span><span class="cx">     else
</span><span class="cx">       u = &quot;&quot;;
</span><span class="cx">     result = jsString(u);
</span><span class="cx">     break;
</span><span class="cx">   case CharCodeAt:
</span><del>-    // Other browsers treat an omitted parameter as 0 rather than NaN.
-    // That doesn't match the ECMA standard, but is needed for site compatibility.
-    dpos = a0-&gt;isUndefined() ? 0 : a0-&gt;toInteger(exec);
-    if (dpos &gt;= 0 &amp;&amp; dpos &lt; len) // false for NaN
</del><ins>+    dpos = a0-&gt;toInteger(exec);
+    if (dpos &gt;= 0 &amp;&amp; dpos &lt; len)
</ins><span class="cx">       result = jsNumber(s[static_cast&lt;int&gt;(dpos)].unicode());
</span><span class="cx">     else
</span><span class="cx">       result = jsNaN();
</span><span class="lines">@@ -485,31 +481,21 @@
</span><span class="cx">   }
</span><span class="cx">   case IndexOf:
</span><span class="cx">     u2 = a0-&gt;toString(exec);
</span><del>-    if (a1-&gt;isUndefined())
</del><ins>+    dpos = a1-&gt;toInteger(exec);
+    if (dpos &lt; 0)
</ins><span class="cx">       dpos = 0;
</span><del>-    else {
-      dpos = a1-&gt;toInteger(exec);
-      if (dpos &gt;= 0) { // false for NaN
-        if (dpos &gt; len)
-          dpos = len;
-      } else
-        dpos = 0;
-    }
</del><ins>+    else if (dpos &gt; len)
+      dpos = len;
</ins><span class="cx">     result = jsNumber(s.find(u2, static_cast&lt;int&gt;(dpos)));
</span><span class="cx">     break;
</span><span class="cx">   case LastIndexOf:
</span><span class="cx">     u2 = a0-&gt;toString(exec);
</span><span class="cx">     d = a1-&gt;toNumber(exec);
</span><del>-    if (a1-&gt;isUndefined() || KJS::isNaN(d))
</del><ins>+    dpos = a1-&gt;toIntegerPreserveNaN(exec);
+    if (dpos &lt; 0)
+      dpos = 0;
+    else if (!(dpos &lt;= len)) // true for NaN
</ins><span class="cx">       dpos = len;
</span><del>-    else {
-      dpos = a1-&gt;toInteger(exec);
-      if (dpos &gt;= 0) { // false for NaN
-        if (dpos &gt; len)
-          dpos = len;
-      } else
-        dpos = 0;
-    }
</del><span class="cx">     result = jsNumber(s.rfind(u2, static_cast&lt;int&gt;(dpos)));
</span><span class="cx">     break;
</span><span class="cx">   case Match:
</span><span class="lines">@@ -658,22 +644,20 @@
</span><span class="cx">     }
</span><span class="cx">     break;
</span><span class="cx">   case Substr: {
</span><del>-    double d = a0-&gt;toInteger(exec);
-    double d2 = a1-&gt;toInteger(exec);
-    if (!(d &gt;= 0)) { // true for NaN
-      d += len;
-      if (!(d &gt;= 0)) // true for NaN
-        d = 0;
</del><ins>+    double start = a0-&gt;toInteger(exec);
+    double length = a1-&gt;isUndefined() ? len : a1-&gt;toInteger(exec);
+    if (start &gt;= len)
+      return jsString(&quot;&quot;);
+    if (length &lt; 0)
+      return jsString(&quot;&quot;);
+    if (start &lt; 0) {
+      start += len;
+      if (start &lt; 0)
+        start = 0;
</ins><span class="cx">     }
</span><del>-    if (isNaN(d2))
-      d2 = len - d;
-    else {
-      if (d2 &lt; 0)
-        d2 = 0;
-      if (d2 &gt; len - d)
-        d2 = len - d;
-    }
-    result = jsString(s.substr(static_cast&lt;int&gt;(d), static_cast&lt;int&gt;(d2)));
</del><ins>+    if (length &gt; len - d)
+      length = len - d;
+    result = jsString(s.substr(static_cast&lt;int&gt;(start), static_cast&lt;int&gt;(length)));
</ins><span class="cx">     break;
</span><span class="cx">   }
</span><span class="cx">   case Substring: {
</span><span class="lines">@@ -852,7 +836,7 @@
</span><span class="cx">     UChar *p = buf;
</span><span class="cx">     ListIterator it = args.begin();
</span><span class="cx">     while (it != args.end()) {
</span><del>-      unsigned short u = it-&gt;toUInt16(exec);
</del><ins>+      unsigned short u = it-&gt;toUInt32(exec);
</ins><span class="cx">       *p++ = UChar(u);
</span><span class="cx">       it++;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsvaluecpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/value.cpp (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/value.cpp        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/JavaScriptCore/kjs/value.cpp        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -61,14 +61,23 @@
</span><span class="cx">     int32_t i;
</span><span class="cx">     if (getTruncatedInt32(i))
</span><span class="cx">         return i;
</span><del>-    return roundValue(exec, const_cast&lt;JSValue*&gt;(this));
</del><ins>+    double d = toNumber(exec);
+    return isNaN(d) ? 0.0 : trunc(d);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+double JSValue::toIntegerPreserveNaN(ExecState *exec) const
+{
+    int32_t i;
+    if (getTruncatedInt32(i))
+        return i;
+    return trunc(toNumber(exec));
+}
+
</ins><span class="cx"> int32_t JSValue::toInt32SlowCase(ExecState* exec, bool&amp; ok) const
</span><span class="cx"> {
</span><span class="cx">     ok = true;
</span><span class="cx"> 
</span><del>-    double d = roundValue(exec, const_cast&lt;JSValue*&gt;(this));
</del><ins>+    double d = toNumber(exec);
</ins><span class="cx">     if (d &gt;= -D32 / 2 &amp;&amp; d &lt; D32 / 2)
</span><span class="cx">         return static_cast&lt;int32_t&gt;(d);
</span><span class="cx"> 
</span><span class="lines">@@ -76,13 +85,12 @@
</span><span class="cx">         ok = false;
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span><del>-    double d32 = fmod(d, D32);
</del><span class="cx"> 
</span><ins>+    double d32 = fmod(trunc(d), D32);
</ins><span class="cx">     if (d32 &gt;= D32 / 2)
</span><span class="cx">         d32 -= D32;
</span><span class="cx">     else if (d32 &lt; -D32 / 2)
</span><span class="cx">         d32 += D32;
</span><del>-
</del><span class="cx">     return static_cast&lt;int32_t&gt;(d32);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -90,7 +98,7 @@
</span><span class="cx"> {
</span><span class="cx">     ok = true;
</span><span class="cx"> 
</span><del>-    double d = roundValue(exec, const_cast&lt;JSValue*&gt;(this));
</del><ins>+    double d = toNumber(exec);
</ins><span class="cx">     if (d &gt;= 0.0 &amp;&amp; d &lt; D32)
</span><span class="cx">         return static_cast&lt;uint32_t&gt;(d);
</span><span class="cx"> 
</span><span class="lines">@@ -98,34 +106,13 @@
</span><span class="cx">         ok = false;
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span><del>-    double d32 = fmod(d, D32);
</del><span class="cx"> 
</span><ins>+    double d32 = fmod(trunc(d), D32);
</ins><span class="cx">     if (d32 &lt; 0)
</span><span class="cx">         d32 += D32;
</span><del>-
</del><span class="cx">     return static_cast&lt;uint32_t&gt;(d32);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-uint16_t JSValue::toUInt16(ExecState *exec) const
-{
-    uint32_t i;
-    if (getTruncatedUInt32(i))
-        return static_cast&lt;uint16_t&gt;(i);
-
-    double d = roundValue(exec, const_cast&lt;JSValue*&gt;(this));
-    if (d &gt;= 0.0 &amp;&amp; d &lt; D16)
-        return static_cast&lt;uint16_t&gt;(d);
-
-    if (isNaN(d) || isInf(d))
-        return 0;
-    double d16 = fmod(d, D16);
-
-    if (d16 &lt; 0)
-        d16 += D16;
-
-    return static_cast&lt;uint16_t&gt;(d16);
-}
-
</del><span class="cx"> float JSValue::toFloat(ExecState* exec) const
</span><span class="cx"> {
</span><span class="cx">     return static_cast&lt;float&gt;(toNumber(exec));
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsvalueh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/value.h (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/value.h        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/JavaScriptCore/kjs/value.h        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -91,11 +91,11 @@
</span><span class="cx"> 
</span><span class="cx">     // Integer conversions.
</span><span class="cx">     double toInteger(ExecState*) const;
</span><ins>+    double toIntegerPreserveNaN(ExecState*) const;
</ins><span class="cx">     int32_t toInt32(ExecState*) const;
</span><span class="cx">     int32_t toInt32(ExecState*, bool&amp; ok) const;
</span><span class="cx">     uint32_t toUInt32(ExecState*) const;
</span><span class="cx">     uint32_t toUInt32(ExecState*, bool&amp; ok) const;
</span><del>-    uint16_t toUInt16(ExecState*) const;
</del><span class="cx"> 
</span><span class="cx">     // Floating point conversions.
</span><span class="cx">     float toFloat(ExecState*) const;
</span><span class="lines">@@ -405,7 +405,7 @@
</span><span class="cx"> ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
</span><span class="cx"> {
</span><span class="cx">     int32_t i;
</span><del>-    if (JSImmediate::isImmediate(this) &amp;&amp; JSImmediate::getTruncatedInt32(this, i))
</del><ins>+    if (getTruncatedInt32(i))
</ins><span class="cx">         return i;
</span><span class="cx">     bool ok;
</span><span class="cx">     return toInt32SlowCase(exec, ok);
</span><span class="lines">@@ -414,7 +414,7 @@
</span><span class="cx"> inline uint32_t JSValue::toUInt32(ExecState* exec) const
</span><span class="cx"> {
</span><span class="cx">     uint32_t i;
</span><del>-    if (JSImmediate::isImmediate(this) &amp;&amp; JSImmediate::getTruncatedUInt32(this, i))
</del><ins>+    if (getTruncatedUInt32(i))
</ins><span class="cx">         return i;
</span><span class="cx">     bool ok;
</span><span class="cx">     return toUInt32SlowCase(exec, ok);
</span><span class="lines">@@ -423,7 +423,7 @@
</span><span class="cx"> inline int32_t JSValue::toInt32(ExecState* exec, bool&amp; ok) const
</span><span class="cx"> {
</span><span class="cx">     int32_t i;
</span><del>-    if (JSImmediate::isImmediate(this) &amp;&amp; JSImmediate::getTruncatedInt32(this, i)) {
</del><ins>+    if (getTruncatedInt32(i)) {
</ins><span class="cx">         ok = true;
</span><span class="cx">         return i;
</span><span class="cx">     }
</span><span class="lines">@@ -433,7 +433,7 @@
</span><span class="cx"> inline uint32_t JSValue::toUInt32(ExecState* exec, bool&amp; ok) const
</span><span class="cx"> {
</span><span class="cx">     uint32_t i;
</span><del>-    if (JSImmediate::isImmediate(this) &amp;&amp; JSImmediate::getTruncatedUInt32(this, i)) {
</del><ins>+    if (getTruncatedUInt32(i)) {
</ins><span class="cx">         ok = true;
</span><span class="cx">         return i;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkJavaScriptCorewtfMathExtrash"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/wtf/MathExtras.h (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/wtf/MathExtras.h        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/JavaScriptCore/wtf/MathExtras.h        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -67,6 +67,7 @@
</span><span class="cx"> inline double round(double num) { return num &gt; 0 ? floor(num + 0.5) : ceil(num - 0.5); }
</span><span class="cx"> inline float roundf(float num) { return num &gt; 0 ? floorf(num + 0.5f) : ceilf(num - 0.5f); }
</span><span class="cx"> inline bool signbit(double num) { return _copysign(1.0, num) &lt; 0; }
</span><ins>+inline double trunc(double num) { return num &gt; 0 ? floor(num) : ceil(num); }
</ins><span class="cx"> 
</span><span class="cx"> inline double nextafter(double x, double y) { return _nextafter(x, y); }
</span><span class="cx"> inline float nextafterf(float x, float y) { return x &gt; y ? x - FLT_EPSILON : x + FLT_EPSILON; }
</span></span></pre></div>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/LayoutTests/ChangeLog        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2007-10-26  Darin Adler  &lt;darin@apple.com&gt;
+
+        Reviewed by Maciej.
+
+        - test changes for http://bugs.webkit.org/show_bug.cgi?id=15703
+          fix numeric functions -- improve correctness and speed
+
+        * fast/js/resources/char-at.js: Updated test to expect that we get the first
+        character if we pass NaN to charAt and charCodeAt; it's what the specification
+        asks for and matches other browsers too.
+        * fast/js/char-at-expected.txt: Updated.
+
</ins><span class="cx"> 2007-10-26  Mark Rowe  &lt;mrowe@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Update expected results.
</span></span></pre></div>
<a id="trunkLayoutTestsfastjscharatexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/js/char-at-expected.txt (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/js/char-at-expected.txt        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/LayoutTests/fast/js/char-at-expected.txt        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -53,8 +53,8 @@
</span><span class="cx"> PASS &quot;x&quot;.charCodeAt(-1) is NaN
</span><span class="cx"> PASS &quot;x&quot;.charAt(-Infinity) is &quot;&quot;
</span><span class="cx"> PASS &quot;x&quot;.charCodeAt(-Infinity) is NaN
</span><del>-PASS &quot;x&quot;.charAt(NaN) is &quot;&quot;
-PASS &quot;x&quot;.charCodeAt(NaN) is NaN
</del><ins>+PASS &quot;x&quot;.charAt(NaN) is &quot;x&quot;
+PASS &quot;x&quot;.charCodeAt(NaN) is 120
</ins><span class="cx"> PASS &quot;xy&quot;.charAt() is &quot;x&quot;
</span><span class="cx"> PASS &quot;xy&quot;.charCodeAt() is 120
</span><span class="cx"> PASS &quot;xy&quot;.charAt(undefined) is &quot;x&quot;
</span><span class="lines">@@ -79,8 +79,8 @@
</span><span class="cx"> PASS &quot;xy&quot;.charCodeAt(-1) is NaN
</span><span class="cx"> PASS &quot;xy&quot;.charAt(-Infinity) is &quot;&quot;
</span><span class="cx"> PASS &quot;xy&quot;.charCodeAt(-Infinity) is NaN
</span><del>-PASS &quot;xy&quot;.charAt(NaN) is &quot;&quot;
-PASS &quot;xy&quot;.charCodeAt(NaN) is NaN
</del><ins>+PASS &quot;xy&quot;.charAt(NaN) is &quot;x&quot;
+PASS &quot;xy&quot;.charCodeAt(NaN) is 120
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsfastjsresourcescharatjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/js/resources/char-at.js (27094 => 27095)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/js/resources/char-at.js        2007-10-26 06:58:35 UTC (rev 27094)
+++ trunk/LayoutTests/fast/js/resources/char-at.js        2007-10-26 07:51:25 UTC (rev 27095)
</span><span class="lines">@@ -73,12 +73,12 @@
</span><span class="cx"> ['&quot;&quot;', 'NaN'],
</span><span class="cx"> ['&quot;&quot;', 'NaN'],
</span><span class="cx"> ['&quot;&quot;', 'NaN'],
</span><del>-['&quot;&quot;', 'NaN'],
</del><span class="cx"> ['&quot;x&quot;', '120'],
</span><span class="cx"> ['&quot;x&quot;', '120'],
</span><span class="cx"> ['&quot;x&quot;', '120'],
</span><span class="cx"> ['&quot;x&quot;', '120'],
</span><span class="cx"> ['&quot;x&quot;', '120'],
</span><ins>+['&quot;x&quot;', '120'],
</ins><span class="cx"> ['&quot;y&quot;', '121'],
</span><span class="cx"> ['&quot;x&quot;', '120'],
</span><span class="cx"> ['&quot;x&quot;', '120'],
</span><span class="lines">@@ -86,7 +86,7 @@
</span><span class="cx"> ['&quot;&quot;', 'NaN'],
</span><span class="cx"> ['&quot;&quot;', 'NaN'],
</span><span class="cx"> ['&quot;&quot;', 'NaN'],
</span><del>-['&quot;&quot;', 'NaN']];
</del><ins>+['&quot;x&quot;', '120']];
</ins><span class="cx"> 
</span><span class="cx"> for (var i = 0; i &lt; cases.length; ++i)
</span><span class="cx"> {
</span><span class="lines">@@ -94,16 +94,16 @@
</span><span class="cx">     var result = answers[i];
</span><span class="cx">     if (item[1] == &quot;omitted&quot;) {
</span><span class="cx">         shouldBe('&quot;' + item[0] + '&quot;.charAt()', result[0]);
</span><del>-        if (result[1] == 'NaN')
-            shouldBeNaN('&quot;' + item[0] + '&quot;.charCodeAt()');
-        else
-            shouldBe('&quot;' + item[0] + '&quot;.charCodeAt()', result[1]);
</del><ins>+        if (result[1] == 'NaN')
+            shouldBeNaN('&quot;' + item[0] + '&quot;.charCodeAt()');
+        else
+            shouldBe('&quot;' + item[0] + '&quot;.charCodeAt()', result[1]);
</ins><span class="cx">     } else {
</span><span class="cx">         shouldBe('&quot;' + item[0] + '&quot;.charAt(' + item[1] + ')', result[0]);
</span><del>-        if (result[1] == 'NaN')
-            shouldBeNaN('&quot;' + item[0] + '&quot;.charCodeAt(' + item[1] + ')');
-        else
-            shouldBe('&quot;' + item[0] + '&quot;.charCodeAt(' + item[1] + ')', result[1]);
</del><ins>+        if (result[1] == 'NaN')
+            shouldBeNaN('&quot;' + item[0] + '&quot;.charCodeAt(' + item[1] + ')');
+        else
+            shouldBe('&quot;' + item[0] + '&quot;.charCodeAt(' + item[1] + ')', result[1]);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>