Skip to content

Commit 7f24991

Browse files
committed
[MERGE #5608 @boingoing] Use correct deferred stubs for functions declared in parameter scope of function expression
Merge pull request #5608 from boingoing:deferstub_saving_parameter_scope We failed to shift the deferred stubs down to those belonging to the child function when parsing the argument list of a function expression.
2 parents c4c2208 + 7a4826f commit 7f24991

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

lib/Parser/Parse.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5463,8 +5463,15 @@ void Parser::ParseFncDeclHelper(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, us
54635463
m_reparsingLambdaParams = true;
54645464
}
54655465

5466+
uint savedStubCount = m_currDeferredStubCount;
5467+
DeferredFunctionStub* savedStub = m_currDeferredStub;
5468+
ShiftCurrDeferredStubToChildFunction(pnodeFnc, pnodeFncParent);
5469+
54665470
this->ParseFncFormals<buildAST>(pnodeFnc, pnodeFncParent, flags, isTopLevelDeferredFunc);
54675471

5472+
m_currDeferredStub = savedStub;
5473+
m_currDeferredStubCount = savedStubCount;
5474+
54685475
m_reparsingLambdaParams = fLambdaParamsSave;
54695476
}
54705477

@@ -5637,13 +5644,10 @@ void Parser::ParseFncDeclHelper(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, us
56375644
}
56385645
uint savedStubCount = m_currDeferredStubCount;
56395646
DeferredFunctionStub* savedStub = m_currDeferredStub;
5640-
if (pnodeFnc->IsNested() && pnodeFncSave != nullptr && m_currDeferredStub != nullptr && pnodeFncSave->ichMin != pnodeFnc->ichMin)
5641-
{
5642-
DeferredFunctionStub* childStub = m_currDeferredStub + (pnodeFncSave->nestedCount - 1);
5643-
m_currDeferredStubCount = childStub->nestedCount;
5644-
m_currDeferredStub = childStub->deferredStubs;
5645-
}
5647+
ShiftCurrDeferredStubToChildFunction(pnodeFnc, pnodeFncSave);
5648+
56465649
this->FinishFncDecl(pnodeFnc, pNameHint, fLambda, skipFormals, fAllowIn);
5650+
56475651
m_currDeferredStub = savedStub;
56485652
m_currDeferredStubCount = savedStubCount;
56495653
}
@@ -14021,6 +14025,23 @@ bool Parser::IsCreatingStateCache()
1402114025
&& CONFIG_FLAG(ParserStateCache));
1402214026
}
1402314027

14028+
void Parser::ShiftCurrDeferredStubToChildFunction(ParseNodeFnc* pnodeFnc, ParseNodeFnc* pnodeFncParent)
14029+
{
14030+
// Goal here is to shift the current deferred stub to point to the stubs for pnodeFnc
14031+
// so we may continue parsing pnodeFnc using the correct set of stubs instead of the
14032+
// stubs for pnodeFncParent.
14033+
// This function assumes we are in the middle of parsing pnodeFnc which is a child
14034+
// nested in pnodeFncParent.
14035+
if (pnodeFnc->IsNested() && pnodeFncParent != nullptr && m_currDeferredStub != nullptr && pnodeFncParent->ichMin != pnodeFnc->ichMin)
14036+
{
14037+
AssertOrFailFast(pnodeFncParent->nestedCount > 0);
14038+
14039+
DeferredFunctionStub* childStub = m_currDeferredStub + (pnodeFncParent->nestedCount - 1);
14040+
m_currDeferredStubCount = childStub->nestedCount;
14041+
m_currDeferredStub = childStub->deferredStubs;
14042+
}
14043+
}
14044+
1402414045
uint Parser::BuildDeferredStubTreeHelper(ParseNodeBlock* pnodeBlock, DeferredFunctionStub* deferredStubs, uint currentStubIndex, uint deferredStubCount, Recycler *recycler)
1402514046
{
1402614047
Assert(pnodeBlock != nullptr

lib/Parser/Parse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ class Parser
273273

274274
protected:
275275
static uint BuildDeferredStubTreeHelper(ParseNodeBlock* pnodeBlock, DeferredFunctionStub* deferredStubs, uint currentStubIndex, uint deferredStubCount, Recycler *recycler);
276+
void ShiftCurrDeferredStubToChildFunction(ParseNodeFnc* pnodeFnc, ParseNodeFnc* pnodeFncParent);
276277

277278
HRESULT ParseSourceInternal(
278279
__out ParseNodeProg ** parseTree, LPCUTF8 pszSrc, size_t offsetInBytes,

test/Bugs/deferredStubBugs.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var func5 = (a = 123) => (function v6() {
2626
})()
2727
func5();
2828

29-
function func6(a = v => { console.log('pass'); }, b = v => { return a; }) {
29+
function func6(a = v => { console.log(pass); }, b = v => { return a; }) {
3030
function c() {
3131
return b();
3232
}
@@ -84,3 +84,13 @@ function func18(a = class A { meth() { return fail } static meth2() { return fai
8484
return c();
8585
}
8686
console.log(func18());
87+
88+
function func19() {
89+
return (function(a = { b() {} }){ return pass; })();
90+
}
91+
console.log(func19());
92+
93+
function func20() {
94+
return (function(a = { b() {} }, c = function() { return pass; }){ return c(); })();
95+
}
96+
console.log(func20());

0 commit comments

Comments
 (0)