Bug 1253884 - Baldr: fix parsing of (f32.const -0) (r=sunfish)
authorLuke Wagner <luke@mozilla.com>
Sun, 06 Mar 2016 17:46:22 -0600
changeset 323333 f1ff5388e591a53187620f03de8278c496442a05
parent 323332 1e696dae3026753b2a913dbdc049e647219cc01f
child 323334 57e9d3626218d7adf9463db51ad9aae8c44cd709
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1253884
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1253884 - Baldr: fix parsing of (f32.const -0) (r=sunfish) MozReview-Commit-ID: DEDehyShLqw
js/src/asmjs/WasmText.cpp
js/src/jit-test/tests/wasm/basic-const.js
--- a/js/src/asmjs/WasmText.cpp
+++ b/js/src/asmjs/WasmText.cpp
@@ -779,16 +779,17 @@ class WasmToken
         GetLocal,
         If,
         IfElse,
         Import,
         Index,
         UnsignedInteger,
         SignedInteger,
         Memory,
+        NegativeZero,
         Load,
         Local,
         Loop,
         Module,
         Name,
         Nop,
         Offset,
         OpenParen,
@@ -1266,16 +1267,18 @@ WasmTokenStream::literal(const char16_t*
             if (!u.isValid())
                 return LexHexFloatLiteral(begin, end_, &cur_);
 
             cur_++;
         } while (cur_ != end_);
 
         if (*begin == '-') {
             uint64_t value = u.value();
+            if (value == 0)
+                return WasmToken(WasmToken::NegativeZero, begin, cur_);
             if (value > uint64_t(INT64_MIN))
                 return LexHexFloatLiteral(begin, end_, &cur_);
 
             value = -value;
             return WasmToken(int64_t(value), begin, cur_);
         }
     } else {
         while (cur_ != end_) {
@@ -1290,16 +1293,18 @@ WasmTokenStream::literal(const char16_t*
             if (!u.isValid())
                 return LexDecFloatLiteral(begin, end_, &cur_);
 
             cur_++;
         }
 
         if (*begin == '-') {
             uint64_t value = u.value();
+            if (value == 0)
+                return WasmToken(WasmToken::NegativeZero, begin, cur_);
             if (value > uint64_t(INT64_MIN))
                 return LexDecFloatLiteral(begin, end_, &cur_);
 
             value = -value;
             return WasmToken(int64_t(value), begin, cur_);
         }
     }
 
@@ -2265,16 +2270,19 @@ ParseFloatLiteral(WasmParseContext& c, W
         *result = token.index();
         return true;
       case WasmToken::UnsignedInteger:
         *result = token.uint();
         return true;
       case WasmToken::SignedInteger:
         *result = token.sint();
         return true;
+      case WasmToken::NegativeZero:
+        *result = -0.0;
+        return true;
       case WasmToken::Float:
         break;
       default:
         c.ts.generateError(token, c.error);
         return false;
     }
 
     const char16_t* begin = token.begin();
@@ -2340,29 +2348,33 @@ ParseConst(WasmParseContext& c, WasmToke
           case WasmToken::Index:
             return new(c.lifo) WasmAstConst(Val(val.index()));
           case WasmToken::SignedInteger: {
             CheckedInt<int32_t> sint = val.sint();
             if (!sint.isValid())
                 break;
             return new(c.lifo) WasmAstConst(Val(uint32_t(sint.value())));
           }
+          case WasmToken::NegativeZero:
+            return new(c.lifo) WasmAstConst(Val(uint32_t(0)));
           default:
             break;
         }
         break;
       }
       case ValType::I64: {
         switch (val.kind()) {
           case WasmToken::Index:
             return new(c.lifo) WasmAstConst(Val(uint64_t(val.index())));
           case WasmToken::UnsignedInteger:
             return new(c.lifo) WasmAstConst(Val(val.uint()));
           case WasmToken::SignedInteger:
             return new(c.lifo) WasmAstConst(Val(uint64_t(val.sint())));
+          case WasmToken::NegativeZero:
+            return new(c.lifo) WasmAstConst(Val(uint32_t(0)));
           default:
             break;
         }
         break;
       }
       case ValType::F32: {
         float result;
         if (!ParseFloatLiteral(c, val, &result))
--- a/js/src/jit-test/tests/wasm/basic-const.js
+++ b/js/src/jit-test/tests/wasm/basic-const.js
@@ -36,19 +36,21 @@ testConst('i32', '0xffffffff', -1);
 //testConst('i64', '18446744073709551615', -1); // TODO: NYI
 //testConst('i64', '-9223372036854775808', -9223372036854775808); // TODO: NYI
 //testConst('i64', '0x7fffffffffffffff', 9223372036854775807); // TODO: NYI
 //testConst('i64', '0x8000000000000000', -9223372036854775808); // TODO: NYI
 //testConst('i64', '-0x8000000000000000', -9223372036854775808); // TODO: NYI
 //testConst('i64', '0xffffffffffffffff', -1); // TODO: NYI
 
 testConst('f32', '0.0', 0.0);
+testConst('f32', '-0', -0.0);
 testConst('f32', '-0.0', -0.0);
 testConst('f32', '0x0.0', 0.0);
 testConst('f32', '-0x0.0', -0.0);
+testConst('f32', '-0x0', -0.0);
 testConst('f32', '0x0.0p0', 0.0);
 testConst('f32', '-0x0.0p0', -0.0);
 testConst('f32', 'infinity', Infinity);
 testConst('f32', '-infinity', -Infinity);
 testConst('f32', '+infinity', Infinity);
 testConst('f32', 'nan', NaN);
 //testConst('f32', '-nan', NaN); // TODO: NYI
 testConst('f32', '+nan', NaN);
@@ -121,18 +123,20 @@ testConst('f32', '0x0434.234p0', 1076.13
 testConst('f32', '-0x3434.234p0', -13364.1376953125);
 testConst('f32', '0x4.22342p0', 4.133607864379883);
 testConst('f32', '0x30000p-20', 1.875000e-01);
 testConst('f32', '0x0.533fcccp-125', 7.645233588931088e-39);
 testConst('f32', '0', 0);
 
 testConst('f64', '0.0', 0.0);
 testConst('f64', '-0.0', -0.0);
+testConst('f64', '-0', -0.0);
 testConst('f64', '0x0.0', 0.0);
 testConst('f64', '-0x0.0', -0.0);
+testConst('f64', '-0x0', -0.0);
 testConst('f64', '0x0.0p0', 0.0);
 testConst('f64', '-0x0.0p0', -0.0);
 testConst('f64', 'infinity', Infinity);
 testConst('f64', '-infinity', -Infinity);
 testConst('f64', '+infinity', Infinity);
 testConst('f64', 'nan', NaN);
 //testConst('f64', '-nan', NaN); // TODO: NYI
 testConst('f64', '+nan', NaN);