Merge mozilla-central to autoland

--HG--
extra : rebase_source : a5345fa7da5587fdc8dc5e1fd160bbaa03ef6214
This commit is contained in:
arthur.iakab 2018-02-02 12:11:39 +02:00
Родитель 44946573a2 c91fdaccff
Коммит a090750861
13 изменённых файлов: 287 добавлений и 178 удалений

Просмотреть файл

@ -628,10 +628,10 @@ class ParserAnyCharsAccess
{
public:
using TokenStreamSpecific = typename Parser::TokenStream;
using TokenStreamChars = typename TokenStreamSpecific::CharsBase;
using GeneralTokenStreamChars = typename TokenStreamSpecific::GeneralCharsBase;
static inline TokenStreamAnyChars& anyChars(TokenStreamChars* ts);
static inline const TokenStreamAnyChars& anyChars(const TokenStreamChars* ts);
static inline TokenStreamAnyChars& anyChars(GeneralTokenStreamChars* ts);
static inline const TokenStreamAnyChars& anyChars(const GeneralTokenStreamChars* ts);
};
// Specify a value for an ES6 grammar parametrization. We have no enum for
@ -1518,8 +1518,8 @@ class Parser<FullParseHandler, CharT> final
};
template<class Parser>
/* static */ inline TokenStreamAnyChars&
ParserAnyCharsAccess<Parser>::anyChars(TokenStreamChars* ts)
/* static */ inline const TokenStreamAnyChars&
ParserAnyCharsAccess<Parser>::anyChars(const GeneralTokenStreamChars* ts)
{
// The structure we're walking through looks like this:
//
@ -1529,35 +1529,21 @@ ParserAnyCharsAccess<Parser>::anyChars(TokenStreamChars* ts)
// TokenStreamAnyChars anyChars;
// ...;
// };
// struct Parser : ParserBase
// struct Parser : <class that ultimately inherits from ParserBase>
// {
// ...;
// TokenStreamSpecific tokenStream;
// ...;
// };
//
// We're passed a TokenStreamChars* corresponding to a base class of
// Parser::tokenStream. We cast that pointer to a TokenStreamSpecific*,
// We're passed a GeneralTokenStreamChars* (this being a base class of
// Parser::tokenStream). We cast that pointer to a TokenStreamSpecific*,
// then translate that to the enclosing Parser*, then return the |anyChars|
// member within.
auto* tss = static_cast<TokenStreamSpecific*>(ts);
auto tssAddr = reinterpret_cast<uintptr_t>(tss);
using ActualTokenStreamType = decltype(static_cast<Parser*>(nullptr)->tokenStream);
static_assert(mozilla::IsSame<ActualTokenStreamType, TokenStreamSpecific>::value,
"Parser::tokenStream must have type TokenStreamSpecific");
uintptr_t parserAddr = tssAddr - offsetof(Parser, tokenStream);
return reinterpret_cast<Parser*>(parserAddr)->anyChars;
}
template<class Parser>
/* static */ inline const TokenStreamAnyChars&
ParserAnyCharsAccess<Parser>::anyChars(const typename Parser::TokenStream::CharsBase* ts)
{
static_assert(mozilla::IsBaseOf<GeneralTokenStreamChars,
TokenStreamSpecific>::value,
"the static_cast<> below assumes a base-class relationship");
const auto* tss = static_cast<const TokenStreamSpecific*>(ts);
auto tssAddr = reinterpret_cast<uintptr_t>(tss);
@ -1571,6 +1557,16 @@ ParserAnyCharsAccess<Parser>::anyChars(const typename Parser::TokenStream::Chars
return reinterpret_cast<const Parser*>(parserAddr)->anyChars;
}
template<class Parser>
/* static */ inline TokenStreamAnyChars&
ParserAnyCharsAccess<Parser>::anyChars(GeneralTokenStreamChars* ts)
{
const TokenStreamAnyChars& anyCharsConst =
anyChars(const_cast<const GeneralTokenStreamChars*>(ts));
return const_cast<TokenStreamAnyChars&>(anyCharsConst);
}
template <class ParseHandler, typename CharT>
class MOZ_STACK_CLASS AutoAwaitIsKeyword
{

Просмотреть файл

@ -11,6 +11,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/IntegerTypeTraits.h"
#include "mozilla/PodOperations.h"
#include "mozilla/ScopeExit.h"
#include <ctype.h>
#include <stdarg.h>
@ -33,6 +34,7 @@
#include "vm/Unicode.h"
using mozilla::ArrayLength;
using mozilla::MakeScopeExit;
using mozilla::Maybe;
using mozilla::PodArrayZero;
using mozilla::PodAssign;
@ -545,7 +547,7 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getChar(int32_t* cp)
// before it's ungotten.
template<typename CharT, class AnyCharsAccess>
int32_t
TokenStreamSpecific<CharT, AnyCharsAccess>::getCharIgnoreEOL()
GeneralTokenStreamChars<CharT, AnyCharsAccess>::getCharIgnoreEOL()
{
if (MOZ_LIKELY(userbuf.hasRawChars()))
return userbuf.getRawChar();
@ -565,7 +567,7 @@ TokenStreamAnyChars::undoGetChar()
template<typename CharT, class AnyCharsAccess>
void
TokenStreamSpecific<CharT, AnyCharsAccess>::ungetChar(int32_t c)
GeneralTokenStreamChars<CharT, AnyCharsAccess>::ungetChar(int32_t c)
{
if (c == EOF)
return;
@ -588,9 +590,9 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::ungetChar(int32_t c)
}
}
template<typename CharT, class AnyCharsAccess>
template<typename CharT>
void
TokenStreamSpecific<CharT, AnyCharsAccess>::ungetCharIgnoreEOL(int32_t c)
TokenStreamCharsBase<CharT>::ungetCharIgnoreEOL(int32_t c)
{
if (c == EOF)
return;
@ -599,6 +601,22 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::ungetCharIgnoreEOL(int32_t c)
userbuf.ungetRawChar();
}
template<class AnyCharsAccess>
void
TokenStreamChars<char16_t, AnyCharsAccess>::ungetCodePointIgnoreEOL(uint32_t codePoint)
{
MOZ_ASSERT(!userbuf.atStart());
unsigned numUnits = 0;
char16_t units[2];
unicode::UTF16Encode(codePoint, units, &numUnits);
MOZ_ASSERT(numUnits == 1 || numUnits == 2);
while (numUnits-- > 0)
ungetCharIgnoreEOL(units[numUnits]);
}
// Return true iff |n| raw characters can be read from this without reading past
// EOF or a newline, and copy those characters into |cp| if so. The characters
// are not consumed: use skipChars(n) to do so after checking that the consumed
@ -1271,23 +1289,6 @@ IsTokenSane(Token* tp)
}
#endif
template<class AnyCharsAccess>
bool
TokenStreamChars<char16_t, AnyCharsAccess>::matchTrailForLeadSurrogate(char16_t lead,
uint32_t* codePoint)
{
TokenStreamSpecific* ts = asSpecific();
int32_t maybeTrail = ts->getCharIgnoreEOL();
if (!unicode::IsTrailSurrogate(maybeTrail)) {
ts->ungetCharIgnoreEOL(maybeTrail);
return false;
}
*codePoint = unicode::UTF16Decode(lead, maybeTrail);
return true;
}
template<>
MOZ_MUST_USE bool
TokenStreamCharsBase<char16_t>::appendMultiUnitCodepointToTokenbuf(uint32_t codepoint)
@ -1298,26 +1299,49 @@ TokenStreamCharsBase<char16_t>::appendMultiUnitCodepointToTokenbuf(uint32_t code
return tokenbuf.append(lead) && tokenbuf.append(trail);
}
template<class AnyCharsAccess>
void
TokenStreamChars<char16_t, AnyCharsAccess>::matchMultiUnitCodePointSlow(char16_t lead,
uint32_t* codePoint)
{
MOZ_ASSERT(unicode::IsLeadSurrogate(lead),
"matchMultiUnitCodepoint should have ensured |lead| is a lead "
"surrogate");
int32_t maybeTrail = getCharIgnoreEOL();
if (MOZ_LIKELY(unicode::IsTrailSurrogate(maybeTrail))) {
*codePoint = unicode::UTF16Decode(lead, maybeTrail);
} else {
ungetCharIgnoreEOL(maybeTrail);
*codePoint = 0;
}
}
template<typename CharT, class AnyCharsAccess>
bool
TokenStreamSpecific<CharT, AnyCharsAccess>::putIdentInTokenbuf(const CharT* identStart)
{
const CharT* tmp = userbuf.addressOfNextRawChar();
const CharT* const originalAddress = userbuf.addressOfNextRawChar();
userbuf.setAddressOfNextRawChar(identStart);
auto restoreNextRawCharAddress =
MakeScopeExit([this, originalAddress]() {
this->userbuf.setAddressOfNextRawChar(originalAddress);
});
tokenbuf.clear();
for (;;) {
int32_t c = getCharIgnoreEOL();
uint32_t codePoint;
if (isMultiUnitCodepoint(c, &codePoint)) {
if (!matchMultiUnitCodePoint(c, &codePoint))
return false;
if (codePoint) {
if (!unicode::IsIdentifierPart(codePoint))
break;
if (!appendMultiUnitCodepointToTokenbuf(codePoint)) {
userbuf.setAddressOfNextRawChar(tmp);
if (!appendMultiUnitCodepointToTokenbuf(codePoint))
return false;
}
continue;
}
@ -1330,23 +1354,19 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::putIdentInTokenbuf(const CharT* iden
if (MOZ_UNLIKELY(unicode::IsSupplementary(qc))) {
char16_t lead, trail;
unicode::UTF16Encode(qc, &lead, &trail);
if (!tokenbuf.append(lead) || !tokenbuf.append(trail)) {
userbuf.setAddressOfNextRawChar(tmp);
if (!tokenbuf.append(lead) || !tokenbuf.append(trail))
return false;
}
continue;
}
c = qc;
}
if (!tokenbuf.append(c)) {
userbuf.setAddressOfNextRawChar(tmp);
if (!tokenbuf.append(c))
return false;
}
}
userbuf.setAddressOfNextRawChar(tmp);
return true;
}
@ -1500,13 +1520,17 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getTokenInternal(TokenKind* ttp, Mod
goto identifier;
}
uint32_t codePoint;
if (isMultiUnitCodepoint(c, &codePoint) && unicode::IsUnicodeIDStart(codePoint)) {
uint32_t codePoint = c;
if (!matchMultiUnitCodePoint(c, &codePoint))
goto error;
if (codePoint && unicode::IsUnicodeIDStart(codePoint)) {
hadUnicodeEscape = false;
goto identifier;
}
goto badchar;
ungetCodePointIgnoreEOL(codePoint);
error(JSMSG_ILLEGAL_CHARACTER);
goto error;
}
// Get the token kind, based on the first char. The ordering of c1kind
@ -1558,7 +1582,9 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getTokenInternal(TokenKind* ttp, Mod
break;
uint32_t codePoint;
if (isMultiUnitCodepoint(c, &codePoint)) {
if (!matchMultiUnitCodePoint(c, &codePoint))
goto error;
if (codePoint) {
if (!unicode::IsIdentifierPart(codePoint))
break;
@ -1647,9 +1673,9 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getTokenInternal(TokenKind* ttp, Mod
}
uint32_t codePoint;
if (isMultiUnitCodepoint(c, &codePoint) &&
unicode::IsIdentifierStart(codePoint))
{
if (!matchMultiUnitCodePoint(c, &codePoint))
goto error;
if (codePoint && unicode::IsIdentifierStart(codePoint)) {
reportError(JSMSG_IDSTART_AFTER_NUMBER);
goto error;
}
@ -1772,9 +1798,9 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getTokenInternal(TokenKind* ttp, Mod
}
uint32_t codePoint;
if (isMultiUnitCodepoint(c, &codePoint) &&
unicode::IsIdentifierStart(codePoint))
{
if (!matchMultiUnitCodePoint(c, &codePoint))
goto error;
if (codePoint && unicode::IsIdentifierStart(codePoint)) {
reportError(JSMSG_IDSTART_AFTER_NUMBER);
goto error;
}
@ -1839,7 +1865,14 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getTokenInternal(TokenKind* ttp, Mod
hadUnicodeEscape = true;
goto identifier;
}
goto badchar;
// We could point "into" a mistyped escape, e.g. for "\u{41H}" we could
// point at the 'H'. But we don't do that now, so the character after
// the '\' isn't necessarily bad, so just point at the start of
// the actually-invalid escape.
ungetCharIgnoreEOL('\\');
error(JSMSG_BAD_ESCAPE);
goto error;
}
case '|':
@ -2056,9 +2089,11 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getTokenInternal(TokenKind* ttp, Mod
}
goto out;
badchar:
default:
reportError(JSMSG_ILLEGAL_CHARACTER);
// We consumed a bad character/code point. Put it back so the error
// location is the bad character.
ungetCodePointIgnoreEOL(c);
error(JSMSG_ILLEGAL_CHARACTER);
goto error;
}

Просмотреть файл

@ -73,30 +73,62 @@
*
* All such functionality lives in TokenStreamCharsBase<CharT>.
*
* == TokenStreamChars<CharT, AnyCharsAccess> TokenStreamCharsBase<CharT> ==
* == GeneralTokenStreamChars<CharT, AnyCharsAccess>
* TokenStreamCharsBase<CharT> ==
*
* Some functionality operates at a very low level upon character-type-specific
* data, but in distinct ways. For example, "is this character the start of a
* multi-character codepoint?" Consider how such functionality would work on
* various encodings (hypothetically -- we haven't fully implemented any
* particular single-byte encoding support yet):
* Some functionality operates differently on different character types, just
* as for TokenStreamCharsBase, but additionally requires access to character-
* type-agnostic information in TokenStreamAnyChars. For example, getting the
* next character performs different steps for different character types and
* must access TokenStreamAnyChars to update line break information.
*
* * For two-byte text, the character must pass |unicode::IsLeadSurrogate|.
* * For single-byte Latin-1 text, there are no multi-character codepoints.
* * For single-byte UTF-8 text, the answer depends on how many high bits of
* the character are set.
* Such functionality, if it can be defined using the same algorithm for all
* character types, lives in GeneralTokenStreamChars<CharT, AnyCharsAccess>.
* The AnyCharsAccess parameter provides a way for a GeneralTokenStreamChars
* instance to access its corresponding TokenStreamAnyChars, without inheriting
* from it.
*
* GeneralTokenStreamChars<CharT, AnyCharsAccess> is just functionality, no
* actual member data.
*
* Such functionality all lives in TokenStreamChars<CharT, AnyCharsAccess>, a
* declared-but-not-defined template class whose specializations have a common
* public interface (plus whatever private helper functions are desirable).
*
* Why the AnyCharsAccess parameter? Some functionality along these lines
* really wants TokenStreamSpecific, below, e.g. to report an error. Providing
* this parameter allows TokenStreamChars functions to statically cast to this
* presumed superclass to access its functionality.
* == TokenStreamChars<CharT, AnyCharsAccess>
* GeneralTokenStreamChars<CharT, AnyCharsAccess> ==
*
* TokenStreamChars<CharT, AnyCharsAccess> is just functionality, no actual
* member data.
* Some functionality is like that in GeneralTokenStreamChars, *but* it's
* defined entirely differently for different character types.
*
* For example, consider "match a multi-code unit code point" (hypothetically:
* we've only implemented two-byte tokenizing right now):
*
* * For two-byte text, there must be two code units to get, the leading code
* unit must be a UTF-16 lead surrogate, and the trailing code unit must be
* a UTF-16 trailing surrogate. (If any of these fail to hold, a next code
* unit encodes that code point and is not multi-code unit.)
* * For single-byte Latin-1 text, there are no multi-code unit code points.
* * For single-byte UTF-8 text, the first code unit must have N > 1 of its
* highest bits set (and the next unset), and |N - 1| successive code units
* must have their high bit set and next-highest bit unset, *and*
* concatenating all unconstrained bits together must not produce a code
* point value that could have been encoded in fewer code units.
*
* This functionality can't be implemented as member functions in
* GeneralTokenStreamChars because we'd need to *partially specialize* those
* functions -- hold CharT constant while letting AnyCharsAccess vary. But
* C++ forbids function template partial specialization like this: either you
* fix *all* parameters or you fix none of them.
*
* Fortunately, C++ *does* allow *class* template partial specialization. So
* TokenStreamChars is a template class with one specialization per CharT.
* Functions can be defined differently in the different specializations,
* because AnyCharsAccess as the only template parameter on member functions
* *can* vary.
*
* All TokenStreamChars<CharT, AnyCharsAccess> specializations, one per CharT,
* are just functionality, no actual member data.
*
* == TokenStreamSpecific<CharT, AnyCharsAccess>
* TokenStreamChars<CharT, AnyCharsAccess>, TokenStreamShared ==
@ -472,6 +504,7 @@ class TokenStreamAnyChars
TokenStreamAnyChars(JSContext* cx, const ReadOnlyCompileOptions& options,
StrictModeGetter* smg);
template<typename CharT, class AnyCharsAccess> friend class GeneralTokenStreamChars;
template<typename CharT, class AnyCharsAccess> friend class TokenStreamSpecific;
// Accessors.
@ -780,6 +813,9 @@ class TokenStreamAnyChars
template<typename CharT>
class TokenStreamCharsBase
{
protected:
void ungetCharIgnoreEOL(int32_t c);
public:
using CharBuffer = Vector<CharT, 32>;
@ -959,43 +995,93 @@ TokenStreamCharsBase<char16_t>::atomizeChars(JSContext* cx, const char16_t* char
return AtomizeChars(cx, chars, length);
}
template<typename CharT, class AnyCharsAccess> class TokenStreamChars;
template<class AnyCharsAccess>
class TokenStreamChars<char16_t, AnyCharsAccess>
: public TokenStreamCharsBase<char16_t>
template<typename CharT, class AnyCharsAccess>
class GeneralTokenStreamChars
: public TokenStreamCharsBase<CharT>
{
using Self = TokenStreamChars<char16_t, AnyCharsAccess>;
using CharsBase = TokenStreamCharsBase<char16_t>;
using CharsSharedBase = TokenStreamCharsBase<CharT>;
using TokenStreamSpecific = frontend::TokenStreamSpecific<char16_t, AnyCharsAccess>;
protected:
using typename CharsSharedBase::TokenBuf;
using CharsSharedBase::userbuf;
public:
using CharsSharedBase::CharsSharedBase;
TokenStreamAnyChars& anyCharsAccess() {
return AnyCharsAccess::anyChars(this);
}
const TokenStreamAnyChars& anyCharsAccess() const {
return AnyCharsAccess::anyChars(this);
}
using TokenStreamSpecific = frontend::TokenStreamSpecific<CharT, AnyCharsAccess>;
TokenStreamSpecific* asSpecific() {
static_assert(mozilla::IsBaseOf<Self, TokenStreamSpecific>::value,
static_assert(mozilla::IsBaseOf<GeneralTokenStreamChars, TokenStreamSpecific>::value,
"static_cast below presumes an inheritance relationship");
return static_cast<TokenStreamSpecific*>(this);
}
bool matchTrailForLeadSurrogate(char16_t lead, uint32_t* codePoint);
int32_t getCharIgnoreEOL();
public:
using CharsBase::CharsBase;
void ungetChar(int32_t c);
};
TokenStreamAnyChars& anyChars() {
return AnyCharsAccess::anyChars(this);
}
template<typename CharT, class AnyCharsAccess> class TokenStreamChars;
const TokenStreamAnyChars& anyChars() const {
return AnyCharsAccess::anyChars(this);
}
template<class AnyCharsAccess>
class TokenStreamChars<char16_t, AnyCharsAccess>
: public GeneralTokenStreamChars<char16_t, AnyCharsAccess>
{
private:
using Self = TokenStreamChars<char16_t, AnyCharsAccess>;
using GeneralCharsBase = GeneralTokenStreamChars<char16_t, AnyCharsAccess>;
using CharsSharedBase = TokenStreamCharsBase<char16_t>;
MOZ_ALWAYS_INLINE bool isMultiUnitCodepoint(char16_t c, uint32_t* codepoint) {
using GeneralCharsBase::asSpecific;
using typename GeneralCharsBase::TokenStreamSpecific;
void matchMultiUnitCodePointSlow(char16_t lead, uint32_t* codePoint);
protected:
using GeneralCharsBase::anyCharsAccess;
using GeneralCharsBase::getCharIgnoreEOL;
using CharsSharedBase::ungetCharIgnoreEOL;
using GeneralCharsBase::userbuf;
using GeneralCharsBase::GeneralCharsBase;
// |c| must be the code unit just gotten. If it and the subsequent code
// unit form a valid surrogate pair, get the second code unit, set
// |*codePoint| to the code point encoded by the surrogate pair, and return
// true. Otherwise do not get a second code unit, set |*codePoint = 0|,
// and return true.
//
// ECMAScript specifically requires that unpaired UTF-16 surrogates be
// treated as the corresponding code point and not as an error. See
// <https://tc39.github.io/ecma262/#sec-ecmascript-language-types-string-type>.
// Therefore this function always returns true. The |bool| return type
// exists so that a future UTF-8 |TokenStreamChars| can treat malformed
// multi-code unit UTF-8 sequences as errors. (Because ECMAScript only
// interprets UTF-16 inputs, the process of translating the UTF-8 to UTF-16
// would fail, so no script should execute. Technically, we shouldn't even
// be tokenizing -- but it probably isn't realistic to assume every user
// correctly passes only valid UTF-8, at least not without better types in
// our codebase for strings that by construction only contain valid UTF-8.)
MOZ_ALWAYS_INLINE bool matchMultiUnitCodePoint(char16_t c, uint32_t* codePoint) {
if (MOZ_LIKELY(!unicode::IsLeadSurrogate(c)))
return false;
return matchTrailForLeadSurrogate(c, codepoint);
*codePoint = 0;
else
matchMultiUnitCodePointSlow(c, codePoint);
return true;
}
void ungetCodePointIgnoreEOL(uint32_t codePoint);
};
// TokenStream is the lexical scanner for JavaScript source text.
@ -1046,6 +1132,7 @@ class MOZ_STACK_CLASS TokenStreamSpecific
{
public:
using CharsBase = TokenStreamChars<CharT, AnyCharsAccess>;
using GeneralCharsBase = GeneralTokenStreamChars<CharT, AnyCharsAccess>;
using CharsSharedBase = TokenStreamCharsBase<CharT>;
// Anything inherited through a base class whose type depends upon this
@ -1063,6 +1150,7 @@ class MOZ_STACK_CLASS TokenStreamSpecific
using typename CharsSharedBase::Position;
public:
using GeneralCharsBase::anyCharsAccess;
using CharsSharedBase::getTokenbuf;
private:
@ -1073,22 +1161,18 @@ class MOZ_STACK_CLASS TokenStreamSpecific
using CharsSharedBase::appendMultiUnitCodepointToTokenbuf;
using CharsSharedBase::atomizeChars;
using CharsSharedBase::copyTokenbufTo;
using CharsBase::isMultiUnitCodepoint;
using GeneralCharsBase::getCharIgnoreEOL;
using CharsBase::matchMultiUnitCodePoint;
using CharsSharedBase::tokenbuf;
using GeneralCharsBase::ungetChar;
using CharsSharedBase::ungetCharIgnoreEOL;
using CharsBase::ungetCodePointIgnoreEOL;
using CharsSharedBase::userbuf;
public:
TokenStreamSpecific(JSContext* cx, const ReadOnlyCompileOptions& options,
const CharT* base, size_t length);
TokenStreamAnyChars& anyCharsAccess() {
return CharsBase::anyChars();
}
const TokenStreamAnyChars& anyCharsAccess() const {
return CharsBase::anyChars();
}
// If there is an invalid escape in a template, report it and return false,
// otherwise return true.
bool checkForInvalidTemplateEscapeError() {
@ -1360,10 +1444,7 @@ class MOZ_STACK_CLASS TokenStreamSpecific
// and store the character in |*c|. Return false and leave |*c| undefined
// on failure.
MOZ_MUST_USE bool getChar(int32_t* cp);
int32_t getCharIgnoreEOL();
void ungetChar(int32_t c);
void ungetCharIgnoreEOL(int32_t c);
Token* newToken(ptrdiff_t adjust);
uint32_t peekUnicodeEscape(uint32_t* codePoint);
uint32_t peekExtendedUnicodeEscape(uint32_t* codePoint);

Просмотреть файл

@ -261,6 +261,7 @@ MSG_DEF(JSMSG_FROM_AFTER_IMPORT_CLAUSE, 0, JSEXN_SYNTAXERR, "missing keyword 'fr
MSG_DEF(JSMSG_FROM_AFTER_EXPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after export *")
MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage after {0}, starting with {1}")
MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal")
MSG_DEF(JSMSG_BAD_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid escape sequence")
MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character")
MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level of a module")
MSG_DEF(JSMSG_OF_AFTER_FOR_LOOP_DECL, 0, JSEXN_SYNTAXERR, "a declaration in the head of a for-of loop can't have an initializer")

Просмотреть файл

@ -19,7 +19,7 @@ function test()
printBugNumber(BUGNUMBER);
printStatus (summary);
expect = 'SyntaxError: illegal character';
expect = 'SyntaxError';
try
{
@ -29,7 +29,7 @@ function test()
}
catch(ex)
{
actual = ex + '';
actual = ex.constructor.name;
}
reportCompare(expect, actual, summary);

Просмотреть файл

@ -19,7 +19,7 @@ function test()
printBugNumber(BUGNUMBER);
printStatus (summary);
expect = 'SyntaxError: illegal character';
expect = 'SyntaxError';
try
{
@ -27,7 +27,7 @@ function test()
}
catch(ex)
{
actual = ex + '';
actual = ex.constructor.name;
}
reportCompare(expect, actual, summary);

Просмотреть файл

@ -2344,23 +2344,24 @@ static const char kChannelPref[] = "app.update.channel";
// clang-format off
static const char kPrefFileHeader[] =
"# Mozilla User Preferences"
"// Mozilla User Preferences"
NS_LINEBREAK
NS_LINEBREAK
"/* Do not edit this file."
"// DO NOT EDIT THIS FILE."
NS_LINEBREAK
" *"
"//"
NS_LINEBREAK
" * If you make changes to this file while the application is running,"
"// If you make changes to this file while the application is running,"
NS_LINEBREAK
" * the changes will be overwritten when the application exits."
"// the changes will be overwritten when the application exits."
NS_LINEBREAK
" *"
"//"
NS_LINEBREAK
" * To make a manual change to preferences, you can visit the URL "
"about:config"
"// To change a preference value, you can either:"
NS_LINEBREAK
" */"
"// - modify it via the UI (e.g. via about:config in the browser); or"
NS_LINEBREAK
"// - set it within a user.js file in your profile."
NS_LINEBREAK
NS_LINEBREAK;
// clang-format on

Просмотреть файл

@ -497,48 +497,29 @@ pref("parse.error", true);;
//-------------------------------------------------------------------------
// In all of the following we have a \n, a \r, a \r\n, and then an error, so
// the error is on line 4.
// the error is on line 4. (Note: these ones don't use raw string literals
// because MSVC somehow swallows any \r that appears in them.)
// XXX: these are temporarily commented out due to differing results on Windows
#if 0
P(R"(
bad
)",
P("\n \r \r\n bad",
"test:4: prefs parse error: unknown keyword"
);
P(R"(#
# #
bad
)",
P("#\n#\r#\r\n bad",
"test:4: prefs parse error: unknown keyword"
);
P(R"(//
// //
bad
)",
P("//\n//\r//\r\n bad",
"test:4: prefs parse error: unknown keyword"
);
P(R"(/*
*/ bad
)",
P("/*\n \r \r\n*/ bad",
"test:4: prefs parse error: unknown keyword"
);
// Note: the escape sequences do *not* affect the line number.
P(R"(pref("foo\n
\r foo\r\n
foo", bad
)",
P("pref(\"foo\\n\n foo\\r\r foo\\r\\n\r\n foo\", bad);",
"test:4: prefs parse error: unknown keyword"
);
#endif
// clang-format on
}

Просмотреть файл

@ -5,6 +5,7 @@ geckoview:
instance-size: xlarge
loopback-video: true
e10s: false
target: geckoview_example.apk
mozharness:
script: android_emulator_unittest.py
no-read-buildbot-config: true

Просмотреть файл

@ -393,6 +393,15 @@ test_description_schema = Schema({
Any(basestring, None),
),
# The target name, specifying the build artifact to be tested.
# If None or not specified, a transform sets the target based on OS:
# target.dmg (Mac), target.apk (Android), target.tar.bz2 (Linux),
# or target.zip (Windows).
Optional('target'): optionally_keyed_by(
'test-platform',
Any(basestring, None),
),
}, required=True)
@ -499,17 +508,19 @@ def setup_talos(config, tests):
def set_target(config, tests):
for test in tests:
build_platform = test['build-platform']
if build_platform.startswith('macosx'):
target = 'target.dmg'
elif build_platform.startswith('android'):
if 'geckoview' in test['test-name']:
target = 'geckoview_example.apk'
else:
target = None
if 'target' in test:
resolve_keyed_by(test, 'target', item_name=test['test-name'])
target = test['target']
if not target:
if build_platform.startswith('macosx'):
target = 'target.dmg'
elif build_platform.startswith('android'):
target = 'target.apk'
elif build_platform.startswith('win'):
target = 'target.zip'
else:
target = 'target.tar.bz2'
elif build_platform.startswith('win'):
target = 'target.zip'
else:
target = 'target.tar.bz2'
test['mozharness']['build-artifact-name'] = 'public/build/' + target
yield test

Просмотреть файл

@ -376,6 +376,11 @@ class AndroidEmulatorTest(TestingMixin, EmulatorMixin, BaseScript, MozbaseMixin)
self.warning("Failed to take screenshot: %s" % err.strerror)
def _query_package_name(self):
if self.app_name is None:
# For convenience, assume geckoview_example when install target
# looks like geckoview.
if 'geckoview' in self.installer_path:
self.app_name = 'org.mozilla.geckoview_example'
if self.app_name is None:
# Find appname from package-name.txt - assumes download-and-extract
# has completed successfully.

Просмотреть файл

@ -129,7 +129,7 @@ function limitProperties(name, obj, count, log) {
// properties.
if (name === "data" && (
key === "max_pause" ||
key === "num_slices" ||
key === "slices" ||
key === "slices_list" ||
key === "status" ||
key === "timestamp" ||
@ -156,9 +156,6 @@ function limitProperties(name, obj, count, log) {
* etc.
*/
function limitSize(data, log) {
// Store the number of slices so we know if we lost any at the end.
data.num_slices = data.slices_list.length;
data.slices_list.sort((a, b) => b.pause - a.pause);
if (data.slices_list.length > MAX_SLICES) {

Просмотреть файл

@ -30,7 +30,7 @@ function run_test() {
GCTelemetry.observeRaw(make_gc());
// Get it back.
assert_num_entries(1, false);
Assert.equal(20, Object.keys(get_entry()).length);
Assert.equal(19, Object.keys(get_entry()).length);
// "true" will cause the entry to be clared.
assert_num_entries(1, true);
// There are currently no entries.
@ -49,18 +49,18 @@ function run_test() {
// Exactly the limit of fields.
let my_gc_24 = make_gc();
for (let i = 0; i < 4; i++) {
for (let i = 0; i < 5; i++) {
my_gc_24["new_property_" + i] = "Data";
}
GCTelemetry.observeRaw(my_gc_24);
// Assert that it was recorded but has only 7 fields.
// Assert that it was recorded has all 24 fields.
Assert.equal(24, Object.keys(get_entry()).length);
assert_num_entries(1, true);
assert_num_entries(0, false);
// Exactly too many fields.
let my_gc_25 = make_gc();
for (let i = 0; i < 5; i++) {
for (let i = 0; i < 6; i++) {
my_gc_25["new_property_" + i] = "Data";
}
GCTelemetry.observeRaw(my_gc_25);