Skip to content

Commit febfbff

Browse files
author
Suwei Chen
committed
ES6 constructor returns class instead of object upon constructorCache hit.
Github issue chakra-core#1496 ES6 constructor returns class instead of object upon constructorCache hit. constructorCache->ctorHasNoExplicitReturnValue set to 'true' for ES6 class constructors, therefore opcode 'GetNewScObject' is optimized away in inliner. Fix by de-asserting Flags_HasNoExplicitReturnValue for ES6 class constructors.
1 parent eaf47df commit febfbff

File tree

5 files changed

+65
-1
lines changed

5 files changed

+65
-1
lines changed

lib/Parser/Parse.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -6336,7 +6336,7 @@ ParseNodePtr Parser::GenerateEmptyConstructor(bool extends)
63366336
pnodeFnc->sxFnc.SetIsClassMember(TRUE);
63376337
pnodeFnc->sxFnc.SetIsClassConstructor(TRUE);
63386338
pnodeFnc->sxFnc.SetIsBaseClassConstructor(!extends);
6339-
pnodeFnc->sxFnc.SetHasNonThisStmt(extends);
6339+
pnodeFnc->sxFnc.SetHasNonThisStmt();
63406340
pnodeFnc->sxFnc.SetIsGeneratedDefault(TRUE);
63416341

63426342
pnodeFnc->ichLim = m_pscan->IchLimTok();
@@ -7152,6 +7152,7 @@ ParseNodePtr Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint, uin
71527152
pnodeConstructor->sxFnc.hintOffset = constructorShortNameHintOffset;
71537153
pnodeConstructor->sxFnc.pid = pnodeName && pnodeName->sxVar.pid ? pnodeName->sxVar.pid : wellKnownPropertyPids.constructor;
71547154
pnodeConstructor->sxFnc.SetIsClassConstructor(TRUE);
7155+
pnodeConstructor->sxFnc.SetHasNonThisStmt();
71557156
pnodeConstructor->sxFnc.SetIsBaseClassConstructor(pnodeExtends == nullptr);
71567157
}
71577158
else

lib/Runtime/ByteCode/ByteCodeEmitter.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -2727,6 +2727,11 @@ void ByteCodeGenerator::EmitFunctionBody(FuncInfo *funcInfo)
27272727
}
27282728
Assert(!pnode->CapturesSyms());
27292729
EmitTopLevelStatement(pnode, funcInfo, false);
2730+
2731+
if (funcInfo->IsClassConstructor())
2732+
{
2733+
funcInfo->GetParsedFunctionBody()->SetHasNoExplicitReturnValue(false);
2734+
}
27302735
}
27312736

27322737
void ByteCodeGenerator::EmitProgram(ParseNode *pnodeProg)

test/es6/bug_issue_1496.baseline

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
0
2+
1
3+
2
4+
3
5+
4
6+
5
7+
6
8+
7
9+
8
10+
9

test/es6/bug_issue_1496.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
// GitHub Issue1496: ES6 constructor returns class instead of object upon constructorCache hit
7+
//
8+
// -mic:1 -maxsimplejitruncount:2
9+
10+
var Test = {};
11+
12+
class A {
13+
constructor(foo) { this.foo = foo; }
14+
toB() {
15+
return new Test.B(this);
16+
}
17+
}
18+
19+
class B {
20+
constructor(bar) { this.bar = bar; }
21+
}
22+
23+
Test.B = B;
24+
25+
for (var i=0; i<10; i++)
26+
{
27+
var a = new A(i);
28+
var b = a.toB();
29+
30+
try
31+
{
32+
WScript.Echo(b.bar.foo);
33+
}
34+
catch (e)
35+
{
36+
WScript.Echo(e);
37+
WScript.Echo(b);
38+
break;
39+
}
40+
}

test/es6/rlexe.xml

+8
Original file line numberDiff line numberDiff line change
@@ -1331,4 +1331,12 @@
13311331
<compile-flags>-force:deferparse -args summary -endargs</compile-flags>
13321332
</default>
13331333
</test>
1334+
<test>
1335+
<default>
1336+
<files>bug_issue_1496.js</files>
1337+
<compile-flags>-mic:1 -maxsimplejitruncount:2</compile-flags>
1338+
<baseline>bug_issue_1496.baseline</baseline>
1339+
<tags>BugFix,exclude_dynapogo</tags>
1340+
</default>
1341+
</test>
13341342
</regress-exe>

0 commit comments

Comments
 (0)