Bug 1066827 - Part6: Check error in TokenStream.peekTokenPos. r=jwalden
☠☠ backed out by 67766301f672 ☠ ☠
authorTooru Fujisawa <arai_a@mac.com>
Fri, 24 Oct 2014 21:02:00 +0200
changeset 212611 0243acc10d0e5574b1d0fc611a8a09768890c83e
parent 212610 7d9e3126b05b2415b89ffba7010de560d9f3b01b
child 212612 f9c84399eb72da94d1ef82826ed9621962048290
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)
reviewersjwalden
bugs1066827
milestone36.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 1066827 - Part6: Check error in TokenStream.peekTokenPos. r=jwalden
js/src/asmjs/AsmJSModule.cpp
js/src/asmjs/AsmJSValidate.cpp
js/src/frontend/TokenStream.h
--- a/js/src/asmjs/AsmJSModule.cpp
+++ b/js/src/asmjs/AsmJSModule.cpp
@@ -303,17 +303,20 @@ AsmJSModule::lookupHeapAccess(void *pc) 
 
 bool
 AsmJSModule::finish(ExclusiveContext *cx, TokenStream &tokenStream, MacroAssembler &masm,
                     const Label &interruptLabel)
 {
     MOZ_ASSERT(isFinishedWithFunctionBodies() && !isFinished());
 
     uint32_t endBeforeCurly = tokenStream.currentToken().pos.end;
-    uint32_t endAfterCurly = tokenStream.peekTokenPos().end;
+    TokenPos pos;
+    if (!tokenStream.peekTokenPos(&pos))
+        return false;
+    uint32_t endAfterCurly = pos.end;
     MOZ_ASSERT(endBeforeCurly >= srcBodyStart_);
     MOZ_ASSERT(endAfterCurly >= srcBodyStart_);
     pod.srcLength_ = endBeforeCurly - srcStart_;
     pod.srcLengthWithRightBrace_ = endAfterCurly - srcStart_;
 
     // The global data section sits immediately after the executable (and
     // other) data allocated by the MacroAssembler, so ensure it is
     // SIMD-aligned.
@@ -1970,17 +1973,19 @@ class ModuleChars
     Vector<PropertyNameWrapper, 0, SystemAllocPolicy> funCtorArgs_;
 
   public:
     static uint32_t beginOffset(AsmJSParser &parser) {
       return parser.pc->maybeFunction->pn_pos.begin;
     }
 
     static uint32_t endOffset(AsmJSParser &parser) {
-      return parser.tokenStream.peekTokenPos().end;
+      TokenPos pos;
+      MOZ_ALWAYS_TRUE(parser.tokenStream.peekTokenPos(&pos));
+      return pos.end;
     }
 };
 
 class ModuleCharsForStore : ModuleChars
 {
     uint32_t uncompressedSize_;
     uint32_t compressedSize_;
     Vector<char, 0, SystemAllocPolicy> compressedBuffer_;
--- a/js/src/asmjs/AsmJSValidate.cpp
+++ b/js/src/asmjs/AsmJSValidate.cpp
@@ -1453,17 +1453,20 @@ class MOZ_STACK_CLASS ModuleCompiler
         if (pn)
             return failOffset(pn->pn_pos.begin, str);
 
         // The exact rooting static analysis does not perform dataflow analysis, so it believes
         // that unrooted things on the stack during compilation may still be accessed after this.
         // Since pn is typically only null under OOM, this suppression simply forces any GC to be
         // delayed until the compilation is off the stack and more memory can be freed.
         gc::AutoSuppressGC nogc(cx_);
-        return failOffset(tokenStream().peekTokenPos().begin, str);
+        TokenPos pos;
+        if (!tokenStream().peekTokenPos(&pos))
+            return false;
+        return failOffset(pos.begin, str);
     }
 
     bool failfVA(ParseNode *pn, const char *fmt, va_list ap) {
         MOZ_ASSERT(!errorString_);
         MOZ_ASSERT(errorOffset_ == UINT32_MAX);
         MOZ_ASSERT(fmt);
         errorOffset_ = pn ? pn->pn_pos.begin : tokenStream().currentToken().pos.end;
         errorString_.reset(JS_vsmprintf(fmt, ap));
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -398,23 +398,25 @@ class MOZ_STACK_CLASS TokenStream
             *ttp = tokens[(cursor + 1) & ntokensMask].type;
         } else {
             *ttp = getTokenInternal(modifier);
             ungetToken();
         }
         return *ttp != TOK_ERROR;
     }
 
-    TokenPos peekTokenPos(Modifier modifier = None) {
-        if (lookahead != 0)
-            return tokens[(cursor + 1) & ntokensMask].pos;
-        getTokenInternal(modifier);
-        ungetToken();
-        MOZ_ASSERT(lookahead != 0);
-        return tokens[(cursor + 1) & ntokensMask].pos;
+    bool peekTokenPos(TokenPos *posp, Modifier modifier = None) {
+        if (lookahead == 0) {
+            getTokenInternal(modifier);
+            ungetToken();
+            MOZ_ASSERT(lookahead != 0);
+        }
+        Token token = tokens[(cursor + 1) & ntokensMask];
+        *posp = token.pos;
+        return token.type != TOK_ERROR;
     }
 
     // This is like peekToken(), with one exception:  if there is an EOL
     // between the end of the current token and the start of the next token, it
     // return true and store TOK_EOL in |*ttp|.  In that case, no token with
     // TOK_EOL is actually created, just a TOK_EOL TokenKind is returned, and
     // currentToken() shouldn't be consulted.  (This is the only place TOK_EOL
     // is produced.)