Skip to content

Commit ee2c09b

Browse files
committed
Fixes 5701 - Functions declared as methods define a prototype property
ES19 requires that, unless otherwise stated, all methods should have a prototype. ChakraCore adds prototypes to methods defined in objects. In order to not allow prototypes to be added to methods defined in objects, the ErrorOnNew flag is atted to the pNodeFnc's FuncInfo's attributes. Class constructors are methods but are defined to have prototypes, so they are not given the ErrorOnNew flag.
1 parent 3aa8c72 commit ee2c09b

File tree

10 files changed

+193
-132
lines changed

10 files changed

+193
-132
lines changed

lib/Runtime/ByteCode/ByteCodeGenerator.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,14 @@ static Js::FunctionInfo::Attributes GetFunctionInfoAttributes(ParseNodeFnc * pno
12671267
if (pnodeFnc->IsMethod())
12681268
{
12691269
attributes = (Js::FunctionInfo::Attributes)(attributes | Js::FunctionInfo::Attributes::Method);
1270+
1271+
// #sec-runtime-semantics-classdefinitionevaluation calls #sec-makeconstructor. #sec-makeconstructor
1272+
// creates a prototype. Thus a method that is a class constructor has a prototype and should not
1273+
// throw an error when new is called on the method.
1274+
if (!pnodeFnc->IsClassConstructor())
1275+
{
1276+
attributes = (Js::FunctionInfo::Attributes)(attributes | Js::FunctionInfo::Attributes::ErrorOnNew);
1277+
}
12701278
}
12711279
if (pnodeFnc->IsGenerator())
12721280
{

lib/Runtime/Library/InJavascript/Intl.js.bc.32b.h

Lines changed: 32 additions & 32 deletions
Large diffs are not rendered by default.

lib/Runtime/Library/InJavascript/Intl.js.bc.64b.h

Lines changed: 32 additions & 32 deletions
Large diffs are not rendered by default.

lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.32b.h

Lines changed: 32 additions & 32 deletions
Large diffs are not rendered by default.

lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.64b.h

Lines changed: 32 additions & 32 deletions
Large diffs are not rendered by default.

test/AsmJs/bug16252562.baseline

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ bug16252562.js(9, 3)
44
Unhandled parse opcode for asm.js
55

66
Asm.js compilation failed.
7-
new.target: Bar() {console.log(`new.target: ${new.target}`);}
7+
new.target: function () { console.log(`new.target: ${new.target}`); }

test/AsmJs/bug16252562.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ function AsmModule(stdlib, foreign) {
1111
}
1212
return foo;
1313
}
14-
AsmModule(this, {Bar() {console.log(`new.target: ${new.target}`);}})();
14+
AsmModule(this, { Bar: function () { console.log(`new.target: ${new.target}`); } })();
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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+
var failed = false;
7+
8+
var o = {
9+
f() { }
10+
}
11+
12+
if (o.f.hasOwnProperty("prototype")) {
13+
failed = true;
14+
WScript.Echo("Failed: a method within an object literal should not have a prototype");
15+
}
16+
17+
try {
18+
new o.f();
19+
failed = true;
20+
WScript.Echo("Failed: a method within an object literal should not have a prototype and thus new should not be valid");
21+
}
22+
catch (e) {
23+
}
24+
25+
class C {
26+
f() { }
27+
}
28+
29+
if (new C().f.hasOwnProperty("prototype")) {
30+
failed = true;
31+
WScript.Echo("Failed: a method within a class should not have a prototype");
32+
}
33+
34+
if (!(new C().constructor.hasOwnProperty("prototype"))) {
35+
failed = true;
36+
WScript.Echo("Failed: a class' constructor should have a prototype");
37+
}
38+
39+
if (!failed) {
40+
WScript.Echo("Pass");
41+
}

test/Prototypes/rlexe.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,9 @@
4646
<files>shadow2.js</files>
4747
</default>
4848
</test>
49+
<test>
50+
<default>
51+
<files>NoPrototypeForMethod.js</files>
52+
</default>
53+
</test>
4954
</regress-exe>

test/es6/proxyconstruction.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,19 @@ var tests = [
116116
}
117117
},
118118
{
119-
name: "Proxy of Object literal method should be constructable",
119+
name: "Proxy of Object literal function should be constructable",
120120
body() {
121-
let testingMethod = {test() {}}
121+
let testingMethod = {test:function() {}}
122122
testConstructProxy(testingMethod.test, false);
123123
}
124124
},
125+
{
126+
name: "Proxy of Object literal method should not be constructable",
127+
body() {
128+
let testingMethod = { test() { } }
129+
testConstructProxy(testingMethod.test, true);
130+
}
131+
},
125132
{
126133
name: "Proxy of Date object should be constructable",
127134
body() {

0 commit comments

Comments
 (0)