From 232e54543273cd1d8c156b5d86f78298465ad819 Mon Sep 17 00:00:00 2001 From: Nikolay Botev Date: Fri, 13 Sep 2024 15:48:25 +0300 Subject: [PATCH 1/2] Make the Iterator prototype have its own constructor --- packages/runtime/runtime.js | 12 ++++++++++-- test/tests.es6.js | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/runtime/runtime.js b/packages/runtime/runtime.js index 5593ca59d..6af59286f 100644 --- a/packages/runtime/runtime.js +++ b/packages/runtime/runtime.js @@ -86,12 +86,20 @@ var runtime = (function (exports) { // This is a polyfill for %IteratorPrototype% for environments that // don't natively support it. - var IteratorPrototype = {}; + var getProto = Object.getPrototypeOf; + function Iterator() { + if (!IteratorPrototype.isPrototypeOf(this)) { + throw new TypeError("Iterator constructor called on non-iterator object"); + } + if (getProto && getProto(this) === IteratorPrototype) { + throw new TypeError("Cannot instantiate abstract Iterator class"); + } + } + var IteratorPrototype = Iterator.prototype; define(IteratorPrototype, iteratorSymbol, function () { return this; }); - var getProto = Object.getPrototypeOf; var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && diff --git a/test/tests.es6.js b/test/tests.es6.js index b72ddf9cc..6cfb02c27 100644 --- a/test/tests.es6.js +++ b/test/tests.es6.js @@ -2625,6 +2625,9 @@ describe("generator function prototype", function() { it("should follow the expected object model", function() { var GeneratorFunctionPrototype = getProto(f); + var GeneratorPrototype = GeneratorFunctionPrototype.prototype; + var IteratorPrototype = getProto(GeneratorPrototype); + var Iterator = IteratorPrototype.constructor; var GeneratorFunction = GeneratorFunctionPrototype.constructor; assert.strictEqual(GeneratorFunction.name, 'GeneratorFunction'); @@ -2636,6 +2639,9 @@ describe("generator function prototype", function() { getProto(f.prototype)); assert.strictEqual(getProto(GeneratorFunctionPrototype), Function.prototype); + assert.notStrictEqual(IteratorPrototype, Object); + assert.throws(() => Iterator.call({})); + assert.throws(() => new Iterator()); if (typeof process === "undefined" || process.version.slice(1, 3) === "0.") { From a896fde39f6cfb23447dfcca86dcc0824a0b3400 Mon Sep 17 00:00:00 2001 From: Nikolay Botev Date: Fri, 13 Sep 2024 16:12:17 +0300 Subject: [PATCH 2/2] Remove redundant GeneratorFunctionPrototype --- packages/runtime/runtime.js | 16 +++++++--------- test/tests.es6.js | 1 + 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/runtime/runtime.js b/packages/runtime/runtime.js index 6af59286f..47723ebea 100644 --- a/packages/runtime/runtime.js +++ b/packages/runtime/runtime.js @@ -82,7 +82,6 @@ var runtime = (function (exports) { // minifier not to mangle the names of these two functions. function Generator() {} function GeneratorFunction() {} - function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that // don't natively support it. @@ -109,17 +108,16 @@ var runtime = (function (exports) { IteratorPrototype = NativeIteratorPrototype; } - var Gp = GeneratorFunctionPrototype.prototype = - Generator.prototype = Object.create(IteratorPrototype); - GeneratorFunction.prototype = GeneratorFunctionPrototype; - defineProperty(Gp, "constructor", { value: GeneratorFunctionPrototype, configurable: true }); + var Gp = Generator.prototype = Object.create(IteratorPrototype); + GeneratorFunction.prototype = Generator; + defineProperty(Gp, "constructor", { value: Generator, configurable: true }); defineProperty( - GeneratorFunctionPrototype, + Generator, "constructor", { value: GeneratorFunction, configurable: true } ); GeneratorFunction.displayName = define( - GeneratorFunctionPrototype, + Generator, toStringTagSymbol, "GeneratorFunction" ); @@ -146,9 +144,9 @@ var runtime = (function (exports) { exports.mark = function(genFun) { if (Object.setPrototypeOf) { - Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); + Object.setPrototypeOf(genFun, Generator); } else { - genFun.__proto__ = GeneratorFunctionPrototype; + genFun.__proto__ = Generator; define(genFun, toStringTagSymbol, "GeneratorFunction"); } genFun.prototype = Object.create(Gp); diff --git a/test/tests.es6.js b/test/tests.es6.js index 6cfb02c27..5a5cbac23 100644 --- a/test/tests.es6.js +++ b/test/tests.es6.js @@ -2642,6 +2642,7 @@ describe("generator function prototype", function() { assert.notStrictEqual(IteratorPrototype, Object); assert.throws(() => Iterator.call({})); assert.throws(() => new Iterator()); + assert.strictEqual(f() instanceof f, true); if (typeof process === "undefined" || process.version.slice(1, 3) === "0.") {