@@ -4852,7 +4852,7 @@ BOOL Parser::IsDeferredFnc()
4852
4852
}
4853
4853
4854
4854
template <bool buildAST>
4855
- ParseNode * Parser::ParseFncDeclCheckScope (ushort flags, bool resetParsingSuperRestrictionState)
4855
+ ParseNode * Parser::ParseFncDeclCheckScope (ushort flags, bool resetParsingSuperRestrictionState, bool fAllowIn )
4856
4856
{
4857
4857
ParseNodeBlock * pnodeFncBlockScope = nullptr ;
4858
4858
ParseNodePtr *ppnodeScopeSave = nullptr ;
@@ -4880,7 +4880,7 @@ ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool resetParsingSuperR
4880
4880
}
4881
4881
}
4882
4882
4883
- ParseNodeFnc * pnodeFnc = ParseFncDeclInternal<buildAST>(flags, nullptr , /* needsPIDOnRCurlyScan */ false , resetParsingSuperRestrictionState, /* fUnaryOrParen */ false , noStmtContext);
4883
+ ParseNodeFnc * pnodeFnc = ParseFncDeclInternal<buildAST>(flags, nullptr , /* needsPIDOnRCurlyScan */ false , resetParsingSuperRestrictionState, /* fUnaryOrParen */ false , noStmtContext, fAllowIn );
4884
4884
4885
4885
if (pnodeFncBlockScope)
4886
4886
{
@@ -4899,14 +4899,14 @@ ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool resetParsingSuperR
4899
4899
}
4900
4900
4901
4901
template <bool buildAST>
4902
- ParseNodeFnc * Parser::ParseFncDeclNoCheckScope (ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen )
4902
+ ParseNodeFnc * Parser::ParseFncDeclNoCheckScope (ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen , bool fAllowIn )
4903
4903
{
4904
4904
Assert ((flags & fFncDeclaration ) == 0 );
4905
- return ParseFncDeclInternal<buildAST>(flags, pNameHint, needsPIDOnRCurlyScan, resetParsingSuperRestrictionState, fUnaryOrParen , /* noStmtContext */ false );
4905
+ return ParseFncDeclInternal<buildAST>(flags, pNameHint, needsPIDOnRCurlyScan, resetParsingSuperRestrictionState, fUnaryOrParen , /* noStmtContext */ false , fAllowIn );
4906
4906
}
4907
4907
4908
4908
template <bool buildAST>
4909
- ParseNodeFnc * Parser::ParseFncDeclInternal (ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen , bool noStmtContext)
4909
+ ParseNodeFnc * Parser::ParseFncDeclInternal (ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen , bool noStmtContext, bool fAllowIn )
4910
4910
{
4911
4911
AutoParsingSuperRestrictionStateRestorer restorer (this );
4912
4912
if (resetParsingSuperRestrictionState)
@@ -4987,7 +4987,7 @@ ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, c
4987
4987
4988
4988
IdentPtr pFncNamePid = nullptr ;
4989
4989
bool needScanRCurly = true ;
4990
- ParseFncDeclHelper<buildAST>(pnodeFnc, pNameHint, flags, fUnaryOrParen , noStmtContext, &needScanRCurly, fModule , &pFncNamePid);
4990
+ ParseFncDeclHelper<buildAST>(pnodeFnc, pNameHint, flags, fUnaryOrParen , noStmtContext, &needScanRCurly, fModule , &pFncNamePid, fAllowIn );
4991
4991
AddNestedCapturedNames (pnodeFnc);
4992
4992
4993
4993
AnalysisAssert (pnodeFnc);
@@ -5159,7 +5159,7 @@ void Parser::AppendFunctionToScopeList(bool fDeclaration, ParseNodeFnc * pnodeFn
5159
5159
Parse a function definition.
5160
5160
***************************************************************************/
5161
5161
template <bool buildAST>
5162
- void Parser::ParseFncDeclHelper (ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, ushort flags, bool fUnaryOrParen , bool noStmtContext, bool *pNeedScanRCurly, bool skipFormals, IdentPtr* pFncNamePid)
5162
+ void Parser::ParseFncDeclHelper (ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, ushort flags, bool fUnaryOrParen , bool noStmtContext, bool *pNeedScanRCurly, bool skipFormals, IdentPtr* pFncNamePid, bool fAllowIn )
5163
5163
{
5164
5164
Assert (pnodeFnc);
5165
5165
ParseNodeFnc * pnodeFncParent = GetCurrentFunctionNode ();
@@ -5559,7 +5559,7 @@ void Parser::ParseFncDeclHelper(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, us
5559
5559
{
5560
5560
fDeferred = true ;
5561
5561
5562
- this ->ParseTopLevelDeferredFunc (pnodeFnc, pnodeFncSave, pNameHint, fLambda , pNeedScanRCurly);
5562
+ this ->ParseTopLevelDeferredFunc (pnodeFnc, pnodeFncSave, pNameHint, fLambda , pNeedScanRCurly, fAllowIn );
5563
5563
}
5564
5564
else
5565
5565
{
@@ -5594,13 +5594,13 @@ void Parser::ParseFncDeclHelper(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, us
5594
5594
m_currDeferredStubCount = childStub->nestedCount ;
5595
5595
m_currDeferredStub = childStub->deferredStubs ;
5596
5596
}
5597
- this ->FinishFncDecl (pnodeFnc, pNameHint, fLambda , skipFormals);
5597
+ this ->FinishFncDecl (pnodeFnc, pNameHint, fLambda , skipFormals, fAllowIn );
5598
5598
m_currDeferredStub = savedStub;
5599
5599
m_currDeferredStubCount = savedStubCount;
5600
5600
}
5601
5601
else
5602
5602
{
5603
- this ->ParseNestedDeferredFunc (pnodeFnc, fLambda , pNeedScanRCurly, &strictModeTurnedOn);
5603
+ this ->ParseNestedDeferredFunc (pnodeFnc, fLambda , pNeedScanRCurly, &strictModeTurnedOn, fAllowIn );
5604
5604
}
5605
5605
}
5606
5606
@@ -5789,7 +5789,7 @@ void Parser::UpdateCurrentNodeFunc(ParseNodeFnc * pnodeFnc, bool fLambda)
5789
5789
}
5790
5790
}
5791
5791
5792
- void Parser::ParseTopLevelDeferredFunc (ParseNodeFnc * pnodeFnc, ParseNodeFnc * pnodeFncParent, LPCOLESTR pNameHint, bool fLambda , bool *pNeedScanRCurly)
5792
+ void Parser::ParseTopLevelDeferredFunc (ParseNodeFnc * pnodeFnc, ParseNodeFnc * pnodeFncParent, LPCOLESTR pNameHint, bool fLambda , bool *pNeedScanRCurly, bool fAllowIn )
5793
5793
{
5794
5794
// Parse a function body that is a transition point from building AST to doing fast syntax check.
5795
5795
@@ -5826,7 +5826,7 @@ void Parser::ParseTopLevelDeferredFunc(ParseNodeFnc * pnodeFnc, ParseNodeFnc * p
5826
5826
// Their more-complicated text extents won't match the deferred-stub and the single expression should be fast to scan, anyway.
5827
5827
if (fLambda && !*pNeedScanRCurly)
5828
5828
{
5829
- ParseExpressionLambdaBody<false >(pnodeFnc);
5829
+ ParseExpressionLambdaBody<false >(pnodeFnc, fAllowIn );
5830
5830
}
5831
5831
else if (pnodeFncParent != nullptr && m_currDeferredStub != nullptr && !pnodeFncParent->HasDefaultArguments ())
5832
5832
{
@@ -6220,15 +6220,15 @@ ParseNodeFnc * Parser::CreateDummyFuncNode(bool fDeclaration)
6220
6220
return pnodeFnc;
6221
6221
}
6222
6222
6223
- void Parser::ParseNestedDeferredFunc (ParseNodeFnc * pnodeFnc, bool fLambda , bool *pNeedScanRCurly, bool *pStrictModeTurnedOn)
6223
+ void Parser::ParseNestedDeferredFunc (ParseNodeFnc * pnodeFnc, bool fLambda , bool *pNeedScanRCurly, bool *pStrictModeTurnedOn, bool fAllowIn )
6224
6224
{
6225
6225
// Parse a function nested inside another deferred function.
6226
6226
6227
6227
size_t lengthBeforeBody = this ->GetSourceLength ();
6228
6228
6229
6229
if (m_token.tk != tkLCurly && fLambda )
6230
6230
{
6231
- ParseExpressionLambdaBody<false >(pnodeFnc);
6231
+ ParseExpressionLambdaBody<false >(pnodeFnc, fAllowIn );
6232
6232
*pNeedScanRCurly = false ;
6233
6233
}
6234
6234
else
@@ -6855,7 +6855,7 @@ ParseNodeFnc * Parser::GenerateEmptyConstructor(bool extends)
6855
6855
}
6856
6856
6857
6857
template <bool buildAST>
6858
- void Parser::ParseExpressionLambdaBody (ParseNodeFnc * pnodeLambda)
6858
+ void Parser::ParseExpressionLambdaBody (ParseNodeFnc * pnodeLambda, bool fAllowIn )
6859
6859
{
6860
6860
ParseNodePtr *lastNodeRef = nullptr ;
6861
6861
@@ -6876,7 +6876,7 @@ void Parser::ParseExpressionLambdaBody(ParseNodeFnc * pnodeLambda)
6876
6876
// The scanner needs to create a pid in the case of a string constant token immediately following the lambda body expression.
6877
6877
// Otherwise, we'll save null for the string constant pid which will AV during ByteCode generation.
6878
6878
BYTE fScanDeferredFlagsSave = this ->GetScanner ()->SetDeferredParse (FALSE );
6879
- ParseNodePtr result = ParseExpr<buildAST>(koplAsg, nullptr , TRUE , FALSE , nullptr , nullptr , nullptr , &token, false , nullptr , &lastRParen);
6879
+ ParseNodePtr result = ParseExpr<buildAST>(koplAsg, nullptr , fAllowIn , FALSE , nullptr , nullptr , nullptr , &token, false , nullptr , &lastRParen);
6880
6880
this ->GetScanner ()->SetDeferredParseFlags (fScanDeferredFlagsSave );
6881
6881
6882
6882
this ->MarkEscapingRef (result, &token);
@@ -6974,7 +6974,7 @@ void Parser::CheckStrictFormalParameters()
6974
6974
Assert (m_token.tk == tkRParen);
6975
6975
}
6976
6976
6977
- void Parser::FinishFncNode (ParseNodeFnc * pnodeFnc)
6977
+ void Parser::FinishFncNode (ParseNodeFnc * pnodeFnc, bool fAllowIn )
6978
6978
{
6979
6979
AnalysisAssert (pnodeFnc);
6980
6980
@@ -7141,7 +7141,7 @@ void Parser::FinishFncNode(ParseNodeFnc * pnodeFnc)
7141
7141
const charcount_t ichLim = pnodeFnc->ichLim ;
7142
7142
const size_t cbLim = pnodeFnc->cbLim ;
7143
7143
7144
- this ->FinishFncDecl (pnodeFnc, NULL , fLambda );
7144
+ this ->FinishFncDecl (pnodeFnc, NULL , fLambda , /* skipCurlyBraces */ false , fAllowIn );
7145
7145
7146
7146
#if DBG
7147
7147
// The pnode extent may not match the original extent.
@@ -7174,7 +7174,7 @@ void Parser::FinishFncNode(ParseNodeFnc * pnodeFnc)
7174
7174
this ->GetScanner ()->SetAwaitIsKeywordRegion (fPreviousAwaitIsKeyword );
7175
7175
}
7176
7176
7177
- void Parser::FinishFncDecl (ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, bool fLambda , bool skipCurlyBraces)
7177
+ void Parser::FinishFncDecl (ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, bool fLambda , bool skipCurlyBraces, bool fAllowIn )
7178
7178
{
7179
7179
LPCOLESTR name = NULL ;
7180
7180
JS_ETW (int32 startAstSize = *m_pCurrentAstSize);
@@ -7196,7 +7196,7 @@ void Parser::FinishFncDecl(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, bool fL
7196
7196
7197
7197
if (fLambda && m_token.tk != tkLCurly)
7198
7198
{
7199
- ParseExpressionLambdaBody<true >(pnodeFnc);
7199
+ ParseExpressionLambdaBody<true >(pnodeFnc, fAllowIn );
7200
7200
}
7201
7201
else
7202
7202
{
@@ -8846,15 +8846,15 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
8846
8846
this ->GetScanner ()->SeekTo (termStart);
8847
8847
}
8848
8848
}
8849
- pnode = ParseFncDeclNoCheckScope<buildAST>(flags, nullptr , /* needsPIDOnRCurlyScan = */ false , /* resetParsingSuperRestrictionState = */ false );
8849
+ pnode = ParseFncDeclNoCheckScope<buildAST>(flags, nullptr , /* needsPIDOnRCurlyScan = */ false , /* resetParsingSuperRestrictionState = */ false , /* fUnaryOrParen = */ false , fAllowIn );
8850
8850
if (isAsyncMethod)
8851
8851
{
8852
8852
pnode->AsParseNodeFnc ()->cbMin = iecpMin;
8853
8853
pnode->ichMin = ichMin;
8854
8854
}
8855
8855
8856
8856
// ArrowFunction/AsyncArrowFunction is part of AssignmentExpression, which should terminate the expression unless followed by a comma
8857
- if (m_token.tk != tkComma)
8857
+ if (m_token.tk != tkComma && m_token. tk != tkIN )
8858
8858
{
8859
8859
if (!(IsTerminateToken ()))
8860
8860
{
0 commit comments