Commit faf5e681 authored by neis's avatar neis Committed by Commit bot

Make generators non-constructable.

BUG=v8:4163,v8:4630
LOG=y

R=rossberg

Review URL: https://codereview.chromium.org/1590873002

Cr-Commit-Position: refs/heads/master@{#33360}
parent ec30425a
......@@ -548,7 +548,7 @@ Handle<JSFunction> ApiNatives::CreateApiFunction(
// Mark instance as callable in the map.
if (!obj->instance_call_handler()->IsUndefined()) {
map->set_is_callable();
map->set_is_constructor();
map->set_is_constructor(true);
}
// Recursively copy parent instance templates' accessors,
......
......@@ -483,7 +483,7 @@ void Genesis::SetFunctionInstanceDescriptor(Handle<Map> map,
Handle<Map> Genesis::CreateSloppyFunctionMap(FunctionMode function_mode) {
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
SetFunctionInstanceDescriptor(map, function_mode);
if (IsFunctionModeWithPrototype(function_mode)) map->set_is_constructor();
map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
map->set_is_callable();
return map;
}
......@@ -715,7 +715,7 @@ Handle<Map> Genesis::CreateStrictFunctionMap(
FunctionMode function_mode, Handle<JSFunction> empty_function) {
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
SetStrictFunctionInstanceDescriptor(map, function_mode);
if (IsFunctionModeWithPrototype(function_mode)) map->set_is_constructor();
map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
map->set_is_callable();
Map::SetPrototype(map, empty_function);
return map;
......@@ -726,7 +726,7 @@ Handle<Map> Genesis::CreateStrongFunctionMap(
Handle<JSFunction> empty_function, bool is_constructor) {
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
SetStrongFunctionInstanceDescriptor(map);
if (is_constructor) map->set_is_constructor();
map->set_is_constructor(is_constructor);
Map::SetPrototype(map, empty_function);
map->set_is_callable();
map->set_is_extensible(is_constructor);
......@@ -789,6 +789,7 @@ void Genesis::CreateIteratorMaps() {
// Generator functions do not have "caller" or "arguments" accessors.
Handle<Map> sloppy_generator_function_map =
Map::Copy(strict_function_map, "SloppyGeneratorFunction");
sloppy_generator_function_map->set_is_constructor(false);
Map::SetPrototype(sloppy_generator_function_map,
generator_function_prototype);
native_context()->set_sloppy_generator_function_map(
......@@ -796,6 +797,7 @@ void Genesis::CreateIteratorMaps() {
Handle<Map> strict_generator_function_map =
Map::Copy(strict_function_map, "StrictGeneratorFunction");
strict_generator_function_map->set_is_constructor(false);
Map::SetPrototype(strict_generator_function_map,
generator_function_prototype);
native_context()->set_strict_generator_function_map(
......@@ -804,6 +806,7 @@ void Genesis::CreateIteratorMaps() {
Handle<Map> strong_function_map(native_context()->strong_function_map());
Handle<Map> strong_generator_function_map =
Map::Copy(strong_function_map, "StrongGeneratorFunction");
strong_generator_function_map->set_is_constructor(false);
Map::SetPrototype(strong_generator_function_map,
generator_function_prototype);
native_context()->set_strong_generator_function_map(
......@@ -1626,7 +1629,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
native_context()->set_bound_function_without_constructor_map(*map);
map = Map::Copy(map, "IsConstructor");
map->set_is_constructor();
map->set_is_constructor(true);
native_context()->set_bound_function_with_constructor_map(*map);
}
......@@ -2453,7 +2456,7 @@ void Genesis::InstallJSProxyMaps() {
Handle<Map> proxy_function_map =
Map::Copy(isolate()->sloppy_function_without_prototype_map(), "Proxy");
proxy_function_map->set_is_constructor();
proxy_function_map->set_is_constructor(true);
native_context()->set_proxy_function_map(*proxy_function_map);
Handle<Map> proxy_map =
......@@ -2468,7 +2471,7 @@ void Genesis::InstallJSProxyMaps() {
Handle<Map> proxy_constructor_map =
Map::Copy(proxy_callable_map, "constructor Proxy");
proxy_constructor_map->set_is_constructor();
proxy_constructor_map->set_is_constructor(true);
native_context()->set_proxy_constructor_map(*proxy_constructor_map);
}
......
......@@ -1024,8 +1024,9 @@ inline bool IsClassConstructor(FunctionKind kind) {
inline bool IsConstructable(FunctionKind kind, LanguageMode mode) {
if (IsAccessorFunction(kind)) return false;
if (IsConciseMethod(kind) && !IsGeneratorFunction(kind)) return false;
if (IsConciseMethod(kind)) return false;
if (IsArrowFunction(kind)) return false;
if (IsGeneratorFunction(kind)) return false;
if (is_strong(mode)) return IsClassConstructor(kind);
return true;
}
......
......@@ -4470,8 +4470,12 @@ bool Map::has_non_instance_prototype() {
}
void Map::set_is_constructor() {
set_bit_field(bit_field() | (1 << kIsConstructor));
void Map::set_is_constructor(bool value) {
if (value) {
set_bit_field(bit_field() | (1 << kIsConstructor));
} else {
set_bit_field(bit_field() & ~(1 << kIsConstructor));
}
}
......
......@@ -12919,7 +12919,8 @@ void JSFunction::SetInstancePrototype(Handle<JSFunction> function,
void JSFunction::SetPrototype(Handle<JSFunction> function,
Handle<Object> value) {
DCHECK(function->IsConstructor());
DCHECK(function->IsConstructor() ||
IsGeneratorFunction(function->shared()->kind()));
Handle<Object> construct_prototype = value;
// If the value is not a JSReceiver, store the value in the map's
......
......@@ -5551,7 +5551,7 @@ class Map: public HeapObject {
// Tells whether the instance has a [[Construct]] internal method.
// This property is implemented according to ES6, section 7.2.4.
inline void set_is_constructor();
inline void set_is_constructor(bool value);
inline bool is_constructor() const;
// Tells whether the instance with this map should be ignored by the
......
......@@ -22,11 +22,8 @@ RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
RUNTIME_ASSERT(function->shared()->is_generator());
Handle<JSGeneratorObject> generator;
if (frame->IsConstructor()) {
generator = handle(JSGeneratorObject::cast(frame->receiver()));
} else {
generator = isolate->factory()->NewJSGeneratorObject(function);
}
DCHECK(!frame->IsConstructor());
generator = isolate->factory()->NewJSGeneratorObject(function);
generator->set_function(*function);
generator->set_context(Context::cast(frame->context()));
generator->set_receiver(frame->receiver());
......
......@@ -101,9 +101,9 @@ function TestGenerator(g, expected_values_for_next,
testThrow(function*() { return yield* g(); });
if (g instanceof GeneratorFunction) {
testNext(function() { return new g(); });
testSend(function() { return new g(); });
testThrow(function() { return new g(); });
testNext(g);
testSend(g);
testThrow(g);
}
}
......@@ -258,18 +258,6 @@ TestGenerator(
"foo",
[1, 2, undefined]);
TestGenerator(
function g18() {
function* g() { yield this.x; yield this.y; }
var iter = new g;
iter.x = 1;
iter.y = 2;
return iter;
},
[1, 2, undefined],
"foo",
[1, 2, undefined]);
TestGenerator(
function* g19() {
var x = 1;
......
......@@ -59,18 +59,12 @@ function TestGeneratorObject() {
assertEquals("[object Generator]", String(iter));
assertEquals([], Object.getOwnPropertyNames(iter));
assertTrue(iter !== g());
// g() is the same as new g().
iter = new g();
assertSame(g.prototype, Object.getPrototypeOf(iter));
assertTrue(iter instanceof g);
assertEquals("Generator", %_ClassOf(iter));
assertEquals("[object Generator]", String(iter));
assertEquals("[object Generator]", Object.prototype.toString.call(iter));
var gf = iter.__proto__.constructor;
assertEquals("[object GeneratorFunction]", Object.prototype.toString.call(gf));
assertEquals([], Object.getOwnPropertyNames(iter));
assertTrue(iter !== new g());
// generators are not constructable.
assertThrows(()=>new g());
}
TestGeneratorObject();
......
......@@ -239,16 +239,14 @@ function assertIteratorResult(value, done, result) {
})();
(function TestGeneratorConstructable() {
(function TestGeneratorNotConstructable() {
var object = {
*method() {
yield 1;
}
};
var g = new object.method();
assertIteratorResult(1, false, g.next());
assertIteratorResult(undefined, true, g.next());
assertThrows(()=>new object.method());
})();
......
......@@ -279,10 +279,7 @@
(function() {
function* f() { yield 1; yield 2; }
function* g() { yield 3; yield 4; }
var o = Reflect.construct(f, [], g);
assertEquals([1, 2], [...o]);
assertTrue(o.__proto__ === g.prototype);
assertTrue(o.__proto__ !== f.prototype);
assertThrows(()=>Reflect.construct(f, [], g));
})();
(function () {
......
......@@ -382,11 +382,6 @@
'built-ins/ArrayBuffer/length-is-not-number': [FAIL],
'built-ins/ArrayBuffer/positive-integer-length': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=4630
'language/statements/generators/invoke-as-constructor': [FAIL],
'language/expressions/generators/invoke-as-constructor': [FAIL],
'language/expressions/object/method-definition/generator-invoke-ctor': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=4633
'built-ins/Promise/reject-function-name': [FAIL],
'built-ins/Promise/resolve-function-name': [FAIL],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment