Bug 957513 - Re-enable decimal literals starting with `08` or `09` on Aurora. r=jorendorff,a=backout
authorTill Schneidereit <till@tillschneidereit.net>
Mon, 16 Jun 2014 23:56:38 +0200
changeset 208123 301e62e44f1824f041ac0a1b82ab2f1650071522
parent 208122 874608951fc8defbe869bca306ba04754feb3663
child 208124 7f309a3a4d3d5aa0c2ee64e5f7a0f8d9c387fa0b
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff, backout
bugs957513
milestone32.0a2
Bug 957513 - Re-enable decimal literals starting with `08` or `09` on Aurora. r=jorendorff,a=backout
browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-01.js
js/src/frontend/TokenStream.cpp
js/src/jit-test/tests/parser/parseOctal.js
js/src/js.msg
js/src/tests/ecma/LexicalConventions/7.7.3-2.js
js/src/tests/js1_5/LexicalConventions/lexical-001.js
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-01.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-01.js
@@ -100,17 +100,17 @@ function test() {
         "myVar.prop = 'xlerb'": "xlerb"
       }))
       .then(() => deleteWatchExpression("myVar.prop = 'xlerb'"))
       .then(() => testEdit("self", "2507", {
         "myVar.prop": 2507,
         "myVar.prop + 42": 2549
       }))
       .then(() => deleteWatchExpression("myVar.prop + 42"))
-      .then(() => testEdit("self", "910", {
+      .then(() => testEdit("self", "0910", {
         "myVar.prop": 910
       }))
       .then(() => deleteLastWatchExpression("myVar.prop"))
       .then(() => testWatchExpressionsRemoved())
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
       .then(null, aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -1396,26 +1396,30 @@ TokenStream::getTokenInternal(Modifier m
                 goto error;
             }
             numStart = userbuf.addressOfNextRawChar() - 1;  // one past the '0o'
             while ('0' <= c && c <= '7')
                 c = getCharIgnoreEOL();
         } else if (JS7_ISDEC(c)) {
             radix = 8;
             numStart = userbuf.addressOfNextRawChar() - 1;  // one past the '0'
-
-            // Octal integer literals are not permitted in strict mode code.
-            if (!reportStrictModeError(JSMSG_DEPRECATED_OCTAL))
-                goto error;
+            while (JS7_ISDEC(c)) {
+                // Octal integer literals are not permitted in strict mode code.
+                if (!reportStrictModeError(JSMSG_DEPRECATED_OCTAL))
+                    goto error;
 
-            while (JS7_ISDEC(c)) {
-                // Even in sloppy mode, 08 or 09 is a syntax error.
+                // Outside strict mode, we permit 08 and 09 as decimal numbers,
+                // which makes our behaviour a superset of the ECMA numeric
+                // grammar. We might not always be so permissive, so we warn
+                // about it.
                 if (c >= '8') {
-                    reportError(JSMSG_BAD_OCTAL, c == '8' ? "8" : "9");
-                    goto error;
+                    if (!reportWarning(JSMSG_BAD_OCTAL, c == '8' ? "08" : "09")) {
+                        goto error;
+                    }
+                    goto decimal;   // use the decimal scanner for the rest of the number
                 }
                 c = getCharIgnoreEOL();
             }
         } else {
             // '0' not followed by 'x', 'X' or a digit;  scan as a decimal number.
             numStart = userbuf.addressOfNextRawChar() - 1;
             goto decimal;
         }
deleted file mode 100644
--- a/js/src/jit-test/tests/parser/parseOctal.js
+++ /dev/null
@@ -1,8 +0,0 @@
-load(libdir + 'asserts.js');
-
-for (var code of ["08", "09", "01238", "01239", "08e+1"]) {
-    assertThrowsInstanceOf(() => Function(code), SyntaxError);
-    assertThrowsInstanceOf(() => eval(code), SyntaxError);
-}
-
-var ok = [0.8, 0.08, 0e8, 1e08, 1e+08];
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -190,17 +190,17 @@ MSG_DEF(JSMSG_MISSING_EXPONENT,       13
 MSG_DEF(JSMSG_OUT_OF_MEMORY,          137, 0, JSEXN_ERR, "out of memory")
 MSG_DEF(JSMSG_UNTERMINATED_STRING,    138, 0, JSEXN_SYNTAXERR, "unterminated string literal")
 MSG_DEF(JSMSG_TOO_MANY_PARENS,        139, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression")
 MSG_DEF(JSMSG_UNTERMINATED_COMMENT,   140, 0, JSEXN_SYNTAXERR, "unterminated comment")
 MSG_DEF(JSMSG_UNTERMINATED_REGEXP,    141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal")
 MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE, 142, 0, JSEXN_TYPEERR, "bad cloned function scope chain")
 MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS,   143, 0, JSEXN_SYNTAXERR, "missing octal digits after '0o'")
 MSG_DEF(JSMSG_ILLEGAL_CHARACTER,      144, 0, JSEXN_SYNTAXERR, "illegal character")
-MSG_DEF(JSMSG_BAD_OCTAL,              145, 1, JSEXN_SYNTAXERR, "numbers starting with 0 followed by a digit are octals and can't contain {0}")
+MSG_DEF(JSMSG_BAD_OCTAL,              145, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant")
 MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 146, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size")
 MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION,     147, 1, JSEXN_INTERNALERR, "uncaught exception: {0}")
 MSG_DEF(JSMSG_INVALID_BACKREF,        148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference")
 MSG_DEF(JSMSG_BAD_BACKREF,            149, 0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses")
 MSG_DEF(JSMSG_PRECISION_RANGE,        150, 1, JSEXN_RANGEERR, "precision {0} out of range")
 MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER,   151, 1, JSEXN_TYPEERR, "invalid {0} usage")
 MSG_DEF(JSMSG_BAD_ARRAY_LENGTH,       152, 0, JSEXN_RANGEERR, "invalid array length")
 MSG_DEF(JSMSG_CANT_DESCRIBE_PROPS,    153, 1, JSEXN_TYPEERR, "can't describe non-native properties of class {0}")
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma/LexicalConventions/7.7.3-2.js
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+/**
+   File Name:          7.7.3-2.js
+   ECMA Section:       7.7.3 Numeric Literals
+
+   Description:
+
+   This is a regression test for
+   http://scopus.mcom.com/bugsplat/show_bug.cgi?id=122884
+
+   Waldemar's comments:
+
+   A numeric literal that starts with either '08' or '09' is interpreted as a
+   decimal literal; it should be an error instead.  (Strictly speaking, according
+   to ECMA v1 such literals should be interpreted as two integers -- a zero
+   followed by a decimal number whose first digit is 8 or 9, but this is a bug in
+   ECMA that will be fixed in v2.  In any case, there is no place in the grammar
+   where two consecutive numbers would be legal.)
+
+   Author:             christine@netscape.com
+   Date:               15 june 1998
+
+*/
+var SECTION = "7.7.3-2";
+var VERSION = "ECMA_1";
+var TITLE   = "Numeric Literals";
+var BUGNUMBER="122884";
+
+startTest();
+
+writeHeaderToLog( SECTION + " "+ TITLE);
+
+new TestCase( SECTION,
+	      "9",
+	      9,
+	      9 );
+
+new TestCase( SECTION,
+	      "09",
+	      9,
+	      09 );
+
+new TestCase( SECTION,
+	      "099",
+	      99,
+	      099 );
+
+
+new TestCase( SECTION,
+	      "077",
+	      63,
+	      077 );
+
+test();
--- a/js/src/tests/js1_5/LexicalConventions/lexical-001.js
+++ b/js/src/tests/js1_5/LexicalConventions/lexical-001.js
@@ -4,16 +4,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 /*
  * Date: 26 November 2000
  *
  *SUMMARY: Testing numeric literals that begin with 0.
  *This test arose from Bugzilla bug 49233.
+ *The best explanation is from jsscan.c:               
+ *
+ *     "We permit 08 and 09 as decimal numbers, which makes
+ *     our behaviour a superset of the ECMA numeric grammar. 
+ *     We might not always be so permissive, so we warn about it."
+ *
+ *Thus an expression 010 will evaluate, as always, as an octal (to 8).
+ *However, 018 will evaluate as a decimal, to 18. Even though the
+ *user began the expression as an octal, he later used a non-octal
+ *digit. We forgive this and assume he intended a decimal. If the
+ *JavaScript "strict" option is set though, we will give a warning.
  */
 
 //-------------------------------------------------------------------------------------------------
 var BUGNUMBER = '49233';
 var summary = 'Testing numeric literals that begin with 0';
 var statprefix = 'Testing ';
 var quote = "'";
 var asString = new Array();
@@ -24,40 +35,97 @@ var expect = new Array();
   asString[0]='01'
   actual[0]=01
   expect[0]=1
 
   asString[1]='07'
   actual[1]=07
   expect[1]=7
 
+  asString[2]='08'
+  actual[2]=08
+  expect[2]=8
+
+  asString[3]='09'
+  actual[3]=09
+  expect[3]=9
+
   asString[4]='010'
   actual[4]=010
   expect[4]=8
 
   asString[5]='017'
   actual[5]=017
   expect[5]=15
 
+  asString[6]='018'
+  actual[6]=018
+  expect[6]=18
+
+  asString[7]='019'
+  actual[7]=019
+  expect[7]=19
+
+  asString[8]='079'
+  actual[8]=079
+  expect[8]=79
+
+  asString[9]='0079'
+  actual[9]=0079
+  expect[9]=79
+
+  asString[10]='099'
+  actual[10]=099
+  expect[10]=99
+
+  asString[11]='0099'
+  actual[11]=0099
+  expect[11]=99
+
   asString[12]='000000000077'
   actual[12]=000000000077
   expect[12]=63
 
+  asString[13]='000000000078'
+  actual[13]=000000000078
+  expect[13]=78
+
   asString[14]='0000000000770000'
   actual[14]=0000000000770000
   expect[14]=258048
 
+  asString[15]='0000000000780000'
+  actual[15]=0000000000780000
+  expect[15]=780000
+
+  asString[16]='0765432198'
+  actual[16]=0765432198
+  expect[16]=765432198
+
+  asString[17]='00076543219800'
+  actual[17]=00076543219800
+  expect[17]=76543219800
+
   asString[18]='0000001001007'
   actual[18]=0000001001007
   expect[18]=262663
 
+  asString[19]='0000001001009'
+  actual[19]=0000001001009
+  expect[19]=1001009
+
   asString[20]='070'
   actual[20]=070
   expect[20]=56
 
+  asString[21]='080'
+  actual[21]=080
+  expect[21]=80
+
+
 
 //-------------------------------------------------------------------------------------------------
   test();
 //-------------------------------------------------------------------------------------------------
 
 
 function showStatus(msg)
 {