Bug 1322019 - Part 1: Put unary operator inside parens in expression decompilation. r=nbp
authorTooru Fujisawa <arai_a@mac.com>
Mon, 27 Feb 2017 20:02:55 +0900
changeset 374079 bcb3bb41c374eaa64fd64d651148b59b70acf377
parent 374078 f9cc96d0a27a659a90e153051010e0d5436d7a2b
child 374080 20cd9a2ede17439c9a8c87fc7c6542ff93945a24
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1322019
milestone54.0a1
Bug 1322019 - Part 1: Put unary operator inside parens in expression decompilation. r=nbp
js/src/jit-test/tests/basic/expression-autopsy.js
js/src/jsopcode.cpp
--- a/js/src/jit-test/tests/basic/expression-autopsy.js
+++ b/js/src/jit-test/tests/basic/expression-autopsy.js
@@ -82,30 +82,34 @@ check("(o[0] = 4).foo", "o[0].foo");
 // undefined in that case.
 check("this.x", "this.x", false);
 
 for (let tok of ["|", "^", "&", "==", "!==", "===", "!==", "<", "<=", ">", ">=",
                  ">>", "<<", ">>>", "+", "-", "*", "/", "%"]) {
     check("o[(undef " + tok + " 4)]");
 }
 
-check("o[!(o)]");
-check("o[~(o)]");
-check("o[+ (o)]");
-check("o[- (o)]");
+check("o[(!o)]");
+check("o[(~o)]");
+check("o[(+ o)]");
+check("o[(- o)]");
 
+check("o[(!(o + 1))]");
+check("o[(~(o + 1))]");
+check("o[(+ (o + 1))]");
+check("o[(- (o + 1))]");
 
 // A few one off tests
 check_one("6", (function () { 6() }), " is not a function");
 check_one("4", (function() { (4||eval)(); }), " is not a function");
 check_one("0", (function () { Array.prototype.reverse.call('123'); }), " is read-only");
 check_one("(intermediate value)[Symbol.iterator](...).next(...).value",
           function () { ieval("{ let x; var [a, b, [c0, c1]] = [x, x, x]; }") }, " is undefined");
-check_one("void 1", function() { (void 1)(); }, " is not a function");
-check_one("void o[1]", function() { var o = []; (void o[1])() }, " is not a function");
+check_one("(void 1)", function() { (void 1)(); }, " is not a function");
+check_one("(void o[1])", function() { var o = []; (void o[1])() }, " is not a function");
 
 // Manual testing for this case: the only way to trigger an error is *not* on
 // an attempted property access during destructuring, and the error message
 // invoking ToObject(null) is different: "can't convert {0} to object".
 try
 {
   (function() {
     var [{x}] = [null, {}];
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -1238,18 +1238,18 @@ ExpressionDecompiler::decompilePC(jsbyte
                        write(" ") &&
                        write(token) &&
                        write(" ") &&
                        decompilePCForStackOperand(pc, -1) &&
                        write(")");
             break;
           }
           case 1:
-            return write(token) &&
-                   write("(") &&
+            return write("(") &&
+                   write(token) &&
                    decompilePCForStackOperand(pc, -1) &&
                    write(")");
           default:
             break;
         }
     }
 
     switch (op) {
@@ -1380,17 +1380,19 @@ ExpressionDecompiler::decompilePC(jsbyte
         JSString* str = ValueToSource(cx, objv);
         if (!str)
             return false;
         return write(str);
       }
       case JSOP_CHECKISOBJ:
         return decompilePCForStackOperand(pc, -1);
       case JSOP_VOID:
-        return write("void ") && decompilePCForStackOperand(pc, -1);
+        return write("(void ") &&
+               decompilePCForStackOperand(pc, -1) &&
+               write(")");
       default:
         break;
     }
     return write("(intermediate value)");
 }
 
 bool
 ExpressionDecompiler::init()