diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index c1db6ef8ab2..d0604aaab8f 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -2990,7 +2990,7 @@ Parser::forStatement() pn->setOp(JSOP_ITER); pn->pn_iflags = 0; - if (tokenStream.matchToken(TOK_NAME)) { + if (allowsForEachIn() && tokenStream.matchToken(TOK_NAME)) { if (tokenStream.currentToken().name() == context->names().each) pn->pn_iflags = JSITER_FOREACH; else @@ -5119,7 +5119,7 @@ Parser::comprehensionTail(ParseNode *kid, unsigned blockid, bool isGenexp, pn2->setOp(JSOP_ITER); pn2->pn_iflags = JSITER_ENUMERATE; - if (tokenStream.matchToken(TOK_NAME)) { + if (allowsForEachIn() && tokenStream.matchToken(TOK_NAME)) { if (tokenStream.currentToken().name() == context->names().each) pn2->pn_iflags |= JSITER_FOREACH; else diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index f052304cfdf..510adfb697f 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -468,6 +468,16 @@ struct Parser : private AutoGCRooter ParseNode *propertyQualifiedIdentifier(); #endif /* JS_HAS_XML_SUPPORT */ + bool allowsForEachIn() { +#if !JS_HAS_FOR_EACH_IN + return false; +#elif JS_HAS_XML_SUPPORT + return allowsXML() || tokenStream.hasMoarXML(); +#else + return versionNumber() >= JSVERSION_1_6; +#endif + } + bool setAssignmentLhsOps(ParseNode *pn, JSOp op); bool matchInOrOf(bool *isForOfp); }; diff --git a/js/src/jsversion.h b/js/src/jsversion.h index 475525177a6..50e2fa6beb0 100644 --- a/js/src/jsversion.h +++ b/js/src/jsversion.h @@ -61,6 +61,7 @@ #define JS_HAS_CONST 0 /* has JS2 const as alternative var */ #define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */ #define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */ +#define JS_HAS_FOR_EACH_IN 0 /* has for each (lhs in iterable) */ #define JS_HAS_GENERATORS 0 /* has yield in generator function */ #define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycomp */ #define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = ... */ @@ -82,6 +83,7 @@ #define JS_HAS_CONST 1 /* has JS2 const as alternative var */ #define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */ #define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */ +#define JS_HAS_FOR_EACH_IN 0 /* has for each (lhs in iterable) */ #define JS_HAS_GENERATORS 0 /* has yield in generator function */ #define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycomp */ #define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = ... */ @@ -99,6 +101,7 @@ #define JS_HAS_CONST 1 /* has JS2 const as alternative var */ #define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */ #define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */ +#define JS_HAS_FOR_EACH_IN 1 /* has for each (lhs in iterable) */ #define JS_HAS_GENERATORS 0 /* has yield in generator function */ #define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycomp */ #define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = ... */ @@ -116,6 +119,7 @@ #define JS_HAS_CONST 1 /* has JS2 const as alternative var */ #define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */ #define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */ +#define JS_HAS_FOR_EACH_IN 1 /* has for each (lhs in iterable) */ #define JS_HAS_GENERATORS 1 /* has yield in generator function */ #define JS_HAS_BLOCK_SCOPE 1 /* has block scope via let/arraycomp */ #define JS_HAS_DESTRUCTURING 1 /* has [a,b] = ... or {p:a,q:b} = ... */ @@ -133,6 +137,7 @@ #define JS_HAS_CONST 1 /* has JS2 const as alternative var */ #define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */ #define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */ +#define JS_HAS_FOR_EACH_IN 1 /* has for each (lhs in iterable) */ #define JS_HAS_GENERATORS 1 /* has yield in generator function */ #define JS_HAS_BLOCK_SCOPE 1 /* has block scope via let/arraycomp */ #define JS_HAS_DESTRUCTURING 2 /* has [a,b] = ... or {p:a,q:b} = ... */