Bug 992274 - Tweak an edge case in line number handling. r=jorendorff, a=1.2.x+
authorNicholas Nethercote <nnethercote@mozilla.com>
Sun, 06 Apr 2014 21:31:04 -0700
changeset 157125 de68af39488298ba1b980f88195ef10f22914c7b
parent 157124 7a0be20beae7c4dfc368a198e7579dabe3813ac9
child 157126 7f26289a37185a8db0710be11744bcb2b0e8c854
push id503
push userryanvm@gmail.com
push dateFri, 09 May 2014 18:24:20 +0000
reviewersjorendorff, 1.2.x
bugs992274
milestone26.0
Bug 992274 - Tweak an edge case in line number handling. r=jorendorff, a=1.2.x+
js/src/frontend/Parser.cpp
js/src/frontend/TokenStream.cpp
js/src/frontend/TokenStream.h
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2125,17 +2125,18 @@ Parser<FullParseHandler>::functionArgsAn
         Parser<SyntaxParseHandler> *parser = handler.syntaxParser;
         if (!parser)
             break;
 
         {
             // Move the syntax parser to the current position in the stream.
             TokenStream::Position position(keepAtoms);
             tokenStream.tell(&position);
-            parser->tokenStream.seek(position, tokenStream);
+            if (!parser->tokenStream.seek(position, tokenStream))
+                return false;
 
             ParseContext<SyntaxParseHandler> funpc(parser, outerpc, SyntaxParseHandler::null(), funbox,
                                                    newDirectives, outerpc->staticLevel + 1,
                                                    outerpc->blockidGen);
             if (!funpc.init(tokenStream))
                 return false;
 
             if (!parser->functionArgsAndBodyGeneric(SyntaxParseHandler::NodeGeneric,
@@ -2148,17 +2149,18 @@ Parser<FullParseHandler>::functionArgsAn
                 }
                 return false;
             }
 
             outerpc->blockidGen = funpc.blockidGen;
 
             // Advance this parser over tokens processed by the syntax parser.
             parser->tokenStream.tell(&position);
-            tokenStream.seek(position, parser->tokenStream);
+            if (!tokenStream.seek(position, parser->tokenStream))
+                return false;
         }
 
         if (!addFreeVariablesFromLazyFunction(fun, pc))
             return false;
 
         pn->pn_blockid = outerpc->blockid();
         PropagateTransitiveParseFlags(funbox, outerpc->sc);
         return true;
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -156,30 +156,33 @@ TokenStream::SourceCoords::add(uint32_t 
 
     } else {
         // We have seen this newline before (and ungot it).  Do nothing (other
         // than checking it hasn't mysteriously changed).
         JS_ASSERT(lineStartOffsets_[lineIndex] == lineStartOffset);
     }
 }
 
-JS_ALWAYS_INLINE void
+JS_ALWAYS_INLINE bool
 TokenStream::SourceCoords::fill(const TokenStream::SourceCoords &other)
 {
     JS_ASSERT(lineStartOffsets_.back() == MAX_PTR);
     JS_ASSERT(other.lineStartOffsets_.back() == MAX_PTR);
 
     if (lineStartOffsets_.length() >= other.lineStartOffsets_.length())
-        return;
+        return true;
 
     uint32_t sentinelIndex = lineStartOffsets_.length() - 1;
     lineStartOffsets_[sentinelIndex] = other.lineStartOffsets_[sentinelIndex];
 
-    for (size_t i = sentinelIndex + 1; i < other.lineStartOffsets_.length(); i++)
-        (void)lineStartOffsets_.append(other.lineStartOffsets_[i]);
+    for (size_t i = sentinelIndex + 1; i < other.lineStartOffsets_.length(); i++) {
+        if (!lineStartOffsets_.append(other.lineStartOffsets_[i]))
+            return false;
+    }
+    return true;
 }
 
 JS_ALWAYS_INLINE uint32_t
 TokenStream::SourceCoords::lineIndexOf(uint32_t offset) const
 {
     uint32_t iMin, iMax, iMid;
 
     if (lineStartOffsets_[lastLineIndex_] <= offset) {
@@ -536,21 +539,23 @@ TokenStream::seek(const Position &pos)
     prevLinebase = pos.prevLinebase;
     lookahead = pos.lookahead;
 
     tokens[cursor] = pos.currentToken;
     for (unsigned i = 0; i < lookahead; i++)
         tokens[(cursor + 1 + i) & ntokensMask] = pos.lookaheadTokens[i];
 }
 
-void
+bool
 TokenStream::seek(const Position &pos, const TokenStream &other)
 {
-    srcCoords.fill(other.srcCoords);
+    if (!srcCoords.fill(other.srcCoords))
+        return false;
     seek(pos);
+    return true;
 }
 
 bool
 TokenStream::reportStrictModeErrorNumberVA(uint32_t offset, bool strictMode, unsigned errorNumber,
                                            va_list args)
 {
     // In strict mode code, this is an error, not merely a warning.
     unsigned flags = JSREPORT_STRICT;
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -585,17 +585,17 @@ class MOZ_STACK_CLASS TokenStream
         Token currentToken;
         unsigned lookahead;
         Token lookaheadTokens[maxLookahead];
     };
 
     void advance(size_t position);
     void tell(Position *);
     void seek(const Position &pos);
-    void seek(const Position &pos, const TokenStream &other);
+    bool seek(const Position &pos, const TokenStream &other);
 
     size_t positionToOffset(const Position &pos) const {
         return pos.buf - userbuf.base();
     }
 
     bool hasSourceMap() const {
         return sourceMap != NULL;
     }
@@ -669,17 +669,17 @@ class MOZ_STACK_CLASS TokenStream
 
         uint32_t lineIndexToNum(uint32_t lineIndex) const { return lineIndex + initialLineNum_; }
         uint32_t lineNumToIndex(uint32_t lineNum)   const { return lineNum   - initialLineNum_; }
 
       public:
         SourceCoords(ExclusiveContext *cx, uint32_t ln);
 
         void add(uint32_t lineNum, uint32_t lineStartOffset);
-        void fill(const SourceCoords &other);
+        bool fill(const SourceCoords &other);
 
         bool isOnThisLine(uint32_t offset, uint32_t lineNum) const {
             uint32_t lineIndex = lineNumToIndex(lineNum);
             JS_ASSERT(lineIndex + 1 < lineStartOffsets_.length());  // +1 due to sentinel
             return lineStartOffsets_[lineIndex] <= offset &&
                    offset < lineStartOffsets_[lineIndex + 1];
         }