From 3b624a179682a6b8351eea8cba28cf21e2afcdcd Mon Sep 17 00:00:00 2001 From: mike Date: Mon, 6 Apr 2015 14:04:43 -0700 Subject: [PATCH] Re-implement %Generator% intrinsic as an object From ES6 25.2.3 ("Properties of the GeneratorFunction Prototype Object"): > The GeneratorFunction prototype object is an ordinary object. It is > not a function object and does not have an [[ECMAScriptCode]] internal > slot or any other of the internal slots listed in Table 27 or Table > 56. Introduce one assertion for the value's type and additional tests for its properties. Remove an invalid assertion that fails as a result of this fix. BUG=v8:3991 LOG=N Review URL: https://codereview.chromium.org/1062633002 Cr-Commit-Position: refs/heads/master@{#27603} --- src/bootstrapper.cc | 18 ++++++++++++++---- src/generator.js | 7 ------- test/mjsunit/builtins.js | 18 ++++++++++++++++-- test/mjsunit/es6/generators-runtime.js | 18 +++++++++++++++++- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 3c957364fc..93ebb3f0fe 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -2059,10 +2059,20 @@ bool Genesis::InstallNatives() { Handle builtins(native_context()->builtins()); Handle generator_object_prototype = factory()->NewJSObject(isolate()->object_function(), TENURED); - Handle generator_function_prototype = - InstallFunction(builtins, "GeneratorFunctionPrototype", - JS_FUNCTION_TYPE, JSFunction::kHeaderSize, - generator_object_prototype, Builtins::kIllegal); + Handle generator_function_prototype = + factory()->NewJSObject(isolate()->object_function(), TENURED); + JSObject::AddProperty( + builtins, + factory()->InternalizeUtf8String("GeneratorFunctionPrototype"), + generator_function_prototype, + static_cast(DONT_ENUM | DONT_DELETE | READ_ONLY)); + + JSObject::AddProperty( + generator_function_prototype, + factory()->InternalizeUtf8String("prototype"), + generator_object_prototype, + static_cast(DONT_ENUM | READ_ONLY)); + InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE, JSFunction::kSize, generator_function_prototype, Builtins::kIllegal); diff --git a/src/generator.js b/src/generator.js index fa6e9764ad..338b7085a3 100644 --- a/src/generator.js +++ b/src/generator.js @@ -67,12 +67,6 @@ function GeneratorObjectIterator() { return this; } -function GeneratorFunctionPrototypeConstructor(x) { - if (%_IsConstructCall()) { - throw MakeTypeError('not_constructor', ['GeneratorFunctionPrototype']); - } -} - function GeneratorFunctionConstructor(arg1) { // length == 1 var source = NewFunctionString(arguments, 'function*'); var global_proxy = %GlobalProxy(global); @@ -109,7 +103,6 @@ function SetUpGenerators() { %InternalSetPrototype(GeneratorFunctionPrototype, $Function.prototype); %AddNamedProperty(GeneratorFunctionPrototype, symbolToStringTag, "GeneratorFunction", DONT_ENUM | READ_ONLY); - %SetCode(GeneratorFunctionPrototype, GeneratorFunctionPrototypeConstructor); %AddNamedProperty(GeneratorFunctionPrototype, "constructor", GeneratorFunction, DONT_ENUM | READ_ONLY); %InternalSetPrototype(GeneratorFunction, $Function); diff --git a/test/mjsunit/builtins.js b/test/mjsunit/builtins.js index fe7d35d8ea..5035e67309 100644 --- a/test/mjsunit/builtins.js +++ b/test/mjsunit/builtins.js @@ -39,12 +39,26 @@ function isFunction(obj) { } function isV8Native(name) { - return name == "GeneratorFunctionPrototype" || + return name == "GeneratorFunction" || + name == "GeneratorFunctionPrototype" || name == "SetIterator" || name == "MapIterator" || name == "ArrayIterator" || name == "StringIterator"; } +var V8NativePrototypes = { + GeneratorFunction: Function.prototype, + // TODO(jugglinmike): Update the following values to the %IteratorPrototype% + // intrinsic once it is implemented. + // Issue 3568: Generator Prototype should have an object between itself + // and Object.prototype + // https://code.google.com/p/v8/issues/detail?id=3568 + GeneratorFunctionPrototype: Object.prototype, + SetIterator: Object.prototype, + MapIterator: Object.prototype, + ArrayIterator: Object.prototype, + StringIterator: Object.prototype +}; function checkConstructor(func, name) { // A constructor is a function with a prototype and properties on the @@ -62,7 +76,7 @@ function checkConstructor(func, name) { assertFalse(proto_desc.writable, name); assertFalse(proto_desc.configurable, name); var prototype = proto_desc.value; - assertEquals(isV8Native(name) ? Object.prototype : null, + assertEquals(V8NativePrototypes[name] || null, Object.getPrototypeOf(prototype), name); for (var i = 0; i < propNames.length; i++) { diff --git a/test/mjsunit/es6/generators-runtime.js b/test/mjsunit/es6/generators-runtime.js index 8fa70b62e0..88380dfec0 100644 --- a/test/mjsunit/es6/generators-runtime.js +++ b/test/mjsunit/es6/generators-runtime.js @@ -78,6 +78,23 @@ function TestGeneratorFunctionPrototype() { Object.getPrototypeOf(GeneratorFunctionPrototype)); assertSame(GeneratorFunctionPrototype, Object.getPrototypeOf(function* () {})); + assertSame("object", typeof GeneratorFunctionPrototype); + + var constructor_desc = Object.getOwnPropertyDescriptor( + GeneratorFunctionPrototype, "constructor"); + assertTrue(constructor_desc !== undefined); + assertSame(GeneratorFunction, constructor_desc.value); + assertFalse(constructor_desc.writable); + assertFalse(constructor_desc.enumerable); + assertTrue(constructor_desc.configurable); + + var prototype_desc = Object.getOwnPropertyDescriptor( + GeneratorFunctionPrototype, "prototype"); + assertTrue(prototype_desc !== undefined); + assertSame(GeneratorObjectPrototype, prototype_desc.value); + assertFalse(prototype_desc.writable); + assertFalse(prototype_desc.enumerable); + assertTrue(prototype_desc.configurable); } TestGeneratorFunctionPrototype(); @@ -136,7 +153,6 @@ TestGeneratorFunction(); function TestPerGeneratorPrototype() { assertTrue((function*(){}).prototype !== (function*(){}).prototype); assertTrue((function*(){}).prototype !== g.prototype); - assertTrue(g.prototype instanceof GeneratorFunctionPrototype); assertSame(GeneratorObjectPrototype, Object.getPrototypeOf(g.prototype)); assertTrue(!(g.prototype instanceof Function)); assertSame(typeof (g.prototype), "object");