mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-09-09 04:54:33 +00:00
#430: implement destructuring default arguments from M932080 +test changes
This commit is contained in:
parent
289bb253c1
commit
a9e9d0bb5f
@ -717,7 +717,6 @@ template <typename ParseHandler>
|
||||
Parser<ParseHandler>::~Parser()
|
||||
{
|
||||
MOZ_ASSERT(checkOptionsCalled);
|
||||
|
||||
alloc.release(tempPoolMark);
|
||||
|
||||
/*
|
||||
@ -3865,6 +3864,70 @@ Parser<ParseHandler>::AutoPushStmtInfoPC::makeInnermostLexicalScope(StaticBlockO
|
||||
return generateBlockId();
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
Parser<ParseHandler>::PossibleError::PossibleError(Parser<ParseHandler>& parser)
|
||||
: parser_(parser)
|
||||
{
|
||||
state_ = ErrorState::None;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
void
|
||||
Parser<ParseHandler>::PossibleError::setPending(ParseReportKind kind, unsigned errorNumber,
|
||||
bool strict)
|
||||
{
|
||||
// If we report an error later, we'll do it from the position where we set
|
||||
// the state to pending.
|
||||
offset_ = parser_.pos().begin;
|
||||
reportKind_ = kind;
|
||||
strict_ = strict;
|
||||
errorNumber_ = errorNumber;
|
||||
state_ = ErrorState::Pending;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
void
|
||||
Parser<ParseHandler>::PossibleError::setResolved()
|
||||
{
|
||||
state_ = ErrorState::None;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::PossibleError::hasError()
|
||||
{
|
||||
return state_ == ErrorState::Pending;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::PossibleError::checkForExprErrors()
|
||||
{
|
||||
bool err = hasError();
|
||||
if (err) {
|
||||
parser_.reportWithOffset(reportKind_, strict_, offset_, errorNumber_);
|
||||
}
|
||||
return !err;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
void
|
||||
Parser<ParseHandler>::PossibleError::transferErrorTo(PossibleError* other)
|
||||
{
|
||||
if (other) {
|
||||
MOZ_ASSERT(this != other);
|
||||
MOZ_ASSERT(!other->hasError());
|
||||
// We should never allow fields to be copied between instances
|
||||
// that point to different underlying parsers.
|
||||
MOZ_ASSERT(&parser_ == &other->parser_);
|
||||
other->offset_ = offset_;
|
||||
other->reportKind_ = reportKind_;
|
||||
other->errorNumber_ = errorNumber_;
|
||||
other->strict_ = strict_;
|
||||
other->state_ = state_;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
static inline bool
|
||||
OuterLet(ParseContext<ParseHandler>* pc, StmtInfoPC* stmt, HandleAtom atom)
|
||||
@ -4301,7 +4364,8 @@ Parser<ParseHandler>::destructuringExpr(YieldHandling yieldHandling, BindData<Pa
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(tt));
|
||||
|
||||
pc->inDeclDestructuring = true;
|
||||
Node pn = primaryExpr(yieldHandling, TripledotProhibited, tt);
|
||||
Node pn = primaryExpr(yieldHandling, TripledotProhibited,
|
||||
nullptr /* possibleError */, tt);
|
||||
pc->inDeclDestructuring = false;
|
||||
if (!pn)
|
||||
return null();
|
||||
@ -4454,10 +4518,10 @@ Parser<ParseHandler>::expressionAfterForInOrOf(ParseNodeKind forHeadKind,
|
||||
YieldHandling yieldHandling)
|
||||
{
|
||||
MOZ_ASSERT(forHeadKind == PNK_FORIN || forHeadKind == PNK_FOROF);
|
||||
|
||||
return forHeadKind == PNK_FOROF
|
||||
Node pn = forHeadKind == PNK_FOROF
|
||||
? assignExpr(InAllowed, yieldHandling, TripledotProhibited)
|
||||
: expr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
return pn;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
@ -4473,7 +4537,11 @@ Parser<ParseHandler>::declarationPattern(Node decl, TokenKind tt, BindData<Parse
|
||||
Node pattern;
|
||||
{
|
||||
pc->inDeclDestructuring = true;
|
||||
pattern = primaryExpr(yieldHandling, TripledotProhibited, tt);
|
||||
|
||||
// No possible error is required because we already know we're
|
||||
// destructuring.
|
||||
pattern = primaryExpr(yieldHandling, TripledotProhibited,
|
||||
nullptr /* possibleError */ , tt);
|
||||
pc->inDeclDestructuring = false;
|
||||
}
|
||||
if (!pattern)
|
||||
@ -4518,7 +4586,14 @@ Parser<ParseHandler>::declarationPattern(Node decl, TokenKind tt, BindData<Parse
|
||||
return null();
|
||||
}
|
||||
|
||||
MUST_MATCH_TOKEN(TOK_ASSIGN, JSMSG_BAD_DESTRUCT_DECL);
|
||||
TokenKind token;
|
||||
if (!tokenStream.getToken(&token, TokenStream::None))
|
||||
return null();
|
||||
|
||||
if (token != TOK_ASSIGN) {
|
||||
report(ParseError, false, null(), JSMSG_BAD_DESTRUCT_DECL);
|
||||
return null();
|
||||
}
|
||||
|
||||
Node init = assignExpr(forHeadKind ? InProhibited : InAllowed,
|
||||
yieldHandling, TripledotProhibited);
|
||||
@ -6653,7 +6728,6 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
|
||||
if (!catchName)
|
||||
return null();
|
||||
break;
|
||||
|
||||
case TOK_YIELD:
|
||||
if (yieldHandling == YieldIsKeyword) {
|
||||
report(ParseError, false, null(), JSMSG_RESERVED_ID, "yield");
|
||||
@ -7280,9 +7354,12 @@ Parser<ParseHandler>::statement(YieldHandling yieldHandling, bool canHaveDirecti
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling, InvokedPrediction invoked)
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
Node pn = assignExpr(inHandling, yieldHandling, tripledotHandling, invoked);
|
||||
Node pn = assignExpr(inHandling, yieldHandling, tripledotHandling,
|
||||
possibleError, invoked);
|
||||
if (!pn)
|
||||
return null();
|
||||
|
||||
@ -7297,9 +7374,26 @@ Parser<ParseHandler>::expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
return null();
|
||||
while (true) {
|
||||
|
||||
pn = assignExpr(inHandling, yieldHandling, tripledotHandling);
|
||||
// Additional calls to assignExpr should not reuse the possibleError
|
||||
// which had been passed into the function. Otherwise we would lose
|
||||
// information needed to determine whether or not we're dealing with
|
||||
// a non-recoverable situation.
|
||||
PossibleError possibleErrorInner(*this);
|
||||
pn = assignExpr(inHandling, yieldHandling, tripledotHandling,
|
||||
&possibleErrorInner);
|
||||
if (!pn)
|
||||
return null();
|
||||
|
||||
// If we find an error here we should report it immedately instead of
|
||||
// passing it back out of the function.
|
||||
if (possibleErrorInner.hasError()) {
|
||||
|
||||
// We begin by checking for an outer pending error since it would
|
||||
// have occurred first.
|
||||
if (possibleError->checkForExprErrors())
|
||||
possibleErrorInner.checkForExprErrors();
|
||||
return null();
|
||||
}
|
||||
handler.addList(seq, pn);
|
||||
|
||||
if (!tokenStream.matchToken(&matched, TOK_COMMA))
|
||||
@ -7310,6 +7404,19 @@ Parser<ParseHandler>::expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
return seq;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
PossibleError possibleError(*this);
|
||||
Node pn = expr(inHandling, yieldHandling, tripledotHandling, &possibleError, invoked);
|
||||
if (!pn || !possibleError.checkForExprErrors())
|
||||
return null();
|
||||
return pn;
|
||||
}
|
||||
|
||||
static const JSOp ParseNodeKindToJSOp[] = {
|
||||
JSOP_OR,
|
||||
JSOP_AND,
|
||||
@ -7397,7 +7504,9 @@ Precedence(ParseNodeKind pnk) {
|
||||
template <typename ParseHandler>
|
||||
MOZ_ALWAYS_INLINE typename ParseHandler::Node
|
||||
Parser<ParseHandler>::orExpr1(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling, InvokedPrediction invoked)
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
// Shift-reduce parser for the binary operator part of the JS expression
|
||||
// syntax.
|
||||
@ -7410,7 +7519,7 @@ Parser<ParseHandler>::orExpr1(InHandling inHandling, YieldHandling yieldHandling
|
||||
|
||||
Node pn;
|
||||
for (;;) {
|
||||
pn = unaryExpr(yieldHandling, tripledotHandling, invoked);
|
||||
pn = unaryExpr(yieldHandling, tripledotHandling, possibleError, invoked);
|
||||
if (!pn)
|
||||
return pn;
|
||||
|
||||
@ -7465,19 +7574,22 @@ Parser<ParseHandler>::orExpr1(InHandling inHandling, YieldHandling yieldHandling
|
||||
template <typename ParseHandler>
|
||||
MOZ_ALWAYS_INLINE typename ParseHandler::Node
|
||||
Parser<ParseHandler>::condExpr1(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling, InvokedPrediction invoked)
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
Node condition = orExpr1(inHandling, yieldHandling, tripledotHandling, invoked);
|
||||
Node condition = orExpr1(inHandling, yieldHandling, tripledotHandling, possibleError, invoked);
|
||||
if (!condition || !tokenStream.isCurrentTokenType(TOK_HOOK))
|
||||
return condition;
|
||||
|
||||
Node thenExpr = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
Node thenExpr = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
|
||||
possibleError);
|
||||
if (!thenExpr)
|
||||
return null();
|
||||
|
||||
MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_IN_COND);
|
||||
|
||||
Node elseExpr = assignExpr(inHandling, yieldHandling, TripledotProhibited);
|
||||
Node elseExpr = assignExpr(inHandling, yieldHandling, TripledotProhibited,
|
||||
possibleError);
|
||||
if (!elseExpr)
|
||||
return null();
|
||||
|
||||
@ -7490,7 +7602,8 @@ Parser<ParseHandler>::condExpr1(InHandling inHandling, YieldHandling yieldHandli
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::checkAndMarkAsAssignmentLhs(Node target, AssignmentFlavor flavor)
|
||||
Parser<ParseHandler>::checkAndMarkAsAssignmentLhs(Node target, AssignmentFlavor flavor,
|
||||
PossibleError* possibleError)
|
||||
{
|
||||
MOZ_ASSERT(flavor != KeyedDestructuringAssignment,
|
||||
"destructuring must use special checking/marking code, not "
|
||||
@ -7502,7 +7615,13 @@ Parser<ParseHandler>::checkAndMarkAsAssignmentLhs(Node target, AssignmentFlavor
|
||||
return false;
|
||||
}
|
||||
|
||||
return checkDestructuringPattern(nullptr, target);
|
||||
bool isDestructuring = checkDestructuringPattern(nullptr, target);
|
||||
// Here we've successfully distinguished between destructuring and
|
||||
// an object literal. In the case where "CoverInitializedName"
|
||||
// syntax was used there will be a pending error that needs clearing.
|
||||
if (possibleError && isDestructuring)
|
||||
possibleError->setResolved();
|
||||
return isDestructuring;
|
||||
}
|
||||
|
||||
// All other permitted targets are simple.
|
||||
@ -7530,9 +7649,12 @@ Parser<ParseHandler>::checkAndMarkAsAssignmentLhs(Node target, AssignmentFlavor
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling, InvokedPrediction invoked)
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
JS_CHECK_RECURSION(context, return null());
|
||||
MOZ_ASSERT(!possibleError->hasError());
|
||||
|
||||
// It's very common at this point to have a "detectably simple" expression,
|
||||
// i.e. a name/number/string token followed by one of the following tokens
|
||||
@ -7582,9 +7704,11 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
|
||||
TokenStream::Position start(keepAtoms);
|
||||
tokenStream.tell(&start);
|
||||
|
||||
Node lhs = condExpr1(inHandling, yieldHandling, tripledotHandling, invoked);
|
||||
if (!lhs)
|
||||
PossibleError possibleErrorInner(*this);
|
||||
Node lhs = condExpr1(inHandling, yieldHandling, tripledotHandling, &possibleErrorInner, invoked);
|
||||
if (!lhs) {
|
||||
return null();
|
||||
}
|
||||
|
||||
ParseNodeKind kind;
|
||||
JSOp op;
|
||||
@ -7604,6 +7728,7 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
|
||||
case TOK_POWASSIGN: kind = PNK_POWASSIGN; op = JSOP_POW; break;
|
||||
|
||||
case TOK_ARROW: {
|
||||
|
||||
// A line terminator between ArrowParameters and the => should trigger a SyntaxError.
|
||||
tokenStream.ungetToken();
|
||||
TokenKind next = TOK_EOF;
|
||||
@ -7666,24 +7791,42 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
|
||||
|
||||
default:
|
||||
MOZ_ASSERT(!tokenStream.isCurrentTokenAssignment());
|
||||
possibleErrorInner.transferErrorTo(possibleError);
|
||||
tokenStream.ungetToken();
|
||||
return lhs;
|
||||
}
|
||||
|
||||
AssignmentFlavor flavor = kind == PNK_ASSIGN ? PlainAssignment : CompoundAssignment;
|
||||
if (!checkAndMarkAsAssignmentLhs(lhs, flavor))
|
||||
if (!checkAndMarkAsAssignmentLhs(lhs, flavor, &possibleErrorInner))
|
||||
return null();
|
||||
if (!possibleErrorInner.checkForExprErrors())
|
||||
return null();
|
||||
|
||||
bool saved = pc->inDeclDestructuring;
|
||||
pc->inDeclDestructuring = false;
|
||||
Node rhs = assignExpr(inHandling, yieldHandling, TripledotProhibited);
|
||||
Node rhs = assignExpr(inHandling, yieldHandling, TripledotProhibited,
|
||||
possibleError);
|
||||
pc->inDeclDestructuring = saved;
|
||||
if (!rhs)
|
||||
return null();
|
||||
|
||||
return handler.newAssignment(kind, lhs, rhs, pc, op);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
PossibleError possibleError(*this);
|
||||
Node expr = assignExpr(inHandling, yieldHandling, tripledotHandling, &possibleError, invoked);
|
||||
if (!expr || !possibleError.checkForExprErrors())
|
||||
return null();
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::isValidSimpleAssignmentTarget(Node node,
|
||||
@ -7808,8 +7951,9 @@ typename ParseHandler::Node
|
||||
Parser<ParseHandler>::unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, JSOp op,
|
||||
uint32_t begin)
|
||||
{
|
||||
Node kid = unaryExpr(yieldHandling, TripledotProhibited);
|
||||
if (!kid)
|
||||
PossibleError possibleError(*this);
|
||||
Node kid = unaryExpr(yieldHandling, TripledotProhibited, &possibleError);
|
||||
if (!kid || !possibleError.checkForExprErrors())
|
||||
return null();
|
||||
return handler.newUnary(kind, op, begin, kid);
|
||||
}
|
||||
@ -7817,7 +7961,7 @@ Parser<ParseHandler>::unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kin
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked)
|
||||
PossibleError* possibleError, InvokedPrediction invoked)
|
||||
{
|
||||
JS_CHECK_RECURSION(context, return null());
|
||||
|
||||
@ -7849,7 +7993,7 @@ Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling t
|
||||
// // Evaluates expression, triggering a runtime ReferenceError for
|
||||
// // the undefined name.
|
||||
// typeof (1, nonExistentName);
|
||||
Node kid = unaryExpr(yieldHandling, TripledotProhibited);
|
||||
Node kid = unaryExpr(yieldHandling, TripledotProhibited, possibleError);
|
||||
if (!kid)
|
||||
return null();
|
||||
|
||||
@ -7862,7 +8006,7 @@ Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling t
|
||||
TokenKind tt2;
|
||||
if (!tokenStream.getToken(&tt2, TokenStream::Operand))
|
||||
return null();
|
||||
Node pn2 = memberExpr(yieldHandling, TripledotProhibited, tt2, true);
|
||||
Node pn2 = memberExpr(yieldHandling, TripledotProhibited, possibleError, tt2, true);
|
||||
if (!pn2)
|
||||
return null();
|
||||
AssignmentFlavor flavor = (tt == TOK_INC) ? IncrementAssignment : DecrementAssignment;
|
||||
@ -7874,7 +8018,7 @@ Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling t
|
||||
}
|
||||
|
||||
case TOK_DELETE: {
|
||||
Node expr = unaryExpr(yieldHandling, TripledotProhibited);
|
||||
Node expr = unaryExpr(yieldHandling, TripledotProhibited, possibleError);
|
||||
if (!expr)
|
||||
return null();
|
||||
|
||||
@ -7890,7 +8034,7 @@ Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling t
|
||||
}
|
||||
|
||||
default: {
|
||||
Node pn = memberExpr(yieldHandling, tripledotHandling, tt, /* allowCallSyntax = */ true,
|
||||
Node pn = memberExpr(yieldHandling, tripledotHandling, possibleError, tt, /* allowCallSyntax = */ true,
|
||||
invoked);
|
||||
if (!pn)
|
||||
return null();
|
||||
@ -8266,7 +8410,11 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode* bodyExpr, unsigned
|
||||
case TOK_LB:
|
||||
case TOK_LC:
|
||||
pc->inDeclDestructuring = true;
|
||||
pn3 = primaryExpr(YieldIsKeyword, TripledotProhibited, tt);
|
||||
|
||||
// No possible error is needed here either because we already
|
||||
// know we are destructuring.
|
||||
pn3 = primaryExpr(YieldIsKeyword, TripledotProhibited,
|
||||
nullptr /* = possibleError */, tt);
|
||||
pc->inDeclDestructuring = false;
|
||||
if (!pn3)
|
||||
return null();
|
||||
@ -8935,7 +9083,8 @@ Parser<ParseHandler>::checkAndMarkSuperScope()
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
TokenKind tt, bool allowCallSyntax, InvokedPrediction invoked)
|
||||
PossibleError* possibleError, TokenKind tt,
|
||||
bool allowCallSyntax, InvokedPrediction invoked)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(tt));
|
||||
|
||||
@ -8959,7 +9108,8 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
|
||||
// Gotten by tryNewTarget
|
||||
tt = tokenStream.currentToken().type;
|
||||
Node ctorExpr = memberExpr(yieldHandling, TripledotProhibited, tt, false, PredictInvoked);
|
||||
Node ctorExpr = memberExpr(yieldHandling, TripledotProhibited,
|
||||
possibleError, tt, false, PredictInvoked);
|
||||
if (!ctorExpr)
|
||||
return null();
|
||||
|
||||
@ -8984,7 +9134,7 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
if (!lhs)
|
||||
return null();
|
||||
} else {
|
||||
lhs = primaryExpr(yieldHandling, tripledotHandling, tt, invoked);
|
||||
lhs = primaryExpr(yieldHandling, tripledotHandling, possibleError, tt, invoked);
|
||||
if (!lhs)
|
||||
return null();
|
||||
}
|
||||
@ -9015,7 +9165,7 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
return null();
|
||||
}
|
||||
} else if (tt == TOK_LB) {
|
||||
Node propExpr = expr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
Node propExpr = expr(InAllowed, yieldHandling, TripledotProhibited, possibleError);
|
||||
if (!propExpr)
|
||||
return null();
|
||||
|
||||
@ -9143,6 +9293,19 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling, TokenKind tt,
|
||||
bool allowCallSyntax, InvokedPrediction invoked)
|
||||
{
|
||||
PossibleError possibleError(*this);
|
||||
Node pn = memberExpr(yieldHandling, tripledotHandling, &possibleError, tt,
|
||||
allowCallSyntax, invoked);
|
||||
if (!pn || !possibleError.checkForExprErrors())
|
||||
return null();
|
||||
return pn;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::newName(PropertyName* name)
|
||||
@ -9515,13 +9678,15 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling, Node propList,
|
||||
return propName;
|
||||
}
|
||||
|
||||
if (ltok == TOK_NAME && (tt == TOK_COMMA || tt == TOK_RC)) {
|
||||
if (ltok == TOK_NAME && (tt == TOK_COMMA || tt == TOK_RC || tt == TOK_ASSIGN)) {
|
||||
if (isGenerator) {
|
||||
report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
|
||||
return null();
|
||||
}
|
||||
tokenStream.ungetToken();
|
||||
*propType = PropertyType::Shorthand;
|
||||
*propType = tt == TOK_ASSIGN ?
|
||||
PropertyType::CoverInitializedName :
|
||||
PropertyType::Shorthand;
|
||||
return propName;
|
||||
}
|
||||
|
||||
@ -9562,7 +9727,7 @@ Parser<ParseHandler>::computedPropertyName(YieldHandling yieldHandling, Node lit
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling)
|
||||
Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LC));
|
||||
|
||||
@ -9571,6 +9736,7 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling)
|
||||
return null();
|
||||
|
||||
bool seenPrototypeMutation = false;
|
||||
bool seenCoverInitializedName = false;
|
||||
RootedAtom propAtom(context);
|
||||
for (;;) {
|
||||
TokenKind tt;
|
||||
@ -9629,6 +9795,43 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling)
|
||||
|
||||
if (!handler.addShorthand(literal, propName, nameExpr))
|
||||
return null();
|
||||
} else if (propType == PropertyType::CoverInitializedName) {
|
||||
/*
|
||||
* Support, e.g., |var {x=1, y=2} = o| as destructuring shorthand
|
||||
* with default values, as per ES6 12.14.5 (2016/2/4)
|
||||
*/
|
||||
if (!tokenStream.checkForKeyword(propAtom, nullptr))
|
||||
return null();
|
||||
|
||||
Node lhs = identifierName(yieldHandling);
|
||||
if (!lhs)
|
||||
return null();
|
||||
|
||||
tokenStream.consumeKnownToken(TOK_ASSIGN);
|
||||
Node rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
if (!rhs)
|
||||
return null();
|
||||
|
||||
Node propExpr = handler.newAssignment(PNK_ASSIGN, lhs, rhs, pc, JSOP_NOP);
|
||||
if (!propExpr)
|
||||
return null();
|
||||
|
||||
if (!handler.addPropertyDefinition(literal, propName, propExpr))
|
||||
return null();
|
||||
|
||||
if (!abortIfSyntaxParser())
|
||||
return null();
|
||||
|
||||
if (!seenCoverInitializedName) {
|
||||
seenCoverInitializedName = true;
|
||||
// "shorthand default" or "CoverInitializedName" syntax is only
|
||||
// valid in the case of destructuring. Here we set a pending error so
|
||||
// that later in the parse, once we've determined whether or not we're
|
||||
// destructuring, the error can be reported or ignored appropriately.
|
||||
if (possibleError)
|
||||
possibleError->setPending(ParseError, JSMSG_BAD_PROP_ID, false);
|
||||
}
|
||||
|
||||
} else {
|
||||
// FIXME: Implement ES6 function "name" property semantics
|
||||
// (bug 883377).
|
||||
@ -9728,7 +9931,8 @@ Parser<ParseHandler>::tryNewTarget(Node &newTarget)
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
TokenKind tt, InvokedPrediction invoked)
|
||||
PossibleError* possibleError, TokenKind tt,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(tt));
|
||||
JS_CHECK_RECURSION(context, return null());
|
||||
@ -9744,7 +9948,7 @@ Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
return arrayInitializer(yieldHandling);
|
||||
|
||||
case TOK_LC:
|
||||
return objectLiteral(yieldHandling);
|
||||
return objectLiteral(yieldHandling, possibleError);
|
||||
|
||||
case TOK_LP: {
|
||||
TokenKind next;
|
||||
@ -9776,7 +9980,7 @@ Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
return generatorComprehension(begin);
|
||||
}
|
||||
|
||||
Node expr = exprInParens(InAllowed, yieldHandling, TripledotAllowed);
|
||||
Node expr = exprInParens(InAllowed, yieldHandling, TripledotAllowed, possibleError);
|
||||
if (!expr)
|
||||
return null();
|
||||
MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
|
||||
@ -9880,6 +10084,16 @@ Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::exprInParens(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LP));
|
||||
return expr(inHandling, yieldHandling, tripledotHandling, possibleError, PredictInvoked);
|
||||
}
|
||||
|
||||
// Legacy generator comprehensions can appear anywhere an expression is
|
||||
// enclosed in parentheses, even if those parentheses are part of statement
|
||||
// syntax or a function call:
|
||||
|
@ -364,6 +364,7 @@ enum PropListType { ObjectLiteral, ClassBody, DerivedClassBody };
|
||||
enum class PropertyType {
|
||||
Normal,
|
||||
Shorthand,
|
||||
CoverInitializedName,
|
||||
Getter,
|
||||
GetterNoExpressionClosure,
|
||||
Setter,
|
||||
@ -405,6 +406,72 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
operator StmtInfoPC*() { return &stmt_; }
|
||||
};
|
||||
|
||||
/*
|
||||
* A class for temporarily stashing errors while parsing continues.
|
||||
*
|
||||
* The ability to stash an error is useful for handling situations where we
|
||||
* aren't able to verify that an error has occurred until later in the parse.
|
||||
* For instance | ({x=1}) | is always parsed as an object literal with
|
||||
* a SyntaxError, however, in the case where it is followed by '=>' we rewind
|
||||
* and reparse it as a valid arrow function. Here a PossibleError would be
|
||||
* set to 'pending' when the initial SyntaxError was encountered then 'resolved'
|
||||
* just before rewinding the parser.
|
||||
*
|
||||
* When using PossibleError one should set a pending error at the location
|
||||
* where an error occurs. From that point, the error may be resolved
|
||||
* (invalidated) or left until the PossibleError is checked.
|
||||
*
|
||||
* Ex:
|
||||
* PossibleError possibleError(*this);
|
||||
* possibleError.setPending(ParseError, JSMSG_BAD_PROP_ID, false);
|
||||
* // A JSMSG_BAD_PROP_ID ParseError is reported, returns false.
|
||||
* possibleError.checkForExprErrors();
|
||||
*
|
||||
* PossibleError possibleError(*this);
|
||||
* possibleError.setPending(ParseError, JSMSG_BAD_PROP_ID, false);
|
||||
* possibleError.setResolved();
|
||||
* // Returns true, no error is reported.
|
||||
* possibleError.checkForExprErrors();
|
||||
*
|
||||
* PossibleError possibleError(*this);
|
||||
* // Returns true, no error is reported.
|
||||
* possibleError.checkForExprErrors();
|
||||
*/
|
||||
class MOZ_STACK_CLASS PossibleError
|
||||
{
|
||||
enum ErrorState { None, Pending };
|
||||
ErrorState state_;
|
||||
|
||||
// Error reporting fields.
|
||||
uint32_t offset_;
|
||||
unsigned errorNumber_;
|
||||
ParseReportKind reportKind_;
|
||||
Parser<ParseHandler>& parser_;
|
||||
bool strict_;
|
||||
|
||||
public:
|
||||
explicit PossibleError(Parser<ParseHandler>& parser);
|
||||
|
||||
// Set a pending error.
|
||||
void setPending(ParseReportKind kind, unsigned errorNumber, bool strict);
|
||||
|
||||
// Resolve any pending error.
|
||||
void setResolved();
|
||||
|
||||
// Return true if an error is pending without reporting
|
||||
bool hasError();
|
||||
|
||||
// If there is a pending error report it and return false, otherwise return
|
||||
// true.
|
||||
bool checkForExprErrors();
|
||||
|
||||
// Pass pending errors between possible error instances. This is useful
|
||||
// for extending the lifetime of a pending error beyond the scope of
|
||||
// the PossibleError where it was initially set (keeping in mind that
|
||||
// PossibleError is a MOZ_STACK_CLASS).
|
||||
void transferErrorTo(PossibleError* other);
|
||||
};
|
||||
|
||||
public:
|
||||
ExclusiveContext* const context;
|
||||
LifoAlloc& alloc;
|
||||
@ -754,7 +821,15 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
|
||||
Node expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node assignExpr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node assignExpr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
@ -762,16 +837,26 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
Node yieldExpression(InHandling inHandling);
|
||||
Node condExpr1(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node orExpr1(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node unaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node memberExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError, TokenKind tt,
|
||||
bool allowCallSyntax, InvokedPrediction invoked = PredictUninvoked);
|
||||
Node memberExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling, TokenKind tt,
|
||||
bool allowCallSyntax, InvokedPrediction invoked = PredictUninvoked);
|
||||
Node primaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling, TokenKind tt,
|
||||
Node primaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError, TokenKind tt,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node exprInParens(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError);
|
||||
Node exprInParens(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling);
|
||||
|
||||
@ -848,7 +933,8 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
ForInOrOfTarget
|
||||
};
|
||||
|
||||
bool checkAndMarkAsAssignmentLhs(Node pn, AssignmentFlavor flavor);
|
||||
bool checkAndMarkAsAssignmentLhs(Node pn, AssignmentFlavor flavor,
|
||||
PossibleError* possibleError=nullptr);
|
||||
bool matchInOrOf(bool* isForInp, bool* isForOfp);
|
||||
|
||||
bool checkFunctionArguments();
|
||||
@ -903,7 +989,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
Node arrayInitializer(YieldHandling yieldHandling);
|
||||
Node newRegExp();
|
||||
|
||||
Node objectLiteral(YieldHandling yieldHandling);
|
||||
Node objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError);
|
||||
|
||||
enum PrepareLexicalKind {
|
||||
PrepareLet,
|
||||
|
@ -1181,62 +1181,6 @@ function test_syntax(postfixes, check_error, ignore_opts) {
|
||||
test("for each (let x in y ");
|
||||
test("for each (let x in y) ");
|
||||
|
||||
// Legacy array comprehensions
|
||||
|
||||
test("[x ");
|
||||
test("[x for ");
|
||||
test("[x for ( ");
|
||||
test("[x for (x ");
|
||||
test("[x for (x of ");
|
||||
test("[x for (x of y ");
|
||||
test("[x for (x of y) ");
|
||||
test("[x for (x of y) if ");
|
||||
test("[x for (x of y) if ( ");
|
||||
test("[x for (x of y) if (x ");
|
||||
test("[x for (x of y) if (x == ");
|
||||
test("[x for (x of y) if (x == 1 ");
|
||||
test("[x for (x of y) if (x == 1) ");
|
||||
test("[x for (x of y) if (x == 1)] ");
|
||||
|
||||
test("[x for (x in ");
|
||||
test("[x for (x in y ");
|
||||
test("[x for (x in y) ");
|
||||
|
||||
test("[x for each ");
|
||||
test("[x for each ( ");
|
||||
test("[x for each (x ");
|
||||
test("[x for each (x in ");
|
||||
test("[x for each (x in y ");
|
||||
test("[x for each (x in y) ");
|
||||
|
||||
// Generator expressions
|
||||
|
||||
test("(x ");
|
||||
test("(x for ");
|
||||
test("(x for ( ");
|
||||
test("(x for (x ");
|
||||
test("(x for (x of ");
|
||||
test("(x for (x of y ");
|
||||
test("(x for (x of y) ");
|
||||
test("(x for (x of y) if ");
|
||||
test("(x for (x of y) if ( ");
|
||||
test("(x for (x of y) if (x ");
|
||||
test("(x for (x of y) if (x == ");
|
||||
test("(x for (x of y) if (x == 1 ");
|
||||
test("(x for (x of y) if (x == 1) ");
|
||||
test("(x for (x of y) if (x == 1)) ");
|
||||
|
||||
test("(x for (x in ");
|
||||
test("(x for (x in y ");
|
||||
test("(x for (x in y) ");
|
||||
|
||||
test("(x for each ");
|
||||
test("(x for each ( ");
|
||||
test("(x for each (x ");
|
||||
test("(x for each (x in ");
|
||||
test("(x for each (x in y ");
|
||||
test("(x for each (x in y) ");
|
||||
|
||||
// asm.js
|
||||
|
||||
test("(function() { 'use asm'; ");
|
||||
|
@ -1,4 +0,0 @@
|
||||
function f1(g=((function () { return 4; }) for (x of [1]))) {
|
||||
return g.next()();
|
||||
}
|
||||
assertEq(f1(), 4);
|
@ -1,35 +1,41 @@
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
function f1(f=(function () { return typeof this !== "object"; })) { "use strict"; return f; }
|
||||
eval(`"use strict";
|
||||
function f1(f=(function () { return typeof this !== "object"; })) { return f; }
|
||||
assertEq(f1()(), true);
|
||||
`);
|
||||
|
||||
function f2(f=(function () { "use strict"; return (function () { return typeof this !== "object"; }) })) { assertEq(typeof this, "object"); return f; }
|
||||
assertEq(f2()()(), true);
|
||||
function f3(f=(function () { return (function () { return typeof this !== "object"; }) })) { "use strict"; return f; }
|
||||
|
||||
eval(`"use strict";
|
||||
function f3(f=(function () { return (function () { return typeof this !== "object"; }) })) { return f; }
|
||||
assertEq(f3()()(), true);
|
||||
`);
|
||||
|
||||
// These should be okay.
|
||||
function f4(f=(function () { with (Object) {} }), g=(function () { "use strict"; })) {}
|
||||
function f5(g=(function () { "use strict"; }), f=(function () { with (Object) {} })) {}
|
||||
function f6(f=(function () { return (x for (y in (function g() {}))); })) {}
|
||||
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a=delete x) { 'use strict'; }");
|
||||
eval("'use strict'; function f(a=delete x) { }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
Math.sin(4);
|
||||
eval("function f(a='\\251') { 'use strict'; }");
|
||||
eval("'use strict'; function f(a='\\251') { }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a='\\251', b=delete x) { 'use strict'; }");
|
||||
eval("'use strict'; function f(a='\\251', b=delete x) { }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a=delete x, b='\\251') { 'use strict'; }");
|
||||
eval("'use strict'; function f(a=delete x, b='\\251') { }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a=(function () { '\\251'; })) { 'use strict'; }");
|
||||
eval("'use strict'; function f(a=(function () { '\\251'; })) { }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a=(function () { with (Object) {} })) { 'use strict'; }");
|
||||
eval("'use strict'; function f(a=(function () { with (Object) {} })) { }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a=(function (b, b) {})) { 'use strict'; }");
|
||||
eval("'use strict'; function f(a=(function (b, b) {})) { }");
|
||||
}, SyntaxError);
|
||||
|
@ -1,7 +0,0 @@
|
||||
// No 'arguments' binding in genexprs at toplevel.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
delete this.arguments; // it is defined in the shell
|
||||
var iter = (arguments for (x of [1]));
|
||||
assertThrowsInstanceOf(() => iter.next(), ReferenceError);
|
@ -1,4 +0,0 @@
|
||||
// 'arguments' is lexically scoped in genexprs at toplevel.
|
||||
|
||||
var arguments = 8;
|
||||
assertEq((arguments for (x of [1])).next(), 8);
|
@ -1,6 +0,0 @@
|
||||
// 'arguments' is lexically scoped in genexpr in toplevel let-block.
|
||||
|
||||
{
|
||||
let arguments = [];
|
||||
assertEq((arguments for (p in {a: 1})).next(), arguments);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
// 'arguments' is lexically scoped in genexpr in function.
|
||||
|
||||
function f() {
|
||||
assertEq((arguments for (x of [0])).next(),
|
||||
(arguments for (y of [1])).next());
|
||||
}
|
||||
f();
|
@ -1,8 +0,0 @@
|
||||
// 'arguments' binding can be closed over and outlives the function activation.
|
||||
|
||||
function f() {
|
||||
return (arguments for (x of [1]));
|
||||
}
|
||||
|
||||
var args = f("ponies").next();
|
||||
assertEq(args[0], "ponies");
|
@ -1,12 +0,0 @@
|
||||
// 'arguments' works in nested genexprs.
|
||||
|
||||
function f() {
|
||||
return ((((((arguments for (u of [0]))
|
||||
for (v of [1]))
|
||||
for (w of [2]))
|
||||
for (x of [3]))
|
||||
for (y of [4]))
|
||||
for (z of [5]));
|
||||
}
|
||||
var args = f("ponies").next().next().next().next().next().next();
|
||||
assertEq(args[0], "ponies");
|
@ -1,13 +0,0 @@
|
||||
// |jit-test| error:TypeError
|
||||
|
||||
// Binary: cache/js-dbg-32-86c8e18f20eb-linux
|
||||
// Flags:
|
||||
//
|
||||
(function(){
|
||||
for each (var x in new (
|
||||
(function (){x})()
|
||||
for each (y in [])
|
||||
)
|
||||
)
|
||||
{const functional=undefined}
|
||||
})()
|
@ -1,4 +0,0 @@
|
||||
// Binary: cache/js-dbg-64-55b6298ff619-linux
|
||||
// Flags:
|
||||
//
|
||||
for(let x in []) {((x = [] for(x in [])) for(y in 0))}
|
@ -1,9 +0,0 @@
|
||||
// Binary: cache/js-dbg-32-b22e82ce2364-linux
|
||||
// Flags: -j
|
||||
//
|
||||
x = (w for (x in []))
|
||||
for (w in [0, 0, 0, 0]) {
|
||||
(function() {
|
||||
[c for (z in x)]
|
||||
})()
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
// Binary: cache/js-dbg-32-e0fc487c23f4-linux
|
||||
// Flags: -j
|
||||
//
|
||||
try {
|
||||
for (window = (0
|
||||
for (x in V)); f;) {}
|
||||
} catch(e) {}
|
||||
for each(let z in [0, 0, 0, 0, 0, 0, 0, 0, 0]) {
|
||||
for (v in window) {}
|
||||
}
|
||||
var e, V
|
@ -1,18 +0,0 @@
|
||||
// Binary: cache/js-dbg-64-acf3c1fb7c94-linux
|
||||
// Flags:
|
||||
//
|
||||
|
||||
genexp = "x * x for (x in [])";
|
||||
genexpParened = "(" + genexp + ")";
|
||||
needParens(2, "if (1, xx) { }");
|
||||
function needParens(section, pat, exp) {
|
||||
ft = pat.replace(/xx/, genexpParened);
|
||||
try {
|
||||
f = new Function(ft);
|
||||
} catch(e) { }
|
||||
overParenTest(section, f, exp);
|
||||
}
|
||||
function overParenTest(section, f, exp) {
|
||||
var uf = "" + f;
|
||||
if (uf.indexOf(genexpParened) != -1) { }
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
// Binary: cache/js-dbg-64-defbe00ca091-linux
|
||||
// Flags:
|
||||
//
|
||||
if (typeof disassemble == 'function') {
|
||||
disassemble(eval(("(function(){(a for each (e in b));})")));
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
// Binary: cache/js-dbg-32-0f66a7ecf8de-linux
|
||||
// Flags:
|
||||
//
|
||||
function n(b = ((function() {}), function() {
|
||||
(a for (r in [function() {}]))
|
||||
})) {}
|
@ -1,10 +0,0 @@
|
||||
Error.prototype.__proto__.p = 5;
|
||||
f = Function("return( \"\" <arguments for(w in[]))");
|
||||
for (i in f()) {}
|
||||
|
||||
(function() {
|
||||
for (a in (
|
||||
arguments for (l in [0])
|
||||
))
|
||||
{}
|
||||
})()
|
@ -1,10 +0,0 @@
|
||||
// 'this' in generator-expression in strict-mode toplevel
|
||||
// is the same as global 'this'.
|
||||
|
||||
"use strict";
|
||||
|
||||
var it1 = (this for (x of [0]));
|
||||
assertEq(it1.next(), this);
|
||||
|
||||
var it2 = (this for (x of (this for (y of (this for (z of [0]))))));
|
||||
assertEq(it2.next(), this);
|
@ -1,11 +0,0 @@
|
||||
// 'this' in escaping generator-expression in a method
|
||||
// is the same as 'this' in the enclosing method.
|
||||
|
||||
var obj = {
|
||||
f: function () {
|
||||
assertEq(this, obj);
|
||||
return (this for (x of [0]));
|
||||
}
|
||||
};
|
||||
|
||||
assertEq(obj.f().next(), obj);
|
@ -1,11 +0,0 @@
|
||||
// 'this' in escaping generator-expression in a method
|
||||
// is the same as 'this' in the enclosing method
|
||||
// even if the method does not otherwise use 'this'.
|
||||
|
||||
var obj = {
|
||||
f: function () {
|
||||
return (this for (x of [0]));
|
||||
}
|
||||
};
|
||||
|
||||
assertEq(obj.f().next(), obj);
|
@ -1,13 +0,0 @@
|
||||
// 'this' in a generator-expression non-strict function produces the expected
|
||||
// object.
|
||||
|
||||
Number.prototype.iters = function () {
|
||||
return [(this for (x of [0])),
|
||||
(this for (y of [0]))];
|
||||
};
|
||||
|
||||
var [a, b] = (3).iters();
|
||||
var three = a.next();
|
||||
assertEq(Object.prototype.toString.call(three), '[object Number]');
|
||||
assertEq(+three, 3);
|
||||
assertEq(b.next(), three);
|
@ -1,13 +0,0 @@
|
||||
|
||||
a = (function() {
|
||||
with({}) var x, arguments, arguments
|
||||
})()
|
||||
|
||||
b = (function() {
|
||||
with({}) {
|
||||
var x = Math, arguments
|
||||
({
|
||||
get: (1 for (x in [])),
|
||||
})
|
||||
}
|
||||
})()
|
@ -4,6 +4,7 @@ load(libdir + 'eqArrayHelper.js');
|
||||
|
||||
var arrayPattern = '[a = 1, b = 2, c = 3, d = 4, e = 5, f = 6]';
|
||||
var objectPattern = '{0: a = 1, 1: b = 2, 2: c = 3, 3: d = 4, 4: e = 5, 5: f = 6}';
|
||||
var objectPatternShorthand = '{a = 1, b = 2, c = 3, d = 4, e = 5, f = 6}';
|
||||
var nestedPattern = '{a: a = 1, b: [b = 2] = [], c: {c: [c]} = {c: [3]}, d: {d, e} = {d: 4, e: 5}, f: f = 6}';
|
||||
|
||||
function testAll(fn) {
|
||||
@ -17,6 +18,11 @@ function testAll(fn) {
|
||||
assertEqArray(fn(objectPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]);
|
||||
assertEqArray(fn(objectPattern, [0, false]), [0, false, 3, 4, 5, 6]);
|
||||
|
||||
assertEqArray(fn(objectPatternShorthand, {}), [1, 2, 3, 4, 5, 6]);
|
||||
assertEqArray(fn(objectPatternShorthand, {a: 2, b: 3, c: 4, d: 5, e: 6, f: 7, g: 8, h: 9}), [2, 3, 4, 5, 6, 7]);
|
||||
assertEqArray(fn(objectPatternShorthand, {a: undefined, b: 0, c: false, d: null, e: "", f: undefined}),
|
||||
[1, 0, false, null, "", 6]);
|
||||
assertEqArray(fn(objectPatternShorthand, {a: 0, b: false}), [0, false, 3, 4, 5, 6]);
|
||||
assertEqArray(fn(nestedPattern, {}), [1, 2, 3, 4, 5, 6]);
|
||||
assertEqArray(fn(nestedPattern, {a: 2, b: [], c: undefined}), [2, 2, 3, 4, 5, 6]);
|
||||
assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}}), [1, 3, 4, 4, 5, 6]);
|
||||
@ -175,5 +181,9 @@ if (defaultsSupportedInForVar) {
|
||||
b = undefined;
|
||||
for (let {1: c = 10} in " ") { b = c; }
|
||||
assertEq(b, 10);
|
||||
|
||||
b = undefined;
|
||||
for (let {c = 10} in " ") { b = c; }
|
||||
assertEq(b, 10);
|
||||
`)();
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
function getgen() {
|
||||
gen = getgen.caller;
|
||||
}
|
||||
var gen;
|
||||
(getgen() for (x of [1])).next();
|
||||
assertEq(gen.toSource(), "function genexp() {\n [generator expression]\n}");
|
||||
assertEq(gen.toString(), gen.toSource());
|
@ -1,6 +0,0 @@
|
||||
function outer() {
|
||||
(function() {x})
|
||||
assertEq(((function() {return x}) for (x in [42])).next()(), "0");
|
||||
var x;
|
||||
}
|
||||
outer();
|
@ -1,8 +0,0 @@
|
||||
var g = newGlobal();
|
||||
var dbg = new g.Debugger(this);
|
||||
|
||||
try {
|
||||
function f() {}
|
||||
(1 for (x in []))
|
||||
} catch (e) {}
|
||||
gc()
|
@ -1,5 +0,0 @@
|
||||
assertEq(((function() arguments) for (x in [1])).next()(42)[0], 42);
|
||||
assertEq(((function() {return arguments}) for (x in [1])).next()(42)[0], 42);
|
||||
assertEq(((function() {return arguments[0] + arguments[1]}) for (x in [1])).next()(41,1), 42);
|
||||
assertEq(((function() {return arguments[0] + (function() { return arguments[0]})(arguments[1])}) for (x in [1])).next()(41,1), 42);
|
||||
assertEq(((function() { var arguments = 3; return arguments}) for (x in [1])).next()(42), 3);
|
@ -179,6 +179,7 @@ isParseError('for (let [x, y, x] in o) {}');
|
||||
isParseError('for (let [x, [y, [x]]] in o) {}');
|
||||
|
||||
// for(let ... in ...) scoping bugs (bug 1069480)
|
||||
// XXX: ES6 now requires these to be ReferenceErrors; see the test from ESR52.
|
||||
test('for each (let [x, y] in x) {return x + y;}', [['ponies', '']], undefined);
|
||||
test('for each (let [{0: x, 1: y}, z] in x) {return x + y + z;}', [[['po','nies'], '']], undefined);
|
||||
test('for (let x in eval("x")) {return x;}', {ponies:true}, undefined);
|
||||
@ -190,18 +191,6 @@ test('try {for (let x in eval("throw x")) {}} catch (e) {return e;}', undefined,
|
||||
test('try {for each (let x in x) {eval("throw x");}} catch (e) {return e;}', ['ponies'], undefined);
|
||||
test('for each (let {x: y, y: x} in [{x: x, y: x}]) {return y;}', undefined, undefined);
|
||||
|
||||
// genexps
|
||||
test('return (i for (i in x)).next();', {ponies:true});
|
||||
test('return (eval("i") for (i in x)).next();', {ponies:true});
|
||||
test('return (eval("i") for (i in eval("x"))).next();', {ponies:true});
|
||||
test('try {return (eval("throw i") for (i in x)).next();} catch (e) {return e;}', {ponies:true});
|
||||
|
||||
// array comprehension
|
||||
test('return [i for (i in x)][0];', {ponies:true});
|
||||
test('return [eval("i") for (i in x)][0];', {ponies:true});
|
||||
test('return [eval("i") for (i in eval("x"))][0];', {ponies:true});
|
||||
test('try {return [eval("throw i") for (i in x)][0];} catch (e) {return e;}', {ponies:true});
|
||||
|
||||
// don't forget about switch craziness
|
||||
test('var y = 3;switch (function () {return eval("y");}()) {case 3:let y;return x;default:;}');
|
||||
test('switch (x) {case 3:let y;return 3;case 4:let z;return 4;default:return x;}');
|
||||
|
@ -21,14 +21,6 @@ test("for (let x in h()) ;", 'declarative');
|
||||
test("for (let x in {a:1}) h();", 'declarative');
|
||||
test("try { throw new Error; } catch (x) { h(x) }", 'declarative');
|
||||
test("'use strict'; eval('var z = 1; h();');", 'declarative');
|
||||
test("for (var x in [h(m) for (m in [1])]) ;", 'declarative');
|
||||
test("for (var x in (h(m) for (m in [1]))) ;", 'declarative');
|
||||
|
||||
// Since a generator-expression is effectively a function, the innermost scope
|
||||
// is a function scope, and thus declarative. Thanks to an odd design decision,
|
||||
// m is already in scope at the point of the call to h(). The answer here is
|
||||
// not all that important, but we shouldn't crash.
|
||||
test("for (var x in (0 for (m in h()))) ;", 'declarative');
|
||||
|
||||
dbg.onDebuggerStatement = function (frame) {
|
||||
assertEq(frame.eval("h(), 2 + 2;").return, 4);
|
||||
|
@ -40,5 +40,3 @@ test("function r(n) { for (var i = 0; i < n; i++) yield i; } debugger;",
|
||||
"S[S]");
|
||||
test("function* qux(n) { for (var i = 0; i < n; i++) yield i; } debugger;",
|
||||
"S[S]");
|
||||
test("var it = (3 for (p in obj)); debugger;",
|
||||
"S[S]");
|
||||
|
@ -52,9 +52,6 @@ test(function () { g.eval("function r(n) { for (var i=0;i<n;i++) yield i; }"); }
|
||||
// eval declaring a star generator
|
||||
test(function () { g.eval("function* sg(n) { for (var i=0;i<n;i++) yield i; }"); });
|
||||
|
||||
// eval with a generator-expression
|
||||
test(function () { g.eval("var it = (obj[p] for (p in obj));"); });
|
||||
|
||||
// eval creating several instances of a closure
|
||||
test(function () { g.eval("for (var i = 0; i < 7; i++)\n" +
|
||||
" obj = function () { return obj; };\n"); });
|
||||
|
@ -26,11 +26,3 @@ test("for ([a, b] of c) { a.m(b); }");
|
||||
// for-let-of
|
||||
test("for (let a of b) { f(a); }");
|
||||
test("for (let [a, b] of c) { a.m(b); }");
|
||||
|
||||
// array comprehensions
|
||||
test("return [a for (a of b)];");
|
||||
test("return [[b, a] for ([a, b] of c.items())];");
|
||||
|
||||
// generator expressions
|
||||
test("return (a for (a of b));");
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
// for-of can iterate over generator-iterators produced by generator-expressions.
|
||||
|
||||
function g() {
|
||||
yield 1;
|
||||
yield 2;
|
||||
}
|
||||
|
||||
var it = g();
|
||||
for (var i = 0; i < 10; i++) {
|
||||
let prev = it;
|
||||
it = (k + 1 for (k of prev));
|
||||
}
|
||||
|
||||
var arr = [v for (v of it)];
|
||||
assertEq(arr.join(), "11,12");
|
@ -1,15 +0,0 @@
|
||||
// |jit-test| error: TypeError
|
||||
|
||||
x = 2;
|
||||
|
||||
function tryItOut(c) {
|
||||
return eval("(function(){" + c + "})");
|
||||
}
|
||||
|
||||
function doit() {
|
||||
var f = tryItOut("((( \"\" \n for each (eval in [null, this, null, this, (1/0), new String('q'), new String('q'), null, null, null, new String('q'), new String('q'), new String('q'), null]) if (this)).eval(x = x)));");
|
||||
f();
|
||||
}
|
||||
|
||||
doit();
|
||||
|
13
js/src/jit-test/tests/tenfourfox/issue430.js
Normal file
13
js/src/jit-test/tests/tenfourfox/issue430.js
Normal file
@ -0,0 +1,13 @@
|
||||
function
|
||||
request(endpoint, {
|
||||
httpMethod = 'GET',
|
||||
params = {},
|
||||
resultAs = 'json',
|
||||
data = {}
|
||||
} = {}) {
|
||||
return resultAs;
|
||||
}
|
||||
|
||||
assertEq(request(), "json");
|
||||
assertEq(request(null, { httpMethod: 'POST' }), "json");
|
||||
assertEq(request(null, { resultAs: 'xml' }), "xml");
|
9
js/src/jit-test/tests/tenfourfox/test-new-generators.js
Normal file
9
js/src/jit-test/tests/tenfourfox/test-new-generators.js
Normal file
@ -0,0 +1,9 @@
|
||||
function* gen() {
|
||||
yield 1;
|
||||
yield 2;
|
||||
yield 3;
|
||||
}
|
||||
|
||||
var g = gen(); // "Generator { }"
|
||||
assertEq(g.next().value, 1);
|
||||
assertEq(g.next().value, 2);
|
102
js/src/tests/ecma_6/Object/destructuring-shorthand-defaults.js
Normal file
102
js/src/tests/ecma_6/Object/destructuring-shorthand-defaults.js
Normal file
@ -0,0 +1,102 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Ensure that the syntax used in shorthand destructuring with defaults
|
||||
// e.g. |{x=1, y=2} = {}| properly raises a syntax error within an object
|
||||
// literal. As per ES6 12.2.6 Object Initializer, "NOTE 3."
|
||||
|
||||
const SYNTAX_ERROR_STMTS = [
|
||||
// expressions
|
||||
"({x={}={}}),",
|
||||
"({y={x={}={}={}={}={}={}={}={}}={}}),",
|
||||
"({a=1, b=2, c=3, x=({}={})}),",
|
||||
"({x=1, y={z={1}}})",
|
||||
"({x=1} = {y=1});",
|
||||
"({x: y={z=1}}={})",
|
||||
"({x=1}),",
|
||||
"({z=1}={}, {w=2}, {e=3})=>{};",
|
||||
"({z={x=1}})=>{};",
|
||||
"({x = ({y=1}) => y})",
|
||||
"(({x=1})) => x",
|
||||
// declarations
|
||||
"let o = {x=1};",
|
||||
"var j = {x=1};",
|
||||
"var j = {x={y=1}}={};",
|
||||
"const z = {x=1};",
|
||||
"const z = {x={y=1}}={};",
|
||||
"const {x=1};",
|
||||
"const {x={y=33}}={};",
|
||||
"var {x=1};",
|
||||
"let {x=1};",
|
||||
"let x, y, {z=1}={}, {w=2}, {e=3};",
|
||||
// array initialization
|
||||
"[{x=1, y = ({z=2} = {})}];",
|
||||
// try/catch
|
||||
"try {throw 'a';} catch ({x={y=1}}) {}",
|
||||
// if/else
|
||||
"if ({k: 1, x={y=2}={}}) {}",
|
||||
"if (false) {} else if (true) { ({x=1}) }",
|
||||
// switch
|
||||
"switch ('c') { case 'c': ({x=1}); }",
|
||||
// for
|
||||
"for ({x=1}; 1;) {1}",
|
||||
"for ({x={y=2}}; 1;) {1}",
|
||||
"for (var x = 0; x < 2; x++) { ({x=1, y=2}) }",
|
||||
"for (let x=1;{x=1};){}",
|
||||
"for (let x=1;{x={y=2}};){}",
|
||||
"for (let x=1;1;{x=1}){}",
|
||||
"for (let x=1;1;{x={y=2}}){}",
|
||||
// while
|
||||
"while ({x=1}) {1};",
|
||||
"while ({x={y=2}}={}) {1};",
|
||||
// with
|
||||
"with ({x=1}) {};",
|
||||
"with ({x={y=3}={}}) {};",
|
||||
"with (Math) { ({x=1}) };"
|
||||
]
|
||||
|
||||
for (var stmt of SYNTAX_ERROR_STMTS) {
|
||||
assertThrowsInstanceOf(() => {
|
||||
eval(stmt);
|
||||
}, SyntaxError);
|
||||
}
|
||||
|
||||
const REFERENCE_ERROR_STMTS = [
|
||||
"({x} += {});",
|
||||
"({x = 1}) = {x: 2};",
|
||||
]
|
||||
|
||||
for (var stmt of REFERENCE_ERROR_STMTS) {
|
||||
assertThrowsInstanceOf(() => {
|
||||
eval(stmt);
|
||||
}, ReferenceError);
|
||||
}
|
||||
|
||||
// A few tricky but acceptable cases:
|
||||
// see https://bugzilla.mozilla.org/show_bug.cgi?id=932080#c2
|
||||
|
||||
assertEq((({a = 0}) => a)({}), 0);
|
||||
assertEq((({a = 0} = {}) => a)({}), 0);
|
||||
assertEq((({a = 0} = {}) => a)({a: 1}), 1);
|
||||
|
||||
{
|
||||
let x, y;
|
||||
({x=1} = {});
|
||||
assertEq(x, 1);
|
||||
({x=1} = {x: 4});
|
||||
assertEq(x, 4);
|
||||
({x=1, y=2} = {})
|
||||
assertEq(x, 1);
|
||||
assertEq(y, 2);
|
||||
}
|
||||
|
||||
{
|
||||
let {x={i=1, j=2}={}}={};
|
||||
assertDeepEq(x, ({}));
|
||||
assertEq(i, 1);
|
||||
assertEq(j, 2);
|
||||
}
|
||||
|
||||
if (typeof reportCompare == "function")
|
||||
reportCompare(true, true);
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
* Contributor:
|
||||
* Jeff Walden <jwalden+code@mit.edu>
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 721322;
|
||||
var summary = 'Allow f.arguments in generator expressions';
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
eval("(function() { return (f.arguments for (x in [1])); })()");
|
||||
eval("(function() { var f = { arguments: 12 }; return [f.arguments for (x in [1])]; })()");
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("Tests complete");
|
@ -1,30 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 380237;
|
||||
var summary = 'Decompilation of generator expressions';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f = function() { g = (d for (d in [0])); g.next(); };
|
||||
expect = 'function() { g = (d for (d in [0])); g.next(); }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
* Contributor: Jason Orendorff
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 452498;
|
||||
var summary = 'TM: upvar2 regression tests';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
// ------- Comment #52 From Jason Orendorff
|
||||
|
||||
// Crash in NoteLValue, called from BindDestructuringVar.
|
||||
// NoteLValue assumes pn->pn_lexdef is non-null, but here
|
||||
// pn is itself the definition of x.
|
||||
for (var [x] in null) ;
|
||||
|
||||
// This one only crashes when executed from a file.
|
||||
// Assertion failure: pn != dn->dn_uses, at ../jsparse.cpp:1131
|
||||
for (var f in null)
|
||||
;
|
||||
var f = 1;
|
||||
(f)
|
||||
|
||||
// Assertion failure: pnu->pn_cookie == FREE_UPVAR_COOKIE, at ../jsemit.cpp:1815
|
||||
// In EmitEnterBlock. x has one use, which is pnu here.
|
||||
// pnu is indeed a name, but pnu->pn_cookie is 0.
|
||||
try { eval('let (x = 1) { var x; }'); } catch(ex) {}
|
||||
|
||||
// Assertion failure: cg->upvars.lookup(atom), at ../jsemit.cpp:1992
|
||||
// atom="x", upvars is empty.
|
||||
(1 for each (x in x));
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 452498;
|
||||
var summary = 'TM: upvar2 regression tests';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
// =====
|
||||
|
||||
foo = "" + new Function("while(\u3056){let \u3056 = x}");
|
||||
|
||||
// =====
|
||||
|
||||
function a(){ let c; eval("let c, y"); }
|
||||
a();
|
||||
|
||||
// =====
|
||||
|
||||
try
|
||||
{
|
||||
{x: 1e+81 ? c : arguments}
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
|
||||
// =====
|
||||
|
||||
(function(q){return q;} for each (\u3056 in []))
|
||||
|
||||
// =====
|
||||
|
||||
function f(){ var c; eval("{var c = NaN, c;}"); }
|
||||
f();
|
||||
|
||||
// =====
|
||||
try
|
||||
{
|
||||
eval(
|
||||
' x\n' +
|
||||
' let(x) {\n' +
|
||||
' var x\n'
|
||||
);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
|
||||
// =====
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -44,34 +44,6 @@ function test()
|
||||
}
|
||||
g("for (var x = 0; x < 3; ++x)(new (function(){})());");
|
||||
|
||||
// =====
|
||||
|
||||
try
|
||||
{
|
||||
(function(){new (function ({}, x) { yield (x(1e-81) for (x4 in undefined)) })()})();
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
// =====
|
||||
|
||||
try
|
||||
{
|
||||
(function(){[(function ([y]) { })() for each (x in [])];})();
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
// =====
|
||||
|
||||
try
|
||||
{
|
||||
eval('(function(){for(var x2 = [function(id) { return id } for each (x in []) if ([])] in functional) function(){};})();');
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
|
||||
// =====
|
||||
try
|
||||
{
|
||||
@ -104,21 +76,6 @@ function test()
|
||||
var f = new Function("[] = [( '' )()];");
|
||||
"" + f;
|
||||
|
||||
// =====
|
||||
|
||||
try
|
||||
{
|
||||
eval(
|
||||
'for(let x;' +
|
||||
' ([,,,]' +
|
||||
' .toExponential(new Function(), (function(){}))); [] = {})' +
|
||||
' for(var [x, x] = * in this.__defineSetter__("", function(){}));'
|
||||
);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
|
||||
// =====
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
@ -1,31 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 452498;
|
||||
var summary = 'TM: upvar2 regression tests';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
// ------- Comment #98 From Gary Kwong [:nth10sd]
|
||||
|
||||
uneval(function(){(Number(0) for each (NaN in []) for each (x4 in this))});
|
||||
// Assertion failure: pos == 0, at ../jsopcode.cpp:2963
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 452498;
|
||||
var summary = 'TM: upvar2 regression tests';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
// ------- Comment #99 From Gary Kwong [:nth10sd]
|
||||
|
||||
try
|
||||
{
|
||||
eval("(function x(){x.(this)} )();");
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
|
||||
// Assertion failure: (uint32_t)(index_) < atoms_->length, at ../jsinterp.cpp:327
|
||||
// Crash [@ js_FullTestPropertyCache] at null in opt, -j not required.
|
||||
|
||||
// =====
|
||||
|
||||
try
|
||||
{
|
||||
(function(){try {x} finally {}; ([x in []] for each (x in x))})();
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
|
||||
// Assertion failure: lexdep->frameLevel() <= funbox->level, at ../jsparse.cpp:1735
|
||||
// Crash [@ BindNameToSlot] near null in opt, -j not required.
|
||||
|
||||
// =====
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -55,24 +55,6 @@ function test()
|
||||
}
|
||||
// Assertion failure: regs.sp == StackBase(fp), at ../jsinterp.cpp:2984
|
||||
|
||||
// =====
|
||||
try
|
||||
{
|
||||
do {x} while([[] for (x in []) ]);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
// Assertion failure: !(pnu->pn_dflags & PND_BOUND), at ../jsemit.cpp:1818
|
||||
// =====
|
||||
|
||||
try
|
||||
{
|
||||
{x} ((x=[] for (x in []))); x;
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
// Assertion failure: cg->staticLevel >= level, at ../jsemit.cpp:2014
|
||||
// Crash [@ BindNameToSlot] in opt without -j
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 452498;
|
||||
var summary = 'TM: upvar2 regression tests';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
// ------- Comment #130 From Gary Kwong [:nth10sd]
|
||||
|
||||
// Does not require -j:
|
||||
// =====
|
||||
((function x()x in []) for (y in []))
|
||||
|
||||
// Assertion failure: !(pnu->pn_dflags & PND_BOUND), at ../jsemit.cpp:1818
|
||||
// =====
|
||||
|
||||
|
||||
// Requires -j:
|
||||
// =====
|
||||
for (var x = 0; x < 3; ++x) { new function(){} }
|
||||
|
||||
// Assertion failure: cx->bailExit, at ../jstracer.cpp:4672
|
||||
// Opt crash [@ LeaveTree] near null
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -32,34 +32,6 @@ function test()
|
||||
}
|
||||
}
|
||||
|
||||
// Assertion failure: fp2->fun && fp2->script, at ../jsinterp.cpp:5633
|
||||
// Opt crash [@ js_Interpret]
|
||||
// ===
|
||||
|
||||
try
|
||||
{
|
||||
(x for each (c in []))
|
||||
x
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
|
||||
// Assertion failure: ss->printer->pcstack, at ../jsopcode.cpp:909
|
||||
// ===
|
||||
try
|
||||
{
|
||||
(function(){for(; (this); ((window for (x in [])) for (y in []))) 0});
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
// Assertion failure: level >= tc->staticLevel, at ../jsparse.cpp:5773
|
||||
// ===
|
||||
eval(uneval( function(){
|
||||
((function()y)() for each (x in this))
|
||||
} ))
|
||||
|
||||
// Debug & opt crash [@ BindNameToSlot]
|
||||
|
||||
// -j is required:
|
||||
|
@ -1,44 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 452498;
|
||||
var summary = 'TM: upvar2 regression tests';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
// ------- Comment #138 From Gary Kwong [:nth10sd]
|
||||
|
||||
// Does not require -j:
|
||||
// ===
|
||||
((function x(){ yield (x = undefined) } ) for (y in /x/));
|
||||
|
||||
// Assertion failure: lexdep->frameLevel() <= funbox->level, at ../jsparse.cpp:1820
|
||||
// ===
|
||||
try
|
||||
{
|
||||
for(let x in ( x for (y in x) for each (x in []) )) y;
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
// Assertion failure: cg->upvars.lookup(atom), at ../jsemit.cpp:2034
|
||||
// ===
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 507424;
|
||||
var summary = 'TM: assert with regexp literal inside closure'
|
||||
var actual = '';
|
||||
var expect = 'do not crash';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
start_test();
|
||||
jit(true);
|
||||
|
||||
(new Function("'a'.replace(/a/,function(x){return(/x/ for each(y in[x]))})"))();
|
||||
|
||||
jit(false);
|
||||
actual = 'do not crash'
|
||||
finish_test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function start_test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
}
|
||||
|
||||
function finish_test()
|
||||
{
|
||||
reportCompare(expect, actual, summary);
|
||||
exitFunc ('test');
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
var it = (x for (x in [function(){}]));
|
||||
it.next();
|
||||
|
||||
reportCompare("no assertion failure", "no assertion failure", "See bug 515885.");
|
@ -1,38 +0,0 @@
|
||||
// |reftest| skip-if(Android)
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
/*
|
||||
* In strict mode, generator expressions may not locally bind 'eval'
|
||||
* or 'arguments.'
|
||||
*/
|
||||
assertEq(testLenientAndStrict('(1 for (eval in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(1 for ([eval] in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(1 for ({x:eval} in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(1 for (arguments in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(1 for ([arguments] in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(1 for ({x:arguments} in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
reportCompare(true, true);
|
@ -1,23 +0,0 @@
|
||||
// -*- indent-tabs-mode: nil; js-indent-level: 4 -*-
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
var x = 42;
|
||||
function a() {
|
||||
var x;
|
||||
function b() {
|
||||
x = 43;
|
||||
// When jsparse.cpp's CompExprTransplanter transplants the
|
||||
// comprehension expression 'x' into the scope of the 'for' loop,
|
||||
// it must not bring the placeholder definition node for the
|
||||
// assignment to x above along with it. If it does, x won't appear
|
||||
// in b's lexdeps, we'll never find out that the assignment refers
|
||||
// to a's x, and we'll generate an assignment to the global x.
|
||||
(x for (x in []));
|
||||
}
|
||||
b();
|
||||
}
|
||||
a();
|
||||
assertEq(x, 42);
|
||||
|
||||
reportCompare(true, true);
|
@ -39,8 +39,6 @@ assertGlobalExpr("(function() { })", 11, { functionExpression: () => 11 });
|
||||
assertGlobalExpr("[1,2,3]", 12, { arrayExpression: () => 12 });
|
||||
assertGlobalExpr("({ x: y })", 13, { objectExpression: () => 13 });
|
||||
assertGlobalExpr("this", 14, { thisExpression: () => 14 });
|
||||
assertGlobalExpr("[x for (x in y)]", 17, { comprehensionExpression: () => 17 });
|
||||
assertGlobalExpr("(x for (x in y))", 18, { generatorExpression: () => 18 });
|
||||
assertGlobalExpr("(function() { yield 42 })", genFunExpr("legacy", null, [], blockStmt([exprStmt(19)])), { yieldExpression: () => 19 });
|
||||
|
||||
assertGlobalStmt("switch (x) { case y: }", switchStmt(ident("x"), [1]), { switchCase: () => 1 });
|
||||
@ -50,9 +48,6 @@ assertGlobalStmt("try { } catch (e) { }", tryStmt(blockStmt([]), [], 2, null), {
|
||||
assertGlobalStmt("try { } catch (e if e instanceof A) { } catch (e if e instanceof B) { }",
|
||||
tryStmt(blockStmt([]), [2, 2], null, null),
|
||||
{ catchClause: () => 2 });
|
||||
assertGlobalExpr("[x for (y in z) for (x in y)]",
|
||||
compExpr(ident("x"), [3, 3], null, "legacy"),
|
||||
{ comprehensionBlock: () => 3 });
|
||||
|
||||
assertGlobalExpr("({ x: y } = z)", aExpr("=", 1, ident("z")), { objectPattern: () => 1 });
|
||||
assertGlobalExpr("({ x: y } = z)", aExpr("=", objPatt([2]), ident("z")), { propertyPattern: () => 2 });
|
||||
|
@ -1,79 +1,33 @@
|
||||
// |reftest| skip-if(!xulRuntime.shell)
|
||||
function test() {
|
||||
|
||||
// generator expressions
|
||||
|
||||
assertExpr("( x for (x in foo))",
|
||||
genExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], null, "legacy"));
|
||||
assertExpr("( [x,y] for (x in foo) for (y in bar))",
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], null, "legacy"));
|
||||
assertExpr("( [x,y,z] for (x in foo) for (y in bar) for (z in baz))",
|
||||
genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))],
|
||||
null,
|
||||
"legacy"));
|
||||
|
||||
assertExpr("( x for (x in foo) if (p))",
|
||||
genExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], ident("p"), "legacy"));
|
||||
assertExpr("( [x,y] for (x in foo) for (y in bar) if (p))",
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], ident("p"), "legacy"));
|
||||
assertExpr("( [x,y,z] for (x in foo) for (y in bar) for (z in baz) if (p) )",
|
||||
genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))],
|
||||
ident("p"),
|
||||
"legacy"));
|
||||
|
||||
assertExpr("( x for each (x in foo))",
|
||||
genExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], null, "legacy"));
|
||||
assertExpr("( [x,y] for each (x in foo) for each (y in bar))",
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], null, "legacy"));
|
||||
assertExpr("( [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz))",
|
||||
genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))],
|
||||
null,
|
||||
"legacy"));
|
||||
|
||||
assertExpr("( x for each (x in foo) if (p))",
|
||||
genExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], ident("p"), "legacy"));
|
||||
assertExpr("( [x,y] for each (x in foo) for each (y in bar) if (p))",
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], ident("p"), "legacy"));
|
||||
assertExpr("( [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz) if (p) )",
|
||||
genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))],
|
||||
ident("p"),
|
||||
"legacy"));
|
||||
|
||||
// Generator expressions using for-of can be written in two different styles.
|
||||
function assertLegacyAndModernGenExpr(expr, body, blocks, filter) {
|
||||
assertExpr(expr, genExpr(body, blocks, filter, "legacy"));
|
||||
|
||||
// Transform the legacy genexpr to a modern genexpr and test it that way
|
||||
// too.
|
||||
// Translate legacy genexprs into less legacy genexprs and test them.
|
||||
function assertFormerlyES6GenExpr(expr, body, blocks, filter) {
|
||||
let match = expr.match(/^\((.*?) for (.*)\)$/);
|
||||
assertEq(match !== null, true);
|
||||
let expr2 = "(for " + match[2] + " " + match[1] + ")";
|
||||
assertExpr(expr2, genExpr(body, blocks, filter, "modern"));
|
||||
}
|
||||
|
||||
assertLegacyAndModernGenExpr("( x for (x of foo))",
|
||||
ident("x"), [compOfBlock(ident("x"), ident("foo"))], null);
|
||||
assertLegacyAndModernGenExpr("( [x,y] for (x of foo) for (y of bar))",
|
||||
arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null);
|
||||
assertLegacyAndModernGenExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz))",
|
||||
arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
null);
|
||||
assertFormerlyES6GenExpr("( x for (x of foo))",
|
||||
ident("x"), [compOfBlock(ident("x"), ident("foo"))], null);
|
||||
assertFormerlyES6GenExpr("( [x,y] for (x of foo) for (y of bar))",
|
||||
arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null);
|
||||
assertFormerlyES6GenExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz))",
|
||||
arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
null);
|
||||
|
||||
assertLegacyAndModernGenExpr("( x for (x of foo) if (p))",
|
||||
ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p"));
|
||||
assertLegacyAndModernGenExpr("( [x,y] for (x of foo) for (y of bar) if (p))",
|
||||
arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p"));
|
||||
assertLegacyAndModernGenExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) )",
|
||||
arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
ident("p"));
|
||||
assertFormerlyES6GenExpr("( x for (x of foo) if (p))",
|
||||
ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p"));
|
||||
assertFormerlyES6GenExpr("( [x,y] for (x of foo) for (y of bar) if (p))",
|
||||
arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p"));
|
||||
assertFormerlyES6GenExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) )",
|
||||
arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
ident("p"));
|
||||
|
||||
// Modern generator comprehension with multiple ComprehensionIf.
|
||||
// FormerlyES6 generator comprehension with multiple ComprehensionIf.
|
||||
|
||||
assertExpr("(for (x of foo) x)",
|
||||
genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], null, "modern"));
|
||||
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
/* Don't crash. */
|
||||
try {
|
||||
eval("function f(){}(((f)for(x in function(){}))())");
|
||||
var threwTypeError = false;
|
||||
} catch (x) {
|
||||
var threwTypeError = x instanceof TypeError;
|
||||
}
|
||||
assertEq(threwTypeError, true);
|
||||
|
||||
/* Properly bind f. */
|
||||
assertEq(eval("function f() {}; var i = (f for (f in [1])); uneval([n for (n in i)])"),
|
||||
'["0"]');
|
||||
|
||||
reportCompare(true, true);
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
var expect = true;
|
||||
var actual = expect;
|
||||
|
||||
function f() {
|
||||
'use strict';
|
||||
for (; false; (0 for each (t in eval("")))) { }
|
||||
}
|
||||
fs = "" + f;
|
||||
try {
|
||||
eval("(" + fs + ")");
|
||||
} catch (e) {
|
||||
actual = false;
|
||||
}
|
||||
|
||||
reportCompare(expect, actual, "ok");
|
Loading…
Reference in New Issue
Block a user