зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1191486 - Generators should not have [[Construct]]; r=jorendorff
generator function do not have a [[construct]] trap, so `new` throws called a generator. This is unexpected behavior, so a TypeError is preferred. --HG-- extra : rebase_source : 200c1a59db9dd2a0559de3aa52c8f2c466f76289
This commit is contained in:
Родитель
c3ccaf7607
Коммит
dfe5b037ca
|
@ -1292,10 +1292,9 @@ Parser<ParseHandler>::newFunction(HandleAtom atom, FunctionSyntaxKind kind,
|
|||
break;
|
||||
case Method:
|
||||
MOZ_ASSERT(generatorKind == NotGenerator || generatorKind == StarGenerator);
|
||||
if (generatorKind == NotGenerator)
|
||||
flags = JSFunction::INTERPRETED_METHOD;
|
||||
else
|
||||
flags = JSFunction::INTERPRETED_METHOD_GENERATOR;
|
||||
flags = (generatorKind == NotGenerator
|
||||
? JSFunction::INTERPRETED_METHOD
|
||||
: JSFunction::INTERPRETED_METHOD_GENERATOR);
|
||||
allocKind = gc::AllocKind::FUNCTION_EXTENDED;
|
||||
break;
|
||||
case ClassConstructor:
|
||||
|
@ -1312,8 +1311,9 @@ Parser<ParseHandler>::newFunction(HandleAtom atom, FunctionSyntaxKind kind,
|
|||
allocKind = gc::AllocKind::FUNCTION_EXTENDED;
|
||||
break;
|
||||
default:
|
||||
flags = JSFunction::INTERPRETED_NORMAL;
|
||||
break;
|
||||
flags = (generatorKind == NotGenerator
|
||||
? JSFunction::INTERPRETED_NORMAL
|
||||
: JSFunction::INTERPRETED_GENERATOR);
|
||||
}
|
||||
|
||||
fun = NewFunctionWithProto(context, nullptr, 0, flags, nullptr, atom, proto,
|
||||
|
|
|
@ -81,13 +81,14 @@ class JSFunction : public js::NativeObject
|
|||
ASMJS_CTOR = ASMJS_KIND | NATIVE_CTOR,
|
||||
ASMJS_LAMBDA_CTOR = ASMJS_KIND | NATIVE_CTOR | LAMBDA,
|
||||
INTERPRETED_METHOD = INTERPRETED | METHOD_KIND,
|
||||
INTERPRETED_METHOD_GENERATOR = INTERPRETED | METHOD_KIND | CONSTRUCTOR,
|
||||
INTERPRETED_METHOD_GENERATOR = INTERPRETED | METHOD_KIND,
|
||||
INTERPRETED_CLASS_CONSTRUCTOR = INTERPRETED | CLASSCONSTRUCTOR_KIND | CONSTRUCTOR,
|
||||
INTERPRETED_GETTER = INTERPRETED | GETTER_KIND,
|
||||
INTERPRETED_SETTER = INTERPRETED | SETTER_KIND,
|
||||
INTERPRETED_LAMBDA = INTERPRETED | LAMBDA | CONSTRUCTOR,
|
||||
INTERPRETED_LAMBDA_ARROW = INTERPRETED | LAMBDA | ARROW_KIND,
|
||||
INTERPRETED_NORMAL = INTERPRETED | CONSTRUCTOR,
|
||||
INTERPRETED_GENERATOR = INTERPRETED,
|
||||
NO_XDR_FLAGS = RESOLVED_LENGTH | RESOLVED_NAME,
|
||||
|
||||
STABLE_ACROSS_CLONES = IS_FUN_PROTO | CONSTRUCTOR | EXPR_BODY | HAS_GUESSED_ATOM |
|
||||
|
|
|
@ -67,7 +67,7 @@ assertEq(next.value.hello, 2);
|
|||
assertEq(next.value.world, 3);
|
||||
|
||||
// prototype property
|
||||
assertEq(b.g.hasOwnProperty("prototype"), true);
|
||||
assertEq(b.g.hasOwnProperty("prototype"), false);
|
||||
|
||||
// Strict mode
|
||||
a = {*b(c){"use strict";yield c;}};
|
||||
|
@ -75,13 +75,8 @@ assertEq(a.b(1).next().value, 1);
|
|||
a = {*["b"](c){"use strict";return c;}};
|
||||
assertEq(a.b(1).next().value, 1);
|
||||
|
||||
// Constructing
|
||||
// Generators should not have [[Construct]]
|
||||
a = {*g() { yield 1; }}
|
||||
it = new a.g;
|
||||
next = it.next();
|
||||
assertEq(next.done, false);
|
||||
assertEq(next.value, 1);
|
||||
next = it.next();
|
||||
assertEq(next.done, true);
|
||||
assertThrowsInstanceOf(() => { new a.g }, TypeError);
|
||||
|
||||
reportCompare(0, 0, "ok");
|
||||
|
|
|
@ -13,23 +13,17 @@ class TestClass {
|
|||
|
||||
var test = new TestClass();
|
||||
|
||||
var hasPrototype = [
|
||||
test.constructor,
|
||||
test.generator,
|
||||
TestClass.staticGenerator
|
||||
]
|
||||
|
||||
for (var fun of hasPrototype) {
|
||||
assertEq(fun.hasOwnProperty('prototype'), true);
|
||||
}
|
||||
assertEq(test.constructor.hasOwnProperty('prototype'), true);
|
||||
|
||||
var hasNoPrototype = [
|
||||
test.method,
|
||||
test.generator,
|
||||
TestClass.staticGenerator,
|
||||
Object.getOwnPropertyDescriptor(test.__proto__, 'getter').get,
|
||||
Object.getOwnPropertyDescriptor(test.__proto__, 'setter').set,
|
||||
TestClass.staticMethod,
|
||||
Object.getOwnPropertyDescriptor(TestClass, 'staticGetter').get,
|
||||
Object.getOwnPropertyDescriptor(TestClass, 'staticSetter').set,
|
||||
Object.getOwnPropertyDescriptor(TestClass, 'staticSetter').set
|
||||
]
|
||||
|
||||
for (var fun of hasNoPrototype) {
|
||||
|
|
|
@ -10,10 +10,6 @@ const ITERATIONS = 25;
|
|||
for (let i = 0; i < ITERATIONS; i++)
|
||||
assertEq(generatorNewTarget(undefined).next().value(), undefined);
|
||||
|
||||
for (let i = 0; i < ITERATIONS; i++)
|
||||
assertEq(new generatorNewTarget(generatorNewTarget).next().value(),
|
||||
generatorNewTarget);
|
||||
|
||||
// also check to make sure it's useful in yield inside generators.
|
||||
// Plus, this code is so ugly, how could it not be a test? ;)
|
||||
// Thanks to anba for supplying this ludicrous expression.
|
||||
|
|
|
@ -15,14 +15,6 @@ function TestGeneratorObject() {
|
|||
assertEq(String(iter), "[object Generator]");
|
||||
assertDeepEq(Object.getOwnPropertyNames(iter), []);
|
||||
assertNotEq(g(), iter);
|
||||
|
||||
// g() is the same as new g().
|
||||
iter = new g();
|
||||
assertEq(Object.getPrototypeOf(iter), g.prototype);
|
||||
assertTrue(iter instanceof g);
|
||||
assertEq(String(iter), "[object Generator]");
|
||||
assertDeepEq(Object.getOwnPropertyNames(iter), []);
|
||||
assertNotEq(new g(), iter);
|
||||
}
|
||||
TestGeneratorObject();
|
||||
|
||||
|
|
|
@ -18,11 +18,12 @@ var GeneratorFunctionPrototype = Object.getPrototypeOf(g);
|
|||
var GeneratorFunction = GeneratorFunctionPrototype.constructor;
|
||||
var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype;
|
||||
|
||||
|
||||
// A generator function should have the same set of properties as any
|
||||
// other function.
|
||||
// other function, minus a prototype.
|
||||
function TestGeneratorFunctionInstance() {
|
||||
var f_own_property_names = Object.getOwnPropertyNames(f);
|
||||
f_own_property_names.splice(f_own_property_names.indexOf("prototype"), 1);
|
||||
|
||||
var g_own_property_names = Object.getOwnPropertyNames(g);
|
||||
|
||||
f_own_property_names.sort();
|
||||
|
@ -41,7 +42,6 @@ function TestGeneratorFunctionInstance() {
|
|||
}
|
||||
TestGeneratorFunctionInstance();
|
||||
|
||||
|
||||
// Generators have an additional object interposed in the chain between
|
||||
// themselves and Function.prototype.
|
||||
function TestGeneratorFunctionPrototype() {
|
||||
|
@ -112,15 +112,7 @@ TestGeneratorFunction();
|
|||
|
||||
|
||||
function TestPerGeneratorPrototype() {
|
||||
assertNotEq((function*(){}).prototype, (function*(){}).prototype);
|
||||
assertNotEq((function*(){}).prototype, g.prototype);
|
||||
assertEq(typeof GeneratorFunctionPrototype, "object");
|
||||
assertEq(g.prototype.__proto__.constructor, GeneratorFunctionPrototype, "object");
|
||||
assertEq(Object.getPrototypeOf(g.prototype), GeneratorObjectPrototype);
|
||||
assertFalse(g.prototype instanceof Function);
|
||||
assertEq(typeof (g.prototype), "object");
|
||||
|
||||
assertDeepEq(Object.getOwnPropertyNames(g.prototype), []);
|
||||
assertEq(g.hasOwnProperty("prototype"), false);
|
||||
}
|
||||
TestPerGeneratorPrototype();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче