[JSC] Generator should have internal fields
https://bugs.webkit.org/show_bug.cgi?id=201159

Reviewed by Keith Miller.

JSTests:

* stress/create-generator.js: Added.
(shouldBe):
(test.generator):
(test):
* stress/generator-construct-failure.js: Added.
(shouldThrow):
(TypeError):
* stress/generator-prototype-change.js: Added.
(shouldBe):
(gen):
* stress/generator-prototype-closure.js: Added.
(shouldBe):
(test.gen):
(test):
* stress/object-assign-fast-path.js:

Source/JavaScriptCore:

This patch makes generator's internal states InternalField instead of private properties.
Each generator function produces a generator with different [[Prototype]], which makes generators have different Structures.
As a result, Generator.prototype.next etc.'s implementation becomes megamorphic even if it is not necessary.

If we make these structures adaptively poly-proto, some generators get poly-proto structures while others are not, resulting
in megamorphic lookup in Generator.prototype.next. If we make all the generator's structure poly-proto, it makes Generator.prototype.next
lookup suboptimal for now.

In this patch, we start with a relatively simple solution. This patch introduces JSGenerator class, and it has internal fields for generator's internal
states. We extend promise-internal-field access bytecodes to access to these fields from bytecode so that Generator.prototype.next can access
these fields without using megamorphic get_by_id_direct.

And we attach JSGeneratorType to JSGenerator so that we can efficiently implement `@isGenerator()` check in bytecode.

We reserve the offset = 0 slot for the future poly-proto extension for JSGenerator. By reserving this slot, non-poly-proto JSGenerator and poly-proto
JSGenerator still can offer the way to access to the same Generator internal fields with the same offset while poly-proto JSGenerator can get offset = 0
inline-storage slot for PolyProto implementation.

This patch adds op_create_generator since it is distinct from op_create_promise once we add PolyProto support.
In the future when we introduce some kind of op_create_async_generator we will probably share only one bytecode for both generator and async generator.

This patch offers around 10% improvement in JetStream2/Basic. And this patch is the basis of optimization of JetStream2/async-fs which leverages async generators significantly.

This patch includes several design decisions.

    1. We add a new JSGenerator instead of leveraging JSFinalObject. The main reason is that we would like to have JSGeneratorType to quickly query `@isGenerator`.
    2. This patch currently does not include object-allocation-sinking support for JSGenerator, but it is trivial, and will be added. And this patch also does not include poly-proto
       support for JSGenerator. The main reason is simply because this patch is already large enough, and I do not want to make this patch larger and larger.
    3. We can support arbitrary sized inline-storage: Reserving 0-5 offsets for internal fields, and start putting all the other things to the subsequent internal fields. But for now,
       we are not taking this approach just because I'm not sure this is necessary. If we found such a pattern, we can easily extend the current one but for now, I would like to keep
       this patch simple.

* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* builtins/AsyncFunctionPrototype.js:
(globalPrivate.asyncFunctionResume):
* builtins/GeneratorPrototype.js:
(globalPrivate.generatorResume):
(next):
(return):
(throw):
* bytecode/BytecodeGeneratorification.cpp:
(JSC::BytecodeGeneratorification::run):
* bytecode/BytecodeIntrinsicRegistry.cpp:
(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
* bytecode/BytecodeIntrinsicRegistry.h:
* bytecode/BytecodeList.rb:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::finalizeLLIntInlineCaches):
* bytecode/SpeculatedType.cpp:
(JSC::speculationFromJSType):
* bytecode/SpeculatedType.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitPutGeneratorFields):
(JSC::BytecodeGenerator::emitCreateGenerator):
(JSC::BytecodeGenerator::emitNewGenerator):
(JSC::BytecodeGenerator::emitYield):
(JSC::BytecodeGenerator::emitDelegateYield):
(JSC::BytecodeGenerator::emitGeneratorStateChange):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitIsGenerator):
(JSC::BytecodeGenerator::generatorStateRegister):
(JSC::BytecodeGenerator::generatorValueRegister):
(JSC::BytecodeGenerator::generatorResumeModeRegister):
(JSC::BytecodeGenerator::generatorFrameRegister):
* bytecompiler/NodesCodegen.cpp:
(JSC::generatorInternalFieldIndex):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_getGeneratorInternalField):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_putGeneratorInternalField):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_isGenerator):
(JSC::FunctionNode::emitBytecode):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupIsCellWithType):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGNode.h:
(JSC::DFG::Node::convertToNewGenerator):
(JSC::DFG::Node::speculatedTypeForQuery):
(JSC::DFG::Node::hasStructure):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCreatePromise):
(JSC::DFG::SpeculativeJIT::compileCreateGenerator):
(JSC::DFG::SpeculativeJIT::compileNewGenerator):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStoreBarrierInsertionPhase.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileNewGenerator):
(JSC::FTL::DFG::LowerDFGToB3::compileCreatePromise):
(JSC::FTL::DFG::LowerDFGToB3::compileCreateGenerator):
(JSC::FTL::DFG::LowerDFGToB3::isCellWithType):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_get_internal_field):
(JSC::JIT::emit_op_put_internal_field):
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::createSubclassStructureSlow):
* runtime/InternalFunction.h:
(JSC::InternalFunction::createSubclassStructure):
* runtime/JSGenerator.cpp: Added.
(JSC::JSGenerator::create):
(JSC::JSGenerator::createStructure):
(JSC::JSGenerator::JSGenerator):
(JSC::JSGenerator::finishCreation):
(JSC::JSGenerator::visitChildren):
* runtime/JSGenerator.h: Copied from Source/JavaScriptCore/runtime/JSGeneratorFunction.h.
* runtime/JSGeneratorFunction.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::generatorStructure const):
* runtime/JSType.cpp:
(WTF::printInternal):
* runtime/JSType.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@250025 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog
index 2db1dda..6f0d4a1 100644
--- a/JSTests/ChangeLog
+++ b/JSTests/ChangeLog
@@ -1,5 +1,28 @@
 2019-09-17  Yusuke Suzuki  <ysuzuki@apple.com>
 
+        [JSC] Generator should have internal fields
+        https://bugs.webkit.org/show_bug.cgi?id=201159
+
+        Reviewed by Keith Miller.
+
+        * stress/create-generator.js: Added.
+        (shouldBe):
+        (test.generator):
+        (test):
+        * stress/generator-construct-failure.js: Added.
+        (shouldThrow):
+        (TypeError):
+        * stress/generator-prototype-change.js: Added.
+        (shouldBe):
+        (gen):
+        * stress/generator-prototype-closure.js: Added.
+        (shouldBe):
+        (test.gen):
+        (test):
+        * stress/object-assign-fast-path.js:
+
+2019-09-17  Yusuke Suzuki  <ysuzuki@apple.com>
+
         Follow-up after String.codePointAt optimization
         https://bugs.webkit.org/show_bug.cgi?id=201889
 
diff --git a/JSTests/stress/create-generator.js b/JSTests/stress/create-generator.js
new file mode 100644
index 0000000..92d0305
--- /dev/null
+++ b/JSTests/stress/create-generator.js
@@ -0,0 +1,20 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function test() {
+    function* generator() {
+        return this;
+    }
+
+    var g = generator();
+    shouldBe(g.__proto__, generator.prototype);
+    return g;
+}
+
+for (var i = 0; i < 1e6; ++i) {
+    var g1 = test();
+    var g2 = test();
+    shouldBe(g1.__proto__ != g2.__proto__, true);
+}
diff --git a/JSTests/stress/generator-construct-failure.js b/JSTests/stress/generator-construct-failure.js
new file mode 100644
index 0000000..0e4a3c7
--- /dev/null
+++ b/JSTests/stress/generator-construct-failure.js
@@ -0,0 +1,24 @@
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+function* gen() { }
+
+shouldThrow(() => {
+    new gen()
+}, `TypeError: function is not a constructor (evaluating 'new gen()')`);
+
+shouldThrow(() => {
+    Reflect.construct(gen, [], {});
+}, `TypeError: Reflect.construct requires the first argument be a constructor`);
diff --git a/JSTests/stress/generator-prototype-change.js b/JSTests/stress/generator-prototype-change.js
new file mode 100644
index 0000000..9871172
--- /dev/null
+++ b/JSTests/stress/generator-prototype-change.js
@@ -0,0 +1,18 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function* gen()
+{
+}
+var originalPrototype = gen.prototype;
+
+for (var i = 0; i < 1e6; ++i) {
+    var g = gen();
+    shouldBe(g.__proto__, gen.prototype);
+}
+gen.prototype = {};
+var g = gen();
+shouldBe(g.__proto__, gen.prototype);
+shouldBe(g.__proto__ !== originalPrototype, true);
diff --git a/JSTests/stress/generator-prototype-closure.js b/JSTests/stress/generator-prototype-closure.js
new file mode 100644
index 0000000..4b28ed6
--- /dev/null
+++ b/JSTests/stress/generator-prototype-closure.js
@@ -0,0 +1,22 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function test() {
+    function* gen()
+    {
+    }
+    var originalPrototype = gen.prototype;
+
+    var g = gen();
+    shouldBe(g.__proto__, gen.prototype);
+    gen.prototype = {};
+    var g = gen();
+    shouldBe(g.__proto__, gen.prototype);
+    shouldBe(g.__proto__ !== originalPrototype, true);
+}
+noInline(test);
+
+for (var i = 0; i < 1e5; ++i)
+    test();
diff --git a/JSTests/stress/object-assign-fast-path.js b/JSTests/stress/object-assign-fast-path.js
index 5c6d547..ecb90d5 100644
--- a/JSTests/stress/object-assign-fast-path.js
+++ b/JSTests/stress/object-assign-fast-path.js
@@ -128,14 +128,18 @@
     shouldBe(okCalled, 1);
 }
 {
-    let builtin = createBuiltin(`(function (obj) {
-        return @getByIdDirectPrivate(obj, "generatorState");
+    let builtinPut = createBuiltin(`(function (obj, value) {
+        @putByIdDirectPrivate(obj, "next", value);
     })`);
-    function* hello() { }
-    let generator = hello();
-    shouldBe(typeof builtin(generator), "number");
-    let result = Object.assign({}, generator);
-    shouldBe(typeof builtin(result), "undefined");
+    let builtinGet = createBuiltin(`(function (obj) {
+        return @getByIdDirectPrivate(obj, "next");
+    })`);
+    var object = {};
+    var value = 42;
+    builtinPut(object, value);
+    shouldBe(typeof builtinGet(object), "number");
+    let result = Object.assign({}, object);
+    shouldBe(typeof builtinGet(result), "undefined");
 }
 {
     let object = {};
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 8bfadca..e12172e 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,166 @@
+2019-09-17  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] Generator should have internal fields
+        https://bugs.webkit.org/show_bug.cgi?id=201159
+
+        Reviewed by Keith Miller.
+
+        This patch makes generator's internal states InternalField instead of private properties.
+        Each generator function produces a generator with different [[Prototype]], which makes generators have different Structures.
+        As a result, Generator.prototype.next etc.'s implementation becomes megamorphic even if it is not necessary.
+
+        If we make these structures adaptively poly-proto, some generators get poly-proto structures while others are not, resulting
+        in megamorphic lookup in Generator.prototype.next. If we make all the generator's structure poly-proto, it makes Generator.prototype.next
+        lookup suboptimal for now.
+
+        In this patch, we start with a relatively simple solution. This patch introduces JSGenerator class, and it has internal fields for generator's internal
+        states. We extend promise-internal-field access bytecodes to access to these fields from bytecode so that Generator.prototype.next can access
+        these fields without using megamorphic get_by_id_direct.
+
+        And we attach JSGeneratorType to JSGenerator so that we can efficiently implement `@isGenerator()` check in bytecode.
+
+        We reserve the offset = 0 slot for the future poly-proto extension for JSGenerator. By reserving this slot, non-poly-proto JSGenerator and poly-proto
+        JSGenerator still can offer the way to access to the same Generator internal fields with the same offset while poly-proto JSGenerator can get offset = 0
+        inline-storage slot for PolyProto implementation.
+
+        This patch adds op_create_generator since it is distinct from op_create_promise once we add PolyProto support.
+        In the future when we introduce some kind of op_create_async_generator we will probably share only one bytecode for both generator and async generator.
+
+        This patch offers around 10% improvement in JetStream2/Basic. And this patch is the basis of optimization of JetStream2/async-fs which leverages async generators significantly.
+
+        This patch includes several design decisions.
+
+            1. We add a new JSGenerator instead of leveraging JSFinalObject. The main reason is that we would like to have JSGeneratorType to quickly query `@isGenerator`.
+            2. This patch currently does not include object-allocation-sinking support for JSGenerator, but it is trivial, and will be added. And this patch also does not include poly-proto
+               support for JSGenerator. The main reason is simply because this patch is already large enough, and I do not want to make this patch larger and larger.
+            3. We can support arbitrary sized inline-storage: Reserving 0-5 offsets for internal fields, and start putting all the other things to the subsequent internal fields. But for now,
+               we are not taking this approach just because I'm not sure this is necessary. If we found such a pattern, we can easily extend the current one but for now, I would like to keep
+               this patch simple.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * builtins/AsyncFunctionPrototype.js:
+        (globalPrivate.asyncFunctionResume):
+        * builtins/GeneratorPrototype.js:
+        (globalPrivate.generatorResume):
+        (next):
+        (return):
+        (throw):
+        * bytecode/BytecodeGeneratorification.cpp:
+        (JSC::BytecodeGeneratorification::run):
+        * bytecode/BytecodeIntrinsicRegistry.cpp:
+        (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
+        * bytecode/BytecodeIntrinsicRegistry.h:
+        * bytecode/BytecodeList.rb:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::finishCreation):
+        (JSC::CodeBlock::finalizeLLIntInlineCaches):
+        * bytecode/SpeculatedType.cpp:
+        (JSC::speculationFromJSType):
+        * bytecode/SpeculatedType.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitPutGeneratorFields):
+        (JSC::BytecodeGenerator::emitCreateGenerator):
+        (JSC::BytecodeGenerator::emitNewGenerator):
+        (JSC::BytecodeGenerator::emitYield):
+        (JSC::BytecodeGenerator::emitDelegateYield):
+        (JSC::BytecodeGenerator::emitGeneratorStateChange):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::emitIsGenerator):
+        (JSC::BytecodeGenerator::generatorStateRegister):
+        (JSC::BytecodeGenerator::generatorValueRegister):
+        (JSC::BytecodeGenerator::generatorResumeModeRegister):
+        (JSC::BytecodeGenerator::generatorFrameRegister):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::generatorInternalFieldIndex):
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_getGeneratorInternalField):
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_putGeneratorInternalField):
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_isGenerator):
+        (JSC::FunctionNode::emitBytecode):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGClobbersExitState.cpp:
+        (JSC::DFG::clobbersExitState):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::fixupIsCellWithType):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToNewGenerator):
+        (JSC::DFG::Node::speculatedTypeForQuery):
+        (JSC::DFG::Node::hasStructure):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCreatePromise):
+        (JSC::DFG::SpeculativeJIT::compileCreateGenerator):
+        (JSC::DFG::SpeculativeJIT::compileNewGenerator):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStoreBarrierInsertionPhase.cpp:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileNewGenerator):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCreatePromise):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCreateGenerator):
+        (JSC::FTL::DFG::LowerDFGToB3::isCellWithType):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_get_internal_field):
+        (JSC::JIT::emit_op_put_internal_field):
+        * llint/LowLevelInterpreter.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/InternalFunction.cpp:
+        (JSC::InternalFunction::createSubclassStructureSlow):
+        * runtime/InternalFunction.h:
+        (JSC::InternalFunction::createSubclassStructure):
+        * runtime/JSGenerator.cpp: Added.
+        (JSC::JSGenerator::create):
+        (JSC::JSGenerator::createStructure):
+        (JSC::JSGenerator::JSGenerator):
+        (JSC::JSGenerator::finishCreation):
+        (JSC::JSGenerator::visitChildren):
+        * runtime/JSGenerator.h: Copied from Source/JavaScriptCore/runtime/JSGeneratorFunction.h.
+        * runtime/JSGeneratorFunction.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::generatorStructure const):
+        * runtime/JSType.cpp:
+        (WTF::printInternal):
+        * runtime/JSType.h:
+
 2019-09-17  Keith Miller  <keith_miller@apple.com>
 
         Move comment explaining our Options to OptionsList.h
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 62edca9..fb40b0e 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -1803,6 +1803,7 @@
 		E3400EC122A1CC7B009DED54 /* FunctionExecutableInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E3400EC022A1CC78009DED54 /* FunctionExecutableInlines.h */; };
 		E34E657520668EAA00FB81AC /* ParseHash.h in Headers */ = {isa = PBXBuildFile; fileRef = E34E657320668E8D00FB81AC /* ParseHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E34EDBF71DB5FFC900DC87A5 /* FrameTracers.h in Headers */ = {isa = PBXBuildFile; fileRef = E34EDBF61DB5FFC100DC87A5 /* FrameTracers.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		E34F930E2322D882002B8DB4 /* JSGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = E34F930C2322D881002B8DB4 /* JSGenerator.h */; };
 		E350708A1DC49BBF0089BCD6 /* DOMJITSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = E35070891DC49BB60089BCD6 /* DOMJITSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E354622B1B6065D100545386 /* ConstructAbility.h in Headers */ = {isa = PBXBuildFile; fileRef = E354622A1B6065D100545386 /* ConstructAbility.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E3555B8A1DAE03A500F36921 /* DOMJITCallDOMGetterSnippet.h in Headers */ = {isa = PBXBuildFile; fileRef = E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterSnippet.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4901,6 +4902,8 @@
 		E34E657320668E8D00FB81AC /* ParseHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseHash.h; sourceTree = "<group>"; };
 		E34E657420668E8E00FB81AC /* ParseHash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParseHash.cpp; sourceTree = "<group>"; };
 		E34EDBF61DB5FFC100DC87A5 /* FrameTracers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FrameTracers.h; sourceTree = "<group>"; };
+		E34F930B2322D881002B8DB4 /* JSGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGenerator.cpp; sourceTree = "<group>"; };
+		E34F930C2322D881002B8DB4 /* JSGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenerator.h; sourceTree = "<group>"; };
 		E35070891DC49BB60089BCD6 /* DOMJITSignature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITSignature.h; sourceTree = "<group>"; };
 		E354622A1B6065D100545386 /* ConstructAbility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstructAbility.h; sourceTree = "<group>"; };
 		E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterSnippet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITCallDOMGetterSnippet.h; sourceTree = "<group>"; };
@@ -7176,6 +7179,8 @@
 				F692A85E0255597D01FF60F7 /* JSFunction.cpp */,
 				F692A85F0255597D01FF60F7 /* JSFunction.h */,
 				A72028B91797603D0098028C /* JSFunctionInlines.h */,
+				E34F930B2322D881002B8DB4 /* JSGenerator.cpp */,
+				E34F930C2322D881002B8DB4 /* JSGenerator.h */,
 				70B7918C1C024462002481E2 /* JSGeneratorFunction.cpp */,
 				70B7918D1C024462002481E2 /* JSGeneratorFunction.h */,
 				0F2B66C317B6B5AB00A7AE3F /* JSGenericTypedArrayView.h */,
@@ -9638,6 +9643,7 @@
 				0F2B66F017B6B5AB00A7AE3F /* JSFloat64Array.h in Headers */,
 				BC18C41F0E16F5CD00B34460 /* JSFunction.h in Headers */,
 				A72028BA1797603D0098028C /* JSFunctionInlines.h in Headers */,
+				E34F930E2322D882002B8DB4 /* JSGenerator.h in Headers */,
 				70B7919C1C024A49002481E2 /* JSGeneratorFunction.h in Headers */,
 				0F2B66F117B6B5AB00A7AE3F /* JSGenericTypedArrayView.h in Headers */,
 				0F2B66F217B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructor.h in Headers */,
diff --git a/Source/JavaScriptCore/Sources.txt b/Source/JavaScriptCore/Sources.txt
index 6a331d1..43ea530 100644
--- a/Source/JavaScriptCore/Sources.txt
+++ b/Source/JavaScriptCore/Sources.txt
@@ -824,6 +824,7 @@
 runtime/JSDestructibleObjectHeapCellType.cpp
 runtime/JSFixedArray.cpp
 runtime/JSFunction.cpp
+runtime/JSGenerator.cpp
 runtime/JSGeneratorFunction.cpp
 runtime/JSGlobalLexicalEnvironment.cpp
 runtime/JSGlobalObject.cpp
diff --git a/Source/JavaScriptCore/builtins/AsyncFunctionPrototype.js b/Source/JavaScriptCore/builtins/AsyncFunctionPrototype.js
index 5214bd6..968cf1e 100644
--- a/Source/JavaScriptCore/builtins/AsyncFunctionPrototype.js
+++ b/Source/JavaScriptCore/builtins/AsyncFunctionPrototype.js
@@ -31,22 +31,22 @@
 
     @assert(@isPromise(promise));
 
-    var state = @getByIdDirectPrivate(generator, "generatorState");
+    var state = @getGeneratorInternalField(generator, @generatorFieldState);
     var value = @undefined;
 
     if (state === @GeneratorStateCompleted || (resumeMode !== @GeneratorResumeModeNormal && resumeMode !== @GeneratorResumeModeThrow))
         @throwTypeError("Async function illegally resumed");
 
     try {
-        @putByIdDirectPrivate(generator, "generatorState", @GeneratorStateExecuting);
-        value = @getByIdDirectPrivate(generator, "generatorNext").@call(@getByIdDirectPrivate(generator, "generatorThis"), generator, state, sentValue, resumeMode, @getByIdDirectPrivate(generator, "generatorFrame"));
-        if (@getByIdDirectPrivate(generator, "generatorState") === @GeneratorStateExecuting) {
-            @putByIdDirectPrivate(generator, "generatorState", @GeneratorStateCompleted);
+        @putGeneratorInternalField(generator, @generatorFieldState, @GeneratorStateExecuting);
+        value = @getGeneratorInternalField(generator, @generatorFieldNext).@call(@getGeneratorInternalField(generator, @generatorFieldThis), generator, state, sentValue, resumeMode, @getGeneratorInternalField(generator, @generatorFieldFrame));
+        if (@getGeneratorInternalField(generator, @generatorFieldState) === @GeneratorStateExecuting) {
+            @putGeneratorInternalField(generator, @generatorFieldState, @GeneratorStateCompleted);
             @resolvePromiseWithFirstResolvingFunctionCallCheck(promise, value);
             return promise;
         }
     } catch (error) {
-        @putByIdDirectPrivate(generator, "generatorState", @GeneratorStateCompleted);
+        @putGeneratorInternalField(generator, @generatorFieldState, @GeneratorStateCompleted);
         @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, error);
         return promise;
     }
diff --git a/Source/JavaScriptCore/builtins/GeneratorPrototype.js b/Source/JavaScriptCore/builtins/GeneratorPrototype.js
index b2801df..8393ea2 100644
--- a/Source/JavaScriptCore/builtins/GeneratorPrototype.js
+++ b/Source/JavaScriptCore/builtins/GeneratorPrototype.js
@@ -34,14 +34,14 @@
     var done = state === @GeneratorStateCompleted;
     if (!done) {
         try {
-            @putByIdDirectPrivate(generator, "generatorState", @GeneratorStateExecuting);
-            value = @getByIdDirectPrivate(generator, "generatorNext").@call(generatorThis, generator, state, sentValue, resumeMode, @getByIdDirectPrivate(generator, "generatorFrame"));
-            if (@getByIdDirectPrivate(generator, "generatorState") === @GeneratorStateExecuting) {
-                @putByIdDirectPrivate(generator, "generatorState", @GeneratorStateCompleted);
+            @putGeneratorInternalField(generator, @generatorFieldState, @GeneratorStateExecuting);
+            value = @getGeneratorInternalField(generator, @generatorFieldNext).@call(generatorThis, generator, state, sentValue, resumeMode, @getGeneratorInternalField(generator, @generatorFieldFrame));
+            if (@getGeneratorInternalField(generator, @generatorFieldState) === @GeneratorStateExecuting) {
+                @putGeneratorInternalField(generator, @generatorFieldState, @GeneratorStateCompleted);
                 done = true;
             }
         } catch (error) {
-            @putByIdDirectPrivate(generator, "generatorState", @GeneratorStateCompleted);
+            @putGeneratorInternalField(generator, @generatorFieldState, @GeneratorStateCompleted);
             throw error;
         }
     }
@@ -52,43 +52,43 @@
 {
     "use strict";
 
-    var state = @getByIdDirectPrivate(this, "generatorState");
-    if (typeof state !== "number")
+    if (!@isGenerator(this))
         @throwTypeError("|this| should be a generator");
 
+    var state = @getGeneratorInternalField(this, @generatorFieldState);
     if (state === @GeneratorStateExecuting)
         @throwTypeError("Generator is executing");
 
-    return @generatorResume(this, state, @getByIdDirectPrivate(this, "generatorThis"), value, @undefined, @GeneratorResumeModeNormal);
+    return @generatorResume(this, state, @getGeneratorInternalField(this, @generatorFieldThis), value, @undefined, @GeneratorResumeModeNormal);
 }
 
 function return(value)
 {
     "use strict";
 
-    var state = @getByIdDirectPrivate(this, "generatorState");
-    if (typeof state !== "number")
+    if (!@isGenerator(this))
         @throwTypeError("|this| should be a generator");
 
+    var state = @getGeneratorInternalField(this, @generatorFieldState);
     if (state === @GeneratorStateExecuting)
         @throwTypeError("Generator is executing");
 
-    return @generatorResume(this, state, @getByIdDirectPrivate(this, "generatorThis"), value, value, @GeneratorResumeModeReturn);
+    return @generatorResume(this, state, @getGeneratorInternalField(this, @generatorFieldThis), value, value, @GeneratorResumeModeReturn);
 }
 
 function throw(exception)
 {
     "use strict";
 
-    var state = @getByIdDirectPrivate(this, "generatorState");
-    if (typeof state !== "number")
+    if (!@isGenerator(this))
         @throwTypeError("|this| should be a generator");
 
+    var state = @getGeneratorInternalField(this, @generatorFieldState);
     if (state === @GeneratorStateExecuting)
         @throwTypeError("Generator is executing");
 
     if (state === @GeneratorStateCompleted)
         throw exception;
 
-    return @generatorResume(this, state, @getByIdDirectPrivate(this, "generatorThis"), exception, @undefined, @GeneratorResumeModeThrow);
+    return @generatorResume(this, state, @getGeneratorInternalField(this, @generatorFieldThis), exception, @undefined, @GeneratorResumeModeThrow);
 }
diff --git a/Source/JavaScriptCore/bytecode/BytecodeGeneratorification.cpp b/Source/JavaScriptCore/bytecode/BytecodeGeneratorification.cpp
index 9544bcb..286051c 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeGeneratorification.cpp
+++ b/Source/JavaScriptCore/bytecode/BytecodeGeneratorification.cpp
@@ -36,7 +36,7 @@
 #include "InterpreterInlines.h"
 #include "JSCInlines.h"
 #include "JSCJSValueInlines.h"
-#include "JSGeneratorFunction.h"
+#include "JSGenerator.h"
 #include "Label.h"
 #include "StrongInlines.h"
 #include "UnlinkedCodeBlock.h"
@@ -223,7 +223,7 @@
     {
         auto nextToEnterPoint = enterPoint().next();
         unsigned switchTableIndex = m_codeBlock->numberOfSwitchJumpTables();
-        VirtualRegister state = virtualRegisterForArgument(static_cast<int32_t>(JSGeneratorFunction::GeneratorArgument::State));
+        VirtualRegister state = virtualRegisterForArgument(static_cast<int32_t>(JSGenerator::GeneratorArgument::State));
         auto& jumpTable = m_codeBlock->addSwitchJumpTable();
         jumpTable.min = 0;
         jumpTable.branchOffsets.resize(m_yields.size() + 1);
@@ -238,7 +238,7 @@
     }
 
     for (const YieldData& data : m_yields) {
-        VirtualRegister scope = virtualRegisterForArgument(static_cast<int32_t>(JSGeneratorFunction::GeneratorArgument::Frame));
+        VirtualRegister scope = virtualRegisterForArgument(static_cast<int32_t>(JSGenerator::GeneratorArgument::Frame));
 
         auto instruction = m_instructions.at(data.point);
         // Emit save sequence.
diff --git a/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp b/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp
index 198443d..06fc581 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp
+++ b/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp
@@ -33,7 +33,7 @@
 #include "IterationKind.h"
 #include "JSAsyncGeneratorFunction.h"
 #include "JSCInlines.h"
-#include "JSGeneratorFunction.h"
+#include "JSGenerator.h"
 #include "JSGlobalObject.h"
 #include "JSModuleLoader.h"
 #include "JSPromise.h"
@@ -72,13 +72,19 @@
     m_promiseStateMask.set(m_vm, jsNumber(JSPromise::stateMask));
     m_promiseFlagsIsHandled.set(m_vm, jsNumber(JSPromise::isHandledFlag));
     m_promiseFlagsIsFirstResolvingFunctionCalled.set(m_vm, jsNumber(JSPromise::isFirstResolvingFunctionCalledFlag));
+    // FIXME: Clean up JSInternalObjectImpl field registry.
+    // https://bugs.webkit.org/show_bug.cgi?id=201894
     m_promiseFieldFlags.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Field::Flags)));
     m_promiseFieldReactionsOrResult.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Field::ReactionsOrResult)));
-    m_GeneratorResumeModeNormal.set(m_vm, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode)));
-    m_GeneratorResumeModeThrow.set(m_vm, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::ThrowMode)));
-    m_GeneratorResumeModeReturn.set(m_vm, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::ReturnMode)));
-    m_GeneratorStateCompleted.set(m_vm, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorState::Completed)));
-    m_GeneratorStateExecuting.set(m_vm, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorState::Executing)));
+    m_generatorFieldState.set(m_vm, jsNumber(static_cast<unsigned>(JSGenerator::Field::State)));
+    m_generatorFieldNext.set(m_vm, jsNumber(static_cast<unsigned>(JSGenerator::Field::Next)));
+    m_generatorFieldThis.set(m_vm, jsNumber(static_cast<unsigned>(JSGenerator::Field::This)));
+    m_generatorFieldFrame.set(m_vm, jsNumber(static_cast<unsigned>(JSGenerator::Field::Frame)));
+    m_GeneratorResumeModeNormal.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode)));
+    m_GeneratorResumeModeThrow.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::ThrowMode)));
+    m_GeneratorResumeModeReturn.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::ReturnMode)));
+    m_GeneratorStateCompleted.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorState::Completed)));
+    m_GeneratorStateExecuting.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorState::Executing)));
     m_AsyncGeneratorStateCompleted.set(m_vm, jsNumber(static_cast<int32_t>(JSAsyncGeneratorFunction::AsyncGeneratorState::Completed)));
     m_AsyncGeneratorStateExecuting.set(m_vm, jsNumber(static_cast<int32_t>(JSAsyncGeneratorFunction::AsyncGeneratorState::Executing)));
     m_AsyncGeneratorStateSuspendedStart.set(m_vm, jsNumber(static_cast<int32_t>(JSAsyncGeneratorFunction::AsyncGeneratorState::SuspendedStart)));
diff --git a/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h b/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h
index d5f6c3b..280b7f9 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h
+++ b/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h
@@ -42,11 +42,13 @@
     macro(getByIdDirect) \
     macro(getByIdDirectPrivate) \
     macro(getPromiseInternalField) \
+    macro(getGeneratorInternalField) \
     macro(idWithProfile) \
     macro(isObject) \
     macro(isJSArray) \
     macro(isProxyObject) \
     macro(isDerivedArray) \
+    macro(isGenerator) \
     macro(isPromise) \
     macro(isRegExpObject) \
     macro(isMap) \
@@ -61,6 +63,7 @@
     macro(putByIdDirectPrivate) \
     macro(putByValDirect) \
     macro(putPromiseInternalField) \
+    macro(putGeneratorInternalField) \
     macro(toNumber) \
     macro(toString) \
     macro(toObject) \
@@ -98,6 +101,10 @@
     macro(promiseFlagsIsFirstResolvingFunctionCalled) \
     macro(promiseFieldFlags) \
     macro(promiseFieldReactionsOrResult) \
+    macro(generatorFieldState) \
+    macro(generatorFieldNext) \
+    macro(generatorFieldThis) \
+    macro(generatorFieldFrame) \
     macro(GeneratorResumeModeNormal) \
     macro(GeneratorResumeModeThrow) \
     macro(GeneratorResumeModeReturn) \
diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.rb b/Source/JavaScriptCore/bytecode/BytecodeList.rb
index 3b3998a..1ba41f1 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeList.rb
+++ b/Source/JavaScriptCore/bytecode/BytecodeList.rb
@@ -134,6 +134,20 @@
         isInternalPromise: bool,
     }
 
+op :create_generator,
+    args: {
+        dst: VirtualRegister,
+        callee: VirtualRegister,
+    },
+    metadata: {
+        cachedCallee: WriteBarrier[JSCell]
+    }
+
+op :new_generator,
+    args: {
+        dst: VirtualRegister,
+    }
+
 op :get_argument,
     args: {
         dst: VirtualRegister,
diff --git a/Source/JavaScriptCore/bytecode/BytecodeUseDef.h b/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
index be08596..4079249 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
+++ b/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
@@ -80,6 +80,7 @@
     case op_jmp:
     case op_new_object:
     case op_new_promise:
+    case op_new_generator:
     case op_enter:
     case op_argument_count:
     case op_catch:
@@ -194,6 +195,7 @@
     USES(OpNewArrayWithSize, length)
     USES(OpCreateThis, callee)
     USES(OpCreatePromise, callee)
+    USES(OpCreateGenerator, callee)
     USES(OpDelById, base)
     USES(OpNewFunc, scope)
     USES(OpNewAsyncGeneratorFunc, scope)
@@ -385,6 +387,7 @@
     DEFS(OpToPrimitive, dst)
     DEFS(OpCreateThis, dst)
     DEFS(OpCreatePromise, dst)
+    DEFS(OpCreateGenerator, dst)
     DEFS(OpNewArray, dst)
     DEFS(OpNewArrayWithSpread, dst)
     DEFS(OpSpread, dst)
@@ -465,6 +468,7 @@
     DEFS(OpMov, dst)
     DEFS(OpNewObject, dst)
     DEFS(OpNewPromise, dst)
+    DEFS(OpNewGenerator, dst)
     DEFS(OpToThis, srcDst)
     DEFS(OpGetScope, dst)
     DEFS(OpCreateDirectArguments, dst)
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 1382f69..5b4ab15 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -568,6 +568,7 @@
         LINK(OpPutById)
         LINK(OpCreateThis)
         LINK(OpCreatePromise)
+        LINK(OpCreateGenerator)
 
         LINK(OpAdd)
         LINK(OpMul)
@@ -1274,6 +1275,9 @@
         m_metadata->forEach<OpCreatePromise>([&] (auto& metadata) {
             handleCreateBytecode(metadata, "op_create_promise"_s);
         });
+        m_metadata->forEach<OpCreateGenerator>([&] (auto& metadata) {
+            handleCreateBytecode(metadata, "op_create_generator"_s);
+        });
 
         m_metadata->forEach<OpResolveScope>([&] (auto& metadata) {
             // Right now this isn't strictly necessary. Any symbol tables that this will refer to
diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.cpp b/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
index 42b626c..6d4e220 100644
--- a/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
+++ b/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
@@ -579,7 +579,7 @@
     return NotTypedArray;
 }
 
-SpeculatedType speculationFromJSType(JSType type)
+Optional<SpeculatedType> speculationFromJSType(JSType type)
 {
     switch (type) {
     case StringType:
@@ -609,9 +609,8 @@
     case DataViewType:
         return SpecDataViewObject;
     default:
-        ASSERT_NOT_REACHED();
+        return WTF::nullopt;
     }
-    return SpecNone;
 }
 
 SpeculatedType leastUpperBoundOfStrictlyEquivalentSpeculations(SpeculatedType type)
diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.h b/Source/JavaScriptCore/bytecode/SpeculatedType.h
index b929bc2..b1153b4 100644
--- a/Source/JavaScriptCore/bytecode/SpeculatedType.h
+++ b/Source/JavaScriptCore/bytecode/SpeculatedType.h
@@ -497,7 +497,7 @@
 // If it's an anyInt(), it'll return speculated types from the Int52 lattice.
 // Otherwise, it'll return types from the JSValue lattice.
 JS_EXPORT_PRIVATE SpeculatedType int52AwareSpeculationFromValue(JSValue);
-SpeculatedType speculationFromJSType(JSType);
+Optional<SpeculatedType> speculationFromJSType(JSType);
 
 SpeculatedType speculationFromTypedArrayType(TypedArrayType); // only valid for typed views.
 TypedArrayType typedArrayTypeFromSpeculation(SpeculatedType);
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 6883545..fb47b5e 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -683,7 +683,17 @@
 
     switch (parseMode) {
     case SourceParseMode::GeneratorWrapperFunctionMode:
-    case SourceParseMode::GeneratorWrapperMethodMode:
+    case SourceParseMode::GeneratorWrapperMethodMode: {
+        m_generatorRegister = addVar();
+
+        // FIXME: Emit to_this only when Generator uses it.
+        // https://bugs.webkit.org/show_bug.cgi?id=151586
+        emitToThis();
+
+        emitCreateGenerator(m_generatorRegister, &m_calleeRegister);
+        break;
+    }
+
     case SourceParseMode::AsyncGeneratorWrapperMethodMode:
     case SourceParseMode::AsyncGeneratorWrapperFunctionMode: {
         m_generatorRegister = addVar();
@@ -711,7 +721,7 @@
             emitToThis();
         }
 
-        emitNewObject(m_generatorRegister);
+        emitNewGenerator(m_generatorRegister);
         emitNewPromise(promiseRegister(), m_isBuiltinFunction);
         break;
     }
@@ -866,7 +876,10 @@
             // Generatorification inserts lexical environment creation if necessary. Otherwise, we convert it to op_mov frame, `undefined`.
             OpCreateGeneratorFrameEnvironment::emit(this, generatorFrameRegister(), scopeRegister(), VirtualRegister { symbolTableConstantIndex }, addConstantValue(jsUndefined()));
         }
-        emitPutById(generatorRegister(), propertyNames().builtinNames().generatorFramePrivateName(), generatorFrameRegister());
+        if (parseMode == SourceParseMode::AsyncGeneratorBodyMode)
+            emitPutById(generatorRegister(), propertyNames().builtinNames().generatorFramePrivateName(), generatorFrameRegister());
+        else
+            emitPutInternalField(generatorRegister(), static_cast<unsigned>(JSGenerator::Field::Frame), generatorFrameRegister());
     }
 
     bool shouldInitializeBlockScopedFunctions = false; // We generate top-level function declarations in ::generate().
@@ -2698,20 +2711,12 @@
 
 void BytecodeGenerator::emitPutGeneratorFields(RegisterID* nextFunction)
 {
-    // FIXME: Currently, we just create an object and store generator related fields as its properties for ease.
-    // But to make it efficient, we will introduce JSGenerator class, add opcode new_generator and use its C++ fields instead of these private properties.
-    // https://bugs.webkit.org/show_bug.cgi?id=151545
-
-    emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorNextPrivateName(), nextFunction, PropertyNode::KnownDirect);
+    emitPutInternalField(m_generatorRegister, static_cast<unsigned>(JSGenerator::Field::Next), nextFunction);
 
     // We do not store 'this' in arrow function within constructor,
     // because it might be not initialized, if super is called later.
     if (!(isDerivedConstructorContext() && m_codeBlock->parseMode() == SourceParseMode::AsyncArrowFunctionMode))
-        emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorThisPrivateName(), &m_thisRegister, PropertyNode::KnownDirect);
-
-    emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorStatePrivateName(), emitLoad(nullptr, jsNumber(0)), PropertyNode::KnownDirect);
-
-    emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorFramePrivateName(), emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect);
+        emitPutInternalField(m_generatorRegister, static_cast<unsigned>(JSGenerator::Field::This), &m_thisRegister);
 }
 
 void BytecodeGenerator::emitPutAsyncGeneratorFields(RegisterID* nextFunction)
@@ -2858,6 +2863,18 @@
     return dst;
 }
 
+RegisterID* BytecodeGenerator::emitCreateGenerator(RegisterID* dst, RegisterID* newTarget)
+{
+    OpCreateGenerator::emit(this, dst, newTarget);
+    return dst;
+}
+
+RegisterID* BytecodeGenerator::emitNewGenerator(RegisterID* dst)
+{
+    OpNewGenerator::emit(this, dst);
+    return dst;
+}
+
 void BytecodeGenerator::emitTDZCheck(RegisterID* target)
 {
     OpCheckTdz::emit(this, target);
@@ -4544,11 +4561,11 @@
 
     Ref<Label> normalLabel = newLabel();
     RefPtr<RegisterID> condition = newTemporary();
-    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode))));
+    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode))));
     emitJumpIfTrue(condition.get(), normalLabel.get());
 
     Ref<Label> throwLabel = newLabel();
-    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::ThrowMode))));
+    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::ThrowMode))));
     emitJumpIfTrue(condition.get(), throwLabel.get());
     // Return.
     {
@@ -4656,10 +4673,10 @@
                 Ref<Label> returnLabel = newLabel();
                 {
                     RefPtr<RegisterID> condition = newTemporary();
-                    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode))));
+                    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode))));
                     emitJumpIfTrue(condition.get(), normalLabel.get());
 
-                    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::ReturnMode))));
+                    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::ReturnMode))));
                     emitJumpIfTrue(condition.get(), returnLabel.get());
 
                     // Fallthrough to ThrowMode.
@@ -4761,7 +4778,10 @@
 void BytecodeGenerator::emitGeneratorStateChange(int32_t state)
 {
     RegisterID* completedState = emitLoad(nullptr, jsNumber(state));
-    emitPutById(generatorRegister(), propertyNames().builtinNames().generatorStatePrivateName(), completedState);
+    if (m_codeBlock->parseMode() == SourceParseMode::AsyncGeneratorBodyMode)
+        emitPutById(generatorRegister(), propertyNames().builtinNames().generatorStatePrivateName(), completedState);
+    else
+        emitPutInternalField(generatorRegister(), static_cast<unsigned>(JSGenerator::Field::State), completedState);
 }
 
 bool BytecodeGenerator::emitJumpViaFinallyIfNeeded(int targetLabelScopeDepth, Label& jumpTarget)
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index 4f36a73..2694b22 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -35,7 +35,7 @@
 #include "Interpreter.h"
 #include "JSAsyncGeneratorFunction.h"
 #include "JSBigInt.h"
-#include "JSGeneratorFunction.h"
+#include "JSGenerator.h"
 #include "JSTemplateObjectDescriptor.h"
 #include "Label.h"
 #include "LabelScope.h"
@@ -724,12 +724,14 @@
 
         RegisterID* emitCreateThis(RegisterID* dst);
         RegisterID* emitCreatePromise(RegisterID* dst, RegisterID* newTarget, bool isInternalPromise);
+        RegisterID* emitCreateGenerator(RegisterID* dst, RegisterID* newTarget);
         void emitTDZCheck(RegisterID* target);
         bool needsTDZCheck(const Variable&);
         void emitTDZCheckIfNecessary(const Variable&, RegisterID* target, RegisterID* scope);
         void liftTDZCheckIfPossible(const Variable&);
         RegisterID* emitNewObject(RegisterID* dst);
         RegisterID* emitNewPromise(RegisterID* dst, bool isInternalPromise);
+        RegisterID* emitNewGenerator(RegisterID* dst);
         RegisterID* emitNewArray(RegisterID* dst, ElementNode*, unsigned length, IndexingType recommendedIndexingType); // stops at first elision
         RegisterID* emitNewArrayBuffer(RegisterID* dst, JSImmutableButterfly*, IndexingType recommendedIndexingType);
         // FIXME: new_array_with_spread should use an array allocation profile and take a recommendedIndexingType
@@ -866,6 +868,7 @@
         RegisterID* emitToIndexString(RegisterID* dst, RegisterID* index);
 
         RegisterID* emitIsCellWithType(RegisterID* dst, RegisterID* src, JSType);
+        RegisterID* emitIsGenerator(RegisterID* dst, RegisterID* src) { return emitIsCellWithType(dst, src, JSGeneratorType); }
         RegisterID* emitIsJSArray(RegisterID* dst, RegisterID* src) { return emitIsCellWithType(dst, src, ArrayType); }
         RegisterID* emitIsPromise(RegisterID* dst, RegisterID* src) { return emitIsCellWithType(dst, src, JSPromiseType); }
         RegisterID* emitIsProxyObject(RegisterID* dst, RegisterID* src) { return emitIsCellWithType(dst, src, ProxyObjectType); }
@@ -988,10 +991,10 @@
         void emitGeneratorStateChange(int32_t state);
         RegisterID* emitYield(RegisterID* argument, JSAsyncGeneratorFunction::AsyncGeneratorSuspendReason = JSAsyncGeneratorFunction::AsyncGeneratorSuspendReason::Yield);
         RegisterID* emitDelegateYield(RegisterID* argument, ThrowableExpressionData*);
-        RegisterID* generatorStateRegister() { return &m_parameters[static_cast<int32_t>(JSGeneratorFunction::GeneratorArgument::State)]; }
-        RegisterID* generatorValueRegister() { return &m_parameters[static_cast<int32_t>(JSGeneratorFunction::GeneratorArgument::Value)]; }
-        RegisterID* generatorResumeModeRegister() { return &m_parameters[static_cast<int32_t>(JSGeneratorFunction::GeneratorArgument::ResumeMode)]; }
-        RegisterID* generatorFrameRegister() { return &m_parameters[static_cast<int32_t>(JSGeneratorFunction::GeneratorArgument::Frame)]; }
+        RegisterID* generatorStateRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::GeneratorArgument::State)]; }
+        RegisterID* generatorValueRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::GeneratorArgument::Value)]; }
+        RegisterID* generatorResumeModeRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::GeneratorArgument::ResumeMode)]; }
+        RegisterID* generatorFrameRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::GeneratorArgument::Frame)]; }
 
         CodeType codeType() const { return m_codeType; }
 
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 2c65f50..652766a 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -34,7 +34,7 @@
 #include "JIT.h"
 #include "JSCInlines.h"
 #include "JSFunction.h"
-#include "JSGeneratorFunction.h"
+#include "JSGenerator.h"
 #include "JSGlobalObject.h"
 #include "JSImmutableButterfly.h"
 #include "LabelScope.h"
@@ -1020,6 +1020,20 @@
     return JSPromise::Field::Flags;
 }
 
+static JSGenerator::Field generatorInternalFieldIndex(BytecodeIntrinsicNode* node)
+{
+    if (node->emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldState)
+        return JSGenerator::Field::State;
+    if (node->emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldNext)
+        return JSGenerator::Field::Next;
+    if (node->emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldThis)
+        return JSGenerator::Field::This;
+    if (node->emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldFrame)
+        return JSGenerator::Field::Frame;
+    RELEASE_ASSERT_NOT_REACHED();
+    return JSGenerator::Field::State;
+}
+
 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getPromiseInternalField(BytecodeGenerator& generator, RegisterID* dst)
 {
     ArgumentListNode* node = m_args->m_listNode;
@@ -1033,6 +1047,19 @@
     return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
 }
 
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getGeneratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
+{
+    ArgumentListNode* node = m_args->m_listNode;
+    RefPtr<RegisterID> base = generator.emitNode(node);
+    node = node->m_next;
+    RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
+    unsigned index = static_cast<unsigned>(generatorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
+    ASSERT(index < JSGenerator::numberOfInternalFields);
+    ASSERT(!node->m_next);
+
+    return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
+}
+
 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_argument(BytecodeGenerator& generator, RegisterID* dst)
 {
     ArgumentListNode* node = m_args->m_listNode;
@@ -1118,6 +1145,22 @@
     return generator.move(dst, generator.emitPutInternalField(base.get(), index, value.get()));
 }
 
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putGeneratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
+{
+    ArgumentListNode* node = m_args->m_listNode;
+    RefPtr<RegisterID> base = generator.emitNode(node);
+    node = node->m_next;
+    RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
+    unsigned index = static_cast<unsigned>(generatorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
+    ASSERT(index < JSGenerator::numberOfInternalFields);
+    node = node->m_next;
+    RefPtr<RegisterID> value = generator.emitNode(node);
+
+    ASSERT(!node->m_next);
+
+    return generator.move(dst, generator.emitPutInternalField(base.get(), index, value.get()));
+}
+
 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tailCallForwardArguments(BytecodeGenerator& generator, RegisterID* dst)
 {
     ArgumentListNode* node = m_args->m_listNode;
@@ -1231,6 +1274,15 @@
 
     return generator.move(dst, generator.emitIdWithProfile(idValue.get(), speculation));
 }
+
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isGenerator(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
+{
+    ArgumentListNode* node = m_args->m_listNode;
+    RefPtr<RegisterID> src = generator.emitNode(node);
+    ASSERT(!node->m_next);
+
+    return generator.move(dst, generator.emitIsGenerator(generator.tempDestination(dst), src.get()));
+}
     
 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isJSArray(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
 {
@@ -3993,7 +4045,7 @@
         generator.move(args.argumentRegister(argumentCount++), generator.generatorRegister());
         generator.move(args.argumentRegister(argumentCount++), generator.promiseRegister());
         generator.emitLoad(args.argumentRegister(argumentCount++), jsUndefined());
-        generator.emitLoad(args.argumentRegister(argumentCount++), jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode)));
+        generator.emitLoad(args.argumentRegister(argumentCount++), jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode)));
         // JSTextPosition(int _line, int _offset, int _lineStartOffset)
         JSTextPosition divot(firstLine(), startOffset(), lineStartOffset());
 
@@ -4010,11 +4062,11 @@
         Ref<Label> generatorBodyLabel = generator.newLabel();
         {
             RefPtr<RegisterID> condition = generator.newTemporary();
-            generator.emitEqualityOp<OpStricteq>(condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode))));
+            generator.emitEqualityOp<OpStricteq>(condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode))));
             generator.emitJumpIfTrue(condition.get(), generatorBodyLabel.get());
 
             Ref<Label> throwLabel = generator.newLabel();
-            generator.emitEqualityOp<OpStricteq>(condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::ThrowMode))));
+            generator.emitEqualityOp<OpStricteq>(condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::ThrowMode))));
             generator.emitJumpIfTrue(condition.get(), throwLabel.get());
 
             generator.emitReturn(generator.generatorValueRegister());
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
index c2fe3ab..9b637fd 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
@@ -37,6 +37,7 @@
 #include "GetterSetter.h"
 #include "HashMapImpl.h"
 #include "JITOperations.h"
+#include "JSGenerator.h"
 #include "JSImmutableButterfly.h"
 #include "JSInternalPromise.h"
 #include "JSInternalPromiseConstructor.h"
@@ -1564,18 +1565,27 @@
             }
             break;
 
-        case IsCellWithType:
-            if (!(child.m_type & ~node->speculatedTypeForQuery())) {
+        case IsCellWithType: {
+            Optional<SpeculatedType> filter = node->speculatedTypeForQuery();
+            if (!filter) {
+                if (!(child.m_type & SpecCell)) {
+                    setConstant(node, jsBoolean(false));
+                    constantWasSet = true;
+                }
+                break;
+            }
+            if (!(child.m_type & ~filter.value())) {
                 setConstant(node, jsBoolean(true));
                 constantWasSet = true;
                 break;
             }
-            if (!(child.m_type & node->speculatedTypeForQuery())) {
+            if (!(child.m_type & filter.value())) {
                 setConstant(node, jsBoolean(false));
                 constantWasSet = true;
                 break;
             }
             break;
+        }
 
         case IsTypedArrayView:
             if (!(child.m_type & ~SpecTypedArrayView)) {
@@ -2676,10 +2686,42 @@
         break;
     }
 
+    case CreateGenerator: {
+        JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
+        if (JSValue base = forNode(node->child1()).m_value) {
+            if (auto* function = jsDynamicCast<JSFunction*>(m_graph.m_vm, base)) {
+                if (FunctionRareData* rareData = function->rareData()) {
+                    if (rareData->allocationProfileWatchpointSet().isStillValid()) {
+                        Structure* structure = rareData->internalFunctionAllocationStructure();
+                        if (structure
+                            && structure->classInfo() == JSGenerator::info()
+                            && structure->globalObject() == globalObject
+                            && rareData->allocationProfileWatchpointSet().isStillValid()) {
+                            m_graph.freeze(rareData);
+                            m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
+                            m_state.setFoundConstants(true);
+                            didFoldClobberWorld();
+                            setForNode(node, structure);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        clobberWorld();
+        setTypeForNode(node, SpecObjectOther);
+        break;
+    }
+
     case NewPromise:
         ASSERT(!!node->structure().get());
         setForNode(node, node->structure());
         break;
+
+    case NewGenerator:
+        ASSERT(!!node->structure().get());
+        setForNode(node, node->structure());
+        break;
         
     case NewObject:
         ASSERT(!!node->structure().get());
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index b17cdf8..f6a7d53 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -4850,8 +4850,6 @@
                             m_graph.freeze(rareData);
                             m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
                             
-                            // The callee is still live up to this point.
-                            addToGraph(Phantom, callee);
                             Node* object = addToGraph(NewObject, OpInfo(m_graph.registerStructure(structure)));
                             if (structure->hasPolyProto()) {
                                 StorageAccessData* data = m_graph.m_storageAccessData.add();
@@ -4861,6 +4859,8 @@
                                 addToGraph(PutByOffset, OpInfo(data), object, object, weakJSConstant(prototype));
                             }
                             set(VirtualRegister(bytecode.m_dst), object);
+                            // The callee is still live up to this point.
+                            addToGraph(Phantom, callee);
                             alreadyEmitted = true;
                         }
                     }
@@ -4930,9 +4930,9 @@
                                 m_graph.freeze(rareData);
                                 m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
 
+                                set(VirtualRegister(bytecode.m_dst), addToGraph(NewPromise, OpInfo(m_graph.registerStructure(structure)), OpInfo(bytecode.m_isInternalPromise)));
                                 // The callee is still live up to this point.
                                 addToGraph(Phantom, callee);
-                                set(VirtualRegister(bytecode.m_dst), addToGraph(NewPromise, OpInfo(m_graph.registerStructure(structure)), OpInfo(bytecode.m_isInternalPromise)));
                                 alreadyEmitted = true;
                             }
                         }
@@ -4944,6 +4944,52 @@
             NEXT_OPCODE(op_create_promise);
         }
 
+        case op_create_generator: {
+            JSGlobalObject* globalObject = m_graph.globalObjectFor(currentNodeOrigin().semantic);
+            auto bytecode = currentInstruction->as<OpCreateGenerator>();
+            Node* callee = get(VirtualRegister(bytecode.m_callee));
+
+            bool alreadyEmitted = false;
+
+            JSFunction* function = callee->dynamicCastConstant<JSFunction*>(*m_vm);
+            if (!function) {
+                JSCell* cachedFunction = bytecode.metadata(codeBlock).m_cachedCallee.unvalidatedGet();
+                if (cachedFunction
+                    && cachedFunction != JSCell::seenMultipleCalleeObjects()
+                    && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell)) {
+                    ASSERT(cachedFunction->inherits<JSFunction>(*m_vm));
+
+                    FrozenValue* frozen = m_graph.freeze(cachedFunction);
+                    addToGraph(CheckCell, OpInfo(frozen), callee);
+
+                    function = static_cast<JSFunction*>(cachedFunction);
+                }
+            }
+
+            if (function) {
+                if (FunctionRareData* rareData = function->rareData()) {
+                    if (rareData->allocationProfileWatchpointSet().isStillValid()) {
+                        Structure* structure = rareData->internalFunctionAllocationStructure();
+                        if (structure
+                            && structure->classInfo() == JSGenerator::info()
+                            && structure->globalObject() == globalObject
+                            && rareData->allocationProfileWatchpointSet().isStillValid()) {
+                            m_graph.freeze(rareData);
+                            m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
+
+                            set(VirtualRegister(bytecode.m_dst), addToGraph(NewGenerator, OpInfo(m_graph.registerStructure(structure))));
+                            // The callee is still live up to this point.
+                            addToGraph(Phantom, callee);
+                            alreadyEmitted = true;
+                        }
+                    }
+                }
+            }
+            if (!alreadyEmitted)
+                set(VirtualRegister(bytecode.m_dst), addToGraph(CreateGenerator, callee));
+            NEXT_OPCODE(op_create_generator);
+        }
+
         case op_new_object: {
             auto bytecode = currentInstruction->as<OpNewObject>();
             set(bytecode.m_dst,
@@ -4958,6 +5004,13 @@
             set(bytecode.m_dst, addToGraph(NewPromise, OpInfo(m_graph.registerStructure(bytecode.m_isInternalPromise ? globalObject->internalPromiseStructure() : globalObject->promiseStructure())), OpInfo(bytecode.m_isInternalPromise)));
             NEXT_OPCODE(op_new_promise);
         }
+
+        case op_new_generator: {
+            auto bytecode = currentInstruction->as<OpNewGenerator>();
+            JSGlobalObject* globalObject = m_graph.globalObjectFor(currentNodeOrigin().semantic);
+            set(bytecode.m_dst, addToGraph(NewGenerator, OpInfo(m_graph.registerStructure(globalObject->generatorStructure()))));
+            NEXT_OPCODE(op_new_generator);
+        }
             
         case op_new_array: {
             auto bytecode = currentInstruction->as<OpNewArray>();
diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
index c0ee98a..71ec7f1 100644
--- a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
@@ -117,6 +117,7 @@
     case op_check_tdz:
     case op_create_this:
     case op_create_promise:
+    case op_create_generator:
     case op_bitnot:
     case op_bitand:
     case op_bitor:
@@ -212,6 +213,7 @@
     case op_end:
     case op_new_object:
     case op_new_promise:
+    case op_new_generator:
     case op_new_array:
     case op_new_array_with_size:
     case op_new_array_buffer:
diff --git a/Source/JavaScriptCore/dfg/DFGClobberize.h b/Source/JavaScriptCore/dfg/DFGClobberize.h
index 303f479..9a8ad07 100644
--- a/Source/JavaScriptCore/dfg/DFGClobberize.h
+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h
@@ -668,6 +668,7 @@
     case NumberToStringWithRadix:
     case CreateThis:
     case CreatePromise:
+    case CreateGenerator:
     case InstanceOf:
     case StringValueOf:
     case ObjectKeys:
@@ -1566,6 +1567,7 @@
 
     case NewObject:
     case NewPromise:
+    case NewGenerator:
     case NewRegexp:
     case NewSymbol:
     case NewStringObject:
diff --git a/Source/JavaScriptCore/dfg/DFGClobbersExitState.cpp b/Source/JavaScriptCore/dfg/DFGClobbersExitState.cpp
index 370fd1d..d2f7ba4 100644
--- a/Source/JavaScriptCore/dfg/DFGClobbersExitState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGClobbersExitState.cpp
@@ -58,6 +58,7 @@
     case Arrayify:
     case NewObject:
     case NewPromise:
+    case NewGenerator:
     case NewRegexp:
     case NewSymbol:
     case NewStringObject:
diff --git a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
index 99d875e..f3f5cb6 100644
--- a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
@@ -778,6 +778,30 @@
                 break;
             }
 
+            case CreateGenerator: {
+                JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
+                if (JSValue base = m_state.forNode(node->child1()).m_value) {
+                    if (auto* function = jsDynamicCast<JSFunction*>(m_graph.m_vm, base)) {
+                        if (FunctionRareData* rareData = function->rareData()) {
+                            if (rareData->allocationProfileWatchpointSet().isStillValid()) {
+                                Structure* structure = rareData->internalFunctionAllocationStructure();
+                                if (structure
+                                    && structure->classInfo() == JSGenerator::info()
+                                    && structure->globalObject() == globalObject
+                                    && rareData->allocationProfileWatchpointSet().isStillValid()) {
+                                    m_graph.freeze(rareData);
+                                    m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
+                                    node->convertToNewGenerator(m_graph.registerStructure(structure));
+                                    changed = true;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
+            }
+
             case ObjectCreate: {
                 if (JSValue base = m_state.forNode(node->child1()).m_value) {
                     JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
diff --git a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
index 4072f91..c9733d0 100644
--- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
@@ -333,6 +333,7 @@
     case TryGetById:
     case CreateThis:
     case CreatePromise:
+    case CreateGenerator:
     case ObjectCreate:
     case ObjectKeys:
     case AllocatePropertyStorage:
@@ -341,6 +342,7 @@
     case ArrayifyToStructure:
     case NewObject:
     case NewPromise:
+    case NewGenerator:
     case NewArray:
     case NewArrayWithSpread:
     case Spread:
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index ec040af..d064322 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -1647,6 +1647,7 @@
         case CheckCell:
         case CreateThis:
         case CreatePromise:
+        case CreateGenerator:
         case GetButterfly: {
             fixEdge<CellUse>(node->child1());
             break;
@@ -2404,6 +2405,7 @@
         case ProfileControlFlow:
         case NewObject:
         case NewPromise:
+        case NewGenerator:
         case NewRegexp:
         case DeleteById:
         case DeleteByVal:
@@ -2574,61 +2576,64 @@
 
     void fixupIsCellWithType(Node* node)
     {
-        switch (node->speculatedTypeForQuery()) {
-        case SpecString:
-            if (node->child1()->shouldSpeculateString()) {
-                m_insertionSet.insertNode(
-                    m_indexInBlock, SpecNone, Check, node->origin,
-                    Edge(node->child1().node(), StringUse));
-                m_graph.convertToConstant(node, jsBoolean(true));
-                observeUseKindOnNode<StringUse>(node);
-                return;
-            }
-            break;
+        Optional<SpeculatedType> filter = node->speculatedTypeForQuery();
+        if (filter) {
+            switch (filter.value()) {
+            case SpecString:
+                if (node->child1()->shouldSpeculateString()) {
+                    m_insertionSet.insertNode(
+                        m_indexInBlock, SpecNone, Check, node->origin,
+                        Edge(node->child1().node(), StringUse));
+                    m_graph.convertToConstant(node, jsBoolean(true));
+                    observeUseKindOnNode<StringUse>(node);
+                    return;
+                }
+                break;
 
-        case SpecProxyObject:
-            if (node->child1()->shouldSpeculateProxyObject()) {
-                m_insertionSet.insertNode(
-                    m_indexInBlock, SpecNone, Check, node->origin,
-                    Edge(node->child1().node(), ProxyObjectUse));
-                m_graph.convertToConstant(node, jsBoolean(true));
-                observeUseKindOnNode<ProxyObjectUse>(node);
-                return;
-            }
-            break;
+            case SpecProxyObject:
+                if (node->child1()->shouldSpeculateProxyObject()) {
+                    m_insertionSet.insertNode(
+                        m_indexInBlock, SpecNone, Check, node->origin,
+                        Edge(node->child1().node(), ProxyObjectUse));
+                    m_graph.convertToConstant(node, jsBoolean(true));
+                    observeUseKindOnNode<ProxyObjectUse>(node);
+                    return;
+                }
+                break;
 
-        case SpecRegExpObject:
-            if (node->child1()->shouldSpeculateRegExpObject()) {
-                m_insertionSet.insertNode(
-                    m_indexInBlock, SpecNone, Check, node->origin,
-                    Edge(node->child1().node(), RegExpObjectUse));
-                m_graph.convertToConstant(node, jsBoolean(true));
-                observeUseKindOnNode<RegExpObjectUse>(node);
-                return;
-            }
-            break;
+            case SpecRegExpObject:
+                if (node->child1()->shouldSpeculateRegExpObject()) {
+                    m_insertionSet.insertNode(
+                        m_indexInBlock, SpecNone, Check, node->origin,
+                        Edge(node->child1().node(), RegExpObjectUse));
+                    m_graph.convertToConstant(node, jsBoolean(true));
+                    observeUseKindOnNode<RegExpObjectUse>(node);
+                    return;
+                }
+                break;
 
-        case SpecArray:
-            if (node->child1()->shouldSpeculateArray()) {
-                m_insertionSet.insertNode(
-                    m_indexInBlock, SpecNone, Check, node->origin,
-                    Edge(node->child1().node(), ArrayUse));
-                m_graph.convertToConstant(node, jsBoolean(true));
-                observeUseKindOnNode<ArrayUse>(node);
-                return;
-            }
-            break;
+            case SpecArray:
+                if (node->child1()->shouldSpeculateArray()) {
+                    m_insertionSet.insertNode(
+                        m_indexInBlock, SpecNone, Check, node->origin,
+                        Edge(node->child1().node(), ArrayUse));
+                    m_graph.convertToConstant(node, jsBoolean(true));
+                    observeUseKindOnNode<ArrayUse>(node);
+                    return;
+                }
+                break;
 
-        case SpecDerivedArray:
-            if (node->child1()->shouldSpeculateDerivedArray()) {
-                m_insertionSet.insertNode(
-                    m_indexInBlock, SpecNone, Check, node->origin,
-                    Edge(node->child1().node(), DerivedArrayUse));
-                m_graph.convertToConstant(node, jsBoolean(true));
-                observeUseKindOnNode<DerivedArrayUse>(node);
-                return;
+            case SpecDerivedArray:
+                if (node->child1()->shouldSpeculateDerivedArray()) {
+                    m_insertionSet.insertNode(
+                        m_indexInBlock, SpecNone, Check, node->origin,
+                        Edge(node->child1().node(), DerivedArrayUse));
+                    m_graph.convertToConstant(node, jsBoolean(true));
+                    observeUseKindOnNode<DerivedArrayUse>(node);
+                    return;
+                }
+                break;
             }
-            break;
         }
 
         if (node->child1()->shouldSpeculateCell()) {
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index ab8ab42..a594cf0 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -281,8 +281,8 @@
             }
         }
     }
-    if (node->hasSpeculatedTypeForQuery())
-        out.print(comma, SpeculationDump(node->speculatedTypeForQuery()));
+    if (node->hasQueriedType())
+        out.print(comma, node->queriedType());
     if (node->hasStorageAccessData()) {
         StorageAccessData& storageAccessData = node->storageAccessData();
         out.print(comma, "id", storageAccessData.identifierNumber, "{", identifiers()[storageAccessData.identifierNumber], "}");
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index 676df63..2d5524a 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -767,6 +767,15 @@
         m_opInfo2 = internal;
     }
 
+    void convertToNewGenerator(RegisteredStructure structure)
+    {
+        ASSERT(m_op == CreateGenerator);
+        setOpAndDefaultFlags(NewGenerator);
+        children.reset();
+        m_opInfo = structure;
+        m_opInfo2 = OpInfoWrapper();
+    }
+
     void convertToNewArrayBuffer(FrozenValue* immutableButterfly);
     
     void convertToDirectCall(FrozenValue*);
@@ -1372,7 +1381,7 @@
         return op() == IsCellWithType;
     }
 
-    SpeculatedType speculatedTypeForQuery()
+    Optional<SpeculatedType> speculatedTypeForQuery()
     {
         return speculationFromJSType(queriedType());
     }
@@ -1909,6 +1918,7 @@
         case ArrayifyToStructure:
         case NewObject:
         case NewPromise:
+        case NewGenerator:
         case NewStringObject:
             return true;
         default:
diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h
index 2618520b..1ebdfd1 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeType.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h
@@ -54,6 +54,7 @@
     macro(ToThis, NodeResultJS) \
     macro(CreateThis, NodeResultJS) /* Note this is not MustGenerate since we're returning it anyway. */ \
     macro(CreatePromise, NodeResultJS | NodeMustGenerate) \
+    macro(CreateGenerator, NodeResultJS | NodeMustGenerate) \
     macro(GetCallee, NodeResultJS) \
     macro(SetCallee, NodeMustGenerate) \
     macro(GetArgumentCountIncludingThis, NodeResultInt32) \
@@ -341,6 +342,7 @@
     /* Allocations. */\
     macro(NewObject, NodeResultJS) \
     macro(NewPromise, NodeResultJS) \
+    macro(NewGenerator, NodeResultJS) \
     macro(NewArray, NodeResultJS | NodeHasVarArgs) \
     macro(NewArrayWithSpread, NodeResultJS | NodeHasVarArgs) \
     macro(NewArrayWithSize, NodeResultJS | NodeMustGenerate) \
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index afa2822..c315c26 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -398,6 +398,16 @@
     RELEASE_AND_RETURN(scope, JSInternalPromise::create(vm, structure));
 }
 
+JSCell* JIT_OPERATION operationCreateGenerator(ExecState* exec, JSObject* constructor, JSGlobalObject* globalObject)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(vm, exec);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+    Structure* structure = InternalFunction::createSubclassStructure(exec, nullptr, constructor, globalObject->generatorStructure());
+    RETURN_IF_EXCEPTION(scope, nullptr);
+    RELEASE_AND_RETURN(scope, JSGenerator::create(vm, structure));
+}
+
 JSCell* JIT_OPERATION operationCallObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget)
 {
     VM& vm = exec->vm();
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h
index b98e621..744a50d 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.h
+++ b/Source/JavaScriptCore/dfg/DFGOperations.h
@@ -50,6 +50,7 @@
 JSCell* JIT_OPERATION operationCreateThis(ExecState*, JSObject* constructor, uint32_t inlineCapacity) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationCreatePromise(ExecState*, JSObject* constructor, JSGlobalObject*) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationCreateInternalPromise(ExecState*, JSObject* constructor, JSGlobalObject*) WTF_INTERNAL;
+JSCell* JIT_OPERATION operationCreateGenerator(ExecState*, JSObject* constructor, JSGlobalObject*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationToThis(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueMod(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index 00ac55c..c3d921c 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -1015,6 +1015,11 @@
         case NewPromise:
             setPrediction(SpecPromiseObject);
             break;
+
+        case CreateGenerator:
+        case NewGenerator:
+            setPrediction(SpecObjectOther);
+            break;
             
         case ArraySlice:
         case NewArrayWithSpread:
diff --git a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
index 6837e23..7d8eee84 100644
--- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
+++ b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
@@ -179,6 +179,7 @@
     case ToThis:
     case CreateThis:
     case CreatePromise:
+    case CreateGenerator:
     case ObjectCreate:
     case ObjectKeys:
     case GetCallee:
@@ -321,6 +322,7 @@
     case ConstructForwardVarargs:
     case NewObject:
     case NewPromise:
+    case NewGenerator:
     case NewArray:
     case NewArrayWithSize:
     case NewArrayBuffer:
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 9b4246f..1cf76ce 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -12722,6 +12722,7 @@
     m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfRareData()), rareDataGPR);
     slowCases.append(m_jit.branchTestPtr(MacroAssembler::Zero, rareDataGPR));
     m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure()), structureGPR);
+    slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, structureGPR));
     m_jit.move(TrustedImmPtr(node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info()), scratch1GPR);
     slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset())));
     m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), scratch1GPR);
@@ -12742,6 +12743,51 @@
     cellResult(resultGPR, node);
 }
 
+void SpeculativeJIT::compileCreateGenerator(Node* node)
+{
+    JSGlobalObject* globalObject = m_jit.globalObjectFor(node->origin.semantic);
+
+    SpeculateCellOperand callee(this, node->child1());
+    GPRTemporary result(this);
+    GPRTemporary structure(this);
+    GPRTemporary scratch1(this);
+    GPRTemporary scratch2(this);
+
+    GPRReg calleeGPR = callee.gpr();
+    GPRReg resultGPR = result.gpr();
+    GPRReg structureGPR = structure.gpr();
+    GPRReg scratch1GPR = scratch1.gpr();
+    GPRReg scratch2GPR = scratch2.gpr();
+    // Rare data is only used to access the allocator & structure
+    // We can avoid using an additional GPR this way
+    GPRReg rareDataGPR = structureGPR;
+
+    MacroAssembler::JumpList slowCases;
+
+    slowCases.append(m_jit.branchIfNotFunction(calleeGPR));
+    m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfRareData()), rareDataGPR);
+    slowCases.append(m_jit.branchTestPtr(MacroAssembler::Zero, rareDataGPR));
+    m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure()), structureGPR);
+    slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, structureGPR));
+    m_jit.move(TrustedImmPtr(JSGenerator::info()), scratch1GPR);
+    slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset())));
+    m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), scratch1GPR);
+    slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::globalObjectOffset())));
+
+    auto butterfly = TrustedImmPtr(nullptr);
+    emitAllocateJSObjectWithKnownSize<JSGenerator>(resultGPR, structureGPR, butterfly, scratch1GPR, scratch2GPR, slowCases, sizeof(JSGenerator));
+    m_jit.storeTrustedValue(jsNull(), CCallHelpers::Address(resultGPR, JSInternalFieldObjectImpl<>::offsetOfInternalField(static_cast<unsigned>(JSGenerator::Field::PolyProto))));
+    m_jit.storeTrustedValue(jsNumber(static_cast<int32_t>(JSGenerator::GeneratorState::Init)), CCallHelpers::Address(resultGPR, JSInternalFieldObjectImpl<>::offsetOfInternalField(static_cast<unsigned>(JSGenerator::Field::State))));
+    m_jit.storeTrustedValue(jsUndefined(), CCallHelpers::Address(resultGPR, JSInternalFieldObjectImpl<>::offsetOfInternalField(static_cast<unsigned>(JSGenerator::Field::Next))));
+    m_jit.storeTrustedValue(jsUndefined(), CCallHelpers::Address(resultGPR, JSInternalFieldObjectImpl<>::offsetOfInternalField(static_cast<unsigned>(JSGenerator::Field::This))));
+    m_jit.storeTrustedValue(jsUndefined(), CCallHelpers::Address(resultGPR, JSInternalFieldObjectImpl<>::offsetOfInternalField(static_cast<unsigned>(JSGenerator::Field::Frame))));
+    m_jit.mutatorFence(m_jit.vm());
+
+    addSlowPathGenerator(slowPathCall(slowCases, this, operationCreateGenerator, resultGPR, calleeGPR, TrustedImmPtr::weakPointer(m_jit.graph(), globalObject)));
+
+    cellResult(resultGPR, node);
+}
+
 void SpeculativeJIT::compileNewObject(Node* node)
 {
     GPRTemporary result(this);
@@ -12798,6 +12844,33 @@
     cellResult(resultGPR, node);
 }
 
+void SpeculativeJIT::compileNewGenerator(Node* node)
+{
+    GPRTemporary result(this);
+    GPRTemporary scratch1(this);
+    GPRTemporary scratch2(this);
+
+    GPRReg resultGPR = result.gpr();
+    GPRReg scratch1GPR = scratch1.gpr();
+    GPRReg scratch2GPR = scratch2.gpr();
+
+    MacroAssembler::JumpList slowCases;
+
+    FrozenValue* structure = m_graph.freezeStrong(node->structure().get());
+    auto butterfly = TrustedImmPtr(nullptr);
+    emitAllocateJSObjectWithKnownSize<JSGenerator>(resultGPR, TrustedImmPtr(structure), butterfly, scratch1GPR, scratch2GPR, slowCases, sizeof(JSGenerator));
+    m_jit.storeTrustedValue(jsNull(), CCallHelpers::Address(resultGPR, JSInternalFieldObjectImpl<>::offsetOfInternalField(static_cast<unsigned>(JSGenerator::Field::PolyProto))));
+    m_jit.storeTrustedValue(jsNumber(static_cast<int32_t>(JSGenerator::GeneratorState::Init)), CCallHelpers::Address(resultGPR, JSInternalFieldObjectImpl<>::offsetOfInternalField(static_cast<unsigned>(JSGenerator::Field::State))));
+    m_jit.storeTrustedValue(jsUndefined(), CCallHelpers::Address(resultGPR, JSInternalFieldObjectImpl<>::offsetOfInternalField(static_cast<unsigned>(JSGenerator::Field::Next))));
+    m_jit.storeTrustedValue(jsUndefined(), CCallHelpers::Address(resultGPR, JSInternalFieldObjectImpl<>::offsetOfInternalField(static_cast<unsigned>(JSGenerator::Field::This))));
+    m_jit.storeTrustedValue(jsUndefined(), CCallHelpers::Address(resultGPR, JSInternalFieldObjectImpl<>::offsetOfInternalField(static_cast<unsigned>(JSGenerator::Field::Frame))));
+    m_jit.mutatorFence(m_jit.vm());
+
+    addSlowPathGenerator(slowPathCall(slowCases, this, operationNewGenerator, resultGPR, TrustedImmPtr(structure)));
+
+    cellResult(resultGPR, node);
+}
+
 void SpeculativeJIT::compileToPrimitive(Node* node)
 {
     DFG_ASSERT(m_jit.graph(), node, node->child1().useKind() == UntypedUse, node->child1().useKind());
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index c8354a1..2d322d4 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -1474,8 +1474,10 @@
     void compileObjectCreate(Node*);
     void compileCreateThis(Node*);
     void compileCreatePromise(Node*);
+    void compileCreateGenerator(Node*);
     void compileNewObject(Node*);
     void compileNewPromise(Node*);
+    void compileNewGenerator(Node*);
     void compileToPrimitive(Node*);
     void compileLogShadowChickenPrologue(Node*);
     void compileLogShadowChickenTail(Node*);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index e9e9291..a6d46a5 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -3157,6 +3157,11 @@
         break;
     }
 
+    case CreateGenerator: {
+        compileCreateGenerator(node);
+        break;
+    }
+
     case NewObject: {
         compileNewObject(node);
         break;
@@ -3167,6 +3172,11 @@
         break;
     }
 
+    case NewGenerator: {
+        compileNewGenerator(node);
+        break;
+    }
+
     case GetCallee: {
         compileGetCallee(node);
         break;
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index eec210e..3733843 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -3483,6 +3483,11 @@
         compileCreatePromise(node);
         break;
     }
+
+    case CreateGenerator: {
+        compileCreateGenerator(node);
+        break;
+    }
         
     case NewObject: {
         compileNewObject(node);
@@ -3494,6 +3499,11 @@
         break;
     }
 
+    case NewGenerator: {
+        compileNewGenerator(node);
+        break;
+    }
+
     case GetCallee: {
         compileGetCallee(node);
         break;
diff --git a/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp b/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp
index 5d20c9e..54917db 100644
--- a/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp
@@ -322,6 +322,7 @@
             switch (m_node->op()) {
             case NewObject:
             case NewPromise:
+            case NewGenerator:
             case NewArray:
             case NewArrayWithSize:
             case NewArrayBuffer:
diff --git a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
index 1989478..ead259a 100644
--- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
+++ b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
@@ -75,6 +75,7 @@
     case GetButterfly:
     case NewObject:
     case NewPromise:
+    case NewGenerator:
     case NewStringObject:
     case NewSymbol:
     case NewArray:
@@ -380,6 +381,7 @@
     case FilterInByIdStatus:
     case CreateThis:
     case CreatePromise:
+    case CreateGenerator:
     case DataViewGetInt:
     case DataViewGetFloat:
     case DataViewSet:
diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
index 1e1dc7a..8b9b58a 100644
--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
@@ -78,6 +78,7 @@
 #include "JSAsyncFunction.h"
 #include "JSAsyncGeneratorFunction.h"
 #include "JSCInlines.h"
+#include "JSGenerator.h"
 #include "JSGeneratorFunction.h"
 #include "JSImmutableButterfly.h"
 #include "JSLexicalEnvironment.h"
@@ -1048,6 +1049,9 @@
         case NewPromise:
             compileNewPromise();
             break;
+        case NewGenerator:
+            compileNewGenerator();
+            break;
         case NewStringObject:
             compileNewStringObject();
             break;
@@ -1066,6 +1070,9 @@
         case CreatePromise:
             compileCreatePromise();
             break;
+        case CreateGenerator:
+            compileCreateGenerator();
+            break;
         case Spread:
             compileSpread();
             break;
@@ -5912,6 +5919,31 @@
         setJSValue(m_out.phi(pointerType(), fastResult, slowResult));
     }
 
+    void compileNewGenerator()
+    {
+        LBasicBlock slowCase = m_out.newBlock();
+        LBasicBlock continuation = m_out.newBlock();
+
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowCase);
+
+        LValue generator = allocateObject<JSGenerator>(m_node->structure(), m_out.intPtrZero, slowCase);
+        m_out.store64(m_out.constInt64(JSValue::encode(jsNull())), generator, m_heaps.JSInternalFieldObjectImpl_internalFields[static_cast<unsigned>(JSGenerator::Field::PolyProto)]);
+        m_out.store64(m_out.constInt64(JSValue::encode(jsNumber(static_cast<int32_t>(JSGenerator::GeneratorState::Init)))), generator, m_heaps.JSInternalFieldObjectImpl_internalFields[static_cast<unsigned>(JSGenerator::Field::State)]);
+        m_out.store64(m_out.constInt64(JSValue::encode(jsUndefined())), generator, m_heaps.JSInternalFieldObjectImpl_internalFields[static_cast<unsigned>(JSGenerator::Field::Next)]);
+        m_out.store64(m_out.constInt64(JSValue::encode(jsUndefined())), generator, m_heaps.JSInternalFieldObjectImpl_internalFields[static_cast<unsigned>(JSGenerator::Field::This)]);
+        m_out.store64(m_out.constInt64(JSValue::encode(jsUndefined())), generator, m_heaps.JSInternalFieldObjectImpl_internalFields[static_cast<unsigned>(JSGenerator::Field::Frame)]);
+        mutatorFence();
+        ValueFromBlock fastResult = m_out.anchor(generator);
+        m_out.jump(continuation);
+
+        m_out.appendTo(slowCase, continuation);
+        ValueFromBlock slowResult = m_out.anchor(vmCall(pointerType(), m_out.operation(operationNewGenerator), m_callFrame, frozenPointer(m_graph.freezeStrong(m_node->structure().get()))));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        setJSValue(m_out.phi(pointerType(), fastResult, slowResult));
+    }
+
     void compileNewStringObject()
     {
         RegisteredStructure structure = m_node->structure();
@@ -6279,6 +6311,7 @@
         LBasicBlock derivedCase = m_out.newBlock();
         LBasicBlock isFunctionBlock = m_out.newBlock();
         LBasicBlock hasRareData = m_out.newBlock();
+        LBasicBlock hasStructure = m_out.newBlock();
         LBasicBlock checkGlobalObjectCase = m_out.newBlock();
         LBasicBlock fastAllocationCase = m_out.newBlock();
         LBasicBlock slowCase = m_out.newBlock();
@@ -6294,8 +6327,11 @@
         LValue rareData = m_out.loadPtr(callee, m_heaps.JSFunction_rareData);
         m_out.branch(m_out.isZero64(rareData), rarely(slowCase), usually(hasRareData));
 
-        m_out.appendTo(hasRareData, fastAllocationCase);
+        m_out.appendTo(hasRareData, hasStructure);
         LValue structure = m_out.loadPtr(rareData, m_heaps.FunctionRareData_internalFunctionAllocationProfile_structure);
+        m_out.branch(m_out.isZero64(structure), rarely(slowCase), usually(hasStructure));
+
+        m_out.appendTo(hasStructure, checkGlobalObjectCase);
         m_out.branch(m_out.equal(m_out.loadPtr(structure, m_heaps.Structure_classInfo), m_out.constIntPtr(m_node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info())), usually(checkGlobalObjectCase), rarely(slowCase));
 
         m_out.appendTo(checkGlobalObjectCase, fastAllocationCase);
@@ -6324,6 +6360,57 @@
         setJSValue(result);
     }
 
+    void compileCreateGenerator()
+    {
+        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
+
+        LValue callee = lowCell(m_node->child1());
+
+        LBasicBlock isFunctionBlock = m_out.newBlock();
+        LBasicBlock hasRareData = m_out.newBlock();
+        LBasicBlock hasStructure = m_out.newBlock();
+        LBasicBlock checkGlobalObjectCase = m_out.newBlock();
+        LBasicBlock fastAllocationCase = m_out.newBlock();
+        LBasicBlock slowCase = m_out.newBlock();
+        LBasicBlock continuation = m_out.newBlock();
+
+        m_out.branch(isFunction(callee, provenType(m_node->child1())), usually(isFunctionBlock), rarely(slowCase));
+
+        LBasicBlock lastNext = m_out.appendTo(isFunctionBlock, hasRareData);
+        LValue rareData = m_out.loadPtr(callee, m_heaps.JSFunction_rareData);
+        m_out.branch(m_out.isZero64(rareData), rarely(slowCase), usually(hasRareData));
+
+        m_out.appendTo(hasRareData, hasStructure);
+        LValue structure = m_out.loadPtr(rareData, m_heaps.FunctionRareData_internalFunctionAllocationProfile_structure);
+        m_out.branch(m_out.isZero64(structure), rarely(slowCase), usually(hasStructure));
+
+        m_out.appendTo(hasStructure, checkGlobalObjectCase);
+        m_out.branch(m_out.equal(m_out.loadPtr(structure, m_heaps.Structure_classInfo), m_out.constIntPtr(JSGenerator::info())), usually(checkGlobalObjectCase), rarely(slowCase));
+
+        m_out.appendTo(checkGlobalObjectCase, fastAllocationCase);
+        m_out.branch(m_out.equal(m_out.loadPtr(structure, m_heaps.Structure_globalObject), weakPointer(globalObject)), usually(fastAllocationCase), rarely(slowCase));
+
+        m_out.appendTo(fastAllocationCase, slowCase);
+        LValue generator = allocateObject<JSGenerator>(structure, m_out.intPtrZero, slowCase);
+        m_out.store64(m_out.constInt64(JSValue::encode(jsNull())), generator, m_heaps.JSInternalFieldObjectImpl_internalFields[static_cast<unsigned>(JSGenerator::Field::PolyProto)]);
+        m_out.store64(m_out.constInt64(JSValue::encode(jsNumber(static_cast<int32_t>(JSGenerator::GeneratorState::Init)))), generator, m_heaps.JSInternalFieldObjectImpl_internalFields[static_cast<unsigned>(JSGenerator::Field::State)]);
+        m_out.store64(m_out.constInt64(JSValue::encode(jsUndefined())), generator, m_heaps.JSInternalFieldObjectImpl_internalFields[static_cast<unsigned>(JSGenerator::Field::Next)]);
+        m_out.store64(m_out.constInt64(JSValue::encode(jsUndefined())), generator, m_heaps.JSInternalFieldObjectImpl_internalFields[static_cast<unsigned>(JSGenerator::Field::This)]);
+        m_out.store64(m_out.constInt64(JSValue::encode(jsUndefined())), generator, m_heaps.JSInternalFieldObjectImpl_internalFields[static_cast<unsigned>(JSGenerator::Field::Frame)]);
+        mutatorFence();
+        ValueFromBlock fastResult = m_out.anchor(generator);
+        m_out.jump(continuation);
+
+        m_out.appendTo(slowCase, continuation);
+        ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationCreateGenerator), m_callFrame, callee, weakPointer(globalObject)));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        LValue result = m_out.phi(Int64, fastResult, slowResult);
+
+        setJSValue(result);
+    }
+
     void compileSpread()
     {
         if (m_node->child1()->op() == PhantomNewArrayBuffer) {
@@ -16101,10 +16188,12 @@
         jsValueToStrictInt52(edge, lowJSValue(edge, ManualOperandSpeculation));
     }
 
-    LValue isCellWithType(LValue cell, JSType queriedType, SpeculatedType speculatedTypeForQuery, SpeculatedType type = SpecFullTop)
+    LValue isCellWithType(LValue cell, JSType queriedType, Optional<SpeculatedType> speculatedTypeForQuery, SpeculatedType type = SpecFullTop)
     {
-        if (LValue proven = isProvenValue(type & SpecCell, speculatedTypeForQuery))
-            return proven;
+        if (speculatedTypeForQuery) {
+            if (LValue proven = isProvenValue(type & SpecCell, speculatedTypeForQuery.value()))
+                return proven;
+        }
         return m_out.equal(
             m_out.load8ZeroExt32(cell, m_heaps.JSCell_typeInfoType),
             m_out.constInt32(queriedType));
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index b167f1c..bbfcfe3 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -312,6 +312,8 @@
         DEFINE_SLOW_OP(create_rest)
         DEFINE_SLOW_OP(create_promise)
         DEFINE_SLOW_OP(new_promise)
+        DEFINE_SLOW_OP(create_generator)
+        DEFINE_SLOW_OP(new_generator)
         DEFINE_SLOW_OP(pow)
 
         DEFINE_OP(op_add)
@@ -580,6 +582,7 @@
         DEFINE_SLOWCASE_SLOW_OP(div)
         DEFINE_SLOWCASE_SLOW_OP(create_this)
         DEFINE_SLOWCASE_SLOW_OP(create_promise)
+        DEFINE_SLOWCASE_SLOW_OP(create_generator)
         DEFINE_SLOWCASE_SLOW_OP(to_this)
         DEFINE_SLOWCASE_SLOW_OP(to_primitive)
         DEFINE_SLOWCASE_SLOW_OP(to_number)
diff --git a/Source/JavaScriptCore/jit/JITOperations.cpp b/Source/JavaScriptCore/jit/JITOperations.cpp
index 7af4ee3..efa254c 100644
--- a/Source/JavaScriptCore/jit/JITOperations.cpp
+++ b/Source/JavaScriptCore/jit/JITOperations.cpp
@@ -1394,6 +1394,14 @@
     return JSInternalPromise::create(vm, structure);
 }
 
+JSCell* JIT_OPERATION operationNewGenerator(ExecState* exec, Structure* structure)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(vm, exec);
+
+    return JSGenerator::create(vm, structure);
+}
+
 JSCell* JIT_OPERATION operationNewRegexp(ExecState* exec, JSCell* regexpPtr)
 {
     SuperSamplerScope superSamplerScope(false);
diff --git a/Source/JavaScriptCore/jit/JITOperations.h b/Source/JavaScriptCore/jit/JITOperations.h
index 1c3c272..1b749b2 100644
--- a/Source/JavaScriptCore/jit/JITOperations.h
+++ b/Source/JavaScriptCore/jit/JITOperations.h
@@ -421,6 +421,7 @@
 JSCell* JIT_OPERATION operationNewObject(ExecState*, Structure*) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationNewPromise(ExecState*, Structure*) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationNewInternalPromise(ExecState*, Structure*) WTF_INTERNAL;
+JSCell* JIT_OPERATION operationNewGenerator(ExecState*, Structure*) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationNewRegexp(ExecState*, JSCell*) WTF_INTERNAL;
 UnusedPtr JIT_OPERATION operationHandleTraps(ExecState*) WTF_INTERNAL;
 void JIT_OPERATION operationThrow(ExecState*, EncodedJSValue) WTF_INTERNAL;
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
index 40758e7..369cb10 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -1243,7 +1243,6 @@
     int dst = bytecode.m_dst.offset();
     int base = bytecode.m_base.offset();
     unsigned index = bytecode.m_index;
-    ASSERT(index < JSPromise::numberOfInternalFields);
 
     emitGetVirtualRegister(base, regT1);
     loadPtr(Address(regT1, JSInternalFieldObjectImpl<>::offsetOfInternalField(index)), regT0);
@@ -1258,7 +1257,6 @@
     int base = bytecode.m_base.offset();
     int value = bytecode.m_value.offset();
     unsigned index = bytecode.m_index;
-    ASSERT(index < JSPromise::numberOfInternalFields);
 
     emitGetVirtualRegister(base, regT0);
     emitGetVirtualRegister(value, regT1);
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index d204b40..2576ef4 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -1495,6 +1495,7 @@
 slowPathOp(create_scoped_arguments)
 slowPathOp(create_this)
 slowPathOp(create_promise)
+slowPathOp(create_generator)
 slowPathOp(define_accessor_property)
 slowPathOp(define_data_property)
 slowPathOp(enumerator_generic_pname)
@@ -1530,6 +1531,7 @@
 slowPathOp(typeof)
 slowPathOp(unreachable)
 slowPathOp(new_promise)
+slowPathOp(new_generator)
 
 macro llintSlowPathOp(opcodeName)
     llintOp(op_%opcodeName%, unused, macro (unused, unused, dispatch)
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
index 6586579..1123d17 100644
--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
@@ -309,6 +309,36 @@
     RETURN(result);
 }
 
+SLOW_PATH_DECL(slow_path_create_generator)
+{
+    BEGIN();
+    auto bytecode = pc->as<OpCreateGenerator>();
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    JSObject* constructorAsObject = asObject(GET(bytecode.m_callee).jsValue());
+
+    Structure* structure = InternalFunction::createSubclassStructure(exec, nullptr, constructorAsObject, globalObject->generatorStructure());
+    CHECK_EXCEPTION();
+    JSGenerator* result = JSGenerator::create(vm, structure);
+
+    JSFunction* constructor = jsDynamicCast<JSFunction*>(vm, constructorAsObject);
+    if (constructor && constructor->canUseAllocationProfile()) {
+        WriteBarrier<JSCell>& cachedCallee = bytecode.metadata(exec).m_cachedCallee;
+        if (!cachedCallee)
+            cachedCallee.set(vm, exec->codeBlock(), constructor);
+        else if (cachedCallee.unvalidatedGet() != JSCell::seenMultipleCalleeObjects() && cachedCallee.get() != constructor)
+            cachedCallee.setWithoutWriteBarrier(JSCell::seenMultipleCalleeObjects());
+    }
+    RETURN(result);
+}
+
+SLOW_PATH_DECL(slow_path_new_generator)
+{
+    BEGIN();
+    auto bytecode = pc->as<OpNewGenerator>();
+    JSGenerator* result = JSGenerator::create(vm, exec->lexicalGlobalObject()->generatorStructure());
+    RETURN(result);
+}
+
 SLOW_PATH_DECL(slow_path_to_this)
 {
     BEGIN();
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.h b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
index 2fe75e6..7f90b14 100644
--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.h
+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
@@ -384,6 +384,7 @@
 SLOW_PATH_HIDDEN_DECL(slow_path_is_var_scope);
 SLOW_PATH_HIDDEN_DECL(slow_path_resolve_scope_for_hoisting_func_decl_in_eval);
 SLOW_PATH_HIDDEN_DECL(slow_path_create_promise);
+SLOW_PATH_HIDDEN_DECL(slow_path_create_generator);
 SLOW_PATH_HIDDEN_DECL(slow_path_create_rest);
 SLOW_PATH_HIDDEN_DECL(slow_path_get_by_id_with_this);
 SLOW_PATH_HIDDEN_DECL(slow_path_get_by_val_with_this);
@@ -393,6 +394,7 @@
 SLOW_PATH_HIDDEN_DECL(slow_path_define_accessor_property);
 SLOW_PATH_HIDDEN_DECL(slow_path_throw_static_error);
 SLOW_PATH_HIDDEN_DECL(slow_path_new_promise);
+SLOW_PATH_HIDDEN_DECL(slow_path_new_generator);
 SLOW_PATH_HIDDEN_DECL(slow_path_new_array_with_spread);
 SLOW_PATH_HIDDEN_DECL(slow_path_new_array_buffer);
 SLOW_PATH_HIDDEN_DECL(slow_path_spread);
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.cpp b/Source/JavaScriptCore/runtime/InternalFunction.cpp
index dd4a220..238e543 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.cpp
+++ b/Source/JavaScriptCore/runtime/InternalFunction.cpp
@@ -119,7 +119,6 @@
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
-    ASSERT(!newTarget || newTarget.isConstructor(vm));
 
     ASSERT(baseClass->hasMonoProto());
 
@@ -133,7 +132,7 @@
             return structure;
 
         // Note, Reflect.construct might cause the profile to churn but we don't care.
-        JSValue prototypeValue = newTarget.get(exec, vm.propertyNames->prototype);
+        JSValue prototypeValue = targetFunction->get(exec, vm.propertyNames->prototype);
         RETURN_IF_EXCEPTION(scope, nullptr);
         if (JSObject* prototype = jsDynamicCast<JSObject*>(vm, prototypeValue))
             return targetFunction->rareData(vm)->createInternalFunctionAllocationStructureFromBase(vm, globalObject, prototype, baseClass);
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.h b/Source/JavaScriptCore/runtime/InternalFunction.h
index e53fb48..abf01cc 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.h
+++ b/Source/JavaScriptCore/runtime/InternalFunction.h
@@ -102,8 +102,6 @@
 {
     // We allow newTarget == JSValue() because the API needs to be able to create classes without having a real JS frame.
     // Since we don't allow subclassing in the API we just treat newTarget == JSValue() as newTarget == exec->jsCallee()
-    ASSERT(!newTarget || newTarget.isConstructor(exec->vm()));
-
     if (newTarget && newTarget != baseCallee)
         return createSubclassStructureSlow(exec, newTarget, baseClass);
     return baseClass;
diff --git a/Source/JavaScriptCore/runtime/JSGenerator.cpp b/Source/JavaScriptCore/runtime/JSGenerator.cpp
new file mode 100644
index 0000000..758b707
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/JSGenerator.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSGenerator.h"
+
+#include "JSCInlines.h"
+#include "JSInternalFieldObjectImplInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSGenerator::s_info = { "Generator", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSGenerator) };
+
+JSGenerator* JSGenerator::create(VM& vm, Structure* structure)
+{
+    JSGenerator* generator = new (NotNull, allocateCell<JSGenerator>(vm.heap)) JSGenerator(vm, structure);
+    generator->finishCreation(vm);
+    return generator;
+}
+
+Structure* JSGenerator::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(JSGeneratorType, StructureFlags), info());
+}
+
+JSGenerator::JSGenerator(VM& vm, Structure* structure)
+    : Base(vm, structure)
+{
+}
+
+void JSGenerator::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    internalField(static_cast<unsigned>(Field::PolyProto)).set(vm, this, jsNull());
+    internalField(static_cast<unsigned>(Field::State)).set(vm, this, jsNumber(static_cast<int32_t>(GeneratorState::Init)));
+    internalField(static_cast<unsigned>(Field::Next)).set(vm, this, jsUndefined());
+    internalField(static_cast<unsigned>(Field::This)).set(vm, this, jsUndefined());
+    internalField(static_cast<unsigned>(Field::Frame)).set(vm, this, jsUndefined());
+}
+
+void JSGenerator::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    auto* thisObject = jsCast<JSGenerator*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSGenerator.h b/Source/JavaScriptCore/runtime/JSGenerator.h
new file mode 100644
index 0000000..7b44e77
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/JSGenerator.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSInternalFieldObjectImpl.h"
+
+namespace JSC {
+
+class JSGenerator final : public JSInternalFieldObjectImpl<5> {
+public:
+    using Base = JSInternalFieldObjectImpl<5>;
+
+    // JSGenerator has one inline storage slot, which is pointing internalField(0).
+    static size_t allocationSize(Checked<size_t> inlineCapacity)
+    {
+        ASSERT_UNUSED(inlineCapacity, inlineCapacity == 0U);
+        return sizeof(JSGenerator);
+    }
+
+    enum class GeneratorResumeMode : int32_t {
+        NormalMode = 0,
+        ReturnMode = 1,
+        ThrowMode = 2
+    };
+
+    enum class GeneratorState : int32_t {
+        Completed = -1,
+        Executing = -2,
+        Init = 0,
+    };
+
+    // [this], @generator, @generatorState, @generatorValue, @generatorResumeMode, @generatorFrame.
+    enum class GeneratorArgument : int32_t {
+        ThisValue = 0,
+        Generator = 1,
+        State = 2,
+        Value = 3,
+        ResumeMode = 4,
+        Frame = 5,
+    };
+
+    enum class Field : uint32_t {
+        // FIXME: JSGenerator should support PolyProto, since generator tends to be created with poly proto mode.
+        // We reserve the first internal field for PolyProto property. This offset is identical to JSFinalObject's first inline storage slot which will be used for PolyProto.
+        PolyProto = 0,
+        State,
+        Next,
+        This,
+        Frame,
+    };
+    static_assert(numberOfInternalFields == 5);
+
+    static JSGenerator* create(VM&, Structure*);
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
+
+    DECLARE_EXPORT_INFO;
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+protected:
+    JSGenerator(VM&, Structure*);
+    void finishCreation(VM&);
+};
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSGeneratorFunction.h b/Source/JavaScriptCore/runtime/JSGeneratorFunction.h
index a454b95..efd2890 100644
--- a/Source/JavaScriptCore/runtime/JSGeneratorFunction.h
+++ b/Source/JavaScriptCore/runtime/JSGeneratorFunction.h
@@ -41,28 +41,7 @@
 #endif
     friend class VM;
 public:
-    typedef JSFunction Base;
-
-    enum class GeneratorResumeMode : int32_t {
-        NormalMode = 0,
-        ReturnMode = 1,
-        ThrowMode = 2
-    };
-
-    enum class GeneratorState : int32_t {
-        Completed = -1,
-        Executing = -2,
-    };
-
-    // [this], @generator, @generatorState, @generatorValue, @generatorResumeMode, @generatorFrame.
-    enum class GeneratorArgument : int32_t {
-        ThisValue = 0,
-        Generator = 1,
-        State = 2,
-        Value = 3,
-        ResumeMode = 4,
-        Frame = 5,
-    };
+    using Base = JSFunction;
 
     const static unsigned StructureFlags = Base::StructureFlags;
 
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index aa73fc5..e87e0cb 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -819,6 +819,7 @@
 
     m_generatorPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, m_generatorFunctionPrototype.get(), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
     m_generatorFunctionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->prototype, m_generatorPrototype.get(), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
+    m_generatorStructure.set(vm, this, JSGenerator::createStructure(vm, this, m_generatorPrototype.get()));
 
     m_asyncFunctionPrototype.set(vm, this, AsyncFunctionPrototype::create(vm, AsyncFunctionPrototype::createStructure(vm, this, m_functionPrototype.get())));
     AsyncFunctionConstructor* asyncFunctionConstructor = AsyncFunctionConstructor::create(vm, AsyncFunctionConstructor::createStructure(vm, this, functionConstructor), m_asyncFunctionPrototype.get());
@@ -1767,6 +1768,7 @@
     visitor.append(thisObject->m_generatorFunctionStructure);
     visitor.append(thisObject->m_asyncFunctionStructure);
     visitor.append(thisObject->m_asyncGeneratorFunctionStructure);
+    visitor.append(thisObject->m_generatorStructure);
     thisObject->m_iteratorResultObjectStructure.visit(visitor);
     visitor.append(thisObject->m_regExpMatchesArrayStructure);
     visitor.append(thisObject->m_regExpMatchesArrayWithGroupsStructure);
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index c62315a..1d2bc2d 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -374,6 +374,7 @@
     WriteBarrier<Structure> m_asyncFunctionStructure;
     WriteBarrier<Structure> m_asyncGeneratorFunctionStructure;
     WriteBarrier<Structure> m_generatorFunctionStructure;
+    WriteBarrier<Structure> m_generatorStructure;
     LazyProperty<JSGlobalObject, Structure> m_iteratorResultObjectStructure;
     WriteBarrier<Structure> m_regExpMatchesArrayStructure;
     WriteBarrier<Structure> m_regExpMatchesArrayWithGroupsStructure;
@@ -752,6 +753,7 @@
     Structure* numberObjectStructure() const { return m_numberObjectStructure.get(this); }
     Structure* mapStructure() const { return m_mapStructure.get(); }
     Structure* regExpStructure() const { return m_regExpStructure.get(); }
+    Structure* generatorStructure() const { return m_generatorStructure.get(); }
     Structure* generatorFunctionStructure() const { return m_generatorFunctionStructure.get(); }
     Structure* asyncFunctionStructure() const { return m_asyncFunctionStructure.get(); }
     Structure* asyncGeneratorFunctionStructure() const { return m_asyncGeneratorFunctionStructure.get(); }
diff --git a/Source/JavaScriptCore/runtime/JSType.cpp b/Source/JavaScriptCore/runtime/JSType.cpp
index 849b379..dac5e69 100644
--- a/Source/JavaScriptCore/runtime/JSType.cpp
+++ b/Source/JavaScriptCore/runtime/JSType.cpp
@@ -96,6 +96,7 @@
     CASE(WithScopeType)
     CASE(RegExpObjectType)
     CASE(ProxyObjectType)
+    CASE(JSGeneratorType)
     CASE(JSPromiseType)
     CASE(JSMapType)
     CASE(JSSetType)
diff --git a/Source/JavaScriptCore/runtime/JSType.h b/Source/JavaScriptCore/runtime/JSType.h
index 8d35ac7..01e7022 100644
--- a/Source/JavaScriptCore/runtime/JSType.h
+++ b/Source/JavaScriptCore/runtime/JSType.h
@@ -108,6 +108,7 @@
 
     RegExpObjectType,
     ProxyObjectType,
+    JSGeneratorType,
     JSPromiseType,
     JSMapType,
     JSSetType,