Skip to content

Commit f2416b5

Browse files
committed
Few destructuring fixes
The IsArgument optimization code did not handle the pattern nodes. Added 'cases' for those nop. This happens when we try to find out the 'arguments' usage from a parse node. Here in this case we have an empty pattern and this leads to the assert. We have place holder slots for destructuring patterns - however when we generate the scopeinfo for deferred function we didn't account that piece of information. Fixed that by using the same counter (earlier used for same name args place holder) and increment that for destructuring patterns. Added unittest for those.
1 parent 9ac8d41 commit f2416b5

6 files changed

Lines changed: 37 additions & 6 deletions

File tree

lib/Runtime/ByteCode/ByteCodeEmitter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ bool IsArguments(ParseNode *pnode)
187187
case knopTry:
188188
case knopTryCatch:
189189
case knopTryFinally:
190+
case knopArrayPattern:
191+
case knopObjectPattern:
192+
case knopParamPattern:
190193
return true;
191194

192195
default:

lib/Runtime/ByteCode/ByteCodeGenerator.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,7 +2711,7 @@ FuncInfo* PostVisitFunction(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerat
27112711
if (argSym)
27122712
{
27132713
Assert(top->bodyScope->GetScopeSlotCount() == 0);
2714-
Assert(top->sameNameArgsPlaceHolderSlotCount == 0);
2714+
Assert(top->argsPlaceHolderSlotCount == 0);
27152715
byteCodeGenerator->AssignRegister(argSym);
27162716
uint i = 0;
27172717
auto setArgScopeSlot = [&](ParseNode *pnodeArg)
@@ -2721,10 +2721,14 @@ FuncInfo* PostVisitFunction(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerat
27212721
Symbol* sym = pnodeArg->sxVar.sym;
27222722
if (sym->GetScopeSlot() != Js::Constants::NoProperty)
27232723
{
2724-
top->sameNameArgsPlaceHolderSlotCount++; // Same name args appeared before
2724+
top->argsPlaceHolderSlotCount++; // Same name args appeared before
27252725
}
27262726
sym->SetScopeSlot(i);
27272727
}
2728+
else if (pnodeArg->nop == knopParamPattern)
2729+
{
2730+
top->argsPlaceHolderSlotCount++;
2731+
}
27282732
i++;
27292733
};
27302734

lib/Runtime/ByteCode/FuncInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ FuncInfo::FuncInfo(
7171
inlineCacheMap(nullptr),
7272
slotProfileIdMap(alloc),
7373
localPropIdOffset(-1),
74-
sameNameArgsPlaceHolderSlotCount(0),
74+
argsPlaceHolderSlotCount(0),
7575
thisScopeSlot(Js::Constants::NoProperty),
7676
superScopeSlot(Js::Constants::NoProperty),
7777
superCtorScopeSlot(Js::Constants::NoProperty),

lib/Runtime/ByteCode/FuncInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class FuncInfo
115115
Js::RegSlot yieldRegister;
116116
Js::RegSlot firstTmpReg;
117117
Js::RegSlot curTmpReg;
118-
int sameNameArgsPlaceHolderSlotCount; // count of place holder slots for same name args
118+
int argsPlaceHolderSlotCount; // count of place holder slots for same name args and destructuring patterns
119119
int localPropIdOffset;
120120
Js::RegSlot firstThunkArgReg;
121121
short thunkArgCount;

lib/Runtime/ByteCode/ScopeInfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ namespace Js
5454
{
5555
int count = scope->Count();
5656

57-
// Add same name args place holder slot counts
58-
AddSlotCount(count, scope->GetFunc()->sameNameArgsPlaceHolderSlotCount);
57+
// Add argsPlaceHolder which includes same name args and destructuring patterns on parameters
58+
AddSlotCount(count, scope->GetFunc()->argsPlaceHolderSlotCount);
5959
AddSlotCount(count, scope->GetFunc()->thisScopeSlot != Js::Constants::NoRegister ? 1 : 0);
6060
AddSlotCount(count, scope->GetFunc()->newTargetScopeSlot != Js::Constants::NoRegister ? 1 : 0);
6161

test/es6/destructuring_bugs.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,30 @@ var tests = [
288288
assert.areEqual(a, undefined);
289289
assert.areEqual(b, 1);
290290
}
291+
},
292+
{
293+
name: "Destructuring - Empty object pattern inside call node is a valid syntax",
294+
body: function () {
295+
function f() {
296+
({} = []).Symbol.interator();
297+
eval("");
298+
};
299+
}
300+
},
301+
{
302+
name: "Destructuring - Place holder slots for pattern are accounted when undeferred.",
303+
body: function () {
304+
function foo({a}) {
305+
function x() {}
306+
eval('');
307+
}
308+
foo({});
309+
function foo1(...[b]) {
310+
function x() {}
311+
eval('');
312+
}
313+
foo1([]);
314+
}
291315
}
292316
];
293317

0 commit comments

Comments
 (0)