Bug 1451826 - Part 4: Make TokenStreamSpecific and ErrorReporter, rather than TokenStreamAnyChars. (r=Waldo)
authorEric Faust <efaustbmo@gmail.com>
Fri, 27 Apr 2018 15:02:31 -0700
changeset 472243 6d712c91d06dfb9b968404fcd217dc43670ad2e3
parent 472242 1afcb999264298659ff610d3409f067565e7c031
child 472244 fe50254665a40f07d9c9701f07b699aa638ecc54
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
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 4: Make TokenStreamSpecific and ErrorReporter, rather than TokenStreamAnyChars. (r=Waldo)
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/EitherParser.h
js/src/frontend/Parser.h
js/src/frontend/TokenStream.cpp
js/src/frontend/TokenStream.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -2527,17 +2527,17 @@ LengthOfSetLine(unsigned line)
 
 /* Updates line number notes, not column notes. */
 bool
 BytecodeEmitter::updateLineNumberNotes(uint32_t offset)
 {
     TokenStreamAnyChars* ts = &parser.tokenStream();
     bool onThisLine;
     if (!ts->srcCoords.isOnThisLine(offset, currentLine(), &onThisLine)) {
-        ts->reportErrorNoOffset(JSMSG_OUT_OF_MEMORY);
+        parser.errorReporter().reportErrorNoOffset(JSMSG_OUT_OF_MEMORY);
         return false;
     }
 
     if (!onThisLine) {
         unsigned line = ts->srcCoords.lineNum(offset);
         unsigned delta = line - currentLine();
 
         /*
@@ -4855,17 +4855,17 @@ BytecodeEmitter::emitSetThis(ParseNode* 
     }
 
     return emitSetOrInitializeNameAtLocation(name, lexicalLoc, emitRhs, true);
 }
 
 bool
 BytecodeEmitter::emitScript(ParseNode* body)
 {
-    AutoFrontendTraceLog traceLog(cx, TraceLogger_BytecodeEmission, tokenStream(), body);
+    AutoFrontendTraceLog traceLog(cx, TraceLogger_BytecodeEmission, parser.errorReporter(), body);
 
     setScriptStartOffsetIfUnset(body->pn_pos);
 
     TDZCheckCache tdzCache(this);
     EmitterScope emitterScope(this);
     if (sc->isGlobalContext()) {
         switchToPrologue();
         if (!emitterScope.enterGlobal(this, sc->asGlobalContext()))
@@ -4929,17 +4929,17 @@ BytecodeEmitter::emitScript(ParseNode* b
 
     return true;
 }
 
 bool
 BytecodeEmitter::emitFunctionScript(ParseNode* body)
 {
     FunctionBox* funbox = sc->asFunctionBox();
-    AutoFrontendTraceLog traceLog(cx, TraceLogger_BytecodeEmission, tokenStream(), funbox);
+    AutoFrontendTraceLog traceLog(cx, TraceLogger_BytecodeEmission, parser.errorReporter(), funbox);
 
     setScriptStartOffsetIfUnset(body->pn_pos);
 
     // The ordering of these EmitterScopes is important. The named lambda
     // scope needs to enclose the function scope needs to enclose the extra
     // var scope.
 
     Maybe<EmitterScope> namedLambdaEmitterScope;
--- a/js/src/frontend/EitherParser.h
+++ b/js/src/frontend/EitherParser.h
@@ -162,16 +162,24 @@ struct ScriptSourceMatcher
 struct ParserBaseMatcher
 {
     template<class Parser>
     frontend::ParserBase& match(Parser* parser) {
         return *static_cast<frontend::ParserBase*>(parser);
     }
 };
 
+struct ErrorReporterMatcher
+{
+    template<class Parser>
+    frontend::ErrorReporter& match(Parser* parser) {
+        return parser->tokenStream;
+    }
+};
+
 } // namespace detail
 
 namespace frontend {
 
 template<class ParseHandler>
 class EitherParser
 {
     mozilla::Variant<Parser<ParseHandler, char16_t>* const> parser;
@@ -195,16 +203,20 @@ class EitherParser
     const TokenStreamAnyChars& tokenStream() const {
         return parser.match(detail::TokenStreamMatcher());
     }
 
     ScriptSource* ss() {
         return parser.match(detail::ScriptSourceMatcher());
     }
 
+    ErrorReporter& errorReporter() {
+        return parser.match(detail::ErrorReporterMatcher());
+    }
+
     const JS::ReadOnlyCompileOptions& options() {
         InvokeMemberFunction<detail::GetParser, detail::ParserOptions> optionsMatcher;
         return parser.match(mozilla::Move(optionsMatcher));
     }
 
     ObjectBox* newObjectBox(JSObject* obj) {
         InvokeMemberFunction<detail::GetParser, detail::ParserNewObjectBox,
                              JSObject*>
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -193,17 +193,17 @@ template <class ParseHandler, typename C
 class GeneralParser;
 
 class SourceParseContext: public ParseContext
 {
 public:
     template<typename ParseHandler, typename CharT>
     SourceParseContext(GeneralParser<ParseHandler, CharT>* prs, SharedContext* sc,
                        Directives* newDirectives)
-      : ParseContext(prs->context, prs->pc, sc, prs->anyChars, prs->usedNames, newDirectives,
+      : ParseContext(prs->context, prs->pc, sc, prs->tokenStream, prs->usedNames, newDirectives,
                      mozilla::IsSame<ParseHandler, FullParseHandler>::value)
     { }
 };
 
 template <typename T>
 inline T&
 ParseContext::Statement::as()
 {
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -769,33 +769,37 @@ TokenStreamAnyChars::fillExcludingContex
     }
 
     // Otherwise use this TokenStreamAnyChars's location information.
     err->filename = filename_;
     srcCoords.lineNumAndColumnIndex(offset, &err->lineNumber, &err->columnNumber);
     return true;
 }
 
+template<typename CharT, class AnyCharsAccess>
 bool
-TokenStreamAnyChars::hasTokenizationStarted() const
+TokenStreamSpecific<CharT, AnyCharsAccess>::hasTokenizationStarted() const
 {
-    return isCurrentTokenType(TokenKind::Eof) && !isEOF();
+    const TokenStreamAnyChars& anyChars = anyCharsAccess();
+    return anyChars.isCurrentTokenType(TokenKind::Eof) && !anyChars.isEOF();
 }
 
 void
 TokenStreamAnyChars::lineAndColumnAt(size_t offset, uint32_t* line, uint32_t* column) const
 {
     srcCoords.lineNumAndColumnIndex(offset, line, column);
 }
 
+template<typename CharT, class AnyCharsAccess>
 void
-TokenStreamAnyChars::currentLineAndColumn(uint32_t* line, uint32_t* column) const
+TokenStreamSpecific<CharT, AnyCharsAccess>::currentLineAndColumn(uint32_t* line, uint32_t* column) const
 {
-    uint32_t offset = currentToken().pos.begin;
-    srcCoords.lineNumAndColumnIndex(offset, line, column);
+    const TokenStreamAnyChars& anyChars = anyCharsAccess();
+    uint32_t offset = anyChars.currentToken().pos.begin;
+    anyChars.srcCoords.lineNumAndColumnIndex(offset, line, column);
 }
 
 template<typename CharT, class AnyCharsAccess>
 bool
 TokenStreamSpecific<CharT, AnyCharsAccess>::computeErrorMetadata(ErrorMetadata* err,
                                                                  uint32_t offset)
 {
     if (offset == NoOffset) {
@@ -898,16 +902,27 @@ TokenStreamSpecific<CharT, AnyCharsAcces
         ReportCompileError(anyChars.cx, Move(metadata), nullptr, JSREPORT_ERROR, errorNumber,
                            args);
     }
 
     va_end(args);
 }
 
 void
+TokenStreamAnyChars::reportErrorNoOffset(unsigned errorNumber, ...)
+{
+    va_list args;
+    va_start(args, errorNumber);
+
+    reportErrorNoOffsetVA(errorNumber, args);
+
+    va_end(args);
+}
+
+void
 TokenStreamAnyChars::reportErrorNoOffsetVA(unsigned errorNumber, va_list args)
 {
     ErrorMetadata metadata;
     computeErrorMetadataNoOffset(&metadata);
 
     ReportCompileError(cx, Move(metadata), nullptr, JSREPORT_ERROR, errorNumber, args);
 }
 
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -533,18 +533,17 @@ class MOZ_STACK_CLASS TokenStreamPositio
     size_t linebase;
     size_t prevLinebase;
     Token currentToken;
     unsigned lookahead;
     Token lookaheadTokens[TokenStreamShared::maxLookahead];
 } JS_HAZ_ROOTED;
 
 class TokenStreamAnyChars
-  : public TokenStreamShared,
-    public ErrorReporter
+  : public TokenStreamShared
 {
   public:
     TokenStreamAnyChars(JSContext* cx, const ReadOnlyCompileOptions& options,
                         StrictModeGetter* smg);
 
     template<typename CharT, class AnyCharsAccess> friend class GeneralTokenStreamChars;
     template<typename CharT, class AnyCharsAccess> friend class TokenStreamSpecific;
 
@@ -809,32 +808,30 @@ class TokenStreamAnyChars
 
   public:
     MOZ_MUST_USE bool compileWarning(ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes,
                                      unsigned flags, unsigned errorNumber, va_list args);
 
     // Compute error metadata for an error at no offset.
     void computeErrorMetadataNoOffset(ErrorMetadata* err);
 
-  public:
-    // ErrorReporter API.
+    // ErrorReporter API Helpers
+
+    void lineAndColumnAt(size_t offset, uint32_t *line, uint32_t *column) const;
 
-    const JS::ReadOnlyCompileOptions& options() const final {
+    // This is just straight up duplicated from TokenStreamSpecific's inheritance of
+    // ErrorReporter's reportErrorNoOffset. varargs delenda est.
+    void reportErrorNoOffset(unsigned errorNumber, ...);
+    void reportErrorNoOffsetVA(unsigned errorNumber, va_list args);
+
+    const JS::ReadOnlyCompileOptions& options() const {
         return options_;
     }
 
-    void
-    lineAndColumnAt(size_t offset, uint32_t* line, uint32_t* column) const final;
-
-    void currentLineAndColumn(uint32_t* line, uint32_t* column) const final;
-
-    bool hasTokenizationStarted() const final;
-    void reportErrorNoOffsetVA(unsigned errorNumber, va_list args) final;
-
-    const char* getFilename() const final {
+    const char* getFilename() const {
         return filename_;
     }
 
   protected:
     // Options used for parsing/tokenizing.
     const ReadOnlyCompileOptions& options_;
 
     Token               tokens[ntokens];    // circular token buffer
@@ -1136,17 +1133,18 @@ class TokenStreamChars<char16_t, AnyChar
 // https://groups.google.com/forum/?fromgroups=#!topic/mozilla.dev.tech.js-engine.internals/2JLH5jRcr7E).
 //
 // The method seek() allows rescanning from a previously visited location of
 // the buffer, initially computed by constructing a Position local variable.
 //
 template<typename CharT, class AnyCharsAccess>
 class MOZ_STACK_CLASS TokenStreamSpecific
   : public TokenStreamChars<CharT, AnyCharsAccess>,
-    public TokenStreamShared
+    public TokenStreamShared,
+    public ErrorReporter
 {
   public:
     using CharsBase = TokenStreamChars<CharT, AnyCharsAccess>;
     using GeneralCharsBase = GeneralTokenStreamChars<CharT, AnyCharsAccess>;
     using CharsSharedBase = TokenStreamCharsBase<CharT>;
 
     using Position = TokenStreamPosition<CharT>;
 
@@ -1193,16 +1191,38 @@ class MOZ_STACK_CLASS TokenStreamSpecifi
         if (anyCharsAccess().invalidTemplateEscapeType == InvalidEscapeType::None)
             return true;
 
         reportInvalidEscapeError(anyCharsAccess().invalidTemplateEscapeOffset,
                                  anyCharsAccess().invalidTemplateEscapeType);
         return false;
     }
 
+    // ErrorReporter API.
+
+    const JS::ReadOnlyCompileOptions& options() const final {
+        return anyCharsAccess().options();
+    }
+
+    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 hasTokenizationStarted() const final;
+
+    void reportErrorNoOffsetVA(unsigned errorNumber, va_list args) final {
+        anyCharsAccess().reportErrorNoOffsetVA(errorNumber, args);
+    }
+
+    const char* getFilename() const final {
+        return anyCharsAccess().getFilename();
+    }
+
     // TokenStream-specific error reporters.
     void reportError(unsigned errorNumber, ...);
 
     // Report the given error at the current offset.
     void error(unsigned errorNumber, ...);
 
     // Report the given error at the given offset.
     void errorAt(uint32_t offset, unsigned errorNumber, ...);