Skip to content

Commit e1583ae

Browse files
committed
[MERGE #5712 @wyrichte] Fixes #5701 - Functions declared as methods define a prototype property
Merge pull request #5712 from wyrichte:build/wyrichte/bug_5701_1 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.
2 parents 6efd6f6 + ee2c09b commit e1583ae

10 files changed

+193
-132
lines changed

lib/Runtime/ByteCode/ByteCodeGenerator.cpp

+8
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

+32-32
Large diffs are not rendered by default.

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

+32-32
Large diffs are not rendered by default.

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

+32-32
Large diffs are not rendered by default.

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

+32-32
Large diffs are not rendered by default.

test/AsmJs/bug16252562.baseline

+1-1
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

+1-1
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}`); } })();
+41
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

+5
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

+9-2
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)