<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>202002</bug_id>
          
          <creation_ts>2019-09-19 13:36:01 -0700</creation_ts>
          <short_desc>Consider ensuring that NaNs are always represented by pureNaN before boxing.</short_desc>
          <delta_ts>2019-09-19 19:30:33 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>JavaScriptCore</component>
          <version>WebKit Nightly Build</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</op_sys>
          <bug_status>ASSIGNED</bug_status>
          <resolution></resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Mark Lam">mark.lam</reporter>
          <assigned_to name="Mark Lam">mark.lam</assigned_to>
          <cc>ggaren</cc>
    
    <cc>ysuzuki</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1572455</commentid>
    <comment_count>0</comment_count>
    <who name="Mark Lam">mark.lam</who>
    <bug_when>2019-09-19 13:36:01 -0700</bug_when>
    <thetext>Most double operations will not produce NaNs.  For those that can e.g. division, we can purifyNaN the value before we box it.

If we do this, then we can reduce the JSValue tag to only 14 bits.  The key insight is as follows:

The highest double value we can have will now be negative infinity i.e. starts with 0xfff0.
The &quot;negative&quot; pureNaN will now no longer be possible because we ensure that it gets purified into the &quot;positive&quot; form that starts with 0x7ff8.

This means if we add a DoubleEncodeOffset of 1 &lt;&lt; 50 (starts with 0x0040), negative infinity becomes 0xfff4.  That leaves us 0xfffc for ints, and 0x0000 for pointers.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1572461</commentid>
    <comment_count>1</comment_count>
    <who name="Mark Lam">mark.lam</who>
    <bug_when>2019-09-19 13:51:00 -0700</bug_when>
    <thetext>(In reply to Mark Lam from comment #0)
&gt; Most double operations will not produce NaNs.  For those that can e.g.
&gt; division, we can purifyNaN the value before we box it.
&gt; 
&gt; If we do this, then we can reduce the JSValue tag to only 14 bits.  The key
&gt; insight is as follows:
&gt; 
&gt; The highest double value we can have will now be negative infinity i.e.
&gt; starts with 0xfff0.
&gt; The &quot;negative&quot; pureNaN will now no longer be possible because we ensure that
&gt; it gets purified into the &quot;positive&quot; form that starts with 0x7ff8.
&gt; 
&gt; This means if we add a DoubleEncodeOffset of 1 &lt;&lt; 50 (starts with 0x0040),
&gt; negative infinity becomes 0xfff4.  That leaves us 0xfffc for ints, and
&gt; 0x0000 for pointers.

Correction: 1 &lt;&lt; 50 starts with 0x0004, not 0x0040.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1572528</commentid>
    <comment_count>2</comment_count>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2019-09-19 16:27:03 -0700</bug_when>
    <thetext>I don&apos;t think it&apos;s valid to convert negative NaN to positive NaN. My memory is that the sign bit is observable to the JavaScript programmer.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1572532</commentid>
    <comment_count>3</comment_count>
    <who name="Mark Lam">mark.lam</who>
    <bug_when>2019-09-19 16:36:15 -0700</bug_when>
    <thetext>(In reply to Geoffrey Garen from comment #2)
&gt; I don&apos;t think it&apos;s valid to convert negative NaN to positive NaN. My memory
&gt; is that the sign bit is observable to the JavaScript programmer.

That&apos;s interesting, but would not be spec compliant.  See https://www.ecma-international.org/ecma-262/9.0/index.html#sec-ecmascript-language-types-number-type

&quot;the 9007199254740990 (that is, 253-2) distinct “Not-a-Number” values of the IEEE Standard are represented in ECMAScript as a single special NaN value. (Note that the NaN value is produced by the program expression NaN.) In some implementations, external code might be able to detect a difference between various Not-a-Number values, but such behaviour is implementation-dependent; to ECMAScript code, all NaN values are indistinguishable from each other.&quot;

Do we need to keep the non-compliant behavior?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1572533</commentid>
    <comment_count>4</comment_count>
    <who name="Yusuke Suzuki">ysuzuki</who>
    <bug_when>2019-09-19 16:41:26 -0700</bug_when>
    <thetext>(In reply to Geoffrey Garen from comment #2)
&gt; I don&apos;t think it&apos;s valid to convert negative NaN to positive NaN. My memory
&gt; is that the sign bit is observable to the JavaScript programmer.

I think this is positive-zero and negative-zero, right?

var z = -0;
print(1 / z) // =&gt; -Infinity
var z = 0;
print(1 / z) // =&gt; Infinity

But for NaN, all the calculation with NaN will produce NaN in JS world. And Math.sign(NaN) returns NaN. So I think, in JS world (not saying about wasm world), we do not have a way to distinguish negative and positive NaN.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1572538</commentid>
    <comment_count>5</comment_count>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2019-09-19 16:47:01 -0700</bug_when>
    <thetext>&gt; Do we need to keep the non-compliant behavior?

I wasn&apos;t aware of that spec text. I think it&apos;s new.

I don&apos;t know of any need to stick to our old behavior, given that the spec now mandates a single NaN in JavaScript.</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>