Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 22 additions & 11 deletions lib/Runtime/ByteCode/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3654,15 +3654,20 @@ void ByteCodeGenerator::EmitScopeList(ParseNode *pnode, ParseNode *breakOnBodySc
PushFuncInfo(_u("StartEmitFunction"), funcInfo);
}

if (paramScope && !paramScope->GetCanMergeWithBodyScope())
{
// Before emitting the body scoped functions let us switch the special scope slot to use the body ones
pnode->sxFnc.funcInfo->UseInnerSpecialScopeSlots();
this->EmitScopeList(pnode->sxFnc.pnodeBodyScope->sxBlock.pnodeScopes);
}
else
// In DeferParse scenario, ByteCodeGenerator would not have yet visited the nested
// scopes, so the emitter should also not process these nodes either.
if (pnode->sxFnc.pnodeBody)
{
this->EmitScopeList(pnode->sxFnc.pnodeScopes);
if (paramScope && !paramScope->GetCanMergeWithBodyScope())
{
// Before emitting the body scoped functions let us switch the special scope slot to use the body ones
pnode->sxFnc.funcInfo->UseInnerSpecialScopeSlots();
this->EmitScopeList(pnode->sxFnc.pnodeBodyScope->sxBlock.pnodeScopes);
}
else
{
this->EmitScopeList(pnode->sxFnc.pnodeScopes);
}
}

this->EmitOneFunction(pnode);
Expand Down Expand Up @@ -4135,9 +4140,15 @@ void ByteCodeGenerator::StartEmitFunction(ParseNode *pnodeFnc)

PushScope(paramScope);

// While emitting the functions we have to stop when we see the body scope block.
// Otherwise functions defined in the body scope will not be able to get the right references.
this->EmitScopeList(paramBlock->sxBlock.pnodeScopes, pnodeFnc->sxFnc.pnodeBodyScope);
// In DeferParse scenario, ByteCodeGenerator would not have yet visited the nested
// scopes, so the emitter should also not process these nodes either.
if (pnodeFnc->sxFnc.pnodeBody)
{
// While emitting the functions we have to stop when we see the body scope block.
// Otherwise functions defined in the body scope will not be able to get the right references.
this->EmitScopeList(paramBlock->sxBlock.pnodeScopes, pnodeFnc->sxFnc.pnodeBodyScope);
}

Assert(this->GetCurrentScope() == paramScope);
}

Expand Down
26 changes: 26 additions & 0 deletions test/es6/default-splitscope.js
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,32 @@ var tests = [
return h();
}
assert.areEqual(9, f2(), "Paramater scope remains split");

// Bug 8971506: This used to throw an ASSERT. The test is considered to be passing if no ASSERT is thrown.
function f3(a1 = class c1 extends eval('') { }) {
}

// Bug 8971506: This used to throw an ASSERT. The test is considered to be passing if no ASSERT is thrown.
var f4 = function () {
};
{
f4();
}
function f5() {
function f6(a2 = class c2 extends eval('') { }) {
}
}

// Bug 8971506: This used to throw an ASSERT. The test is considered to be passing if no ASSERT is thrown.
(eval(`
function f6(jirfmx = class c3 {}) { };
`));

// Bug 8971506: This used to throw an ASSERT. The test is considered to be passing if no ASSERT is thrown.
(eval(`
function f7(a3 = class c4 extends false {
}) { };
`));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the extra set of parens around the eval(...) necessary to set up the scopes correctly to repro the issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the extra set of parenthesis aren't necessary.

}
},
{
Expand Down