Backed out changeset 097c455f81fa (bug 1066827)
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 28 Oct 2014 12:22:57 +0100
changeset 212631 63bf295591c06df12a9129604569c45f6b539adb
parent 212630 685abe864bcd2889f020bc874afce24d813b72bd
child 212632 1f10d6520886aa18a2ea1718f3955b0ebb5a9900
push id27721
push usercbook@mozilla.com
push dateTue, 28 Oct 2014 14:55:05 +0000
treeherdermozilla-central@c0ddb1b098ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1066827
milestone36.0a1
backs out097c455f81fab35176f74a6b731b8448f870feaa
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
Backed out changeset 097c455f81fa (bug 1066827)
js/src/frontend/TokenKind.h
js/src/frontend/TokenStream.cpp
js/src/frontend/TokenStream.h
--- a/js/src/frontend/TokenKind.h
+++ b/js/src/frontend/TokenKind.h
@@ -191,16 +191,17 @@
     FOR_EACH_TOKEN_KIND_WITH_RANGE(macro, TOKEN_KIND_RANGE_EMIT_NONE)
 
 namespace js {
 namespace frontend {
 
 // Values of this type are used to index into arrays such as isExprEnding[],
 // so the first value must be zero.
 enum TokenKind {
+    TOK_ERROR = 0,
 #define EMIT_ENUM(name, desc) TOK_##name,
 #define EMIT_ENUM_RANGE(name, value) TOK_##name = TOK_##value,
     FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_ENUM, EMIT_ENUM_RANGE)
 #undef EMIT_ENUM
 #undef EMIT_ENUM_RANGE
     TOK_LIMIT                      // domain size
 };
 
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -511,24 +511,23 @@ TokenStream::TokenBuf::findEOLMax(const 
         n++;
     }
     return p;
 }
 
 void
 TokenStream::advance(size_t position)
 {
-    MOZ_ASSERT(position <= mozilla::PointerRangeSize(userbuf.base(), userbuf.limit()));
     const char16_t *end = userbuf.base() + position;
     while (userbuf.addressOfNextRawChar() < end)
         getChar();
 
     Token *cur = &tokens[cursor];
     cur->pos.begin = userbuf.addressOfNextRawChar() - userbuf.base();
-    MOZ_MAKE_MEM_UNDEFINED(&cur->type, sizeof(cur->type));
+    cur->type = TOK_ERROR;
     lookahead = 0;
 }
 
 void
 TokenStream::tell(Position *pos)
 {
     pos->buf = userbuf.addressOfNextRawChar(/* allowPoisoned = */ true);
     pos->flags = flags;
@@ -939,17 +938,17 @@ TokenStream::atomize(ExclusiveContext *c
 }
 
 #ifdef DEBUG
 static bool
 IsTokenSane(Token *tp)
 {
     // Nb: TOK_EOL should never be used in an actual Token;  it should only be
     // returned as a TokenKind from peekTokenSameLine().
-    if (tp->type < 0 || tp->type >= TOK_LIMIT || tp->type == TOK_EOL)
+    if (tp->type < TOK_ERROR || tp->type >= TOK_LIMIT || tp->type == TOK_EOL)
         return false;
 
     if (tp->pos.end < tp->pos.begin)
         return false;
 
     return true;
 }
 #endif
@@ -1627,26 +1626,29 @@ TokenStream::getTokenInternal(TokenKind 
     tp->pos.end = userbuf.addressOfNextRawChar() - userbuf.base();
     MOZ_ASSERT(IsTokenSane(tp));
     *ttp = tp->type;
     return true;
 
   error:
     flags.isDirtyLine = true;
     tp->pos.end = userbuf.addressOfNextRawChar() - userbuf.base();
-    MOZ_MAKE_MEM_UNDEFINED(&tp->type, sizeof(tp->type));
+    tp->type = TOK_ERROR;
     flags.hadError = true;
 #ifdef DEBUG
     // Poisoning userbuf on error establishes an invariant: once an erroneous
     // token has been seen, userbuf will not be consulted again.  This is true
-    // because the parser will deal with the illegal token by aborting parsing
-    // immediately.
+    // because the parser will either (a) deal with the TOK_ERROR token by
+    // aborting parsing immediately; or (b) if the TOK_ERROR token doesn't
+    // match what it expected, it will unget the token, and the next getToken()
+    // call will immediately return the just-gotten TOK_ERROR token again
+    // without consulting userbuf, thanks to the lookahead buffer.
     userbuf.poison();
 #endif
-    MOZ_MAKE_MEM_UNDEFINED(ttp, sizeof(*ttp));
+    *ttp = TOK_ERROR;
     return false;
 }
 
 bool TokenStream::getStringOrTemplateToken(int qc, Token **tp)
 {
     *tp = newToken(-1);
     int c;
     int nc = -1;
@@ -1802,30 +1804,34 @@ js_fgets(char *buf, int size, FILE *file
 
 const char *
 frontend::TokenKindToDesc(TokenKind tt)
 {
     switch (tt) {
 #define EMIT_CASE(name, desc) case TOK_##name: return desc;
       FOR_EACH_TOKEN_KIND(EMIT_CASE)
 #undef EMIT_CASE
+      case TOK_ERROR:
+        MOZ_ASSERT_UNREACHABLE("TOK_ERROR should not be passed.");
+        break;
       case TOK_LIMIT:
         MOZ_ASSERT_UNREACHABLE("TOK_LIMIT should not be passed.");
         break;
     }
 
     return "<bad TokenKind>";
 }
 
 #ifdef DEBUG
 const char *
 TokenKindToString(TokenKind tt)
 {
     switch (tt) {
 #define EMIT_CASE(name, desc) case TOK_##name: return "TOK_" #name;
       FOR_EACH_TOKEN_KIND(EMIT_CASE)
 #undef EMIT_CASE
+      case TOK_ERROR: return "TOK_ERROR";
       case TOK_LIMIT: break;
     }
 
     return "<bad TokenKind>";
 }
 #endif
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -100,19 +100,19 @@ struct Token
     // constructor on each element, which would call the TokenPos constructor
     // for Token::pos and do nothing.  (All of which is equivalent to just
     // zeroing TokenStream::tokens.)  But MSVC 2013 (2010/2012 don't have this
     // bug) doesn't zero out each element, so we need this extra constructor to
     // make it do the right thing.  (Token is used primarily by reference or
     // pointer, and it's only initialized a very few places, so having a
     // user-defined constructor won't hurt perf.)  See also bug 920318.
     Token()
-      : pos(0, 0)
+      : type(TOK_ERROR),
+        pos(0, 0)
     {
-        MOZ_MAKE_MEM_UNDEFINED(&type, sizeof(type));
     }
 
     // Mutators
 
     void setName(PropertyName *name) {
         MOZ_ASSERT(type == TOK_NAME);
         MOZ_ASSERT(!IsPoisonedPtr(name));
         u.name = name;
@@ -342,18 +342,17 @@ class MOZ_STACK_CLASS TokenStream
     static JSAtom *atomize(ExclusiveContext *cx, CharBuffer &cb);
     bool putIdentInTokenbuf(const char16_t *identStart);
 
     struct Flags
     {
         bool isEOF:1;           // Hit end of file.
         bool isDirtyLine:1;     // Non-whitespace since start of line.
         bool sawOctalEscape:1;  // Saw an octal character escape.
-        bool hadError:1;        // Hit a syntax error, at start or during a
-                                // token.
+        bool hadError:1;        // Returned TOK_ERROR from getToken.
 
         Flags()
           : isEOF(), isDirtyLine(), sawOctalEscape(), hadError()
         {}
     };
 
   public:
     // Sometimes the parser needs to modify how tokens are created.