Bug 1451826 - Part 6: Factor SourceCoords references in BCE to ErrorReporter. (r=Waldo, r=Yoric)
authorEric Faust <efaustbmo@gmail.com>
Fri, 27 Apr 2018 15:02:31 -0700
changeset 472245 df51f81b5ed495e3bcf2c6a19e9b85d08724140e
parent 472244 fe50254665a40f07d9c9701f07b699aa638ecc54
child 472246 9b20e7b26c0db98cd184f9289b32cca17996b7ed
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo, Yoric
bugs1451826
milestone61.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 1451826 - Part 6: Factor SourceCoords references in BCE to ErrorReporter. (r=Waldo, r=Yoric)
js/src/frontend/BinSource.h
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/EitherParser.h
js/src/frontend/ErrorReporter.h
js/src/frontend/TokenStream.h
--- a/js/src/frontend/BinSource.h
+++ b/js/src/frontend/BinSource.h
@@ -224,19 +224,33 @@ class BinASTParser : public BinASTParser
   private: // Implement ErrorReporter
     const ReadOnlyCompileOptions& options_;
 
     const ReadOnlyCompileOptions& options() const override {
         return this->options_;
     }
 
     virtual void lineAndColumnAt(size_t offset, uint32_t* line, uint32_t* column) const override {
-        *line = 0;
-        *column = offset;
+        *line = lineAt(offset);
+        *column = columnAt(offset);
+    }
+    virtual uint32_t lineAt(size_t offset) const override {
+        return 0;
+    }
+    virtual uint32_t columnAt(size_t offset) const override {
+        return offset;
     }
+
+    virtual bool isOnThisLine(size_t offset, uint32_t lineNum, bool *isOnSameLine) const override {
+        if (lineNum != 0)
+            return false;
+        *isOnSameLine = true;
+        return true;
+    }
+
     virtual void currentLineAndColumn(uint32_t* line, uint32_t* column) const override {
         *line = 0;
         *column = offset();
     }
     size_t offset() const {
         if (tokenizer_.isSome())
             return tokenizer_->offset();
 
@@ -289,9 +303,9 @@ class BinParseContext : public ParseCont
 
 
 extern template class BinASTParser<BinTokenReaderMultipart>;
 extern template class BinASTParser<BinTokenReaderTester>;
 
 } // namespace frontend
 } // namespace js
 
-#endif // frontend_BinSource_h
\ No newline at end of file
+#endif // frontend_BinSource_h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -20,17 +20,16 @@
 
 #include "jsapi.h"
 #include "jsnum.h"
 #include "jstypes.h"
 #include "jsutil.h"
 
 #include "ds/Nestable.h"
 #include "frontend/Parser.h"
-#include "frontend/TokenStream.h"
 #include "vm/BytecodeUtil.h"
 #include "vm/Debugger.h"
 #include "vm/GeneratorObject.h"
 #include "vm/JSAtom.h"
 #include "vm/JSContext.h"
 #include "vm/JSFunction.h"
 #include "vm/JSScript.h"
 #include "vm/Stack.h"
@@ -2181,17 +2180,17 @@ BytecodeEmitter::BytecodeEmitter(Bytecod
     MOZ_ASSERT_IF(emitterMode == LazyFunction, lazyScript);
 }
 
 BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent,
                                  const EitherParser<FullParseHandler>& parser, SharedContext* sc,
                                  HandleScript script, Handle<LazyScript*> lazyScript,
                                  TokenPos bodyPosition, EmitterMode emitterMode)
     : BytecodeEmitter(parent, parser, sc, script, lazyScript,
-                      parser.tokenStream().srcCoords.lineNum(bodyPosition.begin),
+                      parser.errorReporter().lineAt(bodyPosition.begin),
                       emitterMode)
 {
     setScriptStartOffsetIfUnset(bodyPosition);
     setFunctionBodyEndPos(bodyPosition);
 }
 
 bool
 BytecodeEmitter::init()
@@ -2524,25 +2523,25 @@ LengthOfSetLine(unsigned line)
 {
     return 1 /* SRC_SETLINE */ + (line > SN_4BYTE_OFFSET_MASK ? 4 : 1);
 }
 
 /* Updates line number notes, not column notes. */
 bool
 BytecodeEmitter::updateLineNumberNotes(uint32_t offset)
 {
-    TokenStreamAnyChars* ts = &parser.tokenStream();
+    ErrorReporter* er = &parser.errorReporter();
     bool onThisLine;
-    if (!ts->srcCoords.isOnThisLine(offset, currentLine(), &onThisLine)) {
-        parser.errorReporter().reportErrorNoOffset(JSMSG_OUT_OF_MEMORY);
+    if (!er->isOnThisLine(offset, currentLine(), &onThisLine)) {
+        er->reportErrorNoOffset(JSMSG_OUT_OF_MEMORY);
         return false;
     }
 
     if (!onThisLine) {
-        unsigned line = ts->srcCoords.lineNum(offset);
+        unsigned line = er->lineAt(offset);
         unsigned delta = line - currentLine();
 
         /*
          * Encode any change in the current source line number by using
          * either several SRC_NEWLINE notes or just one SRC_SETLINE note,
          * whichever consumes less space.
          *
          * NB: We handle backward line number deltas (possible with for
@@ -2568,17 +2567,17 @@ BytecodeEmitter::updateLineNumberNotes(u
 
 /* Updates the line number and column number information in the source notes. */
 bool
 BytecodeEmitter::updateSourceCoordNotes(uint32_t offset)
 {
     if (!updateLineNumberNotes(offset))
         return false;
 
-    uint32_t columnIndex = parser.tokenStream().srcCoords.columnIndex(offset);
+    uint32_t columnIndex = parser.errorReporter().columnAt(offset);
     ptrdiff_t colspan = ptrdiff_t(columnIndex) - ptrdiff_t(current->lastColumn);
     if (colspan != 0) {
         // If the column span is so large that we can't store it, then just
         // discard this information. This can happen with minimized or otherwise
         // machine-generated code. Even gigantic column numbers are still
         // valuable if you have a source map to relate them to something real;
         // but it's better to fail soft here.
         if (!SN_REPRESENTABLE_COLSPAN(colspan))
@@ -3535,22 +3534,16 @@ BytecodeEmitter::tellDebuggerAboutCompil
         return;
 
     // Lazy scripts are never top level (despite always being invoked with a
     // nullptr parent), and so the hook should never be fired.
     if (emitterMode != LazyFunction && !parent)
         Debugger::onNewScript(cx, script);
 }
 
-inline TokenStreamAnyChars&
-BytecodeEmitter::tokenStream()
-{
-    return parser.tokenStream();
-}
-
 void
 BytecodeEmitter::reportError(ParseNode* pn, unsigned errorNumber, ...)
 {
     MOZ_ASSERT_IF(!pn, this->scriptStartOffsetSet);
     uint32_t offset = pn ? pn->pn_pos.begin : this->scriptStartOffset;
 
     va_list args;
     va_start(args, errorNumber);
@@ -7596,17 +7589,17 @@ BytecodeEmitter::emitCStyleFor(ParseNode
         if (!updateSourceCoordNotes(update->pn_pos.begin))
             return false;
         if (!emitTree(update, ValueUsage::IgnoreValue))
             return false;
         if (!emit1(JSOP_POP))
             return false;
 
         /* Restore the absolute line number for source note readers. */
-        uint32_t lineNum = parser.tokenStream().srcCoords.lineNum(pn->pn_pos.end);
+        uint32_t lineNum = parser.errorReporter().lineAt(pn->pn_pos.end);
         if (currentLine() != lineNum) {
             if (!newSrcNote2(SRC_SETLINE, ptrdiff_t(lineNum)))
                 return false;
             current->currentLine = lineNum;
             current->lastColumn = 0;
         }
     }
 
@@ -8038,18 +8031,18 @@ BytecodeEmitter::emitWhile(ParseNode* pn
     // If we have a single-line while, like "while (x) ;", we want to
     // emit the line note before the initial goto, so that the
     // debugger sees a single entry point.  This way, if there is a
     // breakpoint on the line, it will only fire once; and "next"ing
     // will skip the whole loop.  However, for the multi-line case we
     // want to emit the line note after the initial goto, so that
     // "cont" stops on each iteration -- but without a stop before the
     // first iteration.
-    if (parser.tokenStream().srcCoords.lineNum(pn->pn_pos.begin) ==
-        parser.tokenStream().srcCoords.lineNum(pn->pn_pos.end))
+    if (parser.errorReporter().lineAt(pn->pn_pos.begin) ==
+        parser.errorReporter().lineAt(pn->pn_pos.end))
     {
         if (!updateSourceCoordNotes(pn->pn_pos.begin))
             return false;
     }
 
     JumpTarget top{ -1 };
     if (!emitJumpTarget(&top))
         return false;
@@ -9343,17 +9336,17 @@ BytecodeEmitter::emitCallOrNew(ParseNode
             return false;
         checkTypeSet(pn->getOp());
     }
     if (pn->isOp(JSOP_EVAL) ||
         pn->isOp(JSOP_STRICTEVAL) ||
         pn->isOp(JSOP_SPREADEVAL) ||
         pn->isOp(JSOP_STRICTSPREADEVAL))
     {
-        uint32_t lineNum = parser.tokenStream().srcCoords.lineNum(pn->pn_pos.begin);
+        uint32_t lineNum = parser.errorReporter().lineAt(pn->pn_pos.begin);
         if (!emitUint32Operand(JSOP_LINENO, lineNum))
             return false;
     }
 
     return true;
 }
 
 static const JSOp ParseNodeKindToJSOp[] = {
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -381,18 +381,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter
     // Check whether our function is in a run-once context (a toplevel
     // run-one script or a run-once lambda).
     MOZ_MUST_USE bool checkRunOnceContext();
 
     bool needsImplicitThis();
 
     void tellDebuggerAboutCompiledScript(JSContext* cx);
 
-    inline TokenStreamAnyChars& tokenStream();
-
     BytecodeVector& code() const { return current->code; }
     jsbytecode* code(ptrdiff_t offset) const { return current->code.begin() + offset; }
     ptrdiff_t offset() const { return current->code.end() - current->code.begin(); }
     ptrdiff_t prologueOffset() const { return prologue.code.end() - prologue.code.begin(); }
     void switchToMain() { current = &main; }
     void switchToPrologue() { current = &prologue; }
     bool inPrologue() const { return current == &prologue; }
 
--- a/js/src/frontend/EitherParser.h
+++ b/js/src/frontend/EitherParser.h
@@ -138,24 +138,16 @@ struct TokenStreamReportExtraWarning
 {
     static constexpr auto get() -> decltype(&TokenStream::reportExtraWarningErrorNumberVA) {
         return &TokenStream::reportExtraWarningErrorNumberVA;
     }
 };
 
 // Generic matchers.
 
-struct TokenStreamMatcher
-{
-    template<class Parser>
-    frontend::TokenStreamAnyChars& match(Parser* parser) {
-        return parser->anyChars;
-    }
-};
-
 struct ParserBaseMatcher
 {
     template<class Parser>
     frontend::ParserBase& match(Parser* parser) {
         return *static_cast<frontend::ParserBase*>(parser);
     }
 };
 
@@ -183,25 +175,21 @@ class EitherParser
              typename... StoredArgs>
     using InvokeMemberFunction =
         detail::InvokeMemberFunction<GetThis, GetMemberFunction, StoredArgs...>;
 
   public:
     template<class Parser>
     explicit EitherParser(Parser* parser) : parser(parser) {}
 
-    TokenStreamAnyChars& tokenStream() {
-        return parser.match(detail::TokenStreamMatcher());
+    ErrorReporter& errorReporter() {
+        return parser.match(detail::ErrorReporterMatcher());
     }
 
-    const TokenStreamAnyChars& tokenStream() const {
-        return parser.match(detail::TokenStreamMatcher());
-    }
-
-    ErrorReporter& errorReporter() {
+    const ErrorReporter& errorReporter() const {
         return parser.match(detail::ErrorReporterMatcher());
     }
 
     const JS::ReadOnlyCompileOptions& options() {
         InvokeMemberFunction<detail::GetParser, detail::ParserOptions> optionsMatcher;
         return parser.match(mozilla::Move(optionsMatcher));
     }
 
--- a/js/src/frontend/ErrorReporter.h
+++ b/js/src/frontend/ErrorReporter.h
@@ -18,16 +18,19 @@ namespace frontend {
 
 class ErrorReporter
 {
   public:
     virtual const JS::ReadOnlyCompileOptions& options() const = 0;
 
     virtual void lineAndColumnAt(size_t offset, uint32_t* line, uint32_t* column) const = 0;
     virtual void currentLineAndColumn(uint32_t* line, uint32_t* column) const = 0;
+    virtual bool isOnThisLine(size_t offset, uint32_t lineNum, bool *onThisLine) const = 0;
+    virtual uint32_t lineAt(size_t offset) const = 0;
+    virtual uint32_t columnAt(size_t offset) const = 0;
 
     virtual bool hasTokenizationStarted() const = 0;
     virtual void reportErrorNoOffsetVA(unsigned errorNumber, va_list args) = 0;
     virtual const char* getFilename() const = 0;
 
     void reportErrorNoOffset(unsigned errorNumber, ...) {
         va_list args;
         va_start(args, errorNumber);
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -1203,16 +1203,27 @@ class MOZ_STACK_CLASS TokenStreamSpecifi
     }
 
     void
     lineAndColumnAt(size_t offset, uint32_t* line, uint32_t* column) const final {
         anyCharsAccess().lineAndColumnAt(offset, line, column);
     }
 
     void currentLineAndColumn(uint32_t* line, uint32_t* column) const final;
+
+    bool isOnThisLine(size_t offset, uint32_t lineNum, bool *onThisLine) const final {
+        return anyCharsAccess().srcCoords.isOnThisLine(offset, lineNum, onThisLine);
+    }
+    uint32_t lineAt(size_t offset) const final {
+        return anyCharsAccess().srcCoords.lineNum(offset);
+    }
+    uint32_t columnAt(size_t offset) const final {
+        return anyCharsAccess().srcCoords.columnIndex(offset);
+    }
+
     bool hasTokenizationStarted() const final;
 
     void reportErrorNoOffsetVA(unsigned errorNumber, va_list args) final {
         anyCharsAccess().reportErrorNoOffsetVA(errorNumber, args);
     }
 
     const char* getFilename() const final {
         return anyCharsAccess().getFilename();