mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-06 14:44:26 +00:00
Bug 1083913: Make TokenStream::linebase an offset, not a pointer into nothingness. r=shu
This commit is contained in:
parent
29234315de
commit
8e95cb1c57
@ -283,7 +283,6 @@ TokenStream::SourceCoords::lineNumAndColumnIndex(uint32_t offset, uint32_t *line
|
||||
#pragma warning(disable:4351)
|
||||
#endif
|
||||
|
||||
// Initialize members that aren't initialized in |init|.
|
||||
TokenStream::TokenStream(ExclusiveContext *cx, const ReadOnlyCompileOptions &options,
|
||||
const char16_t *base, size_t length, StrictModeGetter *smg)
|
||||
: srcCoords(cx, options.lineno),
|
||||
@ -293,8 +292,8 @@ TokenStream::TokenStream(ExclusiveContext *cx, const ReadOnlyCompileOptions &opt
|
||||
lookahead(),
|
||||
lineno(options.lineno),
|
||||
flags(),
|
||||
linebase(base - options.column),
|
||||
prevLinebase(nullptr),
|
||||
linebase(0),
|
||||
prevLinebase(size_t(-1)),
|
||||
userbuf(cx, base, length, options.column),
|
||||
filename(options.filename()),
|
||||
displayURL_(nullptr),
|
||||
@ -304,11 +303,6 @@ TokenStream::TokenStream(ExclusiveContext *cx, const ReadOnlyCompileOptions &opt
|
||||
mutedErrors(options.mutedErrors()),
|
||||
strictModeGetter(smg)
|
||||
{
|
||||
// Column numbers are computed as offsets from the current line's base, so the
|
||||
// initial line's base must be included in the buffer. linebase and userbuf
|
||||
// were adjusted above, and if we are starting tokenization part way through
|
||||
// this line then adjust the next character.
|
||||
|
||||
// Nb: the following tables could be static, but initializing them here is
|
||||
// much easier. Don't worry, the time to initialize them for each
|
||||
// TokenStream is trivial. See bug 639420.
|
||||
@ -364,9 +358,9 @@ MOZ_ALWAYS_INLINE void
|
||||
TokenStream::updateLineInfoForEOL()
|
||||
{
|
||||
prevLinebase = linebase;
|
||||
linebase = userbuf.addressOfNextRawChar();
|
||||
linebase = userbuf.offset();
|
||||
lineno++;
|
||||
srcCoords.add(lineno, userbuf.offset());
|
||||
srcCoords.add(lineno, linebase);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void
|
||||
@ -451,9 +445,9 @@ TokenStream::ungetChar(int32_t c)
|
||||
if (!userbuf.atStart())
|
||||
userbuf.matchRawCharBackwards('\r');
|
||||
|
||||
MOZ_ASSERT(prevLinebase); // we should never get more than one EOL char
|
||||
MOZ_ASSERT(prevLinebase != size_t(-1)); // we should never get more than one EOL char
|
||||
linebase = prevLinebase;
|
||||
prevLinebase = nullptr;
|
||||
prevLinebase = size_t(-1);
|
||||
lineno--;
|
||||
} else {
|
||||
MOZ_ASSERT(userbuf.peekRawChar() == c);
|
||||
@ -494,10 +488,10 @@ TokenStream::peekChars(int n, char16_t *cp)
|
||||
return i == n;
|
||||
}
|
||||
|
||||
const char16_t *
|
||||
TokenStream::TokenBuf::findEOLMax(const char16_t *p, size_t max)
|
||||
size_t
|
||||
TokenStream::TokenBuf::findEOLMax(size_t start, size_t max)
|
||||
{
|
||||
MOZ_ASSERT(base_ <= p && p <= limit_);
|
||||
const char16_t *p = rawCharPtrAt(start);
|
||||
|
||||
size_t n = 0;
|
||||
while (true) {
|
||||
@ -505,11 +499,11 @@ TokenStream::TokenBuf::findEOLMax(const char16_t *p, size_t max)
|
||||
break;
|
||||
if (n >= max)
|
||||
break;
|
||||
n++;
|
||||
if (TokenBuf::isRawEOLChar(*p++))
|
||||
break;
|
||||
n++;
|
||||
}
|
||||
return p;
|
||||
return start + n;
|
||||
}
|
||||
|
||||
void
|
||||
@ -675,8 +669,6 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
|
||||
// means that any error involving a multi-line token (e.g. an unterminated
|
||||
// multi-line string literal) won't have a context printed.
|
||||
if (offset != NoOffset && err.report.lineno == lineno && !callerFilename) {
|
||||
const char16_t *tokenStart = userbuf.rawCharPtrAt(offset);
|
||||
|
||||
// We show only a portion (a "window") of the line around the erroneous
|
||||
// token -- the first char in the token, plus |windowRadius| chars
|
||||
// before it and |windowRadius - 1| chars after it. This is because
|
||||
@ -684,20 +676,22 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
|
||||
// helpful, and (b) can waste a lot of memory. See bug 634444.
|
||||
static const size_t windowRadius = 60;
|
||||
|
||||
// Truncate at the front if necessary.
|
||||
const char16_t *windowBase = (linebase + windowRadius < tokenStart)
|
||||
? tokenStart - windowRadius
|
||||
: linebase;
|
||||
uint32_t windowOffset = tokenStart - windowBase;
|
||||
// The window must start within the current line, no earlier than
|
||||
// windowRadius characters before offset.
|
||||
size_t windowStart = (offset - linebase > windowRadius) ?
|
||||
offset - windowRadius :
|
||||
linebase;
|
||||
|
||||
// Find EOL, or truncate at the back if necessary.
|
||||
const char16_t *windowLimit = userbuf.findEOLMax(tokenStart, windowRadius);
|
||||
size_t windowLength = windowLimit - windowBase;
|
||||
// The window must end within the current line, no later than
|
||||
// windowRadius after offset.
|
||||
size_t windowEnd = userbuf.findEOLMax(offset, windowRadius);
|
||||
size_t windowLength = windowEnd - windowStart;
|
||||
MOZ_ASSERT(windowLength <= windowRadius * 2);
|
||||
|
||||
// Create the windowed strings.
|
||||
StringBuffer windowBuf(cx);
|
||||
if (!windowBuf.append(windowBase, windowLength) || !windowBuf.append((char16_t)0))
|
||||
if (!windowBuf.append(userbuf.rawCharPtrAt(windowStart), windowLength) ||
|
||||
!windowBuf.append((char16_t)0))
|
||||
return false;
|
||||
|
||||
// Unicode and char versions of the window into the offending source
|
||||
@ -711,8 +705,8 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
|
||||
if (!err.report.linebuf)
|
||||
return false;
|
||||
|
||||
err.report.tokenptr = err.report.linebuf + windowOffset;
|
||||
err.report.uctokenptr = err.report.uclinebuf + windowOffset;
|
||||
err.report.tokenptr = err.report.linebuf + (offset - windowStart);
|
||||
err.report.uctokenptr = err.report.uclinebuf + (offset - windowStart);
|
||||
}
|
||||
|
||||
if (cx->isJSContext())
|
||||
|
@ -266,7 +266,7 @@ class MOZ_STACK_CLASS TokenStream
|
||||
const CharBuffer &getTokenbuf() const { return tokenbuf; }
|
||||
const char *getFilename() const { return filename; }
|
||||
unsigned getLineno() const { return lineno; }
|
||||
unsigned getColumn() const { return userbuf.addressOfNextRawChar() - linebase - 1; }
|
||||
unsigned getColumn() const { return userbuf.offset() - linebase - 1; }
|
||||
bool getMutedErrors() const { return mutedErrors; }
|
||||
JSVersion versionNumber() const { return VersionNumber(options().version); }
|
||||
JSVersion versionWithFlags() const { return options().version; }
|
||||
@ -517,8 +517,8 @@ class MOZ_STACK_CLASS TokenStream
|
||||
const char16_t *buf;
|
||||
Flags flags;
|
||||
unsigned lineno;
|
||||
const char16_t *linebase;
|
||||
const char16_t *prevLinebase;
|
||||
size_t linebase;
|
||||
size_t prevLinebase;
|
||||
Token currentToken;
|
||||
unsigned lookahead;
|
||||
Token lookaheadTokens[maxLookahead];
|
||||
@ -743,9 +743,9 @@ class MOZ_STACK_CLASS TokenStream
|
||||
return c == '\n' || c == '\r' || c == LINE_SEPARATOR || c == PARA_SEPARATOR;
|
||||
}
|
||||
|
||||
// Finds the next EOL, but stops once 'max' characters have been scanned
|
||||
// (*including* the starting char16_t).
|
||||
const char16_t *findEOLMax(const char16_t *p, size_t max);
|
||||
// Returns the offset of the next EOL, but stops once 'max' characters
|
||||
// have been scanned (*including* the char at startOffset).
|
||||
size_t findEOLMax(size_t startOffset, size_t max);
|
||||
|
||||
private:
|
||||
const char16_t *base_; // base of buffer
|
||||
@ -810,8 +810,8 @@ class MOZ_STACK_CLASS TokenStream
|
||||
unsigned lookahead; // count of lookahead tokens
|
||||
unsigned lineno; // current line number
|
||||
Flags flags; // flags -- see above
|
||||
const char16_t *linebase; // start of current line; points into userbuf
|
||||
const char16_t *prevLinebase; // start of previous line; nullptr if on the first line
|
||||
size_t linebase; // start of current line
|
||||
size_t prevLinebase; // start of previous line; size_t(-1) if on the first line
|
||||
TokenBuf userbuf; // user input buffer
|
||||
const char *filename; // input filename or null
|
||||
mozilla::UniquePtr<char16_t[], JS::FreePolicy> displayURL_; // the user's requested source URL or null
|
||||
|
Loading…
x
Reference in New Issue
Block a user