Bug 1166950 - Only give constructor functions a prototype. r=efaust

This commit is contained in:
Tom Schuster 2015-05-25 19:31:46 +02:00
parent fe0dbd43f9
commit 02fbf5716d
4 changed files with 60 additions and 5 deletions

View File

@ -443,16 +443,19 @@ fun_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
* or (Object.prototype, Function.prototype, etc.) have that property
* created eagerly.
*
* ES5 15.3.4: the non-native function object named Function.prototype
* does not have a .prototype property.
*
* ES5 15.3.4.5: bound functions don't have a prototype property. The
* isBuiltin() test covers this case because bound functions are native
* (and thus built-in) functions by definition/construction.
*
* ES6 19.2.4.3: arrow functions also don't have a prototype property.
* In ES6 9.2.8 MakeConstructor the .prototype property is only assigned
* to constructors.
*
* Thus all of the following don't get a .prototype property:
* - Methods (that are not class-constructors or generators)
* - Arrow functions
* - Function.prototype
*/
if (fun->isBuiltin() || fun->isArrow() || fun->isFunctionPrototype())
if (fun->isBuiltin() || !fun->isConstructor())
return true;
if (!ResolveInterpretedFunctionPrototype(cx, fun))

View File

@ -118,6 +118,10 @@ assertEq(b.enumerable, true);
assertEq(b.writable, true);
assertEq(b.value(), 4);
// prototype property
assertEq(a.b.prototype, undefined);
assertEq(a.b.hasOwnProperty("prototype"), false);
// Defining several methods using eval.
var code = "({";
for (i = 0; i < 1000; i++)

View File

@ -66,6 +66,9 @@ assertEq(next.done, true);
assertEq(next.value.hello, 2);
assertEq(next.value.world, 3);
// prototype property
assertEq(b.g.hasOwnProperty("prototype"), true);
// Strict mode
a = {*b(c){"use strict";yield c;}};
assertEq(a.b(1).next().value, 1);

View File

@ -0,0 +1,45 @@
var test = `
class TestClass {
constructor() { }
method() { }
get getter() { }
set setter(x) { }
*generator() { }
static staticMethod() { }
static get staticGetter() { }
static set staticSetter(x) { }
static *staticGenerator() { }
}
var test = new TestClass();
var hasPrototype = [
test.constructor,
test.generator,
TestClass.staticGenerator
]
for (var fun of hasPrototype) {
assertEq(fun.hasOwnProperty('prototype'), true);
}
var hasNoPrototype = [
test.method,
Object.getOwnPropertyDescriptor(test.__proto__, 'getter').get,
Object.getOwnPropertyDescriptor(test.__proto__, 'setter').set,
TestClass.staticMethod,
Object.getOwnPropertyDescriptor(TestClass, 'staticGetter').get,
Object.getOwnPropertyDescriptor(TestClass, 'staticSetter').set,
]
for (var fun of hasNoPrototype) {
assertEq(fun.hasOwnProperty('prototype'), false);
}
`;
if (classesEnabled())
eval(test);
if (typeof reportCompare === "function")
reportCompare(0, 0, "OK");