Skip to content
This repository has been archived by the owner on Oct 15, 2020. It is now read-only.

Commit

Permalink
deps: update ChakraCore to chakra-core/ChakraCore@0a1d70bb3c
Browse files Browse the repository at this point in the history
[MERGE #5471 @aneeshdk] Fixing an issue with super restriction state in undodefer case

Merge pull request #5471 from aneeshdk:users/aneeshd/SuperUndoDeferIssue

We currently store the status of whether super call is allowed or super property is allowed in the Parser. Because of this when we do an undodefer of a member function that state information gets lost. This change is to put that information in the function node itself and use it from there while parsing super references.

Reviewed-By: chakrabot <[email protected]>
  • Loading branch information
aneeshdk authored and kfarnung committed Jul 19, 2018
1 parent d5de45d commit 7fb22f8
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 77 deletions.
88 changes: 25 additions & 63 deletions deps/chakrashim/core/lib/Parser/Parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator
m_funcInArray(0),
m_scopeCountNoAst(0),

m_parsingSuperRestrictionState(ParsingSuperRestrictionState_SuperDisallowed),

m_funcParenExprDepth(0),
m_deferEllipsisError(false),
m_deferEllipsisErrorLoc(), // calls default initializer
Expand Down Expand Up @@ -329,11 +327,6 @@ HRESULT Parser::ParseSourceInternal(

try
{
if ((grfscr & fscrEvalCode) != 0)
{
this->m_parsingSuperRestrictionState = Parser::ParsingSuperRestrictionState_SuperPropertyAllowed;
}

if ((grfscr & fscrIsModuleCode) != 0)
{
// Module source flag should not be enabled unless module is enabled
Expand Down Expand Up @@ -961,6 +954,7 @@ ParseNodeProg * Parser::CreateProgNode(bool isModuleSource, ULONG lineNumber)
pnodeProg->cbMin = this->GetScanner()->IecpMinTok();
pnodeProg->lineNumber = lineNumber;
pnodeProg->homeObjLocation = Js::Constants::NoRegister;
pnodeProg->superRestrictionState = SuperRestrictionState::Disallowed;
return pnodeProg;
}

Expand Down Expand Up @@ -3050,7 +3044,7 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
{
Assert((stub->fncFlags & kFunctionIsLambda) == kFunctionIsLambda);

pnode = ParseFncDeclCheckScope<true>(fFncLambda, /* resetParsingSuperRestrictionState*/ false);
pnode = ParseFncDeclCheckScope<true>(fFncLambda);
break;
}
}
Expand Down Expand Up @@ -3318,7 +3312,7 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
{
flags |= fFncAsync;
}
pnode = ParseFncDeclNoCheckScope<buildAST>(flags, pNameHint, false, true, fUnaryOrParen);
pnode = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::Disallowed, pNameHint, false, true, fUnaryOrParen);
if (isAsyncExpr)
{
pnode->AsParseNodeFnc()->cbMin = iecpMin;
Expand Down Expand Up @@ -4286,10 +4280,8 @@ ParseNodeBin * Parser::ParseMemberGetSet(OpCode nop, LPCOLESTR* ppNameHint)
flags |= fFncOneArg;
}

AutoParsingSuperRestrictionStateRestorer restorer(this);
this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(flags, *ppNameHint,
/*needsPIDOnRCurlyScan*/ false, /*resetParsingSuperRestrictionState*/ false);
ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::PropertyAllowed, *ppNameHint,
/*needsPIDOnRCurlyScan*/ false);

if (isComputedName)
{
Expand Down Expand Up @@ -4610,10 +4602,8 @@ ParseNodePtr Parser::ParseMemberList(LPCOLESTR pNameHint, uint32* pNameHintLengt
// Rewind to the PID and parse a function expression.
this->GetScanner()->SeekTo(atPid);

AutoParsingSuperRestrictionStateRestorer restorer(this);
this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags | (isAsyncMethod ? fFncAsync : fFncNoFlgs), pFullNameHint,
/*needsPIDOnRCurlyScan*/ false, /*resetParsingSuperRestrictionState*/ false);
ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags | (isAsyncMethod ? fFncAsync : fFncNoFlgs), SuperRestrictionState::PropertyAllowed, pFullNameHint,
/*needsPIDOnRCurlyScan*/ false);

if (isAsyncMethod || isGenerator)
{
Expand Down Expand Up @@ -4825,7 +4815,7 @@ BOOL Parser::IsDeferredFnc()
}

template<bool buildAST>
ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool resetParsingSuperRestrictionState, bool fAllowIn)
ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool fAllowIn)
{
ParseNodeBlock * pnodeFncBlockScope = nullptr;
ParseNodePtr *ppnodeScopeSave = nullptr;
Expand Down Expand Up @@ -4853,7 +4843,7 @@ ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool resetParsingSuperR
}
}

ParseNodeFnc * pnodeFnc = ParseFncDeclInternal<buildAST>(flags, nullptr, /* needsPIDOnRCurlyScan */ false, resetParsingSuperRestrictionState, /* fUnaryOrParen */ false, noStmtContext, fAllowIn);
ParseNodeFnc * pnodeFnc = ParseFncDeclInternal<buildAST>(flags, nullptr, /* needsPIDOnRCurlyScan */ false, /* fUnaryOrParen */ false, noStmtContext, SuperRestrictionState::Disallowed, fAllowIn);

if (pnodeFncBlockScope)
{
Expand All @@ -4872,22 +4862,15 @@ ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool resetParsingSuperR
}

template<bool buildAST>
ParseNodeFnc * Parser::ParseFncDeclNoCheckScope(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen, bool fAllowIn)
ParseNodeFnc * Parser::ParseFncDeclNoCheckScope(ushort flags, SuperRestrictionState::State superRestrictionState, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool fUnaryOrParen, bool fAllowIn)
{
Assert((flags & fFncDeclaration) == 0);
return ParseFncDeclInternal<buildAST>(flags, pNameHint, needsPIDOnRCurlyScan, resetParsingSuperRestrictionState, fUnaryOrParen, /* noStmtContext */ false, fAllowIn);
return ParseFncDeclInternal<buildAST>(flags, pNameHint, needsPIDOnRCurlyScan, fUnaryOrParen, /* noStmtContext */ false, superRestrictionState, fAllowIn);
}

template<bool buildAST>
ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen, bool noStmtContext, bool fAllowIn)
ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool fUnaryOrParen, bool noStmtContext, SuperRestrictionState::State superRestrictionState, bool fAllowIn)
{
AutoParsingSuperRestrictionStateRestorer restorer(this);
if (resetParsingSuperRestrictionState)
{
// ParseFncDecl will always reset m_parsingSuperRestrictionState to super disallowed unless explicitly disabled
this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperDisallowed;
}

ParseNodeFnc * pnodeFnc = nullptr;
ParseNodePtr *ppnodeVarSave = nullptr;

Expand Down Expand Up @@ -4923,6 +4906,7 @@ ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, c
pnodeFnc->nestedFuncEscapes = false;
pnodeFnc->cbMin = this->GetScanner()->IecpMinTok();
pnodeFnc->functionId = (*m_nextFunctionId)++;
pnodeFnc->superRestrictionState = superRestrictionState;


// Push new parser state with this new function node
Expand Down Expand Up @@ -6689,7 +6673,7 @@ void Parser::ParseFncFormals(ParseNodeFnc * pnodeFnc, ParseNodeFnc * pnodeParent
template<bool buildAST>
ParseNodePtr Parser::GenerateModuleFunctionWrapper()
{
ParseNodePtr pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fFncModule, nullptr, false, true, true);
ParseNodePtr pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fFncModule, SuperRestrictionState::Disallowed, nullptr, false, true, true);
ParseNodePtr callNode = CreateCallNode(knopCall, pnodeFnc, nullptr);

return callNode;
Expand Down Expand Up @@ -7378,24 +7362,6 @@ LPCOLESTR Parser::ConstructFinalHintNode(IdentPtr pClassName, IdentPtr pMemberNa
return pFinalName;
}

class AutoParsingSuperRestrictionStateRestorer
{
public:
AutoParsingSuperRestrictionStateRestorer(Parser* parser) : m_parser(parser)
{
AssertMsg(this->m_parser != nullptr, "This just should not happen");
this->m_originalParsingSuperRestrictionState = this->m_parser->m_parsingSuperRestrictionState;
}
~AutoParsingSuperRestrictionStateRestorer()
{
AssertMsg(this->m_parser != nullptr, "This just should not happen");
this->m_parser->m_parsingSuperRestrictionState = m_originalParsingSuperRestrictionState;
}
private:
Parser * m_parser;
int m_originalParsingSuperRestrictionState;
};

template<bool buildAST>
ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint, uint32 *pHintLength, uint32 *pShortNameOffset)
{
Expand Down Expand Up @@ -7604,12 +7570,11 @@ ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint,
}

{
AutoParsingSuperRestrictionStateRestorer restorer(this);
this->m_parsingSuperRestrictionState = hasExtends ? ParsingSuperRestrictionState_SuperCallAndPropertyAllowed : ParsingSuperRestrictionState_SuperPropertyAllowed;
SuperRestrictionState::State state = hasExtends ? SuperRestrictionState::CallAndPropertyAllowed : SuperRestrictionState::PropertyAllowed;

// Add the class constructor flag and base class constructor flag if pnodeExtends is nullptr
fncDeclFlags |= fFncClassConstructor | (hasExtends ? kFunctionNone : fFncBaseClassConstructor);
pnodeConstructor = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, pConstructorName, /* needsPIDOnRCurlyScan */ true, /* resetParsingSuperRestrictionState = */false);
pnodeConstructor = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, state, pConstructorName, /* needsPIDOnRCurlyScan */ true);
}

if (pnodeConstructor->IsGenerator())
Expand Down Expand Up @@ -7671,11 +7636,8 @@ ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint,

ParseNodeFnc * pnodeFnc = nullptr;
{
AutoParsingSuperRestrictionStateRestorer restorer(this);
this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags | (isGetter ? fFncNoArg : fFncOneArg),
pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true,
/* resetParsingSuperRestrictionState */false);
SuperRestrictionState::PropertyAllowed, pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true);
}

pnodeFnc->SetIsStaticMember(isStatic);
Expand Down Expand Up @@ -7703,14 +7665,11 @@ ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint,

ParseNodeFnc * pnodeFnc = nullptr;
{
AutoParsingSuperRestrictionStateRestorer restorer(this);
this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;

if (isAsyncMethod)
{
fncDeclFlags |= fFncAsync;
}
pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true, /* resetParsingSuperRestrictionState */false);
pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, SuperRestrictionState::PropertyAllowed, pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true);
if (isAsyncMethod)
{
pnodeFnc->cbMin = iecpMin;
Expand Down Expand Up @@ -8823,7 +8782,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
this->GetScanner()->SeekTo(termStart);
}
}
pnode = ParseFncDeclNoCheckScope<buildAST>(flags, nullptr, /* needsPIDOnRCurlyScan = */false, /* resetParsingSuperRestrictionState = */false, /* fUnaryOrParen = */ false, fAllowIn);
pnode = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::Disallowed, nullptr, /* needsPIDOnRCurlyScan = */false, /* fUnaryOrParen = */ false, fAllowIn);
if (isAsyncMethod)
{
pnode->AsParseNodeFnc()->cbMin = iecpMin;
Expand Down Expand Up @@ -11466,7 +11425,7 @@ ParseNodeProg * Parser::Parse(LPCUTF8 pszSrc, size_t offset, size_t length, char
flags |= fFncLambda;
}

ParseNode * pnodeFnc = ParseFncDeclCheckScope<true>(flags, /* resetParsingSuperRestrictionState*/ false);
ParseNode * pnodeFnc = ParseFncDeclCheckScope<true>(flags);
pnodeProg->pnodeBody = nullptr;
AddToNodeList(&pnodeProg->pnodeBody, &lastNodeRef, pnodeFnc);

Expand Down Expand Up @@ -12278,6 +12237,7 @@ template <bool buildAST>
IdentPtr Parser::ParseSuper(bool fAllowCall)
{
ParseNodeFnc * currentNodeFunc = GetCurrentFunctionNode();
ParseNodeFnc * currentNonLambdaFunc = GetCurrentNonLambdaFunctionNode();
IdentPtr superPid = nullptr;

switch (m_token.tk)
Expand Down Expand Up @@ -12309,12 +12269,14 @@ IdentPtr Parser::ParseSuper(bool fAllowCall)
{
Error(ERRInvalidSuper); // new super() is not allowed
}
else if (this->m_parsingSuperRestrictionState == ParsingSuperRestrictionState_SuperCallAndPropertyAllowed)
else if ((currentNodeFunc->IsConstructor() && currentNodeFunc->superRestrictionState == SuperRestrictionState::CallAndPropertyAllowed)
|| (currentNonLambdaFunc != nullptr && currentNonLambdaFunc->superRestrictionState == SuperRestrictionState::CallAndPropertyAllowed))
{
// Any super access is good within a class constructor
}
else if (this->m_parsingSuperRestrictionState == ParsingSuperRestrictionState_SuperPropertyAllowed)
else if ((this->m_grfscr & fscrEval) == fscrEval || currentNonLambdaFunc->superRestrictionState == SuperRestrictionState::PropertyAllowed)
{
// Currently for eval cases during compile time we use propertyallowed and throw during runtime for error cases
if (m_token.tk == tkLParen)
{
if ((this->m_grfscr & fscrEval) == fscrNil)
Expand Down
15 changes: 3 additions & 12 deletions deps/chakrashim/core/lib/Parser/Parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,15 +493,6 @@ class Parser
charcount_t m_funcInArray;
uint m_scopeCountNoAst;

/*
* Parsing states for super restriction
*/
static const uint ParsingSuperRestrictionState_SuperDisallowed = 0;
static const uint ParsingSuperRestrictionState_SuperCallAndPropertyAllowed = 1;
static const uint ParsingSuperRestrictionState_SuperPropertyAllowed = 2;
uint m_parsingSuperRestrictionState;
friend class AutoParsingSuperRestrictionStateRestorer;

// Used for issuing spread and rest errors when there is ambiguity with lambda parameter lists and parenthesized expressions
uint m_funcParenExprDepth;
bool m_deferEllipsisError;
Expand Down Expand Up @@ -829,9 +820,9 @@ class Parser

template<bool buildAST> void ParseComputedName(ParseNodePtr* ppnodeName, LPCOLESTR* ppNameHint, LPCOLESTR* ppFullNameHint = nullptr, uint32 *pNameLength = nullptr, uint32 *pShortNameOffset = nullptr);
template<bool buildAST> ParseNodeBin * ParseMemberGetSet(OpCode nop, LPCOLESTR* ppNameHint);
template<bool buildAST> ParseNode * ParseFncDeclCheckScope(ushort flags, bool resetParsingSuperRestrictionState = true, bool fAllowIn = true);
template<bool buildAST> ParseNodeFnc * ParseFncDeclNoCheckScope(ushort flags, LPCOLESTR pNameHint = nullptr, const bool needsPIDOnRCurlyScan = false, bool resetParsingSuperRestrictionState = true, bool fUnaryOrParen = false, bool fAllowIn = true);
template<bool buildAST> ParseNodeFnc * ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen, bool noStmtContext, bool fAllowIn = true);
template<bool buildAST> ParseNode * ParseFncDeclCheckScope(ushort flags, bool fAllowIn = true);
template<bool buildAST> ParseNodeFnc * ParseFncDeclNoCheckScope(ushort flags, SuperRestrictionState::State superRestrictionState = SuperRestrictionState::Disallowed, LPCOLESTR pNameHint = nullptr, const bool needsPIDOnRCurlyScan = false, bool fUnaryOrParen = false, bool fAllowIn = true);
template<bool buildAST> ParseNodeFnc * ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool fUnaryOrParen, bool noStmtContext, SuperRestrictionState::State superRestrictionState = SuperRestrictionState::Disallowed, bool fAllowIn = true);
template<bool buildAST> void ParseFncName(ParseNodeFnc * pnodeFnc, ushort flags, IdentPtr* pFncNamePid = nullptr);
template<bool buildAST> void ParseFncFormals(ParseNodeFnc * pnodeFnc, ParseNodeFnc * pnodeParentFnc, ushort flags, bool isTopLevelDeferredFunc = false);
template<bool buildAST> void ParseFncDeclHelper(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, ushort flags, bool fUnaryOrParen, bool noStmtContext, bool *pNeedScanRCurly, bool skipFormals = false, IdentPtr* pFncNamePid = nullptr, bool fAllowIn = true);
Expand Down
2 changes: 1 addition & 1 deletion deps/chakrashim/core/lib/Parser/ptree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,8 +433,8 @@ ParseNodeFnc::ParseNodeFnc(OpCode nop, charcount_t ichMin, charcount_t ichLim)
#endif
this->pRestorePoint = nullptr;
this->deferredStub = nullptr;

this->capturedNames = nullptr;
this->superRestrictionState = SuperRestrictionState::Disallowed;
}

ParseNodeClass::ParseNodeClass(OpCode nop, charcount_t ichMin, charcount_t ichLim)
Expand Down
10 changes: 10 additions & 0 deletions deps/chakrashim/core/lib/Parser/ptree.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,14 @@ enum FncFlags : uint
struct RestorePoint;
struct DeferredFunctionStub;

namespace SuperRestrictionState {
enum State {
Disallowed = 0,
CallAndPropertyAllowed = 1,
PropertyAllowed = 2
};
}

// function declaration
class ParseNodeFnc : public ParseNode
{
Expand Down Expand Up @@ -504,6 +512,8 @@ class ParseNodeFnc : public ParseNode

static const int32 MaxStackClosureAST = 800000;

SuperRestrictionState::State superRestrictionState;

static bool CanBeRedeferred(FncFlags flags) { return !(flags & (kFunctionIsGenerator | kFunctionIsAsync)); }

private:
Expand Down
19 changes: 19 additions & 0 deletions deps/chakrashim/core/test/Bugs/SuperUndoDeferIssue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

var obj = {
mSloppy() {
try {
super[
__v_12000] = 55;
} catch (__v_12004) {
}
try {
} catch (__v_12005) {
}
}
};
// There shouldn't be any SyntaxError
print("PASSED");
8 changes: 7 additions & 1 deletion deps/chakrashim/core/test/Bugs/rlexe.xml
Original file line number Diff line number Diff line change
Expand Up @@ -505,5 +505,11 @@
<default>
<files>bug_OS17614914.js</files>
</default>
</test>
</test>
<test>
<default>
<files>SuperUndoDeferIssue.js</files>
<compile-flags>-forceundodefer</compile-flags>
</default>
</test>
</regress-exe>

0 comments on commit 7fb22f8

Please sign in to comment.